<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 "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/test/test_file_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/download/download_item.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/net/url_request_mock_http_job.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// Variation of DownloadsCompleteObserver from ui_test_utils.cc; the
// specifically targeted download tests need finer granularity on waiting.
// Construction of this class defines a system state, based on some number
// of downloads being seen in a particular state + other events that
// may occur in the download system.  That state will be recorded if it
// occurs at any point after construction.  When that state occurs, the class
// is considered finished.  Callers may either probe for the finished state, or
// wait on it.
class DownloadsObserver : public DownloadManager::Observer,
                          public DownloadItem::Observer {
 public:
  // The action which should be considered the completion of the download.
  enum DownloadFinishedSignal { COMPLETE, FILE_RENAME };

  // Create an object that will be considered completed when |wait_count|
  // download items have entered state |download_finished_signal|.
  // If |finish_on_select_file| is true, the object will also be
  // considered finished if the DownloadManager raises a
  // SelectFileDialogDisplayed() notification.

  // TODO(rdsmith): Add option of "dangerous accept/reject dialog" as
  // a unblocking event; if that shows up when you aren't expecting it,
  // it'll result in a hang/timeout as we'll never get to final rename.
  // This probably means rewriting the interface to take a list of events
  // to treat as completion events.
  DownloadsObserver(DownloadManager* download_manager,
                    size_t wait_count,
                    DownloadFinishedSignal download_finished_signal,
                    bool finish_on_select_file)
      : download_manager_(download_manager),
        wait_count_(wait_count),
        finished_downloads_at_construction_(0),
        waiting_(false),
        download_finished_signal_(download_finished_signal),
        finish_on_select_file_(finish_on_select_file),
        select_file_dialog_seen_(false) {
    download_manager_->AddObserver(this);  // Will call initial ModelChanged().
    finished_downloads_at_construction_ = finished_downloads_.size();
  }

  ~DownloadsObserver() {
    std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
    for (; it != downloads_observed_.end(); ++it) {
      (*it)->RemoveObserver(this);
    }
    download_manager_->RemoveObserver(this);
  }

  // State accessors.
  bool select_file_dialog_seen() { return select_file_dialog_seen_; }

  // Wait for whatever state was specified in the constructor.
  void WaitForFinished() {
    if (!IsFinished()) {
      waiting_ = true;
      ui_test_utils::RunMessageLoop();
      waiting_ = false;
    }
  }

  // Return true if everything's happened that we're configured for.
  bool IsFinished() {
    if (finished_downloads_.size() - finished_downloads_at_construction_
        >= wait_count_)
      return true;
    return (finish_on_select_file_ && select_file_dialog_seen_);
  }

  // DownloadItem::Observer
  virtual void OnDownloadUpdated(DownloadItem* download) {
    if (download_finished_signal_ == COMPLETE &&
        download->state() == DownloadItem::COMPLETE)
      DownloadInFinalState(download);
  }

  virtual void OnDownloadFileCompleted(DownloadItem* download) {
    if (download_finished_signal_ == FILE_RENAME)
      DownloadInFinalState(download);
  }

  virtual void OnDownloadOpened(DownloadItem* download) {}

  // DownloadManager::Observer
  virtual void ModelChanged() {
    // Regenerate DownloadItem observers.  If there are any download items
    // in the COMPLETE state and that's our final state, note them in
    // finished_downloads_ (done by OnDownloadUpdated).
    std::vector<DownloadItem*> downloads;
    download_manager_->SearchDownloads(string16(), &downloads);

    std::vector<DownloadItem*>::iterator it = downloads.begin();
    for (; it != downloads.end(); ++it) {
      OnDownloadUpdated(*it);  // Safe to call multiple times; checks state.

      std::set<DownloadItem*>::const_iterator
          finished_it(finished_downloads_.find(*it));
      std::set<DownloadItem*>::const_iterator
          observed_it(downloads_observed_.find(*it));

      // If it isn't finished and we're aren't observing it, start.
      if (finished_it == finished_downloads_.end() &&
          observed_it == downloads_observed_.end()) {
        (*it)->AddObserver(this);
        downloads_observed_.insert(*it);
        continue;
      }

      // If it is finished and we are observing it, stop.
      if (finished_it != finished_downloads_.end() &&
          observed_it != downloads_observed_.end()) {
        (*it)->RemoveObserver(this);
        downloads_observed_.erase(observed_it);
        continue;
      }
    }
  }

  virtual void SelectFileDialogDisplayed() {
    select_file_dialog_seen_ = true;
    SignalIfFinished();
  }

 private:
  // Called when we know that a download item is in a final state.
  // Note that this is not the same as it first transitioning in to the
  // final state; in the case of DownloadItem::COMPLETE, multiple
  // notifications may occur once the item is in that state.  So we
  // keep our own track of transitions into final.
  void DownloadInFinalState(DownloadItem* download) {
    if (finished_downloads_.find(download) != finished_downloads_.end()) {
      // We've already seen terminal state on this download.
      return;
    }

    // Record the transition.
    finished_downloads_.insert(download);

    SignalIfFinished();
  }

  void SignalIfFinished() {
    if (waiting_ && IsFinished())
      MessageLoopForUI::current()->Quit();
  }

  // The observed download manager.
  DownloadManager* download_manager_;

  // The set of DownloadItem's that have transitioned to their finished state
  // since construction of this object.  When the size of this array
  // reaches wait_count_, we're done.
  std::set<DownloadItem*> finished_downloads_;

  // The set of DownloadItem's we are currently observing.  Generally there
  // won't be any overlap with the above; once we see the final state
  // on a DownloadItem, we'll stop observing it.
  std::set<DownloadItem*> downloads_observed_;

  // The number of downloads to wait on completing.
  size_t wait_count_;

  // The number of downloads entered in final state in initial
  // ModelChanged().  We use |finished_downloads_| to track the incoming
  // transitions to final state we should ignore, and to track the
  // number of final state transitions that occurred between
  // construction and return from wait.  But if the final state is the
  // COMPLETE state, some downloads may be in it (and thus be entered
  // into finished_downloads_) when we construct this class.  We don't
  // want to count those;
  int finished_downloads_at_construction_;

  // Whether an internal message loop has been started and must be quit upon
  // all downloads completing.
  bool waiting_;

  // The action on which to consider the DownloadItem finished.
  DownloadFinishedSignal download_finished_signal_;

  // True if we should transition the DownloadsObserver to finished if
  // the select file dialog comes up.
  bool finish_on_select_file_;

  // True if we've seen the select file dialog.
  bool select_file_dialog_seen_;

  DISALLOW_COPY_AND_ASSIGN(DownloadsObserver);
};

class DownloadTest : public InProcessBrowserTest {
 protected:
  void SetUpInProcessBrowserTestFixture() {
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));
  }

  // Must be called after browser creation.  Creates a temporary
  // directory for downloads that is auto-deleted on destruction.
  bool CreateAndSetDownloadsDirectory() {
    if (downloads_directory_.CreateUniqueTempDir()) {
      browser()->profile()->GetPrefs()->SetFilePath(
          prefs::kDownloadDefaultDirectory,
          downloads_directory_.path());
      return true;
    }
    return false;
  }

  // May only be called inside of an individual test; browser() is NULL
  // outside of that context.
  FilePath GetDownloadDirectory() {
    DownloadManager* download_mananger =
        browser()->profile()->GetDownloadManager();
    return download_mananger->download_prefs()->download_path();
  }

  DownloadsObserver* CreateWaiter(int num_downloads) {
    DownloadManager* download_manager =
        browser()->profile()->GetDownloadManager();
    return new DownloadsObserver(
        download_manager, num_downloads,
        DownloadsObserver::FILE_RENAME,  // Really done
        true);                          // Bail on select file
  }

  // Should only be called when the download is known to have finished
  // (in error or not).
  void CheckDownload(const FilePath& downloaded_filename,
                     const FilePath& origin_filename) {
    // Find the path to which the data will be downloaded.
    FilePath downloaded_file =
        GetDownloadDirectory().Append(downloaded_filename);

    // Find the origin path (from which the data comes).
    FilePath origin_file(test_dir_.Append(origin_filename));
    ASSERT_TRUE(file_util::PathExists(origin_file));

    // Confirm the downloaded data file exists.
    ASSERT_TRUE(file_util::PathExists(downloaded_file));
    int64 origin_file_size = 0;
    int64 downloaded_file_size = 0;
    EXPECT_TRUE(file_util::GetFileSize(origin_file, &origin_file_size));
    EXPECT_TRUE(file_util::GetFileSize(downloaded_file, &downloaded_file_size));
    EXPECT_EQ(origin_file_size, downloaded_file_size);
    EXPECT_TRUE(file_util::ContentsEqual(downloaded_file, origin_file));

#if defined(OS_WIN)
    // Check if the Zone Identifier is correctly set.
    if (file_util::VolumeSupportsADS(downloaded_file))
      EXPECT_TRUE(file_util::HasInternetZoneIdentifier(downloaded_file));
#endif

    // Delete the downloaded copy of the file.
    EXPECT_TRUE(file_util::DieFileDie(downloaded_file, false));
  }

 private:
  // Location of the test data.
  FilePath test_dir_;

  // Location of the downloads directory for these tests
  ScopedTempDir downloads_directory_;
};

