<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/history/history_database.h"

#include <algorithm>
#include <set>
#include <string>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/metrics/histogram.h"
#include "base/rand_util.h"
#include "base/string_util.h"
#include "sql/transaction.h"

#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#endif

namespace history {

namespace {

// Current version number. We write databases at the "current" version number,
// but any previous version that can read the "compatible" one can make do with
// or database without *too* many bad effects.
static const int kCurrentVersionNumber = 23;
static const int kCompatibleVersionNumber = 16;
static const char kEarlyExpirationThresholdKey[] = "early_expiration_threshold";

// Key in the meta table used to determine if we need to migrate thumbnails out
// of history.
static const char kNeedsThumbnailMigrationKey[] = "needs_thumbnail_migration";

void ComputeDatabaseMetrics(const FilePath& history_name,
                            sql::Connection& db) {
  if (base::RandInt(1, 100) != 50)
    return;  // Only do this computation sometimes since it can be expensive.

  int64 file_size = 0;
  if (!file_util::GetFileSize(history_name, &file_size))
    return;
  int file_mb = static_cast<int>(file_size / (1024 * 1024));
  UMA_HISTOGRAM_MEMORY_MB("History.DatabaseFileMB", file_mb);

  sql::Statement url_count(db.GetUniqueStatement("SELECT count(*) FROM urls"));
  if (!url_count.Step())
    return;
  UMA_HISTOGRAM_COUNTS("History.URLTableCount", url_count.ColumnInt(0));

  sql::Statement visit_count(db.GetUniqueStatement(
      "SELECT count(*) FROM visits"));
  if (!visit_count.Step())
    return;
  UMA_HISTOGRAM_COUNTS("History.VisitTableCount", visit_count.ColumnInt(0));
}

}  // namespace

HistoryDatabase::HistoryDatabase()
    : needs_version_17_migration_(false) {
}

HistoryDatabase::~HistoryDatabase() {
}

sql::InitStatus HistoryDatabase::Init(const FilePath& history_name,
                                      sql::ErrorDelegate* error_delegate) {
  db_.set_error_histogram_name("Sqlite.History.Error");

  // Set the exceptional sqlite error handler.
  db_.set_error_delegate(error_delegate);

  // Set the database page size to something a little larger to give us
  // better performance (we're typically seek rather than bandwidth limited).
  // This only has an effect before any tables have been created, otherwise
  // this is a NOP. Must be a power of 2 and a max of 8192.
  db_.set_page_size(4096);

  // Increase the cache size. The page size, plus a little extra, times this
  // value, tells us how much memory the cache will use maximum.
  // 6000 * 4MB = 24MB
  // TODO(brettw) scale this value to the amount of available memory.
  db_.set_cache_size(6000);

  // Note that we don't set exclusive locking here. That's done by
  // BeginExclusiveMode below which is called later (we have to be in shared
  // mode to start out for the in-memory backend to read the data).

  if (!db_.Open(history_name))
    return sql::INIT_FAILURE;

  // Wrap the rest of init in a tranaction. This will prevent the database from
  // getting corrupted if we crash in the middle of initialization or migration.
  sql::Transaction committer(&db_);
  if (!committer.Begin())
    return sql::INIT_FAILURE;

#if defined(OS_MACOSX)
  // Exclude the history file from backups.
  base::mac::SetFileBackupExclusion(history_name);
#endif

  // Prime the cache.
  db_.Preload();

  // Create the tables and indices.
  // NOTE: If you add something here, also add it to
  //       RecreateAllButStarAndURLTables.
  if (!meta_table_.Init(&db_, GetCurrentVersion(), kCompatibleVersionNumber))
    return sql::INIT_FAILURE;
  if (!CreateURLTable(false) || !InitVisitTable() ||
      !InitKeywordSearchTermsTable() || !InitDownloadTable() ||
      !InitSegmentTables())
    return sql::INIT_FAILURE;
  CreateMainURLIndex();
  CreateKeywordSearchTermsIndices();

  // Version check.
  sql::InitStatus version_status = EnsureCurrentVersion();
  if (version_status != sql::INIT_OK)
    return version_status;

  ComputeDatabaseMetrics(history_name, db_);
  return committer.Commit() ? sql::INIT_OK : sql::INIT_FAILURE;
}

void HistoryDatabase::BeginExclusiveMode() {
  // We can't use set_exclusive_locking() since that only has an effect before
  // the DB is opened.
  ignore_result(db_.Execute("PRAGMA locking_mode=EXCLUSIVE"));
}

// static
int HistoryDatabase::GetCurrentVersion() {
  return kCurrentVersionNumber;
}

void HistoryDatabase::BeginTransaction() {
  db_.BeginTransaction();
}

void HistoryDatabase::CommitTransaction() {
  db_.CommitTransaction();
}

void HistoryDatabase::RollbackTransaction() {
  db_.RollbackTransaction();
}

bool HistoryDatabase::RecreateAllTablesButURL() {
  if (!DropVisitTable())
    return false;
  if (!InitVisitTable())
    return false;

  if (!DropKeywordSearchTermsTable())
    return false;
  if (!InitKeywordSearchTermsTable())
    return false;

  if (!DropSegmentTables())
    return false;
  if (!InitSegmentTables())
    return false;

  // We also add the supplementary URL indices at this point. This index is
  // over parts of the URL table that weren't automatically created when the
  // temporary URL table was
  CreateKeywordSearchTermsIndices();
  return true;
}

void HistoryDatabase::Vacuum() {
  DCHECK_EQ(0, db_.transaction_nesting()) <<
      "Can not have a transaction when vacuuming.";
  ignore_result(db_.Execute("VACUUM"));
}

bool HistoryDatabase::Raze() {
  return db_.Raze();
}

void HistoryDatabase::ThumbnailMigrationDone() {
  meta_table_.SetValue(kNeedsThumbnailMigrationKey, 0);
}

bool HistoryDatabase::GetNeedsThumbnailMigration() {
  int value = 0;
  return (meta_table_.GetValue(kNeedsThumbnailMigrationKey, &value) &&
          value != 0);
}

bool HistoryDatabase::SetSegmentID(VisitID visit_id, SegmentID segment_id) {
  sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
      "UPDATE visits SET segment_id = ? WHERE id = ?"));
  s.BindInt64(0, segment_id);
  s.BindInt64(1, visit_id);
  DCHECK(db_.GetLastChangeCount() == 1);

  return s.Run();
}

SegmentID HistoryDatabase::GetSegmentID(VisitID visit_id) {
  sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
      "SELECT segment_id FROM visits WHERE id = ?"));
  s.BindInt64(0, visit_id);

  if (s.Step()) {
    if (s.ColumnType(0) == sql::COLUMN_TYPE_NULL)
      return 0;
    else
      return s.ColumnInt64(0);
  }
  return 0;
}

base::Time HistoryDatabase::GetEarlyExpirationThreshold() {
  if (!cached_early_expiration_threshold_.is_null())
    return cached_early_expiration_threshold_;

  int64 threshold;
  if (!meta_table_.GetValue(kEarlyExpirationThresholdKey, &threshold)) {
    // Set to a very early non-zero time, so it's before all history, but not
    // zero to avoid re-retrieval.
    threshold = 1L;
  }

  cached_early_expiration_threshold_ = base::Time::FromInternalValue(threshold);
  return cached_early_expiration_threshold_;
}

void HistoryDatabase::UpdateEarlyExpirationThreshold(base::Time threshold) {
  meta_table_.SetValue(kEarlyExpirationThresholdKey,
                       threshold.ToInternalValue());
  cached_early_expiration_threshold_ = threshold;
}

sql::Connection& HistoryDatabase::GetDB() {
  return db_;
}

sql::MetaTable& HistoryDatabase::GetMetaTable() {
  return meta_table_;
}

// Migration -------------------------------------------------------------------

sql::InitStatus HistoryDatabase::EnsureCurrentVersion() {
  // We can't read databases newer than we were designed for.
  if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
    LOG(WARNING) << "History database is too new.";
    return sql::INIT_TOO_NEW;
  }

  // NOTICE: If you are changing structures for things shared with the archived
  // history file like URLs, visits, or downloads, that will need migration as
  // well. Instead of putting such migration code in this class, it should be
  // in the corresponding file (url_database.cc, etc.) and called from here and
  // from the archived_database.cc.

  int cur_version = meta_table_.GetVersionNumber();

  // Put migration code here

  if (cur_version == 15) {
    if (!db_.Execute("DROP TABLE starred") || !DropStarredIDFromURLs()) {
      LOG(WARNING) << "Unable to update history database to version 16.";
      return sql::INIT_FAILURE;
    }
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
    meta_table_.SetCompatibleVersionNumber(
        std::min(cur_version, kCompatibleVersionNumber));
  }

  if (cur_version == 16) {
#if !defined(OS_WIN)
    // In this version we bring the time format on Mac & Linux in sync with the
    // Windows version so that profiles can be moved between computers.
    MigrateTimeEpoch();
#endif
    // On all platforms we bump the version number, so on Windows this
    // migration is a NOP. We keep the compatible version at 16 since things
    // will basically still work, just history will be in the future if an
    // old version reads it.
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 17) {
    // Version 17 was for thumbnails to top sites migration. We ended up
    // disabling it though, so 17->18 does nothing.
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 18) {
    // This is the version prior to adding url_source column. We need to
    // migrate the database.
    cur_version = 19;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 19) {
    cur_version++;
    meta_table_.SetVersionNumber(cur_version);
    // Set a key indicating we need to migrate thumbnails. When successfull the
    // key is removed (ThumbnailMigrationDone).
    meta_table_.SetValue(kNeedsThumbnailMigrationKey, 1);
  }

  if (cur_version == 20) {
    // This is the version prior to adding the visit_duration field in visits
    // database. We need to migrate the database.
    if (!MigrateVisitsWithoutDuration()) {
      LOG(WARNING) << "Unable to update history database to version 21.";
      return sql::INIT_FAILURE;
    }
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 21) {
    // The android_urls table's data schemal was changed in version 21.
#if defined(OS_ANDROID)
    if (!MigrateToVersion22()) {
      LOG(WARNING) << "Unable to migrate the android_urls table to version 22";
    }
#endif
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 22) {
    if (!MigrateDownloadsState()) {
      LOG(WARNING) << "Unable to fix invalid downloads state values";
      // Invalid state values may cause crashes.
      return sql::INIT_FAILURE;
    }
    cur_version++;
    meta_table_.SetVersionNumber(cur_version);
  }

  // When the version is too old, we just try to continue anyway, there should
  // not be a released product that makes a database too old for us to handle.
  LOG_IF(WARNING, cur_version < GetCurrentVersion()) <<
         "History database version " << cur_version << " is too old to handle.";

  return sql::INIT_OK;
}

