diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-23 00:06:08 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-23 00:06:08 +0000 |
commit | e3b2bdf416fb07b9ca80f7182e9f6a97eabb30a2 (patch) | |
tree | 339fd96df42f6344c1926f2326a8cac2d5661305 /base | |
parent | 83f67b4efa01fc775e8d67f968f4e35d0a351036 (diff) | |
download | chromium_src-e3b2bdf416fb07b9ca80f7182e9f6a97eabb30a2.zip chromium_src-e3b2bdf416fb07b9ca80f7182e9f6a97eabb30a2.tar.gz chromium_src-e3b2bdf416fb07b9ca80f7182e9f6a97eabb30a2.tar.bz2 |
Move UploadList class to base/
I want to move CrashUploadList to components/breakpad. However, since
other classes in chrome/ also inherit from UploadList, I need to move it
to a "neutral" location.
BUG=247431
R=mark@chromium.org
Review URL: https://chromiumcodereview.appspot.com/19955002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213003 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base.gyp | 1 | ||||
-rw-r--r-- | base/base.gypi | 2 | ||||
-rw-r--r-- | base/upload_list.cc | 98 | ||||
-rw-r--r-- | base/upload_list.h | 99 | ||||
-rw-r--r-- | base/upload_list_unittest.cc | 49 |
5 files changed, 249 insertions, 0 deletions
diff --git a/base/base.gyp b/base/base.gyp index 56a036a..58543eb 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -619,6 +619,7 @@ 'tools_sanity_unittest.cc', 'tracked_objects_unittest.cc', 'tuple_unittest.cc', + 'upload_list_unittest.cc', 'values_unittest.cc', 'version_unittest.cc', 'vlog_unittest.cc', diff --git a/base/base.gypi b/base/base.gypi index 02abd4b..7381bea 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -586,6 +586,8 @@ 'tracking_info.cc', 'tracking_info.h', 'tuple.h', + 'upload_list.cc', + 'upload_list.h', 'values.cc', 'values.h', 'value_conversions.cc', diff --git a/base/upload_list.cc b/base/upload_list.cc new file mode 100644 index 0000000..50aa817 --- /dev/null +++ b/base/upload_list.cc @@ -0,0 +1,98 @@ +// Copyright 2013 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/upload_list.h" + +#include <algorithm> +#include <iterator> + +#include "base/bind.h" +#include "base/file_util.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/threading/sequenced_worker_pool.h" + +namespace base { + +UploadList::UploadInfo::UploadInfo(const std::string& c, const Time& t) + : id(c), time(t) {} + +UploadList::UploadInfo::~UploadInfo() {} + +UploadList::UploadList(Delegate* delegate, + const FilePath& upload_log_path, + SingleThreadTaskRunner* task_runner) + : delegate_(delegate), + upload_log_path_(upload_log_path), + task_runner_(task_runner) {} + +UploadList::~UploadList() {} + +void UploadList::LoadUploadListAsynchronously( + base::SequencedWorkerPool* worker_pool) { + DCHECK(task_runner_->BelongsToCurrentThread()); + worker_pool->PostWorkerTask( + FROM_HERE, + Bind(&UploadList::LoadUploadListAndInformDelegateOfCompletion, this)); +} + +void UploadList::ClearDelegate() { + DCHECK(task_runner_->BelongsToCurrentThread()); + delegate_ = NULL; +} + +void UploadList::LoadUploadListAndInformDelegateOfCompletion() { + LoadUploadList(); + task_runner_->PostTask( + FROM_HERE, Bind(&UploadList::InformDelegateOfCompletion, this)); +} + +void UploadList::LoadUploadList() { + if (PathExists(upload_log_path_)) { + std::string contents; + file_util::ReadFileToString(upload_log_path_, &contents); + std::vector<std::string> log_entries; + SplitStringAlongWhitespace(contents, &log_entries); + ParseLogEntries(log_entries); + } +} + +void UploadList::AppendUploadInfo(const UploadInfo& info) { + uploads_.push_back(info); +} + +void UploadList::ParseLogEntries( + const std::vector<std::string>& log_entries) { + std::vector<std::string>::const_reverse_iterator i; + for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) { + std::vector<std::string> components; + SplitString(*i, ',', &components); + // Skip any blank (or corrupted) lines. + if (components.size() != 2) + continue; + double seconds_since_epoch; + if (!StringToDouble(components[0], &seconds_since_epoch)) + continue; + UploadInfo info(components[1], Time::FromDoubleT(seconds_since_epoch)); + uploads_.push_back(info); + } +} + +void UploadList::InformDelegateOfCompletion() { + DCHECK(task_runner_->BelongsToCurrentThread()); + if (delegate_) + delegate_->OnUploadListAvailable(); +} + +void UploadList::GetUploads(unsigned int max_count, + std::vector<UploadInfo>* uploads) { + DCHECK(task_runner_->BelongsToCurrentThread()); + std::copy(uploads_.begin(), + uploads_.begin() + std::min<size_t>(uploads_.size(), max_count), + std::back_inserter(*uploads)); +} + +} // namespace base diff --git a/base/upload_list.h b/base/upload_list.h new file mode 100644 index 0000000..dd136f0 --- /dev/null +++ b/base/upload_list.h @@ -0,0 +1,99 @@ +// Copyright 2013 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. + +#ifndef BASE_UPLOAD_LIST_H_ +#define BASE_UPLOAD_LIST_H_ + +#include <string> +#include <vector> + +#include "base/base_export.h" +#include "base/files/file_path.h" +#include "base/gtest_prod_util.h" +#include "base/memory/ref_counted.h" +#include "base/time/time.h" + +namespace base { + +class SingleThreadTaskRunner; +class SequencedWorkerPool; + +// Loads and parses an upload list text file of the format +// time,id +// time,id +// etc. +// where each line represents an upload and "time" is Unix time. Must be used +// from the UI thread. The loading and parsing is done on a blocking pool task +// runner. +class BASE_EXPORT UploadList : public RefCountedThreadSafe<UploadList> { + public: + struct BASE_EXPORT UploadInfo { + UploadInfo(const std::string& c, const Time& t); + ~UploadInfo(); + + std::string id; + Time time; + }; + + class Delegate { + public: + // Invoked when the upload list has been loaded. Will be called on the + // UI thread. + virtual void OnUploadListAvailable() = 0; + + protected: + virtual ~Delegate() {} + }; + + // Creates a new upload list with the given callback delegate. + UploadList(Delegate* delegate, + const FilePath& upload_log_path, + SingleThreadTaskRunner* task_runner); + + // Starts loading the upload list. OnUploadListAvailable will be called when + // loading is complete. + void LoadUploadListAsynchronously(SequencedWorkerPool* worker_pool); + + // Clears the delegate, so that any outstanding asynchronous load will not + // call the delegate on completion. + void ClearDelegate(); + + // Populates |uploads| with the |max_count| most recent uploads, + // in reverse chronological order. + // Must be called only after OnUploadListAvailable has been called. + void GetUploads(unsigned int max_count, std::vector<UploadInfo>* uploads); + + protected: + virtual ~UploadList(); + + // Reads the upload log and stores the entries in |uploads_|. + virtual void LoadUploadList(); + + // Adds |info| to |uploads_|. + void AppendUploadInfo(const UploadInfo& info); + + private: + friend class RefCountedThreadSafe<UploadList>; + FRIEND_TEST_ALL_PREFIXES(UploadListTest, ParseLogEntries); + + // Manages the background thread work for LoadUploadListAsynchronously(). + void LoadUploadListAndInformDelegateOfCompletion(); + + // Calls the delegate's callback method, if there is a delegate. + void InformDelegateOfCompletion(); + + // Parses upload log lines, converting them to UploadInfo entries. + void ParseLogEntries(const std::vector<std::string>& log_entries); + + std::vector<UploadInfo> uploads_; + Delegate* delegate_; + const FilePath upload_log_path_; + SingleThreadTaskRunner* task_runner_; + + DISALLOW_COPY_AND_ASSIGN(UploadList); +}; + +} // namespace base + +#endif // BASE_UPLOAD_LIST_H_ diff --git a/base/upload_list_unittest.cc b/base/upload_list_unittest.cc new file mode 100644 index 0000000..41e1782 --- /dev/null +++ b/base/upload_list_unittest.cc @@ -0,0 +1,49 @@ +// Copyright 2013 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 <string> + +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop_proxy.h" +#include "base/strings/string_number_conversions.h" +#include "base/time/time.h" +#include "base/upload_list.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +// Test that UploadList can parse a vector of log entry strings to a vector of +// UploadInfo objects. See the UploadList declaration for a description of the +// log entry string format. +TEST(UploadListTest, ParseLogEntries) { + const char kTestTime[] = "1234567890"; + const char kTestID[] = "0123456789abcdef"; + std::string test_entry = kTestTime; + test_entry += ","; + test_entry.append(kTestID, sizeof(kTestID)); + + scoped_refptr<UploadList> upload_list = + new UploadList(NULL, base::FilePath(), MessageLoopProxy::current()); + + // 1 entry. + std::vector<std::string> log_entries; + log_entries.push_back(test_entry); + upload_list->ParseLogEntries(log_entries); + EXPECT_EQ(1u, upload_list->uploads_.size()); + double time_double = upload_list->uploads_[0].time.ToDoubleT(); + EXPECT_STREQ(kTestTime, base::DoubleToString(time_double).c_str()); + EXPECT_STREQ(kTestID, upload_list->uploads_[0].id.c_str()); + + // Add 3 more entries. + log_entries.push_back(test_entry); + log_entries.push_back(test_entry); + upload_list->ParseLogEntries(log_entries); + EXPECT_EQ(4u, upload_list->uploads_.size()); + time_double = upload_list->uploads_[3].time.ToDoubleT(); + EXPECT_STREQ(kTestTime, base::DoubleToString(time_double).c_str()); + EXPECT_STREQ(kTestID, upload_list->uploads_[3].id.c_str()); +} + +} // namespace base |