// Test is believed good (non-flaky) in itself, but it
// sometimes trips over underlying flakiness in the downloads
// subsystem in in http://crbug.com/63237.  Until that bug is
// fixed, this test should be considered flaky.  It's entered as
// DISABLED since if 63237 does cause a failure, it'll be a timeout.
IN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeType) {
  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
  ASSERT_TRUE(CreateAndSetDownloadsDirectory());

  EXPECT_EQ(1, browser()->tab_count());

  // Setup notification, navigate, and block.
  scoped_ptr<DownloadsObserver> observer(CreateWaiter(1));
  ui_test_utils::NavigateToURL(
      browser(), URLRequestMockHTTPJob::GetMockUrl(file));
  observer->WaitForFinished();

  // Download should be finished; check state.
  EXPECT_FALSE(observer->select_file_dialog_seen());
  EXPECT_EQ(1, browser()->tab_count());
  CheckDownload(file, file);
  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
}

// This test runs correctly, but leaves behind turds in the test user's
// download directory because of http://crbug.com/62099.  No big loss; it
// was primarily confirming DownloadsObserver wait on select file dialog
// functionality anyway.
IN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeTypeSelect) {
  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
  ASSERT_TRUE(CreateAndSetDownloadsDirectory());
  browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload, true);

  EXPECT_EQ(1, browser()->tab_count());

  // Setup notification, navigate, and block.
  scoped_ptr<DownloadsObserver> observer(CreateWaiter(1));
  ui_test_utils::NavigateToURL(
      browser(), URLRequestMockHTTPJob::GetMockUrl(file));
  observer->WaitForFinished();

  // Download should not be finished; check state.
  EXPECT_TRUE(observer->select_file_dialog_seen());
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
}

}  // namespace
<commit_msg>Fix the Visual Studio 2005 build.<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 "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/test/test_file_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/download/download_item.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/net/url_request_mock_http_job.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// Variation of DownloadsCompleteObserver from ui_test_utils.cc; the
// specifically targeted download tests need finer granularity on waiting.
// Construction of this class defines a system state, based on some number
// of downloads being seen in a particular state + other events that
// may occur in the download system.  That state will be recorded if it
// occurs at any point after construction.  When that state occurs, the class
// is considered finished.  Callers may either probe for the finished state, or
// wait on it.
class DownloadsObserver : public DownloadManager::Observer,
                          public DownloadItem::Observer {
 public:
  // The action which should be considered the completion of the download.
  enum DownloadFinishedSignal { COMPLETE, FILE_RENAME };

  // Create an object that will be considered completed when |wait_count|
  // download items have entered state |download_finished_signal|.
  // If |finish_on_select_file| is true, the object will also be
  // considered finished if the DownloadManager raises a
  // SelectFileDialogDisplayed() notification.

  // TODO(rdsmith): Add option of "dangerous accept/reject dialog" as
  // a unblocking event; if that shows up when you aren't expecting it,
  // it'll result in a hang/timeout as we'll never get to final rename.
  // This probably means rewriting the interface to take a list of events
  // to treat as completion events.
  DownloadsObserver(DownloadManager* download_manager,
                    size_t wait_count,
                    DownloadFinishedSignal download_finished_signal,
                    bool finish_on_select_file)
      : download_manager_(download_manager),
        wait_count_(wait_count),
        finished_downloads_at_construction_(0),
        waiting_(false),
        download_finished_signal_(download_finished_signal),
        finish_on_select_file_(finish_on_select_file),
        select_file_dialog_seen_(false) {
    download_manager_->AddObserver(this);  // Will call initial ModelChanged().
    finished_downloads_at_construction_ = finished_downloads_.size();
  }

  ~DownloadsObserver() {
    std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
    for (; it != downloads_observed_.end(); ++it) {
      (*it)->RemoveObserver(this);
    }
    download_manager_->RemoveObserver(this);
  }

  // State accessors.
  bool select_file_dialog_seen() { return select_file_dialog_seen_; }

  // Wait for whatever state was specified in the constructor.
  void WaitForFinished() {
    if (!IsFinished()) {
      waiting_ = true;
      ui_test_utils::RunMessageLoop();
      waiting_ = false;
    }
  }

  // Return true if everything's happened that we're configured for.
  bool IsFinished() {
    if (finished_downloads_.size() - finished_downloads_at_construction_
        >= wait_count_)
      return true;
    return (finish_on_select_file_ && select_file_dialog_seen_);
  }

  // DownloadItem::Observer
  virtual void OnDownloadUpdated(DownloadItem* download) {
    if (download_finished_signal_ == COMPLETE &&
        download->state() == DownloadItem::COMPLETE)
      DownloadInFinalState(download);
  }

  virtual void OnDownloadFileCompleted(DownloadItem* download) {
    if (download_finished_signal_ == FILE_RENAME)
      DownloadInFinalState(download);
  }

  virtual void OnDownloadOpened(DownloadItem* download) {}

  // DownloadManager::Observer
  virtual void ModelChanged() {
    // Regenerate DownloadItem observers.  If there are any download items
    // in the COMPLETE state and that's our final state, note them in
    // finished_downloads_ (done by OnDownloadUpdated).
    std::vector<DownloadItem*> downloads;
    download_manager_->SearchDownloads(string16(), &downloads);

    std::vector<DownloadItem*>::iterator it = downloads.begin();
    for (; it != downloads.end(); ++it) {
      OnDownloadUpdated(*it);  // Safe to call multiple times; checks state.

      std::set<DownloadItem*>::const_iterator
          finished_it(finished_downloads_.find(*it));
      std::set<DownloadItem*>::iterator
          observed_it(downloads_observed_.find(*it));

      // If it isn't finished and we're aren't observing it, start.
      if (finished_it == finished_downloads_.end() &&
          observed_it == downloads_observed_.end()) {
        (*it)->AddObserver(this);
        downloads_observed_.insert(*it);
        continue;
      }

      // If it is finished and we are observing it, stop.
      if (finished_it != finished_downloads_.end() &&
          observed_it != downloads_observed_.end()) {
        (*it)->RemoveObserver(this);
        downloads_observed_.erase(observed_it);
        continue;
      }
    }
  }

  virtual void SelectFileDialogDisplayed() {
    select_file_dialog_seen_ = true;
    SignalIfFinished();
  }

 private:
  // Called when we know that a download item is in a final state.
  // Note that this is not the same as it first transitioning in to the
  // final state; in the case of DownloadItem::COMPLETE, multiple
  // notifications may occur once the item is in that state.  So we
  // keep our own track of transitions into final.
  void DownloadInFinalState(DownloadItem* download) {
    if (finished_downloads_.find(download) != finished_downloads_.end()) {
      // We've already seen terminal state on this download.
      return;
    }

    // Record the transition.
    finished_downloads_.insert(download);

    SignalIfFinished();
  }

  void SignalIfFinished() {
    if (waiting_ && IsFinished())
      MessageLoopForUI::current()->Quit();
  }

  // The observed download manager.
  DownloadManager* download_manager_;

  // The set of DownloadItem's that have transitioned to their finished state
  // since construction of this object.  When the size of this array
  // reaches wait_count_, we're done.
  std::set<DownloadItem*> finished_downloads_;

  // The set of DownloadItem's we are currently observing.  Generally there
  // won't be any overlap with the above; once we see the final state
  // on a DownloadItem, we'll stop observing it.
  std::set<DownloadItem*> downloads_observed_;

  // The number of downloads to wait on completing.
  size_t wait_count_;

  // The number of downloads entered in final state in initial
  // ModelChanged().  We use |finished_downloads_| to track the incoming
  // transitions to final state we should ignore, and to track the
  // number of final state transitions that occurred between
  // construction and return from wait.  But if the final state is the
  // COMPLETE state, some downloads may be in it (and thus be entered
  // into finished_downloads_) when we construct this class.  We don't
  // want to count those;
  int finished_downloads_at_construction_;

  // Whether an internal message loop has been started and must be quit upon
  // all downloads completing.
  bool waiting_;

  // The action on which to consider the DownloadItem finished.
  DownloadFinishedSignal download_finished_signal_;

  // True if we should transition the DownloadsObserver to finished if
  // the select file dialog comes up.
  bool finish_on_select_file_;

  // True if we've seen the select file dialog.
  bool select_file_dialog_seen_;

  DISALLOW_COPY_AND_ASSIGN(DownloadsObserver);
};