#if !defined(OS_WIN)
void HistoryDatabase::MigrateTimeEpoch() {
  // Update all the times in the URLs and visits table in the main database.
  // For visits, clear the indexed flag since we'll delete the FTS databases in
  // the next step.
  ignore_result(db_.Execute(
      "UPDATE urls "
      "SET last_visit_time = last_visit_time + 11644473600000000 "
      "WHERE id IN (SELECT id FROM urls WHERE last_visit_time > 0);"));
  ignore_result(db_.Execute(
      "UPDATE visits "
      "SET visit_time = visit_time + 11644473600000000, is_indexed = 0 "
      "WHERE id IN (SELECT id FROM visits WHERE visit_time > 0);"));
  ignore_result(db_.Execute(
      "UPDATE segment_usage "
      "SET time_slot = time_slot + 11644473600000000 "
      "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);"));

  // Erase all the full text index files. These will take a while to update and
  // are less important, so we just blow them away. Same with the archived
  // database.
  needs_version_17_migration_ = true;
}
#endif

}  // namespace history
<commit_msg>Add history-view-related UMA metrics and histograms for locally managed users.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/history/history_database.h"

#include <algorithm>
#include <set>
#include <string>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/metrics/histogram.h"
#include "base/rand_util.h"
#include "base/string_util.h"
#include "base/time.h"
#include "sql/transaction.h"

#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#endif

namespace history {

namespace {

// Current version number. We write databases at the "current" version number,
// but any previous version that can read the "compatible" one can make do with
// or database without *too* many bad effects.
static const int kCurrentVersionNumber = 23;
static const int kCompatibleVersionNumber = 16;
static const char kEarlyExpirationThresholdKey[] = "early_expiration_threshold";

// Key in the meta table used to determine if we need to migrate thumbnails out
// of history.
static const char kNeedsThumbnailMigrationKey[] = "needs_thumbnail_migration";

void ComputeDatabaseMetrics(const FilePath& history_name,
                            sql::Connection& db) {
  if (base::RandInt(1, 100) != 50)
    return;  // Only do this computation sometimes since it can be expensive.

  base::TimeTicks start_time = base::TimeTicks::Now();
  int64 file_size = 0;
  if (!file_util::GetFileSize(history_name, &file_size))
    return;
  int file_mb = static_cast<int>(file_size / (1024 * 1024));
  UMA_HISTOGRAM_MEMORY_MB("History.DatabaseFileMB", file_mb);

  sql::Statement url_count(db.GetUniqueStatement("SELECT count(*) FROM urls"));
  if (!url_count.Step())
    return;
  UMA_HISTOGRAM_COUNTS("History.URLTableCount", url_count.ColumnInt(0));

  sql::Statement visit_count(db.GetUniqueStatement(
      "SELECT count(*) FROM visits"));
  if (!visit_count.Step())
    return;
  UMA_HISTOGRAM_COUNTS("History.VisitTableCount", visit_count.ColumnInt(0));

  base::Time one_week_ago = base::Time::Now() - base::TimeDelta::FromDays(7);
  sql::Statement weekly_visit_sql(db.GetUniqueStatement(
      "SELECT count(*) FROM visits WHERE visit_time > ?"));
  weekly_visit_sql.BindInt64(0, one_week_ago.ToInternalValue());
  int weekly_visit_count = weekly_visit_sql.ColumnInt(0);
  UMA_HISTOGRAM_COUNTS("History.WeeklyVisitCount", weekly_visit_count);

  base::Time one_month_ago = base::Time::Now() - base::TimeDelta::FromDays(30);
  sql::Statement monthly_visit_sql(db.GetUniqueStatement(
      "SELECT count(*) FROM visits WHERE visit_time > ? AND visit_time <= ?"));
  monthly_visit_sql.BindInt64(0, one_month_ago.ToInternalValue());
  monthly_visit_sql.BindInt64(1, one_week_ago.ToInternalValue());
  UMA_HISTOGRAM_COUNTS("History.MonthlyVisitCount",
                       monthly_visit_sql.ColumnInt(0) + weekly_visit_count);

  UMA_HISTOGRAM_TIMES("History.DatabaseBasicMetricsTime",
                      base::TimeTicks::Now() - start_time);

  // Compute the advanced metrics even less often, pending timing data showing
  // that's not necessary.
  if (base::RandInt(1, 3) == 3) {
    start_time = base::TimeTicks::Now();

    // Collect all URLs visited within the last month.
    sql::Statement url_sql(db.GetUniqueStatement(
        "SELECT url, last_visit_time FROM urls WHERE last_visit_time > ?"));
    url_sql.BindInt64(0, one_month_ago.ToInternalValue());

    // Count URLs (which will always be unique) and unique hosts within the last
    // week and last month.
    int week_url_count = 0;
    int month_url_count = 0;
    std::set<std::string> week_hosts;
    std::set<std::string> month_hosts;
    while (url_sql.Step()) {
      GURL url(url_sql.ColumnString(0));
      base::Time visit_time =
          base::Time::FromInternalValue(url_sql.ColumnInt64(1));
      ++month_url_count;
      month_hosts.insert(url.host());
      if (visit_time > one_week_ago) {
        ++week_url_count;
        week_hosts.insert(url.host());
      }
    }
    UMA_HISTOGRAM_COUNTS("History.WeeklyURLCount", week_url_count);
    UMA_HISTOGRAM_COUNTS_10000("History.WeeklyHostCount", week_hosts.size());
    UMA_HISTOGRAM_COUNTS("History.MonthlyURLCount", month_url_count);
    UMA_HISTOGRAM_COUNTS_10000("History.MonthlyHostCount", month_hosts.size());
    UMA_HISTOGRAM_TIMES("History.DatabaseAdvancedMetricsTime",
                        base::TimeTicks::Now() - start_time);
  }
}

}  // namespace

HistoryDatabase::HistoryDatabase()
    : needs_version_17_migration_(false) {
}

HistoryDatabase::~HistoryDatabase() {
}

sql::InitStatus HistoryDatabase::Init(const FilePath& history_name,
                                      sql::ErrorDelegate* error_delegate) {
  db_.set_error_histogram_name("Sqlite.History.Error");

  // Set the exceptional sqlite error handler.
  db_.set_error_delegate(error_delegate);

  // Set the database page size to something a little larger to give us
  // better performance (we're typically seek rather than bandwidth limited).
  // This only has an effect before any tables have been created, otherwise
  // this is a NOP. Must be a power of 2 and a max of 8192.
  db_.set_page_size(4096);

  // Increase the cache size. The page size, plus a little extra, times this
  // value, tells us how much memory the cache will use maximum.
  // 6000 * 4MB = 24MB
  // TODO(brettw) scale this value to the amount of available memory.
  db_.set_cache_size(6000);

  // Note that we don't set exclusive locking here. That's done by
  // BeginExclusiveMode below which is called later (we have to be in shared
  // mode to start out for the in-memory backend to read the data).

  if (!db_.Open(history_name))
    return sql::INIT_FAILURE;

  // Wrap the rest of init in a tranaction. This will prevent the database from
  // getting corrupted if we crash in the middle of initialization or migration.
  sql::Transaction committer(&db_);
  if (!committer.Begin())
    return sql::INIT_FAILURE;

#if defined(OS_MACOSX)
  // Exclude the history file from backups.
  base::mac::SetFileBackupExclusion(history_name);
#endif

  // Prime the cache.
  db_.Preload();

  // Create the tables and indices.
  // NOTE: If you add something here, also add it to
  //       RecreateAllButStarAndURLTables.
  if (!meta_table_.Init(&db_, GetCurrentVersion(), kCompatibleVersionNumber))
    return sql::INIT_FAILURE;
  if (!CreateURLTable(false) || !InitVisitTable() ||
      !InitKeywordSearchTermsTable() || !InitDownloadTable() ||
      !InitSegmentTables())
    return sql::INIT_FAILURE;
  CreateMainURLIndex();
  CreateKeywordSearchTermsIndices();

  // Version check.
  sql::InitStatus version_status = EnsureCurrentVersion();
  if (version_status != sql::INIT_OK)
    return version_status;

  ComputeDatabaseMetrics(history_name, db_);
  return committer.Commit() ? sql::INIT_OK : sql::INIT_FAILURE;
}

void HistoryDatabase::BeginExclusiveMode() {
  // We can't use set_exclusive_locking() since that only has an effect before
  // the DB is opened.
  ignore_result(db_.Execute("PRAGMA locking_mode=EXCLUSIVE"));
}

// static
int HistoryDatabase::GetCurrentVersion() {
  return kCurrentVersionNumber;
}

void HistoryDatabase::BeginTransaction() {
  db_.BeginTransaction();
}

void HistoryDatabase::CommitTransaction() {
  db_.CommitTransaction();
}

void HistoryDatabase::RollbackTransaction() {
  db_.RollbackTransaction();
}

bool HistoryDatabase::RecreateAllTablesButURL() {
  if (!DropVisitTable())
    return false;
  if (!InitVisitTable())
    return false;

  if (!DropKeywordSearchTermsTable())
    return false;
  if (!InitKeywordSearchTermsTable())
    return false;

  if (!DropSegmentTables())
    return false;
  if (!InitSegmentTables())
    return false;

  // We also add the supplementary URL indices at this point. This index is
  // over parts of the URL table that weren't automatically created when the
  // temporary URL table was
  CreateKeywordSearchTermsIndices();
  return true;
}

void HistoryDatabase::Vacuum() {
  DCHECK_EQ(0, db_.transaction_nesting()) <<
      "Can not have a transaction when vacuuming.";
  ignore_result(db_.Execute("VACUUM"));
}

bool HistoryDatabase::Raze() {
  return db_.Raze();
}

void HistoryDatabase::ThumbnailMigrationDone() {
  meta_table_.SetValue(kNeedsThumbnailMigrationKey, 0);
}

bool HistoryDatabase::GetNeedsThumbnailMigration() {
  int value = 0;
  return (meta_table_.GetValue(kNeedsThumbnailMigrationKey, &value) &&
          value != 0);
}

bool HistoryDatabase::SetSegmentID(VisitID visit_id, SegmentID segment_id) {
  sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
      "UPDATE visits SET segment_id = ? WHERE id = ?"));
  s.BindInt64(0, segment_id);
  s.BindInt64(1, visit_id);
  DCHECK(db_.GetLastChangeCount() == 1);

  return s.Run();
}