class DownloadTest : public InProcessBrowserTest {
 protected:
  void SetUpInProcessBrowserTestFixture() {
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));
  }

  // Must be called after browser creation.  Creates a temporary
  // directory for downloads that is auto-deleted on destruction.
  bool CreateAndSetDownloadsDirectory() {
    if (downloads_directory_.CreateUniqueTempDir()) {
      browser()->profile()->GetPrefs()->SetFilePath(
          prefs::kDownloadDefaultDirectory,
          downloads_directory_.path());
      return true;
    }
    return false;
  }

  // May only be called inside of an individual test; browser() is NULL
  // outside of that context.
  FilePath GetDownloadDirectory() {
    DownloadManager* download_mananger =
        browser()->profile()->GetDownloadManager();
    return download_mananger->download_prefs()->download_path();
  }

  DownloadsObserver* CreateWaiter(int num_downloads) {
    DownloadManager* download_manager =
        browser()->profile()->GetDownloadManager();
    return new DownloadsObserver(
        download_manager, num_downloads,
        DownloadsObserver::FILE_RENAME,  // Really done
        true);                          // Bail on select file
  }

  // Should only be called when the download is known to have finished
  // (in error or not).
  void CheckDownload(const FilePath& downloaded_filename,
                     const FilePath& origin_filename) {
    // Find the path to which the data will be downloaded.
    FilePath downloaded_file =
        GetDownloadDirectory().Append(downloaded_filename);

    // Find the origin path (from which the data comes).
    FilePath origin_file(test_dir_.Append(origin_filename));
    ASSERT_TRUE(file_util::PathExists(origin_file));

    // Confirm the downloaded data file exists.
    ASSERT_TRUE(file_util::PathExists(downloaded_file));
    int64 origin_file_size = 0;
    int64 downloaded_file_size = 0;
    EXPECT_TRUE(file_util::GetFileSize(origin_file, &origin_file_size));
    EXPECT_TRUE(file_util::GetFileSize(downloaded_file, &downloaded_file_size));
    EXPECT_EQ(origin_file_size, downloaded_file_size);
    EXPECT_TRUE(file_util::ContentsEqual(downloaded_file, origin_file));

#if defined(OS_WIN)
    // Check if the Zone Identifier is correctly set.
    if (file_util::VolumeSupportsADS(downloaded_file))
      EXPECT_TRUE(file_util::HasInternetZoneIdentifier(downloaded_file));
#endif

    // Delete the downloaded copy of the file.
    EXPECT_TRUE(file_util::DieFileDie(downloaded_file, false));
  }

 private:
  // Location of the test data.
  FilePath test_dir_;

  // Location of the downloads directory for these tests
  ScopedTempDir downloads_directory_;
};

// Test is believed good (non-flaky) in itself, but it
// sometimes trips over underlying flakiness in the downloads
// subsystem in in http://crbug.com/63237.  Until that bug is
// fixed, this test should be considered flaky.  It's entered as
// DISABLED since if 63237 does cause a failure, it'll be a timeout.
IN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeType) {
  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
  ASSERT_TRUE(CreateAndSetDownloadsDirectory());

  EXPECT_EQ(1, browser()->tab_count());

  // Setup notification, navigate, and block.
  scoped_ptr<DownloadsObserver> observer(CreateWaiter(1));
  ui_test_utils::NavigateToURL(
      browser(), URLRequestMockHTTPJob::GetMockUrl(file));
  observer->WaitForFinished();

  // Download should be finished; check state.
  EXPECT_FALSE(observer->select_file_dialog_seen());
  EXPECT_EQ(1, browser()->tab_count());
  CheckDownload(file, file);
  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
}

// This test runs correctly, but leaves behind turds in the test user's
// download directory because of http://crbug.com/62099.  No big loss; it
// was primarily confirming DownloadsObserver wait on select file dialog
// functionality anyway.
IN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeTypeSelect) {
  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
  ASSERT_TRUE(CreateAndSetDownloadsDirectory());
  browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload, true);

  EXPECT_EQ(1, browser()->tab_count());

  // Setup notification, navigate, and block.
  scoped_ptr<DownloadsObserver> observer(CreateWaiter(1));
  ui_test_utils::NavigateToURL(
      browser(), URLRequestMockHTTPJob::GetMockUrl(file));
  observer->WaitForFinished();

  // Download should not be finished; check state.
  EXPECT_TRUE(observer->select_file_dialog_seen());
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
}

}  // namespace
<|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 "base/string_util.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/extension.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/json_value_serializer.h"
#include "testing/gtest/include/gtest/gtest.h"

class ExtensionTest : public testing::Test {
};

TEST(ExtensionTest, InitFromValueInvalid) {
#if defined(OS_WIN)
  FilePath path(FILE_PATH_LITERAL("c:\\foo"));
#elif defined(OS_POSIX)
  FilePath path(FILE_PATH_LITERAL("/foo"));
#endif
  Extension extension(path);
  std::string error;

  // Start with a valid extension manifest
  std::wstring extensions_dir;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_dir));
  FilePath extensions_path = FilePath::FromWStringHack(extensions_dir)
      .AppendASCII("extensions")
      .AppendASCII("good")
      .AppendASCII("extension1")
      .AppendASCII("1")
      .AppendASCII(Extension::kManifestFilename);

  JSONFileValueSerializer serializer(extensions_path.ToWStringHack());
  scoped_ptr<DictionaryValue> valid_value(
      static_cast<DictionaryValue*>(serializer.Deserialize(&error)));
  ASSERT_TRUE(valid_value.get());
  ASSERT_EQ("", error);
  ASSERT_TRUE(extension.InitFromValue(*valid_value, &error));
  ASSERT_EQ("", error);

  scoped_ptr<DictionaryValue> input_value;

  // Test missing and invalid format versions
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->Remove(Extension::kFormatVersionKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidFormatVersionError, error);

  input_value->SetString(Extension::kFormatVersionKey, "foo");
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidFormatVersionError, error);

  input_value->SetInteger(Extension::kFormatVersionKey, 2);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidFormatVersionError, error);

  // Test missing and invalid ids
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->Remove(Extension::kIdKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidIdError, error);

  input_value->SetInteger(Extension::kIdKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidIdError, error);

  // Test missing and invalid versions
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->Remove(Extension::kVersionKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidVersionError, error);

  input_value->SetInteger(Extension::kVersionKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidVersionError, error);

  // Test missing and invalid names
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->Remove(Extension::kNameKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidNameError, error);

  input_value->SetInteger(Extension::kNameKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidNameError, error);

  // Test invalid description
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->SetInteger(Extension::kDescriptionKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidDescriptionError, error);

  // Test invalid user scripts list
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->SetInteger(Extension::kContentScriptsKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidContentScriptsListError, error);

  // Test invalid user script item
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  ListValue* content_scripts = NULL;
  input_value->GetList(Extension::kContentScriptsKey, &content_scripts);
  ASSERT_FALSE(NULL == content_scripts);
  content_scripts->Set(0, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidContentScriptError));

  // Test missing and invalid matches array
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->GetList(Extension::kContentScriptsKey, &content_scripts);
  DictionaryValue* user_script = NULL;
  content_scripts->GetDictionary(0, &user_script);
  user_script->Remove(Extension::kMatchesKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchesError));

  user_script->Set(Extension::kMatchesKey, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchesError));

  ListValue* matches = new ListValue;
  user_script->Set(Extension::kMatchesKey, matches);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchCountError));

  // Test invalid match element
  matches->Set(0, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchError));

  // Test missing and invalid files array
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->GetList(Extension::kContentScriptsKey, &content_scripts);
  content_scripts->GetDictionary(0, &user_script);
  user_script->Remove(Extension::kJsKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsListError));

  user_script->Set(Extension::kJsKey, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsListError));

  ListValue* files = new ListValue;
  user_script->Set(Extension::kJsKey, files);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsCountError));

  // Test invalid file element
  files->Set(0, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsError));

  // Test too many file elements (more than one not yet supported)
  files->Set(0, Value::CreateStringValue("foo.js"));
  files->Set(1, Value::CreateStringValue("bar.js"));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsCountError));
}

TEST(ExtensionTest, InitFromValueValid) {
#if defined(OS_WIN)
  FilePath path(FILE_PATH_LITERAL("C:\\foo"));
#elif defined(OS_POSIX)
  FilePath path(FILE_PATH_LITERAL("/foo"));
#endif
  Extension extension(path);
  std::string error;
  DictionaryValue input_value;

  // Test minimal extension
  input_value.SetInteger(Extension::kFormatVersionKey, 1);
  input_value.SetString(Extension::kIdKey, "com.google.myextension");
  input_value.SetString(Extension::kVersionKey, "1.0.0.0");
  input_value.SetString(Extension::kNameKey, "my extension");

  EXPECT_TRUE(extension.InitFromValue(input_value, &error));
  EXPECT_EQ("", error);
  EXPECT_EQ("com.google.myextension", extension.id());
  EXPECT_EQ("1.0.0.0", extension.VersionString());
  EXPECT_EQ("my extension", extension.name());
  EXPECT_EQ("chrome-extension://com.google.myextension/",
            extension.url().spec());
  EXPECT_EQ(path.value(), extension.path().value());
}

TEST(ExtensionTest, GetResourceURLAndPath) {
#if defined(OS_WIN)
  FilePath path(FILE_PATH_LITERAL("C:\\foo"));
#elif defined(OS_POSIX)
  FilePath path(FILE_PATH_LITERAL("/foo"));
#endif
  Extension extension(path);
  DictionaryValue input_value;
  input_value.SetInteger(Extension::kFormatVersionKey, 1);
  input_value.SetString(Extension::kIdKey, "com.google.myextension");
  input_value.SetString(Extension::kVersionKey, "1.0.0.0");
  input_value.SetString(Extension::kNameKey, "my extension");
  EXPECT_TRUE(extension.InitFromValue(input_value, NULL));

  EXPECT_EQ(extension.url().spec() + "bar/baz.js",
            Extension::GetResourceURL(extension.url(), "bar/baz.js").spec());
  EXPECT_EQ(extension.url().spec() + "baz.js",
            Extension::GetResourceURL(extension.url(), "bar/../baz.js").spec());
  EXPECT_EQ(extension.url().spec() + "baz.js",
            Extension::GetResourceURL(extension.url(), "../baz.js").spec());

  EXPECT_EQ(path.Append(FILE_PATH_LITERAL("bar"))
                .Append(FILE_PATH_LITERAL("baz.js")).value(),
            Extension::GetResourcePath(extension.path(), "bar/baz.js").value());
  EXPECT_EQ(path.Append(FILE_PATH_LITERAL("baz.js")).value(),
            Extension::GetResourcePath(extension.path(), "bar/../baz.js")
                .value());
  EXPECT_EQ(FilePath().value(),
            Extension::GetResourcePath(extension.path(), "../baz.js").value());
}
<commit_msg>Fixed a unittest that I missed during my previous id format change.<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 "base/string_util.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/extension.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/json_value_serializer.h"
#include "testing/gtest/include/gtest/gtest.h"

class ExtensionTest : public testing::Test {
};

TEST(ExtensionTest, InitFromValueInvalid) {
#if defined(OS_WIN)
  FilePath path(FILE_PATH_LITERAL("c:\\foo"));
#elif defined(OS_POSIX)
  FilePath path(FILE_PATH_LITERAL("/foo"));
#endif
  Extension extension(path);
  std::string error;

  // Start with a valid extension manifest
  std::wstring extensions_dir;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_dir));
  FilePath extensions_path = FilePath::FromWStringHack(extensions_dir)
      .AppendASCII("extensions")
      .AppendASCII("good")
      .AppendASCII("extension1")
      .AppendASCII("1")
      .AppendASCII(Extension::kManifestFilename);

  JSONFileValueSerializer serializer(extensions_path.ToWStringHack());
  scoped_ptr<DictionaryValue> valid_value(
      static_cast<DictionaryValue*>(serializer.Deserialize(&error)));
  ASSERT_TRUE(valid_value.get());
  ASSERT_EQ("", error);
  ASSERT_TRUE(extension.InitFromValue(*valid_value, &error));
  ASSERT_EQ("", error);

  scoped_ptr<DictionaryValue> input_value;

  // Test missing and invalid format versions
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->Remove(Extension::kFormatVersionKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidFormatVersionError, error);

  input_value->SetString(Extension::kFormatVersionKey, "foo");
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidFormatVersionError, error);

  input_value->SetInteger(Extension::kFormatVersionKey, 2);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidFormatVersionError, error);

  // Test missing and invalid ids
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->Remove(Extension::kIdKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidIdError, error);

  input_value->SetInteger(Extension::kIdKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidIdError, error);

  // Test missing and invalid versions
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->Remove(Extension::kVersionKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidVersionError, error);

  input_value->SetInteger(Extension::kVersionKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidVersionError, error);

  // Test missing and invalid names
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->Remove(Extension::kNameKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidNameError, error);

  input_value->SetInteger(Extension::kNameKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidNameError, error);

  // Test invalid description
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->SetInteger(Extension::kDescriptionKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidDescriptionError, error);

  // Test invalid user scripts list
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->SetInteger(Extension::kContentScriptsKey, 42);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_EQ(Extension::kInvalidContentScriptsListError, error);

  // Test invalid user script item
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  ListValue* content_scripts = NULL;
  input_value->GetList(Extension::kContentScriptsKey, &content_scripts);
  ASSERT_FALSE(NULL == content_scripts);
  content_scripts->Set(0, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidContentScriptError));

  // Test missing and invalid matches array
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->GetList(Extension::kContentScriptsKey, &content_scripts);
  DictionaryValue* user_script = NULL;
  content_scripts->GetDictionary(0, &user_script);
  user_script->Remove(Extension::kMatchesKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchesError));

  user_script->Set(Extension::kMatchesKey, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchesError));

  ListValue* matches = new ListValue;
  user_script->Set(Extension::kMatchesKey, matches);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchCountError));

  // Test invalid match element
  matches->Set(0, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchError));

  // Test missing and invalid files array
  input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
  input_value->GetList(Extension::kContentScriptsKey, &content_scripts);
  content_scripts->GetDictionary(0, &user_script);
  user_script->Remove(Extension::kJsKey, NULL);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsListError));

  user_script->Set(Extension::kJsKey, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsListError));

  ListValue* files = new ListValue;
  user_script->Set(Extension::kJsKey, files);
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsCountError));

  // Test invalid file element
  files->Set(0, Value::CreateIntegerValue(42));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsError));

  // Test too many file elements (more than one not yet supported)
  files->Set(0, Value::CreateStringValue("foo.js"));
  files->Set(1, Value::CreateStringValue("bar.js"));
  EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
  EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsCountError));
}

TEST(ExtensionTest, InitFromValueValid) {
#if defined(OS_WIN)
  FilePath path(FILE_PATH_LITERAL("C:\\foo"));
#elif defined(OS_POSIX)
  FilePath path(FILE_PATH_LITERAL("/foo"));
#endif
  Extension extension(path);
  std::string error;
  DictionaryValue input_value;

  // Test minimal extension
  input_value.SetInteger(Extension::kFormatVersionKey, 1);
  input_value.SetString(Extension::kIdKey,
      "00123456789ABCDEF0123456789ABCDEF0123456");
  input_value.SetString(Extension::kVersionKey, "1.0.0.0");
  input_value.SetString(Extension::kNameKey, "my extension");

  EXPECT_TRUE(extension.InitFromValue(input_value, &error));
  EXPECT_EQ("", error);
  EXPECT_EQ("00123456789ABCDEF0123456789ABCDEF0123456", extension.id());
  EXPECT_EQ("1.0.0.0", extension.VersionString());
  EXPECT_EQ("my extension", extension.name());
  EXPECT_EQ("chrome-extension://00123456789abcdef0123456789abcdef0123456/",
            extension.url().spec());
  EXPECT_EQ(path.value(), extension.path().value());
}