SegmentID HistoryDatabase::GetSegmentID(VisitID visit_id) {
  sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
      "SELECT segment_id FROM visits WHERE id = ?"));
  s.BindInt64(0, visit_id);

  if (s.Step()) {
    if (s.ColumnType(0) == sql::COLUMN_TYPE_NULL)
      return 0;
    else
      return s.ColumnInt64(0);
  }
  return 0;
}

base::Time HistoryDatabase::GetEarlyExpirationThreshold() {
  if (!cached_early_expiration_threshold_.is_null())
    return cached_early_expiration_threshold_;

  int64 threshold;
  if (!meta_table_.GetValue(kEarlyExpirationThresholdKey, &threshold)) {
    // Set to a very early non-zero time, so it's before all history, but not
    // zero to avoid re-retrieval.
    threshold = 1L;
  }

  cached_early_expiration_threshold_ = base::Time::FromInternalValue(threshold);
  return cached_early_expiration_threshold_;
}

void HistoryDatabase::UpdateEarlyExpirationThreshold(base::Time threshold) {
  meta_table_.SetValue(kEarlyExpirationThresholdKey,
                       threshold.ToInternalValue());
  cached_early_expiration_threshold_ = threshold;
}

sql::Connection& HistoryDatabase::GetDB() {
  return db_;
}

sql::MetaTable& HistoryDatabase::GetMetaTable() {
  return meta_table_;
}

// Migration -------------------------------------------------------------------

sql::InitStatus HistoryDatabase::EnsureCurrentVersion() {
  // We can't read databases newer than we were designed for.
  if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
    LOG(WARNING) << "History database is too new.";
    return sql::INIT_TOO_NEW;
  }

  // NOTICE: If you are changing structures for things shared with the archived
  // history file like URLs, visits, or downloads, that will need migration as
  // well. Instead of putting such migration code in this class, it should be
  // in the corresponding file (url_database.cc, etc.) and called from here and
  // from the archived_database.cc.

  int cur_version = meta_table_.GetVersionNumber();

  // Put migration code here

  if (cur_version == 15) {
    if (!db_.Execute("DROP TABLE starred") || !DropStarredIDFromURLs()) {
      LOG(WARNING) << "Unable to update history database to version 16.";
      return sql::INIT_FAILURE;
    }
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
    meta_table_.SetCompatibleVersionNumber(
        std::min(cur_version, kCompatibleVersionNumber));
  }

  if (cur_version == 16) {
#if !defined(OS_WIN)
    // In this version we bring the time format on Mac & Linux in sync with the
    // Windows version so that profiles can be moved between computers.
    MigrateTimeEpoch();
#endif
    // On all platforms we bump the version number, so on Windows this
    // migration is a NOP. We keep the compatible version at 16 since things
    // will basically still work, just history will be in the future if an
    // old version reads it.
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 17) {
    // Version 17 was for thumbnails to top sites migration. We ended up
    // disabling it though, so 17->18 does nothing.
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 18) {
    // This is the version prior to adding url_source column. We need to
    // migrate the database.
    cur_version = 19;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 19) {
    cur_version++;
    meta_table_.SetVersionNumber(cur_version);
    // Set a key indicating we need to migrate thumbnails. When successfull the
    // key is removed (ThumbnailMigrationDone).
    meta_table_.SetValue(kNeedsThumbnailMigrationKey, 1);
  }

  if (cur_version == 20) {
    // This is the version prior to adding the visit_duration field in visits
    // database. We need to migrate the database.
    if (!MigrateVisitsWithoutDuration()) {
      LOG(WARNING) << "Unable to update history database to version 21.";
      return sql::INIT_FAILURE;
    }
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 21) {
    // The android_urls table's data schemal was changed in version 21.
#if defined(OS_ANDROID)
    if (!MigrateToVersion22()) {
      LOG(WARNING) << "Unable to migrate the android_urls table to version 22";
    }
#endif
    ++cur_version;
    meta_table_.SetVersionNumber(cur_version);
  }

  if (cur_version == 22) {
    if (!MigrateDownloadsState()) {
      LOG(WARNING) << "Unable to fix invalid downloads state values";
      // Invalid state values may cause crashes.
      return sql::INIT_FAILURE;
    }
    cur_version++;
    meta_table_.SetVersionNumber(cur_version);
  }

  // When the version is too old, we just try to continue anyway, there should
  // not be a released product that makes a database too old for us to handle.
  LOG_IF(WARNING, cur_version < GetCurrentVersion()) <<
         "History database version " << cur_version << " is too old to handle.";

  return sql::INIT_OK;
}

#if !defined(OS_WIN)
void HistoryDatabase::MigrateTimeEpoch() {
  // Update all the times in the URLs and visits table in the main database.
  // For visits, clear the indexed flag since we'll delete the FTS databases in
  // the next step.
  ignore_result(db_.Execute(
      "UPDATE urls "
      "SET last_visit_time = last_visit_time + 11644473600000000 "
      "WHERE id IN (SELECT id FROM urls WHERE last_visit_time > 0);"));
  ignore_result(db_.Execute(
      "UPDATE visits "
      "SET visit_time = visit_time + 11644473600000000, is_indexed = 0 "
      "WHERE id IN (SELECT id FROM visits WHERE visit_time > 0);"));
  ignore_result(db_.Execute(
      "UPDATE segment_usage "
      "SET time_slot = time_slot + 11644473600000000 "
      "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);"));

  // Erase all the full text index files. These will take a while to update and
  // are less important, so we just blow them away. Same with the archived
  // database.
  needs_version_17_migration_ = true;
}
#endif

}  // namespace history
<|endoftext|>


<commit_before>// MenuTheme.hh for FbTk
// Copyright (c) 2002-2004 Henrik Kinnunen (fluxgen at fluxbox dot org)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id$

#ifndef FBTK_MENUTHEME_HH
#define FBTK_MENUTHEME_HH

#include "Theme.hh"
#include "Color.hh"
#include "Font.hh"
#include "Texture.hh"
#include "Text.hh"
#include "Subject.hh"
#include "PixmapWithMask.hh"
#include "GContext.hh"

namespace FbTk {

class MenuTheme:public FbTk::Theme {
public:
    //!! TODO
    // this isn't actually used with a theme item
    // see setMenuMode() for more info
    enum MenuMode {CLICK_OPEN, DELAY_OPEN};

    enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND};
    MenuTheme(int screen_num);
    virtual ~MenuTheme();

    void reconfigTheme();

    bool fallback(ThemeItem_base &item);

    /**
       @name text colors
    */
    ///@{
    inline const FbTk::Color &titleTextColor() const { return *t_text; }
    inline const FbTk::Color &frameTextColor() const { return *f_text; }
    inline const FbTk::Color &highlightTextColor() const { return *h_text; }
    inline const FbTk::Color &disableTextColor() const { return *d_text; }
    ///@}
    /**
       @name textures
    */
    ///@{
    inline const FbTk::Texture &titleTexture() const { return *title; }
    inline const FbTk::Texture &frameTexture() const { return *frame; }
    inline const FbTk::Texture &hiliteTexture() const { return *hilite; }
    ///@}

    inline const FbTk::PixmapWithMask &bulletPixmap() const { return *m_bullet_pixmap; }
    inline const FbTk::PixmapWithMask &selectedPixmap() const { return *m_selected_pixmap; }
    inline const FbTk::PixmapWithMask &unselectedPixmap() const { return *m_unselected_pixmap; }
    /**
       @name fonts
    */
    ///@{
    inline const FbTk::Font &titleFont() const { return *titlefont; }
    inline FbTk::Font &titleFont() { return *titlefont; }
    inline const FbTk::Font &frameFont() const { return *framefont; }
    inline FbTk::Font &frameFont() { return *framefont; }
    ///@}

    inline FbTk::Justify frameFontJustify() const { return *framefont_justify; }
    inline FbTk::Justify titleFontJustify() const { return *titlefont_justify; }

    /**
       @name graphic contexts
    */
    ///@{
    inline const GContext &titleTextGC() const { return t_text_gc; }
    inline const GContext &frameTextGC() const { return f_text_gc; }
    inline const GContext &hiliteTextGC() const { return h_text_gc; }
    inline const GContext &disableTextGC() const { return d_text_gc; }
    inline const GContext &hiliteGC() const { return hilite_gc; }
    inline GContext &titleTextGC() { return t_text_gc; }
    inline GContext &frameTextGC() { return f_text_gc; }
    inline GContext &hiliteTextGC() { return h_text_gc; }
    inline GContext &disableTextGC() { return d_text_gc; }
    inline GContext &hiliteGC() { return hilite_gc; }
    ///@}
    inline BulletType bullet() const { return *m_bullet; }
    inline FbTk::Justify bulletPos() const { return *bullet_pos; }

    inline unsigned int titleHeight() const { return m_real_title_height; }
    inline unsigned int itemHeight() const { return m_real_item_height; }
    inline unsigned int borderWidth() const { return *m_border_width; }
    inline unsigned int bevelWidth() const { return *m_bevel_width; }

    inline unsigned char alpha() const { return m_alpha; }
    inline void setAlpha(unsigned char alpha) { m_alpha = alpha; }
    // this isn't actually a theme item
    // but we'll let it be here for now, until there's a better way to
    // get resources into menu
    inline void setMenuMode(MenuMode mode) { m_menumode = mode; }
    inline MenuMode menuMode() const { return m_menumode; }
    inline void setDelayOpen(int msec) { m_delayopen = msec; }
    inline void setDelayClose(int msec) { m_delayclose = msec; }
    inline int delayOpen() const { return m_delayopen; }
    inline int delayClose() const { return m_delayclose; }