TEST(ExtensionTest, GetResourceURLAndPath) {
#if defined(OS_WIN)
  FilePath path(FILE_PATH_LITERAL("C:\\foo"));
#elif defined(OS_POSIX)
  FilePath path(FILE_PATH_LITERAL("/foo"));
#endif
  Extension extension(path);
  DictionaryValue input_value;
  input_value.SetInteger(Extension::kFormatVersionKey, 1);
  input_value.SetString(Extension::kIdKey,
      "00123456789ABCDEF0123456789ABCDEF0123456");
  input_value.SetString(Extension::kVersionKey, "1.0.0.0");
  input_value.SetString(Extension::kNameKey, "my extension");
  EXPECT_TRUE(extension.InitFromValue(input_value, NULL));

  EXPECT_EQ(extension.url().spec() + "bar/baz.js",
            Extension::GetResourceURL(extension.url(), "bar/baz.js").spec());
  EXPECT_EQ(extension.url().spec() + "baz.js",
            Extension::GetResourceURL(extension.url(), "bar/../baz.js").spec());
  EXPECT_EQ(extension.url().spec() + "baz.js",
            Extension::GetResourceURL(extension.url(), "../baz.js").spec());

  EXPECT_EQ(path.Append(FILE_PATH_LITERAL("bar"))
                .Append(FILE_PATH_LITERAL("baz.js")).value(),
            Extension::GetResourcePath(extension.path(), "bar/baz.js").value());
  EXPECT_EQ(path.Append(FILE_PATH_LITERAL("baz.js")).value(),
            Extension::GetResourcePath(extension.path(), "bar/../baz.js")
                .value());
  EXPECT_EQ(FilePath().value(),
            Extension::GetResourcePath(extension.path(), "../baz.js").value());
}
<|endoftext|>


<commit_before>#include <jni.h>
// To get free disk space
#include <sys/vfs.h>

#include "../../../../../defines.hpp"

#include "../../../../../platform/http_request.hpp"

#include "../../../../../base/logging.hpp"
#include "../../../../../base/string_utils.hpp"

#include "../../../../../coding/zip_reader.hpp"
#include "../../../../../coding/url_encode.hpp"
#include "../../../../../coding/reader_streambuf.hpp"
#include "../../../../../coding/internal/file_data.hpp"

#include "../../../../../platform/platform.hpp"
#include "../../../../../platform/http_request.hpp"

#include "../../../../../std/vector.hpp"
#include "../../../../../std/string.hpp"
#include "../../../../../std/bind.hpp"
#include "../../../../../std/shared_ptr.hpp"

#include "../core/jni_helper.hpp"

#include "Framework.hpp"

// Special error codes to notify GUI about free space
//@{
#define ERR_DOWNLOAD_SUCCESS   0
#define ERR_NOT_ENOUGH_MEMORY     -1
#define ERR_NOT_ENOUGH_FREE_SPACE -2
#define ERR_STORAGE_DISCONNECTED  -3
#define ERR_DOWNLOAD_ERROR -4
#define ERR_NO_MORE_FILES -5
#define ERR_FILE_IN_PROGRESS -6
//@}

struct FileToDownload
{
  vector<string> m_urls;
  string m_fileName;
  string m_pathOnSdcard;
  uint64_t m_fileSize;
};

static string g_apkPath;
static string g_sdcardPath;
static vector<FileToDownload> g_filesToDownload;
static int g_totalDownloadedBytes;
static int g_totalBytesToDownload;
static shared_ptr<downloader::HttpRequest> g_currentRequest;

extern "C"
{
  int HasSpaceForFiles(size_t fileSize)
  {
    struct statfs st;

    if (statfs(g_sdcardPath.c_str(), &st) != 0)
      return ERR_STORAGE_DISCONNECTED;

    if (st.f_bsize * st.f_bavail <= fileSize)
      return ERR_NOT_ENOUGH_FREE_SPACE;

    return fileSize;
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_getBytesToDownload(JNIEnv * env, jobject thiz,
      jstring apkPath, jstring sdcardPath)
  {
    g_apkPath = jni::ToString(apkPath);
    g_sdcardPath = jni::ToString(sdcardPath);

    jint totalBytesToDownload = 0;

    ReaderStreamBuf buffer(GetPlatform().GetReader("external_resources.txt"));

    istream in(&buffer);

    string name;
    int size;

    while (true)
    {
      in >> name;

      if (!in.good())
        break;

      in >> size;

      if (!in.good())
        break;

      FileToDownload f;

      f.m_pathOnSdcard = g_sdcardPath + name;
      f.m_fileName = name;

      uint64_t sizeOnSdcard = 0;
      Platform::GetFileSizeByFullPath(f.m_pathOnSdcard, sizeOnSdcard);

      if (size != sizeOnSdcard)
      {
        LOG(LDEBUG, ("should download : ", name, "sized", size, "bytes"));
        f.m_fileSize = size;
        g_filesToDownload.push_back(f);
        totalBytesToDownload += size;
      }
    }

    g_totalDownloadedBytes = 0;

    int res = HasSpaceForFiles(totalBytesToDownload);

    switch (res)
    {
    case ERR_STORAGE_DISCONNECTED:
      LOG(LWARNING, ("External file system is not available"));
      break;
    case ERR_NOT_ENOUGH_FREE_SPACE:
      LOG(LWARNING, ("Not enough space to extract files"));
      break;
    };

    g_totalBytesToDownload = totalBytesToDownload;
    g_currentRequest.reset();

    return res;
  }

  void DownloadFileFinished(shared_ptr<jobject> obj, downloader::HttpRequest & req)
  {
    int errorCode = 0;

    ASSERT(req.Status() != downloader::HttpRequest::EInProgress, ("should be either Completed or Failed"));

    switch (req.Status())
    {
    case downloader::HttpRequest::ECompleted:
      errorCode = ERR_DOWNLOAD_SUCCESS;
      break;
    case downloader::HttpRequest::EFailed:
      errorCode = ERR_DOWNLOAD_ERROR;
      break;
    };

    g_currentRequest.reset();

    if (errorCode == ERR_DOWNLOAD_SUCCESS)
    {
      FileToDownload & curFile = g_filesToDownload.back();

      /// cleaning up by ourselves
      FileWriter::DeleteFileX(curFile.m_pathOnSdcard + DOWNLOADING_FILE_EXTENSION);
      FileWriter::DeleteFileX(curFile.m_pathOnSdcard + RESUME_FILE_EXTENSION);

      LOG(LDEBUG, ("finished downloading", curFile.m_fileName, "sized", curFile.m_fileSize, "bytes"));

      g_totalDownloadedBytes += curFile.m_fileSize;

      LOG(LDEBUG, ("totalDownloadedBytes:", g_totalDownloadedBytes));

      g_filesToDownload.pop_back();
    }

    JNIEnv * env = jni::GetEnv();

    jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "onDownloadFinished", "(I)V");
    env->CallVoidMethod(*obj.get(), methodID, errorCode);
  }

  void DownloadFileProgress(shared_ptr<jobject> obj, downloader::HttpRequest & req)
  {
    LOG(LDEBUG, (req.Progress().first, "bytes for", g_filesToDownload.back().m_fileName, "was downloaded"));

    FileToDownload & curFile = g_filesToDownload.back();

    jint curTotal = req.Progress().second;
    jint curProgress = req.Progress().first;
    jint glbTotal = g_totalBytesToDownload;
    jint glbProgress = g_totalDownloadedBytes + req.Progress().first;

    JNIEnv * env = jni::GetEnv();

    jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "onDownloadProgress", "(IIII)V");
    env->CallVoidMethod(*obj.get(), methodID,
                         curTotal, curProgress,
                         glbTotal, glbProgress);
  }

  void DownloadURLListFinished(downloader::HttpRequest & req,
      downloader::HttpRequest::CallbackT onFinish,
      downloader::HttpRequest::CallbackT onProgress)
  {
    if (req.Status() == downloader::HttpRequest::EFailed)
      onFinish(req);
    else
    {
      FileToDownload & curFile = g_filesToDownload.back();

      LOG(LDEBUG, ("finished URL list download for", curFile.m_fileName));

      downloader::ParseServerList(req.Data(), curFile.m_urls);

      for (size_t i = 0; i < curFile.m_urls.size(); ++i)
      {
        curFile.m_urls[i] = curFile.m_urls[i] + OMIM_OS_NAME "/"
                          + strings::to_string(g_framework->Storage().GetCurrentVersion()) + "/"
                          + UrlEncode(curFile.m_fileName);
        LOG(LDEBUG, (curFile.m_urls[i]));
      }

      g_currentRequest.reset(downloader::HttpRequest::GetFile(curFile.m_urls,
                                                          curFile.m_pathOnSdcard,
                                                          curFile.m_fileSize,
                                                          onFinish,
                                                          onProgress,
                                                          64 * 1024,
                                                          false));
    }
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_cancelCurrentFile(JNIEnv * env, jobject thiz)
  {
    LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest.get()));
    g_currentRequest.reset();
  }

  JNIEXPORT int JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_startNextFileDownload(JNIEnv * env,
      jobject thiz, jobject observer)
  {
    if (g_filesToDownload.empty())
      return ERR_NO_MORE_FILES;

    FileToDownload & curFile = g_filesToDownload.back();

    LOG(LDEBUG, ("downloading", curFile.m_fileName, "sized", curFile.m_fileSize, "bytes"));

    downloader::HttpRequest::CallbackT onFinish(bind(&DownloadFileFinished, jni::make_global_ref(observer), _1));
    downloader::HttpRequest::CallbackT onProgress(bind(&DownloadFileProgress, jni::make_global_ref(observer), _1));

    g_currentRequest.reset(downloader::HttpRequest::PostJson(GetPlatform().MetaServerUrl(),
                                                         curFile.m_fileName,
                                                         bind(&DownloadURLListFinished, _1,
                                                             onFinish,
                                                             onProgress)));

    return ERR_FILE_IN_PROGRESS;
  }

  // Move downloaded maps from /sdcard/Android/data/com.mapswithme.maps/files/
  // to /sdcard/MapsWithMe
  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_moveMaps(JNIEnv * env, jobject thiz,
      jstring fromPath, jstring toPath)
  {
    string from = jni::ToString(fromPath);
    string to = jni::ToString(toPath);

    Platform & pl = GetPlatform();
    Platform::FilesList files;
    // Move *.mwm files
    pl.GetFilesInDir(from, "*" DATA_FILE_EXTENSION, files);
    for (size_t i = 0; i < files.size(); ++i)
    {
      LOG(LDEBUG, ("moving map from:", from + files[i], ", to:", to + files[i]));
      my::RenameFileX((from + files[i]).c_str(), (to + files[i]).c_str());
    }

    // Delete not finished *.downloading files
    files.clear();
    pl.GetFilesInDir(from, "*" DOWNLOADING_FILE_EXTENSION, files);
    pl.GetFilesInDir(from, "*" RESUME_FILE_EXTENSION, files);
    for (size_t i = 0; i < files.size(); ++i)
      my::DeleteFileX((from + files[i]).c_str());
  }

  JNIEXPORT jstring JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_findCountryByPos(JNIEnv * env, jobject thiz,
      jdouble lat, jdouble lon)
  {
    double x = MercatorBounds::LonToX(lon);
    double y = MercatorBounds::LatToY(lat);

    string name = g_framework->GetCountryName(x, y);

    return env->NewStringUTF(name.c_str());
  }
}
<commit_msg>removed unnecessary code for partial and resume files deletion.<commit_after>#include <jni.h>
// To get free disk space
#include <sys/vfs.h>