    inline const FbTk::Color &borderColor() const { return *m_border_color; }

private:
    FbTk::ThemeItem<FbTk::Color> t_text, f_text, h_text, d_text;
    FbTk::ThemeItem<FbTk::Texture> title, frame, hilite;
    FbTk::ThemeItem<FbTk::Font> titlefont, framefont;
    FbTk::ThemeItem<FbTk::Justify> framefont_justify, titlefont_justify;
    FbTk::ThemeItem<FbTk::Justify> bullet_pos;
    FbTk::ThemeItem<BulletType> m_bullet;
    FbTk::ThemeItem<unsigned int> m_title_height, m_item_height;
    FbTk::ThemeItem<unsigned int> m_border_width;
    FbTk::ThemeItem<unsigned int> m_bevel_width;
    FbTk::ThemeItem<FbTk::Color> m_border_color;
    FbTk::ThemeItem<FbTk::PixmapWithMask> m_bullet_pixmap, m_selected_pixmap, m_unselected_pixmap;

    Display *m_display;
    FbTk::GContext t_text_gc, f_text_gc, h_text_gc, d_text_gc, hilite_gc;

    unsigned char m_alpha;
    MenuMode m_menumode;
    unsigned int m_delayopen; ///< in msec
    unsigned int m_delayclose; ///< in msec
    int m_real_title_height; ///< the calculated item height (from font and menu.titleHeight)
    int m_real_item_height; ///< the calculated item height (from font and menu.itemHeight)
};

} // end namespace FbTk

#endif // FBTK_MENUTHEME_HH
<commit_msg>updated copyright date<commit_after>// MenuTheme.hh for FbTk
// Copyright (c) 2002 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id$

#ifndef FBTK_MENUTHEME_HH
#define FBTK_MENUTHEME_HH

#include "Theme.hh"
#include "Color.hh"
#include "Font.hh"
#include "Texture.hh"
#include "Text.hh"
#include "Subject.hh"
#include "PixmapWithMask.hh"
#include "GContext.hh"

namespace FbTk {

class MenuTheme:public FbTk::Theme {
public:
    //!! TODO
    // this isn't actually used with a theme item
    // see setMenuMode() for more info
    enum MenuMode {CLICK_OPEN, DELAY_OPEN};

    enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND};
    MenuTheme(int screen_num);
    virtual ~MenuTheme();

    void reconfigTheme();

    bool fallback(ThemeItem_base &item);

    /**
       @name text colors
    */
    ///@{
    inline const FbTk::Color &titleTextColor() const { return *t_text; }
    inline const FbTk::Color &frameTextColor() const { return *f_text; }
    inline const FbTk::Color &highlightTextColor() const { return *h_text; }
    inline const FbTk::Color &disableTextColor() const { return *d_text; }
    ///@}
    /**
       @name textures
    */
    ///@{
    inline const FbTk::Texture &titleTexture() const { return *title; }
    inline const FbTk::Texture &frameTexture() const { return *frame; }
    inline const FbTk::Texture &hiliteTexture() const { return *hilite; }
    ///@}

    inline const FbTk::PixmapWithMask &bulletPixmap() const { return *m_bullet_pixmap; }
    inline const FbTk::PixmapWithMask &selectedPixmap() const { return *m_selected_pixmap; }
    inline const FbTk::PixmapWithMask &unselectedPixmap() const { return *m_unselected_pixmap; }
    /**
       @name fonts
    */
    ///@{
    inline const FbTk::Font &titleFont() const { return *titlefont; }
    inline FbTk::Font &titleFont() { return *titlefont; }
    inline const FbTk::Font &frameFont() const { return *framefont; }
    inline FbTk::Font &frameFont() { return *framefont; }
    ///@}

    inline FbTk::Justify frameFontJustify() const { return *framefont_justify; }
    inline FbTk::Justify titleFontJustify() const { return *titlefont_justify; }

    /**
       @name graphic contexts
    */
    ///@{
    inline const GContext &titleTextGC() const { return t_text_gc; }
    inline const GContext &frameTextGC() const { return f_text_gc; }
    inline const GContext &hiliteTextGC() const { return h_text_gc; }
    inline const GContext &disableTextGC() const { return d_text_gc; }
    inline const GContext &hiliteGC() const { return hilite_gc; }
    inline GContext &titleTextGC() { return t_text_gc; }
    inline GContext &frameTextGC() { return f_text_gc; }
    inline GContext &hiliteTextGC() { return h_text_gc; }
    inline GContext &disableTextGC() { return d_text_gc; }
    inline GContext &hiliteGC() { return hilite_gc; }
    ///@}
    inline BulletType bullet() const { return *m_bullet; }
    inline FbTk::Justify bulletPos() const { return *bullet_pos; }

    inline unsigned int titleHeight() const { return m_real_title_height; }
    inline unsigned int itemHeight() const { return m_real_item_height; }
    inline unsigned int borderWidth() const { return *m_border_width; }
    inline unsigned int bevelWidth() const { return *m_bevel_width; }

    inline unsigned char alpha() const { return m_alpha; }
    inline void setAlpha(unsigned char alpha) { m_alpha = alpha; }
    // this isn't actually a theme item
    // but we'll let it be here for now, until there's a better way to
    // get resources into menu
    inline void setMenuMode(MenuMode mode) { m_menumode = mode; }
    inline MenuMode menuMode() const { return m_menumode; }
    inline void setDelayOpen(int msec) { m_delayopen = msec; }
    inline void setDelayClose(int msec) { m_delayclose = msec; }
    inline int delayOpen() const { return m_delayopen; }
    inline int delayClose() const { return m_delayclose; }

    inline const FbTk::Color &borderColor() const { return *m_border_color; }

private:
    FbTk::ThemeItem<FbTk::Color> t_text, f_text, h_text, d_text;
    FbTk::ThemeItem<FbTk::Texture> title, frame, hilite;
    FbTk::ThemeItem<FbTk::Font> titlefont, framefont;
    FbTk::ThemeItem<FbTk::Justify> framefont_justify, titlefont_justify;
    FbTk::ThemeItem<FbTk::Justify> bullet_pos;
    FbTk::ThemeItem<BulletType> m_bullet;
    FbTk::ThemeItem<unsigned int> m_title_height, m_item_height;
    FbTk::ThemeItem<unsigned int> m_border_width;
    FbTk::ThemeItem<unsigned int> m_bevel_width;
    FbTk::ThemeItem<FbTk::Color> m_border_color;
    FbTk::ThemeItem<FbTk::PixmapWithMask> m_bullet_pixmap, m_selected_pixmap, m_unselected_pixmap;

    Display *m_display;
    FbTk::GContext t_text_gc, f_text_gc, h_text_gc, d_text_gc, hilite_gc;

    unsigned char m_alpha;
    MenuMode m_menumode;
    unsigned int m_delayopen; ///< in msec
    unsigned int m_delayclose; ///< in msec
    int m_real_title_height; ///< the calculated item height (from font and menu.titleHeight)
    int m_real_item_height; ///< the calculated item height (from font and menu.itemHeight)
};

} // end namespace FbTk

#endif // FBTK_MENUTHEME_HH
<|endoftext|>


<commit_before>#include "TChain.h"
#include "TTree.h"
#include "TH1D.h"
#include "TF1.h"
#include "TCanvas.h"
#include "TObjArray.h"

#include "AliAnalysisTask.h"
#include "AliAnalysisManager.h"

#include "AliESDEvent.h"
#include "AliESDInputHandler.h"

#include "AliT0CalibOffsetChannelsTask.h"

//#include "AliCDBMetaData.h"
//#include "AliCDBId.h"
//#include "AliCDBEntry.h"
//#include "AliCDBManager.h"
//#include "AliCDBStorage.h"

// Task should calculate channels offset
// Authors: Alla

ClassImp(AliT0CalibOffsetChannelsTask)
//________________________________________________________________________
AliT0CalibOffsetChannelsTask::AliT0CalibOffsetChannelsTask()
  : AliAnalysisTaskSE(),  fESD(0x0), fTzeroObject(0x0),
  fTzeroORA(0x0), fTzeroORC(0x0), fResolution(0x0), fTzeroORAplusORC(0x0),
  fRunNumber(0),fRefPMTA(12), fRefPMTC(0),
  fEvent(0),fStartTime(0), fEndTime(0)
{
  // Constructor

  for( int ip=0; ip < 24; ip++){
    fTimeDiff[ip] = 0;
    fCFD[ip]      = 0;
    fCDBdelays[ip]= 0;
    fCDBcfds[ip]= 0;
    fCFDvsTimestamp[ip] = NULL;
    if (ip<4 ) {
      fCDBT0s[ip]= 0;
      fT0s[ip] =NULL;
    }
  }

  // Define input and output slots here
  // Input slot #0 works with a TChain
  //  DefineInput(0,  TChain::Class());
  //  DefineOutput(1, TObjArray::Class());
}

//________________________________________________________________________
AliT0CalibOffsetChannelsTask::AliT0CalibOffsetChannelsTask(const char *name)
  : AliAnalysisTaskSE(name), fESD(0), fTzeroObject(0),
  fTzeroORA(0x0), fTzeroORC(0x0), fResolution(0x0), fTzeroORAplusORC(0x0),
    fRunNumber(0),fRefPMTA(12), fRefPMTC(0), fEvent(0),
    fStartTime(0), fEndTime(0)
{
  // Constructor

  for( int ip=0; ip < 24; ip++){
    fTimeDiff[ip] = 0;
    fCFD[ip]      = 0;
    fCDBdelays[ip]= 0;
    fCDBcfds[ip]= 0;
    fCFDvsTimestamp[ip] = NULL;

    if (ip<4 ) {
      fCDBT0s[ip]= 0;
      fT0s[ip] =NULL;
    }
  }

  // Define input and output slots here
  // Input slot #0 works with a TChain
  DefineInput(0, TChain::Class());
  DefineOutput(1, TObjArray::Class());
  // Output slot #0 id reserved by the base class for AOD
  // Output slot #1 writes into a TH1 container
}

//________________________________________________________________________
AliT0CalibOffsetChannelsTask::~AliT0CalibOffsetChannelsTask()
{
  // Destructor
  // printf("AliT0CalibOffsetChannels~AliT0CalibOffsetChannels() ");
  delete fTzeroORA;
  delete fTzeroORC;
  delete fResolution;
  delete fTzeroORAplusORC;
  for( Int_t  ip=0; ip < 24; ip++){
    delete fTimeDiff[ip];
    delete fCFD[ip];
    delete fCFDvsTimestamp[ip];
  }
  for( Int_t  ip=0; ip < 4; ip++) delete fT0s[ip];

  delete fTzeroObject;
}

//________________________________________________________________________
/*void AliT0CalibOffsetChannelsTaskX::ConnectInputData(Option_t *) {
  //
  //
  //
  TTree* tree=dynamic_cast<TTree*>(GetInputData(0));
  if (!tree) {
    printf("ERROR: Could not read chain from input slot 0");
  }
  else {
    AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
    if (!esdH) {
      printf ("ERROR: Could not get ESDInputHandler");
    }
    else {
      fESD = esdH->GetEvent();
      printf ("*** CONNECTED NEW EVENT ****");
    }
  }
}
*/
//________________________________________________________________________
void AliT0CalibOffsetChannelsTask::UserCreateOutputObjects()
{
  // Create histograms
  Float_t low = fCDBcfds[fRefPMTC] - 400;
  Float_t high = fCDBcfds[fRefPMTA] + 400;
  printf (" AliT0CalibOffsetChannelsTask %f %f \n",low,high);

  Float_t timestart = Float_t (fStartTime - 300);
  Float_t timeend = Float_t (fEndTime +300);
  Int_t nTimeBins = (fEndTime - fStartTime+600)/600;
  for (Int_t i=0; i<24; i++) {
    fTimeDiff[i]   = new TH1F (Form("CFD1minCFD%d",i+1),"fTimeDiff",150, -300, 300);
    fCFD[i]        = new TH1F(Form("CFD%d",i+1),"CFD",250,low, high);//6000, 7000);
    // fCFDvsTimestamp[i] = new TH2F( Form("hCFDvsTimestamp%i", i+1), Form("CFD vs timestamp%i", i+1), nTimeBins, timestart,  timeend,250,low, high );
    fCFDvsTimestamp[i] = new TH2F( Form("hCFDvsTimestamp%i", i+1), Form("CFD vs timestamp%i", i+1), nTimeBins,fStartTime - 300,  fEndTime +300 ,250,low, high );
    // fCFDvsTimestamp[i]->SetName(Form("hCFDvsTimestamp%i", i+1));
    // fCFDvsTimestamp[i]->SetTitle(Form("CFD vs timestamp%i", i+1));
  }

  fTzeroORAplusORC = new TH1F("fTzeroORAplusORC","ORA+ORC /2",200,-4000,4000);   //or A plus or C
  fResolution      = new TH1F("fResolution","fResolution",200,-2000,2000);// or A minus or C spectrum
  fTzeroORA        = new TH1F("fTzeroORA","fTzeroORA",200,-4000,4000);// or A spectrum
  fTzeroORC        = new TH1F("fTzeroORC","fTzeroORC",200,-4000,4000);// or C spectrum
  TString histname[4] = {"hT0AC","hT0A","hT0C","hResolution"};
  for (int icase=0; icase<4; icase++)
    fT0s[icase] = new TH2F(histname[icase].Data(), histname[icase].Data(), 100, 0, 200, 200, -1000, 1000);

  fTzeroObject     = new TObjArray(0);
  fTzeroObject->SetOwner(kTRUE);

  for (Int_t i=0; i<24; i++)
    fTzeroObject->AddAtAndExpand(fTimeDiff[i],i);

  for (Int_t i=0; i<24; i++)
    fTzeroObject->AddAtAndExpand(fCFD[i],i+24); //24 - 48

  fTzeroObject->AddAtAndExpand(fTzeroORAplusORC, 48);
  fTzeroObject->AddAtAndExpand(fResolution, 49);
  fTzeroObject->AddAtAndExpand(fTzeroORA, 50);
  fTzeroObject->AddAtAndExpand(fTzeroORC, 51);
  for (int icase=0; icase<4; icase++)
    fTzeroObject->AddAtAndExpand(fT0s[icase], 52+icase);
  for (int icase=0; icase<24; icase++)
    fTzeroObject->AddAtAndExpand(fCFDvsTimestamp[icase], 56+icase);

  PostData(1, fTzeroObject);
  fEvent=0;
  // Called once
}

//________________________________________________________________________
void AliT0CalibOffsetChannelsTask::UserExec(Option_t *)
{
  // Main loop
  // Called for each event

  // Post output data.

  fESD = dynamic_cast<AliESDEvent*>(InputEvent());
  if (!fESD) {
    printf("ERROR: fESD not available\n");
    return;
  }
  UInt_t timestamp=fESD->GetTimeStamp();
  /*  if (fEvent==0 )
    for (int iii=0; iii<24; iii++)
    fCFDvsTimestamp[iii]->SetBins(121, timestamp-60, timestamp+72000, 250,fCDBcfds[fRefPMTC]-500, fCDBcfds[fRefPMTA] + 500); */
   fEvent++;

  AliESDTZERO* tz= (AliESDTZERO*) fESD->GetESDTZERO();
  Int_t trigT0 = fESD->GetT0Trig();
  Float_t tvdctr = tz->GetTVDC(0);
  Bool_t eq = kTRUE;
  fRunNumber =  fESD->GetRunNumber() ;
  if( fRunNumber<165747) eq = kFALSE;

  const Double32_t* time = fESD->GetT0time();
  const Double32_t* amp = fESD->GetT0amplitude();

  if(tvdctr>-5 && tvdctr<5 && tvdctr!=0) { //event selection
    //    cout<<" tvdc "<<tvdctr<<endl;
    Double32_t diff;
    for (Int_t i=0; i<24; i++) {
      if( time[i] > 0  && amp[i]>0.1 ){
	if (eq)	{
	  fCFD[i]->Fill( time[i] );//////!!!!!
	  fCFDvsTimestamp[i]->Fill(timestamp,time[i]);
	  if(  time[fRefPMTC] > 0 && i<12)   {
	    diff =  time[i]-time[fRefPMTC];
	    fTimeDiff[i]->Fill( diff);
	  }
	  if(  time[fRefPMTA] >0  && i>11)  {
	    diff =  time[i]-time[fRefPMTA] ;
	    fTimeDiff[i]->Fill( diff);
	  }
	} //eq=1
	else  {
	  fCFD[i]->Fill( time[i] + fCDBdelays[i] );
	  if(  time[fRefPMTC] > 0 && i<12) {
	    diff =  time[i]-time[fRefPMTC] + fCDBdelays[i];
	    fTimeDiff[i]->Fill( diff);
	  } //C
	  if(  time[fRefPMTA] >0  && i>11) {
	    diff =  time[i]-time[fRefPMTA] + fCDBdelays[i];
	    fTimeDiff[i]->Fill( diff);
	  } //A
	} //eq=0
      }

    }
    const Double32_t* mean = fESD->GetT0TOF();
    Double32_t meanTOF = mean[0]  +  fCDBT0s[0] ;
    Double32_t orA = mean[1]  +  fCDBT0s[1] ;
    Double32_t orC = mean[2] + fCDBT0s[2] ;
    Int_t ncont = fESD->GetPrimaryVertexSPD()->GetNContributors();

    if(orA<99999) {
      fTzeroORA->Fill(orA);
       if (ncont>0) fT0s[1]->Fill(ncont, orA);
    }
    if(orC<99999) {
      fTzeroORC->Fill(orC);
       if (ncont>0) fT0s[2]->Fill(ncont, orC);
    }
    if(orA<99999 && orC<99999) {
      fResolution->Fill((orA-orC)/2.);
      fTzeroORAplusORC->Fill(meanTOF);
      if (ncont>0)   {
	fT0s[0]->Fill(ncont,meanTOF );
	fT0s[3]->Fill(ncont,(orA-orC)/2. );
      }
    }
  } //if TVDC on
  PostData(1, fTzeroObject);
}
//________________________________________________________________________
  void AliT0CalibOffsetChannelsTask::Terminate(Option_t *)
{

   // Called once at the end of the query
}
/*
@@@@ start 1495913485 end 1495916316
@@  start 1495913344.000000 end 1495916672.000000 bins 5
*/
<commit_msg>remove amplitude cut when collect calibration data<commit_after>#include "TChain.h"
#include "TTree.h"
#include "TH1D.h"
#include "TF1.h"
#include "TCanvas.h"
#include "TObjArray.h"

#include "AliAnalysisTask.h"
#include "AliAnalysisManager.h"

#include "AliESDEvent.h"
#include "AliESDInputHandler.h"

#include "AliT0CalibOffsetChannelsTask.h"

//#include "AliCDBMetaData.h"
//#include "AliCDBId.h"
//#include "AliCDBEntry.h"
//#include "AliCDBManager.h"
//#include "AliCDBStorage.h"

// Task should calculate channels offset
// Authors: Alla

ClassImp(AliT0CalibOffsetChannelsTask)
//________________________________________________________________________
AliT0CalibOffsetChannelsTask::AliT0CalibOffsetChannelsTask()
  : AliAnalysisTaskSE(),  fESD(0x0), fTzeroObject(0x0),
  fTzeroORA(0x0), fTzeroORC(0x0), fResolution(0x0), fTzeroORAplusORC(0x0),
  fRunNumber(0),fRefPMTA(12), fRefPMTC(0),
  fEvent(0),fStartTime(0), fEndTime(0)
{
  // Constructor

  for( int ip=0; ip < 24; ip++){
    fTimeDiff[ip] = 0;
    fCFD[ip]      = 0;
    fCDBdelays[ip]= 0;
    fCDBcfds[ip]= 0;
    fCFDvsTimestamp[ip] = NULL;
    if (ip<4 ) {
      fCDBT0s[ip]= 0;
      fT0s[ip] =NULL;
    }
  }

  // Define input and output slots here
  // Input slot #0 works with a TChain
  //  DefineInput(0,  TChain::Class());
  //  DefineOutput(1, TObjArray::Class());
}

//________________________________________________________________________
AliT0CalibOffsetChannelsTask::AliT0CalibOffsetChannelsTask(const char *name)
  : AliAnalysisTaskSE(name), fESD(0), fTzeroObject(0),
  fTzeroORA(0x0), fTzeroORC(0x0), fResolution(0x0), fTzeroORAplusORC(0x0),
    fRunNumber(0),fRefPMTA(12), fRefPMTC(0), fEvent(0),
    fStartTime(0), fEndTime(0)
{
  // Constructor

  for( int ip=0; ip < 24; ip++){
    fTimeDiff[ip] = 0;
    fCFD[ip]      = 0;
    fCDBdelays[ip]= 0;
    fCDBcfds[ip]= 0;
    fCFDvsTimestamp[ip] = NULL;

    if (ip<4 ) {
      fCDBT0s[ip]= 0;
      fT0s[ip] =NULL;
    }
  }

  // Define input and output slots here
  // Input slot #0 works with a TChain
  DefineInput(0, TChain::Class());
  DefineOutput(1, TObjArray::Class());
  // Output slot #0 id reserved by the base class for AOD
  // Output slot #1 writes into a TH1 container
}