#include "../../../../../defines.hpp"

#include "../../../../../platform/http_request.hpp"

#include "../../../../../base/logging.hpp"
#include "../../../../../base/string_utils.hpp"

#include "../../../../../coding/zip_reader.hpp"
#include "../../../../../coding/url_encode.hpp"
#include "../../../../../coding/reader_streambuf.hpp"
#include "../../../../../coding/internal/file_data.hpp"

#include "../../../../../platform/platform.hpp"
#include "../../../../../platform/http_request.hpp"

#include "../../../../../std/vector.hpp"
#include "../../../../../std/string.hpp"
#include "../../../../../std/bind.hpp"
#include "../../../../../std/shared_ptr.hpp"

#include "../core/jni_helper.hpp"

#include "Framework.hpp"

// Special error codes to notify GUI about free space
//@{
#define ERR_DOWNLOAD_SUCCESS   0
#define ERR_NOT_ENOUGH_MEMORY     -1
#define ERR_NOT_ENOUGH_FREE_SPACE -2
#define ERR_STORAGE_DISCONNECTED  -3
#define ERR_DOWNLOAD_ERROR -4
#define ERR_NO_MORE_FILES -5
#define ERR_FILE_IN_PROGRESS -6
//@}

struct FileToDownload
{
  vector<string> m_urls;
  string m_fileName;
  string m_pathOnSdcard;
  uint64_t m_fileSize;
};

static string g_apkPath;
static string g_sdcardPath;
static vector<FileToDownload> g_filesToDownload;
static int g_totalDownloadedBytes;
static int g_totalBytesToDownload;
static shared_ptr<downloader::HttpRequest> g_currentRequest;

extern "C"
{
  int HasSpaceForFiles(size_t fileSize)
  {
    struct statfs st;

    if (statfs(g_sdcardPath.c_str(), &st) != 0)
      return ERR_STORAGE_DISCONNECTED;

    if (st.f_bsize * st.f_bavail <= fileSize)
      return ERR_NOT_ENOUGH_FREE_SPACE;

    return fileSize;
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_getBytesToDownload(JNIEnv * env, jobject thiz,
      jstring apkPath, jstring sdcardPath)
  {
    g_apkPath = jni::ToString(apkPath);
    g_sdcardPath = jni::ToString(sdcardPath);

    jint totalBytesToDownload = 0;

    ReaderStreamBuf buffer(GetPlatform().GetReader("external_resources.txt"));

    istream in(&buffer);

    string name;
    int size;

    while (true)
    {
      in >> name;

      if (!in.good())
        break;

      in >> size;

      if (!in.good())
        break;

      FileToDownload f;

      f.m_pathOnSdcard = g_sdcardPath + name;
      f.m_fileName = name;

      uint64_t sizeOnSdcard = 0;
      Platform::GetFileSizeByFullPath(f.m_pathOnSdcard, sizeOnSdcard);

      if (size != sizeOnSdcard)
      {
        LOG(LDEBUG, ("should download : ", name, "sized", size, "bytes"));
        f.m_fileSize = size;
        g_filesToDownload.push_back(f);
        totalBytesToDownload += size;
      }
    }

    g_totalDownloadedBytes = 0;

    int res = HasSpaceForFiles(totalBytesToDownload);

    switch (res)
    {
    case ERR_STORAGE_DISCONNECTED:
      LOG(LWARNING, ("External file system is not available"));
      break;
    case ERR_NOT_ENOUGH_FREE_SPACE:
      LOG(LWARNING, ("Not enough space to extract files"));
      break;
    };

    g_totalBytesToDownload = totalBytesToDownload;
    g_currentRequest.reset();

    return res;
  }

  void DownloadFileFinished(shared_ptr<jobject> obj, downloader::HttpRequest & req)
  {
    int errorCode = 0;

    ASSERT(req.Status() != downloader::HttpRequest::EInProgress, ("should be either Completed or Failed"));

    switch (req.Status())
    {
    case downloader::HttpRequest::ECompleted:
      errorCode = ERR_DOWNLOAD_SUCCESS;
      break;
    case downloader::HttpRequest::EFailed:
      errorCode = ERR_DOWNLOAD_ERROR;
      break;
    };

    g_currentRequest.reset();

    if (errorCode == ERR_DOWNLOAD_SUCCESS)
    {
      FileToDownload & curFile = g_filesToDownload.back();

      LOG(LDEBUG, ("finished downloading", curFile.m_fileName, "sized", curFile.m_fileSize, "bytes"));

      g_totalDownloadedBytes += curFile.m_fileSize;

      LOG(LDEBUG, ("totalDownloadedBytes:", g_totalDownloadedBytes));

      g_filesToDownload.pop_back();
    }

    JNIEnv * env = jni::GetEnv();

    jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "onDownloadFinished", "(I)V");
    env->CallVoidMethod(*obj.get(), methodID, errorCode);
  }

  void DownloadFileProgress(shared_ptr<jobject> obj, downloader::HttpRequest & req)
  {
    LOG(LDEBUG, (req.Progress().first, "bytes for", g_filesToDownload.back().m_fileName, "was downloaded"));

    FileToDownload & curFile = g_filesToDownload.back();

    jint curTotal = req.Progress().second;
    jint curProgress = req.Progress().first;
    jint glbTotal = g_totalBytesToDownload;
    jint glbProgress = g_totalDownloadedBytes + req.Progress().first;

    JNIEnv * env = jni::GetEnv();

    jmethodID methodID = jni::GetJavaMethodID(env, *obj.get(), "onDownloadProgress", "(IIII)V");
    env->CallVoidMethod(*obj.get(), methodID,
                         curTotal, curProgress,
                         glbTotal, glbProgress);
  }

  void DownloadURLListFinished(downloader::HttpRequest & req,
      downloader::HttpRequest::CallbackT onFinish,
      downloader::HttpRequest::CallbackT onProgress)
  {
    if (req.Status() == downloader::HttpRequest::EFailed)
      onFinish(req);
    else
    {
      FileToDownload & curFile = g_filesToDownload.back();

      LOG(LDEBUG, ("finished URL list download for", curFile.m_fileName));

      downloader::ParseServerList(req.Data(), curFile.m_urls);

      for (size_t i = 0; i < curFile.m_urls.size(); ++i)
      {
        curFile.m_urls[i] = curFile.m_urls[i] + OMIM_OS_NAME "/"
                          + strings::to_string(g_framework->Storage().GetCurrentVersion()) + "/"
                          + UrlEncode(curFile.m_fileName);
        LOG(LDEBUG, (curFile.m_urls[i]));
      }

      g_currentRequest.reset(downloader::HttpRequest::GetFile(curFile.m_urls,
                                                          curFile.m_pathOnSdcard,
                                                          curFile.m_fileSize,
                                                          onFinish,
                                                          onProgress,
                                                          64 * 1024,
                                                          false));
    }
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_cancelCurrentFile(JNIEnv * env, jobject thiz)
  {
    LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest.get()));
    g_currentRequest.reset();
  }

  JNIEXPORT int JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_startNextFileDownload(JNIEnv * env,
      jobject thiz, jobject observer)
  {
    if (g_filesToDownload.empty())
      return ERR_NO_MORE_FILES;

    FileToDownload & curFile = g_filesToDownload.back();

    LOG(LDEBUG, ("downloading", curFile.m_fileName, "sized", curFile.m_fileSize, "bytes"));

    downloader::HttpRequest::CallbackT onFinish(bind(&DownloadFileFinished, jni::make_global_ref(observer), _1));
    downloader::HttpRequest::CallbackT onProgress(bind(&DownloadFileProgress, jni::make_global_ref(observer), _1));

    g_currentRequest.reset(downloader::HttpRequest::PostJson(GetPlatform().MetaServerUrl(),
                                                         curFile.m_fileName,
                                                         bind(&DownloadURLListFinished, _1,
                                                             onFinish,
                                                             onProgress)));

    return ERR_FILE_IN_PROGRESS;
  }

  // Move downloaded maps from /sdcard/Android/data/com.mapswithme.maps/files/
  // to /sdcard/MapsWithMe
  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_moveMaps(JNIEnv * env, jobject thiz,
      jstring fromPath, jstring toPath)
  {
    string from = jni::ToString(fromPath);
    string to = jni::ToString(toPath);

    Platform & pl = GetPlatform();
    Platform::FilesList files;
    // Move *.mwm files
    pl.GetFilesInDir(from, "*" DATA_FILE_EXTENSION, files);
    for (size_t i = 0; i < files.size(); ++i)
    {
      LOG(LDEBUG, ("moving map from:", from + files[i], ", to:", to + files[i]));
      my::RenameFileX((from + files[i]).c_str(), (to + files[i]).c_str());
    }

    // Delete not finished *.downloading files
    files.clear();
    pl.GetFilesInDir(from, "*" DOWNLOADING_FILE_EXTENSION, files);
    pl.GetFilesInDir(from, "*" RESUME_FILE_EXTENSION, files);
    for (size_t i = 0; i < files.size(); ++i)
      my::DeleteFileX((from + files[i]).c_str());
  }

  JNIEXPORT jstring JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_findCountryByPos(JNIEnv * env, jobject thiz,
      jdouble lat, jdouble lon)
  {
    double x = MercatorBounds::LonToX(lon);
    double y = MercatorBounds::LatToY(lat);

    string name = g_framework->GetCountryName(x, y);

    return env->NewStringUTF(name.c_str());
  }
}
<|endoftext|>