//________________________________________________________________________
AliT0CalibOffsetChannelsTask::~AliT0CalibOffsetChannelsTask()
{
  // Destructor
  // printf("AliT0CalibOffsetChannels~AliT0CalibOffsetChannels() ");
  delete fTzeroORA;
  delete fTzeroORC;
  delete fResolution;
  delete fTzeroORAplusORC;
  for( Int_t  ip=0; ip < 24; ip++){
    delete fTimeDiff[ip];
    delete fCFD[ip];
    delete fCFDvsTimestamp[ip];
  }
  for( Int_t  ip=0; ip < 4; ip++) delete fT0s[ip];

  delete fTzeroObject;
}

//________________________________________________________________________
/*void AliT0CalibOffsetChannelsTaskX::ConnectInputData(Option_t *) {
  //
  //
  //
  TTree* tree=dynamic_cast<TTree*>(GetInputData(0));
  if (!tree) {
    printf("ERROR: Could not read chain from input slot 0");
  }
  else {
    AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
    if (!esdH) {
      printf ("ERROR: Could not get ESDInputHandler");
    }
    else {
      fESD = esdH->GetEvent();
      printf ("*** CONNECTED NEW EVENT ****");
    }
  }
}
*/
//________________________________________________________________________
void AliT0CalibOffsetChannelsTask::UserCreateOutputObjects()
{
  // Create histograms
  Float_t low = fCDBcfds[fRefPMTC] - 400;
  Float_t high = fCDBcfds[fRefPMTA] + 400;
  printf (" AliT0CalibOffsetChannelsTask %f %f \n",low,high);

  Float_t timestart = Float_t (fStartTime - 300);
  Float_t timeend = Float_t (fEndTime +300);
  Int_t nTimeBins = (fEndTime - fStartTime+600)/600;
  for (Int_t i=0; i<24; i++) {
    fTimeDiff[i]   = new TH1F (Form("CFD1minCFD%d",i+1),"fTimeDiff",150, -300, 300);
    fCFD[i]        = new TH1F(Form("CFD%d",i+1),"CFD",250,low, high);//6000, 7000);
    // fCFDvsTimestamp[i] = new TH2F( Form("hCFDvsTimestamp%i", i+1), Form("CFD vs timestamp%i", i+1), nTimeBins, timestart,  timeend,250,low, high );
    fCFDvsTimestamp[i] = new TH2F( Form("hCFDvsTimestamp%i", i+1), Form("CFD vs timestamp%i", i+1), nTimeBins,fStartTime - 300,  fEndTime +300 ,250,low, high );
    // fCFDvsTimestamp[i]->SetName(Form("hCFDvsTimestamp%i", i+1));
    // fCFDvsTimestamp[i]->SetTitle(Form("CFD vs timestamp%i", i+1));
  }

  fTzeroORAplusORC = new TH1F("fTzeroORAplusORC","ORA+ORC /2",200,-4000,4000);   //or A plus or C
  fResolution      = new TH1F("fResolution","fResolution",200,-2000,2000);// or A minus or C spectrum
  fTzeroORA        = new TH1F("fTzeroORA","fTzeroORA",200,-4000,4000);// or A spectrum
  fTzeroORC        = new TH1F("fTzeroORC","fTzeroORC",200,-4000,4000);// or C spectrum
  TString histname[4] = {"hT0AC","hT0A","hT0C","hResolution"};
  for (int icase=0; icase<4; icase++)
    fT0s[icase] = new TH2F(histname[icase].Data(), histname[icase].Data(), 100, 0, 200, 200, -1000, 1000);

  fTzeroObject     = new TObjArray(0);
  fTzeroObject->SetOwner(kTRUE);

  for (Int_t i=0; i<24; i++)
    fTzeroObject->AddAtAndExpand(fTimeDiff[i],i);

  for (Int_t i=0; i<24; i++)
    fTzeroObject->AddAtAndExpand(fCFD[i],i+24); //24 - 48

  fTzeroObject->AddAtAndExpand(fTzeroORAplusORC, 48);
  fTzeroObject->AddAtAndExpand(fResolution, 49);
  fTzeroObject->AddAtAndExpand(fTzeroORA, 50);
  fTzeroObject->AddAtAndExpand(fTzeroORC, 51);
  for (int icase=0; icase<4; icase++)
    fTzeroObject->AddAtAndExpand(fT0s[icase], 52+icase);
  for (int icase=0; icase<24; icase++)
    fTzeroObject->AddAtAndExpand(fCFDvsTimestamp[icase], 56+icase);

  PostData(1, fTzeroObject);
  fEvent=0;
  // Called once
}

//________________________________________________________________________
void AliT0CalibOffsetChannelsTask::UserExec(Option_t *)
{
  // Main loop
  // Called for each event

  // Post output data.

  fESD = dynamic_cast<AliESDEvent*>(InputEvent());
  if (!fESD) {
    printf("ERROR: fESD not available\n");
    return;
  }
  UInt_t timestamp=fESD->GetTimeStamp();
  /*  if (fEvent==0 )
    for (int iii=0; iii<24; iii++)
    fCFDvsTimestamp[iii]->SetBins(121, timestamp-60, timestamp+72000, 250,fCDBcfds[fRefPMTC]-500, fCDBcfds[fRefPMTA] + 500); */
   fEvent++;

  AliESDTZERO* tz= (AliESDTZERO*) fESD->GetESDTZERO();
  Int_t trigT0 = fESD->GetT0Trig();
  Float_t tvdctr = tz->GetTVDC(0);
  Bool_t eq = kTRUE;
  fRunNumber =  fESD->GetRunNumber() ;
  if( fRunNumber<165747) eq = kFALSE;

  const Double32_t* time = fESD->GetT0time();
  const Double32_t* amp = fESD->GetT0amplitude();

  if(tvdctr>-5 && tvdctr<5 && tvdctr!=0) { //event selection
    //    cout<<" tvdc "<<tvdctr<<endl;
    Double32_t diff;
    for (Int_t i=0; i<24; i++) {
      if( time[i] > 0   ){
	if (eq)	{
	  fCFD[i]->Fill( time[i] );//////!!!!!
	  fCFDvsTimestamp[i]->Fill(timestamp,time[i]);
	  if(  time[fRefPMTC] > 0 && i<12)   {
	    diff =  time[i]-time[fRefPMTC];
	    fTimeDiff[i]->Fill( diff);
	  }
	  if(  time[fRefPMTA] >0  && i>11)  {
	    diff =  time[i]-time[fRefPMTA] ;
	    fTimeDiff[i]->Fill( diff);
	  }
	} //eq=1
	else  {
	  fCFD[i]->Fill( time[i] + fCDBdelays[i] );
	  if(  time[fRefPMTC] > 0 && i<12) {
	    diff =  time[i]-time[fRefPMTC] + fCDBdelays[i];
	    fTimeDiff[i]->Fill( diff);
	  } //C
	  if(  time[fRefPMTA] >0  && i>11) {
	    diff =  time[i]-time[fRefPMTA] + fCDBdelays[i];
	    fTimeDiff[i]->Fill( diff);
	  } //A
	} //eq=0
      }

    }
    const Double32_t* mean = fESD->GetT0TOF();
    Double32_t meanTOF = mean[0]  +  fCDBT0s[0] ;
    Double32_t orA = mean[1]  +  fCDBT0s[1] ;
    Double32_t orC = mean[2] + fCDBT0s[2] ;
    Int_t ncont = fESD->GetPrimaryVertexSPD()->GetNContributors();

    if(orA<99999) {
      fTzeroORA->Fill(orA);
       if (ncont>0) fT0s[1]->Fill(ncont, orA);
    }
    if(orC<99999) {
      fTzeroORC->Fill(orC);
       if (ncont>0) fT0s[2]->Fill(ncont, orC);
    }
    if(orA<99999 && orC<99999) {
      fResolution->Fill((orA-orC)/2.);
      fTzeroORAplusORC->Fill(meanTOF);
      if (ncont>0)   {
	fT0s[0]->Fill(ncont,meanTOF );
	fT0s[3]->Fill(ncont,(orA-orC)/2. );
      }
    }
  } //if TVDC on
  PostData(1, fTzeroObject);
}
//________________________________________________________________________
  void AliT0CalibOffsetChannelsTask::Terminate(Option_t *)
{

   // Called once at the end of the query
}
/*
@@@@ start 1495913485 end 1495916316
@@  start 1495913344.000000 end 1495916672.000000 bins 5
*/
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/chrome_cookie_policy.h"

#include "base/string_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/cookie_prompt_modal_dialog_delegate.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/message_box_handler.h"
#include "net/base/net_errors.h"
#include "net/base/static_cookie_policy.h"

// If we queue up more than this number of completions, then switch from ASK to
// BLOCK.  More than this number of requests at once seems like it could be a
// sign of trouble anyways.
static const size_t kMaxCompletionsPerHost = 10000;

// ----------------------------------------------------------------------------

class ChromeCookiePolicy::PromptDelegate
    : public CookiePromptModalDialogDelegate {
 public:
  PromptDelegate(ChromeCookiePolicy* cookie_policy, const std::string& host)
      : cookie_policy_(cookie_policy),
        host_(host) {
  }

  // CookiesPromptViewDelegate methods:
  virtual void AllowSiteData(bool remember, bool session_expire);
  virtual void BlockSiteData(bool remember);

 private:
  scoped_refptr<ChromeCookiePolicy> cookie_policy_;
  std::string host_;
};

void ChromeCookiePolicy::PromptDelegate::AllowSiteData(bool remember,
                                                       bool session_expire) {
  int policy = net::OK;
  if (session_expire)
    policy = net::OK_FOR_SESSION_ONLY;
  cookie_policy_->DidPromptForSetCookie(host_, policy, remember);
}

void ChromeCookiePolicy::PromptDelegate::BlockSiteData(bool remember) {
  cookie_policy_->DidPromptForSetCookie(host_, net::ERR_ACCESS_DENIED,
                                        remember);
}

// ----------------------------------------------------------------------------

ChromeCookiePolicy::ChromeCookiePolicy(HostContentSettingsMap* map)
    : host_content_settings_map_(map) {
}

ChromeCookiePolicy::~ChromeCookiePolicy() {
  DCHECK(host_completions_map_.empty());
}

int ChromeCookiePolicy::CanGetCookies(const GURL& url,
                                      const GURL& first_party,
                                      net::CompletionCallback* callback) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  if (host_content_settings_map_->BlockThirdPartyCookies()) {
    net::StaticCookiePolicy policy(
        net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
    int rv = policy.CanGetCookies(url, first_party, NULL);
    if (rv != net::OK)
      return rv;
  }

  int policy = CheckPolicy(url);
  if (policy != net::ERR_IO_PENDING)
    return policy;

  DCHECK(callback);

  // If we are currently prompting the user for a 'set-cookie' matching this
  // host, then we need to defer reading cookies.
  HostCompletionsMap::iterator it = host_completions_map_.find(url.host());
  if (it == host_completions_map_.end()) {
    policy = net::OK;
  } else if (it->second.size() >= kMaxCompletionsPerHost) {
    LOG(ERROR) << "Would exceed kMaxCompletionsPerHost";
    policy = net::ERR_ACCESS_DENIED;
  } else {
    it->second.push_back(Completion::ForGetCookies(callback));
    policy = net::ERR_IO_PENDING;
  }
  return policy;
}

int ChromeCookiePolicy::CanSetCookie(const GURL& url,
                                     const GURL& first_party,
                                     const std::string& cookie_line,
                                     net::CompletionCallback* callback) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  if (host_content_settings_map_->BlockThirdPartyCookies()) {
    net::StaticCookiePolicy policy(
        net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
    int rv = policy.CanSetCookie(url, first_party, cookie_line, NULL);
    if (rv != net::OK)
      return rv;
  }

  int policy = CheckPolicy(url);
  if (policy != net::ERR_IO_PENDING)
    return policy;

  DCHECK(callback);

  // Else, ask the user...

  Completions& completions = host_completions_map_[url.host()];

  if (completions.size() >= kMaxCompletionsPerHost) {
    LOG(ERROR) << "Would exceed kMaxCompletionsPerHost";
    policy = net::ERR_ACCESS_DENIED;
  } else {
    completions.push_back(Completion::ForSetCookie(callback));
    policy = net::ERR_IO_PENDING;
  }

  PromptForSetCookie(url, cookie_line);
  return policy;
}

int ChromeCookiePolicy::CheckPolicy(const GURL& url) const {
  ContentSetting setting = host_content_settings_map_->GetContentSetting(
      url, CONTENT_SETTINGS_TYPE_COOKIES);
  if (setting == CONTENT_SETTING_BLOCK)
    return net::ERR_ACCESS_DENIED;
  if (setting == CONTENT_SETTING_ALLOW)
    return net::OK;
  return net::ERR_IO_PENDING;  // Need to prompt.
}

void ChromeCookiePolicy::PromptForSetCookie(const GURL& url,
                                            const std::string& cookie_line) {
  if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableMethod(this, &ChromeCookiePolicy::PromptForSetCookie, url,
                          cookie_line));
    return;
  }

  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  const std::string& host = url.host();

  // The policy may have changed (due to the "remember" option)
  int policy = CheckPolicy(url);
  if (policy != net::ERR_IO_PENDING) {
    DidPromptForSetCookie(host, policy, false);
    return;
  }

  // Show the prompt on top of the current tab.
  Browser* browser = BrowserList::GetLastActive();
  if (!browser || !browser->GetSelectedTabContents()) {
    DidPromptForSetCookie(host, net::ERR_ACCESS_DENIED, false);
    return;
  }

#if defined(OS_WIN)
  RunCookiePrompt(browser->GetSelectedTabContents(), url, cookie_line,
                  new PromptDelegate(this, host));
#else
  // TODO(darin): Enable prompting for other ports.
  DidPromptForSetCookie(host, net::ERR_ACCESS_DENIED, false);
#endif
}

void ChromeCookiePolicy::DidPromptForSetCookie(const std::string& host,
                                               int policy, bool remember) {
  if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
    // Process the remember flag immediately.
    if (remember) {
      ContentSetting content_setting = CONTENT_SETTING_BLOCK;
      if (policy == net::OK || policy == net::OK_FOR_SESSION_ONLY)
        content_setting = CONTENT_SETTING_ALLOW;
      host_content_settings_map_->SetContentSetting(
          host, CONTENT_SETTINGS_TYPE_COOKIES, content_setting);
    }

    ChromeThread::PostTask(
        ChromeThread::IO, FROM_HERE,
        NewRunnableMethod(this, &ChromeCookiePolicy::DidPromptForSetCookie,
                          host, policy, remember));
    return;
  }

  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  // Notify all callbacks, starting with the first until we hit another that
  // is for a 'set-cookie'.
  HostCompletionsMap::iterator it = host_completions_map_.find(host);
  CHECK(it != host_completions_map_.end());

  Completions& completions = it->second;
  CHECK(!completions.empty() && completions[0].is_set_cookie_request());

  // Gather the list of callbacks to notify, and remove them from the
  // completions list before handing control to the callbacks (in case
  // they should call back into us to modify host_completions_map_).

  std::vector<net::CompletionCallback*> callbacks;
  callbacks.push_back(completions[0].callback());
  size_t i = 1;
  for (; i < completions.size(); ++i) {
    if (completions[i].is_set_cookie_request())
      break;
    callbacks.push_back(completions[i].callback());
  }
  completions.erase(completions.begin(), completions.begin() + i);

  if (completions.empty())
    host_completions_map_.erase(it);

  for (size_t j = 0; j < callbacks.size(); ++j)
    callbacks[j]->Run(policy);
}
<commit_msg>The PromptDelegate needs to delete itself once it gets a reply.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/chrome_cookie_policy.h"

#include "base/string_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/cookie_prompt_modal_dialog_delegate.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/message_box_handler.h"
#include "net/base/net_errors.h"
#include "net/base/static_cookie_policy.h"

// If we queue up more than this number of completions, then switch from ASK to
// BLOCK.  More than this number of requests at once seems like it could be a
// sign of trouble anyways.
static const size_t kMaxCompletionsPerHost = 10000;

// ----------------------------------------------------------------------------

// ChromeCookiePolicy cannot just subclass the delegate interface because we
// may have several prompts pending.
class ChromeCookiePolicy::PromptDelegate
    : public CookiePromptModalDialogDelegate {
 public:
  PromptDelegate(ChromeCookiePolicy* cookie_policy, const std::string& host)
      : cookie_policy_(cookie_policy),
        host_(host) {
  }

  // CookiesPromptViewDelegate methods:
  virtual void AllowSiteData(bool remember, bool session_expire);
  virtual void BlockSiteData(bool remember);

 private:
  void NotifyDone(int policy, bool remember);

  scoped_refptr<ChromeCookiePolicy> cookie_policy_;
  std::string host_;
};

void ChromeCookiePolicy::PromptDelegate::AllowSiteData(bool remember,
                                                       bool session_expire) {
  int policy = net::OK;
  if (session_expire)
    policy = net::OK_FOR_SESSION_ONLY;
  NotifyDone(policy, remember);
}

void ChromeCookiePolicy::PromptDelegate::BlockSiteData(bool remember) {
  NotifyDone(net::ERR_ACCESS_DENIED, remember);
}

void ChromeCookiePolicy::PromptDelegate::NotifyDone(int policy, bool remember) {
  cookie_policy_->DidPromptForSetCookie(host_, policy, remember);
  delete this;
}

// ----------------------------------------------------------------------------

ChromeCookiePolicy::ChromeCookiePolicy(HostContentSettingsMap* map)
    : host_content_settings_map_(map) {
}

ChromeCookiePolicy::~ChromeCookiePolicy() {
  DCHECK(host_completions_map_.empty());
}

int ChromeCookiePolicy::CanGetCookies(const GURL& url,
                                      const GURL& first_party,
                                      net::CompletionCallback* callback) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  if (host_content_settings_map_->BlockThirdPartyCookies()) {
    net::StaticCookiePolicy policy(
        net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
    int rv = policy.CanGetCookies(url, first_party, NULL);
    if (rv != net::OK)
      return rv;
  }

  int policy = CheckPolicy(url);
  if (policy != net::ERR_IO_PENDING)
    return policy;

  DCHECK(callback);

  // If we are currently prompting the user for a 'set-cookie' matching this
  // host, then we need to defer reading cookies.
  HostCompletionsMap::iterator it = host_completions_map_.find(url.host());
  if (it == host_completions_map_.end()) {
    policy = net::OK;
  } else if (it->second.size() >= kMaxCompletionsPerHost) {
    LOG(ERROR) << "Would exceed kMaxCompletionsPerHost";
    policy = net::ERR_ACCESS_DENIED;
  } else {
    it->second.push_back(Completion::ForGetCookies(callback));
    policy = net::ERR_IO_PENDING;
  }
  return policy;
}

int ChromeCookiePolicy::CanSetCookie(const GURL& url,
                                     const GURL& first_party,
                                     const std::string& cookie_line,
                                     net::CompletionCallback* callback) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  if (host_content_settings_map_->BlockThirdPartyCookies()) {
    net::StaticCookiePolicy policy(
        net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
    int rv = policy.CanSetCookie(url, first_party, cookie_line, NULL);
    if (rv != net::OK)
      return rv;
  }

  int policy = CheckPolicy(url);
  if (policy != net::ERR_IO_PENDING)
    return policy;

  DCHECK(callback);

  // Else, ask the user...

  Completions& completions = host_completions_map_[url.host()];

  if (completions.size() >= kMaxCompletionsPerHost) {
    LOG(ERROR) << "Would exceed kMaxCompletionsPerHost";
    policy = net::ERR_ACCESS_DENIED;
  } else {
    completions.push_back(Completion::ForSetCookie(callback));
    policy = net::ERR_IO_PENDING;
  }

  PromptForSetCookie(url, cookie_line);
  return policy;
}

int ChromeCookiePolicy::CheckPolicy(const GURL& url) const {
  ContentSetting setting = host_content_settings_map_->GetContentSetting(
      url, CONTENT_SETTINGS_TYPE_COOKIES);
  if (setting == CONTENT_SETTING_BLOCK)
    return net::ERR_ACCESS_DENIED;
  if (setting == CONTENT_SETTING_ALLOW)
    return net::OK;
  return net::ERR_IO_PENDING;  // Need to prompt.
}