<commit_before><commit_msg>[search] Decrease name rank for features matched by alt/old name.<commit_after><|endoftext|>


<commit_before>/*
    Copyright 2012 Frederik Gladhorn <gladhorn@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "atspidbus.h"

#include <qdbusmessage.h>
#include <qdbusreply.h>
#include <qdbusargument.h>

#include <qdebug.h>

#include "atspi/qt-atspi.h"
#include "accessible/accessibleobject_p.h"

using namespace KAccessibleClient;

AtSpiDBus::AtSpiDBus(DBusConnection *conn)
    : m_connection(conn)
{
}

AtSpiDBus::~AtSpiDBus()
{
}

AccessibleObject AtSpiDBus::parent(const AccessibleObject &object)
{
    QDBusMessage message = QDBusMessage::createMethodCall (
                object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetParent"));

    QDBusReply<QVariant> reply = m_connection->connection().call(message);
    if (!reply.isValid()) {
        qWarning() << "Could not access parent." << reply.error().message();
        return AccessibleObject(0, QString(), QString());
    }

    QVariant v = reply.value();
    const QDBusArgument arg = v.value<QDBusArgument>();
    QSpiObjectReference ref;
    arg >> ref;

    return AccessibleObject(const_cast<AtSpiDBus*>(this), ref.service, ref.path.path());
}

QList<AccessibleObject> AtSpiDBus::children(const AccessibleObject &object) const
{
    QList<AccessibleObject> accs;

    QDBusMessage message = QDBusMessage::createMethodCall (
                object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetChildren"));

    QDBusReply<QSpiObjectReferenceList> reply = m_connection->connection().call(message);
    if (!reply.isValid()) {
        qWarning() << "Could not access children." << reply.error().message();
        return accs;
    }

    const QSpiObjectReferenceList children = reply.value();
    Q_FOREACH(const QSpiObjectReference &child, children) {
        accs.append(AccessibleObject(const_cast<AtSpiDBus*>(this), child.service, child.path.path()));
    }

    return accs;
}

QList<AccessibleObject> AtSpiDBus::topLevelAccessibles() const
{
    QString service = QLatin1String("org.a11y.atspi.Registry");
    QString path = QLatin1String("/org/a11y/atspi/accessible/root");
    return children(AccessibleObject(const_cast<AtSpiDBus*>(this), service, path));
}

QString AtSpiDBus::name(const QString &service, const QString &path) const
{
    if (service.isEmpty() || path.isEmpty())
        return QLatin1String("Invalid Object");
    return getProperty(service, path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("Name")).toString();
}

QVariant AtSpiDBus::getProperty ( const QString &service, const QString &path, const QString &interface, const QString &name ) const
{
    QVariantList args;
    args.append ( interface );
    args.append ( name );

    QDBusMessage message = QDBusMessage::createMethodCall (
                service, path, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get") );

    message.setArguments ( args );
    QDBusMessage reply = m_connection->connection().call ( message );
    if (reply.arguments().isEmpty()) return QVariant();

    QDBusVariant v = reply.arguments().at ( 0 ).value<QDBusVariant>();
    return v.variant();
}

<commit_msg>Clean up whitespace.<commit_after>/*
    Copyright 2012 Frederik Gladhorn <gladhorn@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "atspidbus.h"

#include <qdbusmessage.h>
#include <qdbusreply.h>
#include <qdbusargument.h>

#include <qdebug.h>

#include "atspi/qt-atspi.h"
#include "accessible/accessibleobject_p.h"

using namespace KAccessibleClient;

AtSpiDBus::AtSpiDBus(DBusConnection *conn)
    : m_connection(conn)
{
}

AtSpiDBus::~AtSpiDBus()
{
}

AccessibleObject AtSpiDBus::parent(const AccessibleObject &object)
{
    QDBusMessage message = QDBusMessage::createMethodCall (
                object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetParent"));

    QDBusReply<QVariant> reply = m_connection->connection().call(message);
    if (!reply.isValid()) {
        qWarning() << "Could not access parent." << reply.error().message();
        return AccessibleObject(0, QString(), QString());
    }

    QVariant v = reply.value();
    const QDBusArgument arg = v.value<QDBusArgument>();
    QSpiObjectReference ref;
    arg >> ref;

    return AccessibleObject(const_cast<AtSpiDBus*>(this), ref.service, ref.path.path());
}

QList<AccessibleObject> AtSpiDBus::children(const AccessibleObject &object) const
{
    QList<AccessibleObject> accs;

    QDBusMessage message = QDBusMessage::createMethodCall (
                object.d->service, object.d->path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("GetChildren"));

    QDBusReply<QSpiObjectReferenceList> reply = m_connection->connection().call(message);
    if (!reply.isValid()) {
        qWarning() << "Could not access children." << reply.error().message();
        return accs;
    }

    const QSpiObjectReferenceList children = reply.value();
    Q_FOREACH(const QSpiObjectReference &child, children) {
        accs.append(AccessibleObject(const_cast<AtSpiDBus*>(this), child.service, child.path.path()));
    }

    return accs;
}

QList<AccessibleObject> AtSpiDBus::topLevelAccessibles() const
{
    QString service = QLatin1String("org.a11y.atspi.Registry");
    QString path = QLatin1String("/org/a11y/atspi/accessible/root");
    return children(AccessibleObject(const_cast<AtSpiDBus*>(this), service, path));
}

QString AtSpiDBus::name(const QString &service, const QString &path) const
{
    if (service.isEmpty() || path.isEmpty())
        return QLatin1String("Invalid Object");
    return getProperty(service, path, QLatin1String("org.a11y.atspi.Accessible"), QLatin1String("Name")).toString();
}

QVariant AtSpiDBus::getProperty(const QString &service, const QString &path, const QString &interface, const QString &name) const
{
    QVariantList args;
    args.append(interface);
    args.append(name);

    QDBusMessage message = QDBusMessage::createMethodCall (
                service, path, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get"));

    message.setArguments(args);
    QDBusMessage reply = m_connection->connection().call(message);
    if (reply.arguments().isEmpty()) return QVariant();

    QDBusVariant v = reply.arguments().at(0).value<QDBusVariant>();
    return v.variant();
}

<|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/tab_contents/web_contents_view.h"

#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/browser/tab_contents/web_contents.h"

WebContentsView::WebContentsView(WebContents* web_contents)
    : web_contents_(web_contents) {
}

void WebContentsView::RenderWidgetHostDestroyed(RenderWidgetHost* host) {
  for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
       i != pending_widget_views_.end(); ++i) {
    if (host->view() == i->second) {
      pending_widget_views_.erase(i);
      return;
    }
  }
}

void WebContentsView::CreateNewWindow(int route_id,
                                      base::WaitableEvent* modal_dialog_event) {
  // Create the new web contents. This will automatically create the new
  // WebContentsView. In the future, we may want to create the view separately.
  WebContents* new_contents =
      new WebContents(web_contents()->profile(),
                      web_contents()->GetSiteInstance(),
                      route_id,
                      modal_dialog_event);
  new_contents->SetupController(web_contents()->profile());
  WebContentsView* new_view = new_contents->view();

  // TODO(brettw) it seems bogus that we have to call this function on the
  // newly created object and give it one of its own member variables.
  new_view->CreateViewForWidget(new_contents->render_view_host());

  // Save the created window associated with the route so we can show it later.
  pending_contents_[route_id] = new_contents;
}

void WebContentsView::CreateNewWidget(int route_id, bool activatable) {
  // Save the created widget associated with the route so we can show it later.
  pending_widget_views_[route_id] = CreateNewWidgetInternal(route_id,
                                                            activatable);
}

void WebContentsView::ShowCreatedWindow(int route_id,
                                        WindowOpenDisposition disposition,
                                        const gfx::Rect& initial_pos,
                                        bool user_gesture) {
  PendingContents::iterator iter = pending_contents_.find(route_id);
  if (iter == pending_contents_.end()) {
    DCHECK(false);
    return;
  }

  WebContents* new_web_contents = iter->second;
  pending_contents_.erase(route_id);

  if (!new_web_contents->render_widget_host_view() ||
      !new_web_contents->process()->channel()) {
    // The view has gone away or the renderer crashed. Nothing to do.
    return;
  }

  // TODO(brettw) this seems bogus to reach into here and initialize the host.
  new_web_contents->render_view_host()->Init();
  web_contents()->AddNewContents(new_web_contents, disposition, initial_pos,
                                 user_gesture);
}

void WebContentsView::ShowCreatedWidget(int route_id,
                                        const gfx::Rect& initial_pos) {
  PendingWidgetViews::iterator iter = pending_widget_views_.find(route_id);
  if (iter == pending_widget_views_.end()) {
    DCHECK(false);
    return;
  }

  RenderWidgetHostView* widget_host_view = iter->second;
  pending_widget_views_.erase(route_id);

  ShowCreatedWidgetInternal(widget_host_view, initial_pos);
}

RenderWidgetHostView* WebContentsView::CreateNewWidgetInternal(
    int route_id,
    bool activatable) {
  RenderWidgetHost* widget_host =
      new RenderWidgetHost(web_contents_->process(), route_id);
  RenderWidgetHostView* widget_view =
      RenderWidgetHostView::CreateViewForWidget(widget_host);
  widget_view->set_activatable(activatable);

  return widget_view;
}

void WebContentsView::ShowCreatedWidgetInternal(
    RenderWidgetHostView* widget_host_view,
    const gfx::Rect& initial_pos) {
  RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost();
  if (!widget_host->process()->channel()) {
    // The view has gone away or the renderer crashed. Nothing to do.
    return;
  }

  widget_host_view->InitAsPopup(
      web_contents_->render_widget_host_view(), initial_pos);
  web_contents_->delegate()->RenderWidgetShowing();
  widget_host->Init();
}
<commit_msg>When a DOMUI dialog contains HTML with a select or a text-field which would have auto-fill, bringing the popup crashes the browser.  This is because the WebContentView may not have a delegate.<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/tab_contents/web_contents_view.h"

#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/browser/tab_contents/web_contents.h"

WebContentsView::WebContentsView(WebContents* web_contents)
    : web_contents_(web_contents) {
}

void WebContentsView::RenderWidgetHostDestroyed(RenderWidgetHost* host) {
  for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
       i != pending_widget_views_.end(); ++i) {
    if (host->view() == i->second) {
      pending_widget_views_.erase(i);
      return;
    }
  }
}

void WebContentsView::CreateNewWindow(int route_id,
                                      base::WaitableEvent* modal_dialog_event) {
  // Create the new web contents. This will automatically create the new
  // WebContentsView. In the future, we may want to create the view separately.
  WebContents* new_contents =
      new WebContents(web_contents()->profile(),
                      web_contents()->GetSiteInstance(),
                      route_id,
                      modal_dialog_event);
  new_contents->SetupController(web_contents()->profile());
  WebContentsView* new_view = new_contents->view();

  // TODO(brettw) it seems bogus that we have to call this function on the
  // newly created object and give it one of its own member variables.
  new_view->CreateViewForWidget(new_contents->render_view_host());

  // Save the created window associated with the route so we can show it later.
  pending_contents_[route_id] = new_contents;
}

void WebContentsView::CreateNewWidget(int route_id, bool activatable) {
  // Save the created widget associated with the route so we can show it later.
  pending_widget_views_[route_id] = CreateNewWidgetInternal(route_id,
                                                            activatable);
}

void WebContentsView::ShowCreatedWindow(int route_id,
                                        WindowOpenDisposition disposition,
                                        const gfx::Rect& initial_pos,
                                        bool user_gesture) {
  PendingContents::iterator iter = pending_contents_.find(route_id);
  if (iter == pending_contents_.end()) {
    DCHECK(false);
    return;
  }

  WebContents* new_web_contents = iter->second;
  pending_contents_.erase(route_id);

  if (!new_web_contents->render_widget_host_view() ||
      !new_web_contents->process()->channel()) {
    // The view has gone away or the renderer crashed. Nothing to do.
    return;
  }

  // TODO(brettw) this seems bogus to reach into here and initialize the host.
  new_web_contents->render_view_host()->Init();
  web_contents()->AddNewContents(new_web_contents, disposition, initial_pos,
                                 user_gesture);
}

void WebContentsView::ShowCreatedWidget(int route_id,
                                        const gfx::Rect& initial_pos) {
  PendingWidgetViews::iterator iter = pending_widget_views_.find(route_id);
  if (iter == pending_widget_views_.end()) {
    DCHECK(false);
    return;
  }

  RenderWidgetHostView* widget_host_view = iter->second;
  pending_widget_views_.erase(route_id);

  ShowCreatedWidgetInternal(widget_host_view, initial_pos);
}

RenderWidgetHostView* WebContentsView::CreateNewWidgetInternal(
    int route_id,
    bool activatable) {
  RenderWidgetHost* widget_host =
      new RenderWidgetHost(web_contents_->process(), route_id);
  RenderWidgetHostView* widget_view =
      RenderWidgetHostView::CreateViewForWidget(widget_host);
  widget_view->set_activatable(activatable);

  return widget_view;
}

void WebContentsView::ShowCreatedWidgetInternal(
    RenderWidgetHostView* widget_host_view,
    const gfx::Rect& initial_pos) {
  RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost();
  if (!widget_host->process()->channel()) {
    // The view has gone away or the renderer crashed. Nothing to do.
    return;
  }

  widget_host_view->InitAsPopup(
      web_contents_->render_widget_host_view(), initial_pos);
  if (web_contents_->delegate())
    web_contents_->delegate()->RenderWidgetShowing();
  widget_host->Init();
}
<|endoftext|>


<commit_before>/// Program entry point.
///
/// @file

#include <memory>

#include "backnocles/app.hpp"

//==========================================================================

int main(int, char*[])
{
  // place the app instance on the heap instead on the stack
  auto app = std::make_unique<backnocles::AppConstructor>();
  return app->run();
}
<commit_msg>static app instance<commit_after>/// Program entry point.
///
/// @file

#include "backnocles/app.hpp"

//==========================================================================

int main(int, char*[])
{
  // avoid placing the app instance on the stack
  static backnocles::AppConstructor app{};
  return app.run();
}
<|endoftext|>