void ChromeCookiePolicy::PromptForSetCookie(const GURL& url,
                                            const std::string& cookie_line) {
  if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
    ChromeThread::PostTask(
        ChromeThread::UI, FROM_HERE,
        NewRunnableMethod(this, &ChromeCookiePolicy::PromptForSetCookie, url,
                          cookie_line));
    return;
  }

  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  const std::string& host = url.host();

  // The policy may have changed (due to the "remember" option)
  int policy = CheckPolicy(url);
  if (policy != net::ERR_IO_PENDING) {
    DidPromptForSetCookie(host, policy, false);
    return;
  }

  // Show the prompt on top of the current tab.
  Browser* browser = BrowserList::GetLastActive();
  if (!browser || !browser->GetSelectedTabContents()) {
    DidPromptForSetCookie(host, net::ERR_ACCESS_DENIED, false);
    return;
  }

#if defined(OS_WIN)
  RunCookiePrompt(browser->GetSelectedTabContents(), url, cookie_line,
                  new PromptDelegate(this, host));
#else
  // TODO(darin): Enable prompting for other ports.
  DidPromptForSetCookie(host, net::ERR_ACCESS_DENIED, false);
#endif
}

void ChromeCookiePolicy::DidPromptForSetCookie(const std::string& host,
                                               int policy, bool remember) {
  if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
    // Process the remember flag immediately.
    if (remember) {
      ContentSetting content_setting = CONTENT_SETTING_BLOCK;
      if (policy == net::OK || policy == net::OK_FOR_SESSION_ONLY)
        content_setting = CONTENT_SETTING_ALLOW;
      host_content_settings_map_->SetContentSetting(
          host, CONTENT_SETTINGS_TYPE_COOKIES, content_setting);
    }

    ChromeThread::PostTask(
        ChromeThread::IO, FROM_HERE,
        NewRunnableMethod(this, &ChromeCookiePolicy::DidPromptForSetCookie,
                          host, policy, remember));
    return;
  }

  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  // Notify all callbacks, starting with the first until we hit another that
  // is for a 'set-cookie'.
  HostCompletionsMap::iterator it = host_completions_map_.find(host);
  CHECK(it != host_completions_map_.end());

  Completions& completions = it->second;
  CHECK(!completions.empty() && completions[0].is_set_cookie_request());

  // Gather the list of callbacks to notify, and remove them from the
  // completions list before handing control to the callbacks (in case
  // they should call back into us to modify host_completions_map_).

  std::vector<net::CompletionCallback*> callbacks;
  callbacks.push_back(completions[0].callback());
  size_t i = 1;
  for (; i < completions.size(); ++i) {
    if (completions[i].is_set_cookie_request())
      break;
    callbacks.push_back(completions[i].callback());
  }
  completions.erase(completions.begin(), completions.begin() + i);

  if (completions.empty())
    host_completions_map_.erase(it);

  for (size_t j = 0; j < callbacks.size(); ++j)
    callbacks[j]->Run(policy);
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/render_view_context_menu.h"

#include "base/logging.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/template_url_model.h"
#include "webkit/glue/context_node_types.h"

#include "generated_resources.h"

RenderViewContextMenu::RenderViewContextMenu(
    Menu::Delegate* delegate,
    HWND owner,
    ContextNode::Type type,
    const std::wstring& misspelled_word,
    const std::vector<std::wstring>& misspelled_word_suggestions,
    Profile* profile)
    : Menu(delegate, Menu::TOPLEFT, owner),
      misspelled_word_(misspelled_word),
      misspelled_word_suggestions_(misspelled_word_suggestions),
      profile_(profile) {
  InitMenu(type);
}

RenderViewContextMenu::~RenderViewContextMenu() {
}

void RenderViewContextMenu::InitMenu(ContextNode::Type type) {
  switch (type) {
   case ContextNode::PAGE:
    AppendPageItems();
    break;
   case ContextNode::FRAME:
    AppendFrameItems();
    break;
   case ContextNode::LINK:
    AppendLinkItems();
    break;
   case ContextNode::IMAGE:
    AppendImageItems();
    break;
   case ContextNode::IMAGE_LINK:
    AppendLinkItems();
    AppendSeparator();
    AppendImageItems();
    break;
   case ContextNode::SELECTION:
    AppendSelectionItems();
    break;
   case ContextNode::EDITABLE:
    AppendEditableItems();
    break;
   default:
    NOTREACHED() << "Unknown ContextNode::Type";
  }
  AppendSeparator();
  AppendDeveloperItems();
}

void RenderViewContextMenu::AppendDeveloperItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_INSPECTELEMENT);
}

void RenderViewContextMenu::AppendLinkItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKNEWTAB);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVELINKAS);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYLINKLOCATION);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY);
}

void RenderViewContextMenu::AppendImageItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEIMAGEAS);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYIMAGELOCATION);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYIMAGE);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB);
}

void RenderViewContextMenu::AppendPageItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_BACK);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_FORWARD);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_RELOAD);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEPAGEAS);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PRINT);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWPAGESOURCE);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWPAGEINFO);
}

void RenderViewContextMenu::AppendFrameItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_BACK);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_FORWARD);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMENEWTAB);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMENEWWINDOW);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMEOFFTHERECORD);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEFRAMEAS);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PRINTFRAME);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMEINFO);
}

void RenderViewContextMenu::AppendSelectionItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY);
  DCHECK(profile_);
  if (profile_->GetTemplateURLModel()->GetDefaultSearchProvider() != NULL)
    AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SEARCHWEBFOR);
}

void RenderViewContextMenu::AppendEditableItems() {
  // Append Dictionary spell check suggestions.
  for (size_t i = 0; i < misspelled_word_suggestions_.size() &&
       IDC_USESPELLCHECKSUGGESTION_0 + i <= IDC_USESPELLCHECKSUGGESTION_LAST;
       i ++) {
    AppendMenuItemWithLabel(IDC_USESPELLCHECKSUGGESTION_0 + static_cast<int>(i),
                            misspelled_word_suggestions_[i]);
  }
  if (misspelled_word_suggestions_.size() > 0)
    AppendSeparator();

  // If word is misspelled, give option for "Add to dictionary"
  if (!misspelled_word_.empty()) {
    AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY);
    AppendSeparator();
  }

  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_UNDO);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_REDO);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_CUT);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PASTE);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_DELETE);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SELECTALL);
}

<commit_msg>Display "No suggestions found" for misspelled words with no suggestions.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/render_view_context_menu.h"

#include "base/logging.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/template_url_model.h"
#include "chrome/common/l10n_util.h"
#include "webkit/glue/context_node_types.h"

#include "generated_resources.h"

RenderViewContextMenu::RenderViewContextMenu(
    Menu::Delegate* delegate,
    HWND owner,
    ContextNode::Type type,
    const std::wstring& misspelled_word,
    const std::vector<std::wstring>& misspelled_word_suggestions,
    Profile* profile)
    : Menu(delegate, Menu::TOPLEFT, owner),
      misspelled_word_(misspelled_word),
      misspelled_word_suggestions_(misspelled_word_suggestions),
      profile_(profile) {
  InitMenu(type);
}

RenderViewContextMenu::~RenderViewContextMenu() {
}

void RenderViewContextMenu::InitMenu(ContextNode::Type type) {
  switch (type) {
   case ContextNode::PAGE:
    AppendPageItems();
    break;
   case ContextNode::FRAME:
    AppendFrameItems();
    break;
   case ContextNode::LINK:
    AppendLinkItems();
    break;
   case ContextNode::IMAGE:
    AppendImageItems();
    break;
   case ContextNode::IMAGE_LINK:
    AppendLinkItems();
    AppendSeparator();
    AppendImageItems();
    break;
   case ContextNode::SELECTION:
    AppendSelectionItems();
    break;
   case ContextNode::EDITABLE:
    AppendEditableItems();
    break;
   default:
    NOTREACHED() << "Unknown ContextNode::Type";
  }
  AppendSeparator();
  AppendDeveloperItems();
}

void RenderViewContextMenu::AppendDeveloperItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_INSPECTELEMENT);
}

void RenderViewContextMenu::AppendLinkItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKNEWTAB);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKNEWWINDOW);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVELINKAS);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYLINKLOCATION);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY);
}

void RenderViewContextMenu::AppendImageItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEIMAGEAS);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYIMAGELOCATION);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYIMAGE);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB);
}

void RenderViewContextMenu::AppendPageItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_BACK);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_FORWARD);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_RELOAD);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEPAGEAS);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PRINT);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWPAGESOURCE);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWPAGEINFO);
}

void RenderViewContextMenu::AppendFrameItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_BACK);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_FORWARD);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMENEWTAB);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMENEWWINDOW);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENFRAMEOFFTHERECORD);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVEFRAMEAS);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PRINTFRAME);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMESOURCE);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMEINFO);
}

void RenderViewContextMenu::AppendSelectionItems() {
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY);
  DCHECK(profile_);
  if (profile_->GetTemplateURLModel()->GetDefaultSearchProvider() != NULL)
    AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SEARCHWEBFOR);
}

void RenderViewContextMenu::AppendEditableItems() {
  // Append Dictionary spell check suggestions.
  for (size_t i = 0; i < misspelled_word_suggestions_.size() &&
       IDC_USESPELLCHECKSUGGESTION_0 + i <= IDC_USESPELLCHECKSUGGESTION_LAST;
       i ++) {
    AppendMenuItemWithLabel(IDC_USESPELLCHECKSUGGESTION_0 + static_cast<int>(i),
                            misspelled_word_suggestions_[i]);
  }
  if (misspelled_word_suggestions_.size() > 0)
    AppendSeparator();

  // If word is misspelled, give option for "Add to dictionary"
  if (!misspelled_word_.empty()) {
    if (misspelled_word_suggestions_.size() == 0) {
      AppendMenuItemWithLabel(0,
          l10n_util::GetString(IDS_CONTENT_CONTEXT_NO_SPELLING_SUGGESTIONS));
    }
    AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_ADD_TO_DICTIONARY);
    AppendSeparator();
  }

  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_UNDO);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_REDO);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_CUT);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_PASTE);
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_DELETE);
  AppendSeparator();
  AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SELECTALL);
}

<|endoftext|>