Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(744)

Unified Diff: chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc

Issue 2281743002: arc: Add support of default and OEM apps. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
index 791b24f96419f712762339330f2e8525e36dc091..aec6fe89cbf04db47232140441ec1043a4f7a9e7 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -9,15 +9,19 @@
#include <string>
#include <unordered_map>
+#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
+#include "base/json/json_file_value_serializer.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
+#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/task_runner_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
#include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "components/arc/arc_bridge_service.h"
#include "components/crx_file/id_util.h"
@@ -27,26 +31,35 @@
namespace {
-const char kName[] = "name";
-const char kPackageName[] = "package_name";
-const char kPackageVersion[] = "package_version";
const char kActivity[] = "activity";
-const char kShortcut[] = "shortcut";
-const char kIntentUri[] = "intent_uri";
+const char kAppPath[] = "app_path";
const char kIconResourceId[] = "icon_resource_id";
-const char kSticky[] = "sticky";
-const char kNotificationsEnabled[] = "notifications_enabled";
+const char kInstallTime[] = "install_time";
+const char kIntentUri[] = "intent_uri";
const char kLastBackupAndroidId[] = "last_backup_android_id";
const char kLastBackupTime[] = "last_backup_time";
const char kLastLaunchTime[] = "lastlaunchtime";
const char kLaunchable[] = "launchable";
+const char kName[] = "name";
+const char kNotificationsEnabled[] = "notifications_enabled";
+const char kOem[] = "oem";
+const char kOrientationLock[] = "orientation_lock";
+const char kPackageName[] = "package_name";
+const char kPackageVersion[] = "package_version";
+const char kSticky[] = "sticky";
+const char kShortcut[] = "shortcut";
const char kShouldSync[] = "should_sync";
const char kSystem[] = "system";
-const char kOrientationLock[] = "orientation_lock";
-const char kInstallTime[] = "install_time";
+const char kUninstalled[] = "uninstalled";
constexpr int kSetNotificationsEnabledMinVersion = 6;
+// Sub-directory wher Arc apps forward declarations are stored.
+const base::FilePath::CharType kArcDefaultDirectory[] =
+ FILE_PATH_LITERAL("arc");
+const base::FilePath::CharType kArcTestDefaultDirectory[] =
+ FILE_PATH_LITERAL("arc_default_apps");
+
// Provider of write access to a dictionary storing ARC prefs.
class ScopedArcPrefUpdate : public DictionaryPrefUpdate {
public:
@@ -163,38 +176,7 @@ bool GetInt64FromPref(const base::DictionaryValue* dict,
return true;
}
-// Add or update local pref for given package.
-void AddOrUpdatePackagePrefs(PrefService* prefs,
- const arc::mojom::ArcPackageInfo& package) {
- DCHECK(IsArcEnabled());
khmel 2016/08/25 22:06:08 Moved to class declaration, I have to call class f
xiyuan 2016/08/26 19:32:29 Acknowledged.
- const std::string& package_name = package.package_name;
- if (package_name.empty()) {
- VLOG(2) << "Package name cannot be empty.";
- return;
- }
- ScopedArcPrefUpdate update(prefs, package_name, prefs::kArcPackages);
- base::DictionaryValue* package_dict = update.Get();
- const std::string id_str =
- base::Int64ToString(package.last_backup_android_id);
- const std::string time_str = base::Int64ToString(package.last_backup_time);
-
- package_dict->SetBoolean(kShouldSync, package.sync);
- package_dict->SetInteger(kPackageVersion, package.package_version);
- package_dict->SetString(kLastBackupAndroidId, id_str);
- package_dict->SetString(kLastBackupTime, time_str);
- package_dict->SetBoolean(kSystem, package.system);
-}
-
-// Remove given package from local pref.
-void RemovePackageFromPrefs(PrefService* prefs,
- const std::string& package_name) {
- DCHECK(IsArcEnabled());
- DictionaryPrefUpdate update(prefs, prefs::kArcPackages);
- base::DictionaryValue* packages = update.Get();
- const bool removed = packages->RemoveWithoutPathExpansion(package_name,
- nullptr);
- DCHECK(removed);
-}
+bool use_test_default_apps_directory = false;
} // namespace
@@ -214,6 +196,11 @@ void ArcAppListPrefs::RegisterProfilePrefs(
}
// static
+void ArcAppListPrefs::UseTestDefaultAppsDirectory() {
+ use_test_default_apps_directory = true;
+}
+
+// static
ArcAppListPrefs* ArcAppListPrefs::Get(content::BrowserContext* context) {
return ArcAppListPrefsFactory::GetInstance()->GetForBrowserContext(context);
}
@@ -225,6 +212,91 @@ std::string ArcAppListPrefs::GetAppId(const std::string& package_name,
return crx_file::id_util::GenerateId(input);
}
+// static
+std::unique_ptr<ArcAppListPrefs::DefaultAppInfoMap>
+ArcAppListPrefs::ReadDefaultApps() {
+ DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
+
+ std::unique_ptr<DefaultAppInfoMap> apps(new DefaultAppInfoMap);
+
+ base::FilePath base_path;
+ if (!use_test_default_apps_directory) {
+ if (!base::PathService::Get(chrome::DIR_DEFAULT_APPS, &base_path))
+ return apps;
+ base_path = base_path.Append(kArcDefaultDirectory);
+ } else {
+ if (!base::PathService::Get(chrome::DIR_TEST_DATA, &base_path))
+ return apps;
+ base_path = base_path.AppendASCII(kArcTestDefaultDirectory);
+ }
+
+ base::FilePath::StringType extension(".json");
+ base::FileEnumerator json_files(
+ base_path,
+ false, // Recursive.
+ base::FileEnumerator::FILES);
+
+ do {
+ base::FilePath file = json_files.Next();
+ if (file.empty())
+ break;
+ if (file.MatchesExtension(extension)) {
+ JSONFileValueDeserializer deserializer(file);
+ std::string error_msg;
+ std::unique_ptr<base::Value> app_info =
+ deserializer.Deserialize(nullptr, &error_msg);
+ if (!app_info) {
+ VLOG(2) << "Unable to deserialize json data: " << error_msg
+ << " in file " << file.value() << ".";
+ continue;
+ }
+
+ std::unique_ptr<base::DictionaryValue> app_info_dictionary =
+ base::DictionaryValue::From(std::move(app_info));
+ CHECK(app_info_dictionary);
+
+ std::string name;
+ std::string package_name;
+ std::string activity;
+ std::string app_path;
+ bool oem = false;
+
+ app_info_dictionary->GetString(kName, &name);
+ app_info_dictionary->GetString(kPackageName, &package_name);
+ app_info_dictionary->GetString(kActivity, &activity);
+ app_info_dictionary->GetString(kAppPath, &app_path);
+ app_info_dictionary->GetBoolean(kOem, &oem);
+
+ if (name.empty() ||
+ package_name.empty() ||
+ activity.empty() ||
+ app_path.empty()) {
+ VLOG(2) << "Arc app declaration is incomplete in file "
+ << file.value() << ".";
+ continue;
+ }
+
+ const std::string app_id = ArcAppListPrefs::GetAppId(
+ package_name, activity);
+ std::unique_ptr<ArcAppListPrefs::DefaultAppInfo> app(
+ new ArcAppListPrefs::DefaultAppInfo(name,
+ package_name,
+ activity,
+ oem,
+ base_path.Append(app_path)));
+ apps.get()->insert(
+ std::pair<std::string,
+ std::unique_ptr<ArcAppListPrefs::DefaultAppInfo>>(
+ app_id, std::move(app)));
+ } else {
+ DVLOG(1) << "Not considering: " << file.LossyDisplayName()
+ << " (does not have a .json extension)";
+ }
+ } while (true);
+
+ return apps;
+}
+
ArcAppListPrefs::ArcAppListPrefs(
Profile* profile,
arc::InstanceHolder<arc::mojom::AppInstance>* app_instance_holder)
@@ -236,6 +308,7 @@ ArcAppListPrefs::ArcAppListPrefs(
weak_ptr_factory_(this) {
DCHECK(profile);
DCHECK(app_instance_holder);
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
const base::FilePath& base_path = profile->GetPath();
base_path_ = base_path.AppendASCII(prefs::kArcApps);
@@ -243,13 +316,14 @@ ArcAppListPrefs::ArcAppListPrefs(
if (!auth_service)
return;
- if (auth_service->state() != arc::ArcAuthService::State::NOT_INITIALIZED)
- OnOptInEnabled(auth_service->IsArcEnabled());
- auth_service->AddObserver(this);
+ DCHECK(arc::ArcAuthService::IsAllowedForProfile(profile));
- app_instance_holder_->AddObserver(this);
- if (!app_instance_holder_->instance())
- OnInstanceClosed();
+ // Once ready OnDefaultAppsReady is called.
+ base::PostTaskAndReplyWithResult(
+ content::BrowserThread::GetBlockingPool(), FROM_HERE,
+ base::Bind(&ArcAppListPrefs::ReadDefaultApps),
+ base::Bind(&ArcAppListPrefs::OnDefaultAppsReady,
+ weak_ptr_factory_.GetWeakPtr()));
}
ArcAppListPrefs::~ArcAppListPrefs() {
@@ -265,7 +339,29 @@ ArcAppListPrefs::~ArcAppListPrefs() {
auth_service->RemoveObserver(this);
}
+void ArcAppListPrefs::StartPrefs() {
+ arc::ArcAuthService* auth_service = arc::ArcAuthService::Get();
+ CHECK(auth_service);
+
+ if (auth_service->state() != arc::ArcAuthService::State::NOT_INITIALIZED)
+ OnOptInEnabled(auth_service->IsArcEnabled());
+ auth_service->AddObserver(this);
+
+ app_instance_holder_->AddObserver(this);
+ if (!app_instance_holder_->instance())
+ OnInstanceClosed();
+}
+
base::FilePath ArcAppListPrefs::GetAppPath(const std::string& app_id) const {
+ const DefaultAppInfo* default_app = GetDefaultApp(app_id);
+ if (default_app) {
+ const base::DictionaryValue* app = nullptr;
+ const base::DictionaryValue* apps = prefs_->GetDictionary(prefs::kArcApps);
+ // If app is not ready yet, use resources from pre-build.
+ if (!apps || !apps->GetDictionaryWithoutPathExpansion(app_id, &app))
+ return default_app->app_path;
+ }
+
return base_path_.AppendASCII(app_id);
}
@@ -419,16 +515,36 @@ std::unique_ptr<ArcAppListPrefs::PackageInfo> ArcAppListPrefs::GetPackage(
}
std::vector<std::string> ArcAppListPrefs::GetAppIds() const {
- if (!IsArcEnabled())
- return std::vector<std::string>();
+ if (!IsArcEnabled()) {
+ // Default Arc apps available before OptIn.
+ std::vector<std::string> ids;
+ for (const auto& default_app : default_apps_) {
+ if (HasDefaultApp(default_app.first))
+ ids.push_back(default_app.first);
+ }
+ return ids;
+ }
return GetAppIdsNoArcEnabledCheck();
}
std::vector<std::string> ArcAppListPrefs::GetAppIdsNoArcEnabledCheck() const {
std::vector<std::string> ids;
- // crx_file::id_util is de-facto utility for id generation.
const base::DictionaryValue* apps = prefs_->GetDictionary(prefs::kArcApps);
+ CHECK(apps);
+
+ // Include default app ids into the list. In order not to list app twice,
+ // at first step include default apps that do not exist yet.
+ for (const auto& default_app : default_apps_) {
+ const std::string& app_id = default_app.first;
+ const base::DictionaryValue* app = nullptr;
+ if (HasDefaultApp(default_app.first) &&
+ !apps->GetDictionaryWithoutPathExpansion(app_id, &app)) {
+ ids.push_back(app_id);
+ }
+ }
+
+ // crx_file::id_util is de-facto utility for id generation.
for (base::DictionaryValue::Iterator app_id(*apps); !app_id.IsAtEnd();
app_id.Advance()) {
if (!crx_file::id_util::IdIsValid(app_id.key()))
@@ -442,13 +558,27 @@ std::vector<std::string> ArcAppListPrefs::GetAppIdsNoArcEnabledCheck() const {
std::unique_ptr<ArcAppListPrefs::AppInfo> ArcAppListPrefs::GetApp(
const std::string& app_id) const {
- if (!IsArcEnabled())
+ // Information for default app is available before Arc enabled.
+ const DefaultAppInfo* default_app = GetDefaultApp(app_id);
+ if (!IsArcEnabled() && !default_app)
return std::unique_ptr<AppInfo>();
const base::DictionaryValue* app = nullptr;
const base::DictionaryValue* apps = prefs_->GetDictionary(prefs::kArcApps);
- if (!apps || !apps->GetDictionaryWithoutPathExpansion(app_id, &app))
+ if (!apps || !apps->GetDictionaryWithoutPathExpansion(app_id, &app)) {
+ // Default app may not be available at this point so create app info based
+ // on its forward declaration.
+ if (default_app) {
+ return base::MakeUnique<AppInfo>(
+ default_app->name, default_app->package_name, default_app->activity,
+ std::string() /* intent_uri */, std::string() /* icon_resource_id */,
+ base::Time() /* last_launch_time */, base::Time() /* install_time */,
+ false /* sticky */, false /* notifications_enabled */,
+ false /* ready */, true /* showInLauncher */, false /* shortcut */,
+ true /* launchable */, arc::mojom::OrientationLock::NONE);
+ }
return std::unique_ptr<AppInfo>();
+ }
std::string name;
std::string package_name;
@@ -497,6 +627,9 @@ std::unique_ptr<ArcAppListPrefs::AppInfo> ArcAppListPrefs::GetApp(
}
bool ArcAppListPrefs::IsRegistered(const std::string& app_id) const {
+ if (HasDefaultApp(app_id))
+ return true;
+
if (!IsArcEnabled())
return false;
@@ -505,6 +638,11 @@ bool ArcAppListPrefs::IsRegistered(const std::string& app_id) const {
return apps && apps->GetDictionaryWithoutPathExpansion(app_id, &app);
}
+bool ArcAppListPrefs::IsOem(const std::string& app_id) const {
+ const DefaultAppInfo* app_info = GetDefaultApp(app_id);
+ return app_info && app_info->oem;
+}
+
bool ArcAppListPrefs::IsShortcut(const std::string& app_id) const {
std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = GetApp(app_id);
return app_info && app_info->shortcut;
@@ -548,6 +686,9 @@ void ArcAppListPrefs::NotifyRegisteredApps() {
NOTREACHED();
continue;
}
+ // Default apps are reported earlier.
+ if (HasDefaultApp(app_id))
+ continue;
FOR_EACH_OBSERVER(Observer, observer_list_,
OnAppRegistered(app_id, *app_info));
}
@@ -557,8 +698,10 @@ void ArcAppListPrefs::NotifyRegisteredApps() {
void ArcAppListPrefs::RemoveAllApps() {
std::vector<std::string> app_ids = GetAppIdsNoArcEnabledCheck();
- for (const auto& app_id : app_ids)
- RemoveApp(app_id);
+ for (const auto& app_id : app_ids) {
+ if (!HasDefaultApp(app_id))
+ RemoveApp(app_id);
+ }
}
void ArcAppListPrefs::OnOptInEnabled(bool enabled) {
@@ -568,6 +711,64 @@ void ArcAppListPrefs::OnOptInEnabled(bool enabled) {
RemoveAllApps();
}
+void ArcAppListPrefs::OnDefaultAppsReady(
+ std::unique_ptr<DefaultAppInfoMap> apps) {
+
+ default_apps_.swap(*apps.get());
+
+ // Initially consider packages are installed.
+ for (const auto& default_app : default_apps_)
+ default_packages_[default_app.second->package_name] = false;
+
+ // Apply uninstalled packages now.
+ const std::vector<std::string> uninstalled_package_names =
+ GetPackagesFromPrefs(false);
+ for (const auto& uninstalled_package_name : uninstalled_package_names)
+ MaybeMarkDefaultPackageUninstalled(uninstalled_package_name, true);
+
+ // Report default apps first.
+ for (const auto& default_app : default_apps_) {
+ const std::string& app_id = default_app.first;
+ std::unique_ptr<AppInfo> app_info = GetApp(app_id);
+ if (app_info) {
+ FOR_EACH_OBSERVER(Observer, observer_list_,
+ OnAppRegistered(app_id, *app_info));
+ }
+ }
+
+ default_apps_read_ = true;
+ StartPrefs();
+}
+
+const ArcAppListPrefs::DefaultAppInfo* ArcAppListPrefs::GetDefaultApp(
+ const std::string& app_id) const {
+ const auto it = default_apps_.find(app_id);
+ if (it == default_apps_.end())
+ return nullptr;
+ // Check if its package was uninstalled.
+ const auto it_package = default_packages_.find(it->second->package_name);
+ DCHECK(it_package != default_packages_.end());
+ if (it_package->second)
+ return nullptr;
+ return it->second.get();
+}
+
+bool ArcAppListPrefs::HasDefaultApp(const std::string& app_id) const {
+ return GetDefaultApp(app_id) != nullptr;
+}
+
+bool ArcAppListPrefs::HasDefaultPackage(const std::string& package_name) const {
+ return default_packages_.count(package_name);
+}
+
+void ArcAppListPrefs::MaybeMarkDefaultPackageUninstalled(
+ const std::string& package_name, bool uninstalled) {
+ auto it = default_packages_.find(package_name);
+ if (it == default_packages_.end())
+ return;
+ it->second = uninstalled;
+}
+
void ArcAppListPrefs::OnInstanceReady() {
arc::mojom::AppInstance* app_instance = app_instance_holder_->instance();
if (!app_instance) {
@@ -594,9 +795,9 @@ void ArcAppListPrefs::OnInstanceClosed() {
}
}
-void ArcAppListPrefs::MayAddNonLaunchableApp(const std::string& name,
- const std::string& package_name,
- const std::string& activity) {
+void ArcAppListPrefs::MaybeAddNonLaunchableApp(const std::string& name,
+ const std::string& package_name,
+ const std::string& activity) {
DCHECK(IsArcEnabled());
if (IsRegistered(GetAppId(package_name, activity)))
return;
@@ -619,8 +820,8 @@ void ArcAppListPrefs::AddAppAndShortcut(
const bool shortcut,
const bool launchable,
const arc::mojom::OrientationLock orientation_lock) {
- std::string app_id = shortcut ? GetAppId(package_name, intent_uri)
- : GetAppId(package_name, activity);
+ const std::string app_id = shortcut ? GetAppId(package_name, intent_uri)
+ : GetAppId(package_name, activity);
const bool was_registered = IsRegistered(app_id);
if (was_registered) {
std::unique_ptr<ArcAppListPrefs::AppInfo> app_old_info = GetApp(app_id);
@@ -701,13 +902,16 @@ void ArcAppListPrefs::RemoveApp(const std::string& app_id) {
// From now, app is not available.
ready_apps_.erase(app_id);
+ // app_id may be released by observers, get the path first. It should be done
+ // before removing prefs entry in order not to mix with pre-build default apps
+ // files.
+ const base::FilePath app_path = GetAppPath(app_id);
+
// Remove from prefs.
DictionaryPrefUpdate update(prefs_, prefs::kArcApps);
base::DictionaryValue* apps = update.Get();
const bool removed = apps->Remove(app_id, nullptr);
DCHECK(removed);
- // app_id may be released by observers, get the path first.
- const base::FilePath app_path = GetAppPath(app_id);
FOR_EACH_OBSERVER(Observer, observer_list_, OnAppRemoved(app_id));
@@ -716,6 +920,45 @@ void ArcAppListPrefs::RemoveApp(const std::string& app_id) {
FROM_HERE, base::Bind(&DeleteAppFolderFromFileThread, app_path));
}
+void ArcAppListPrefs::AddOrUpdatePackagePrefs(
+ PrefService* prefs, const arc::mojom::ArcPackageInfo& package) {
+ DCHECK(IsArcEnabled());
+ const std::string& package_name = package.package_name;
+ MaybeMarkDefaultPackageUninstalled(package_name, false);
+ if (package_name.empty()) {
+ VLOG(2) << "Package name cannot be empty.";
+ return;
+ }
+ ScopedArcPrefUpdate update(prefs, package_name, prefs::kArcPackages);
+ base::DictionaryValue* package_dict = update.Get();
+ const std::string id_str =
+ base::Int64ToString(package.last_backup_android_id);
+ const std::string time_str = base::Int64ToString(package.last_backup_time);
+
+ package_dict->SetBoolean(kShouldSync, package.sync);
+ package_dict->SetInteger(kPackageVersion, package.package_version);
+ package_dict->SetString(kLastBackupAndroidId, id_str);
+ package_dict->SetString(kLastBackupTime, time_str);
+ package_dict->SetBoolean(kSystem, package.system);
+}
+
+void ArcAppListPrefs::RemovePackageFromPrefs(PrefService* prefs,
+ const std::string& package_name) {
+ DCHECK(IsArcEnabled());
+ MaybeMarkDefaultPackageUninstalled(package_name, true);
+ if (!HasDefaultPackage(package_name)) {
+ DictionaryPrefUpdate update(prefs, prefs::kArcPackages);
+ base::DictionaryValue* packages = update.Get();
+ const bool removed = packages->RemoveWithoutPathExpansion(package_name,
+ nullptr);
+ DCHECK(removed);
+ } else {
+ ScopedArcPrefUpdate update(prefs, package_name, prefs::kArcPackages);
+ base::DictionaryValue* package_dict = update.Get();
+ package_dict->SetBoolean(kUninstalled, true);
+ }
+}
+
void ArcAppListPrefs::OnAppListRefreshed(
mojo::Array<arc::mojom::AppInfoPtr> apps) {
DCHECK(IsArcEnabled());
@@ -740,7 +983,9 @@ void ArcAppListPrefs::OnAppListRefreshed(
// If this is a shortcut, we just mark it as ready.
ready_apps_.insert(app_id);
} else {
- RemoveApp(app_id);
+ // Default apps may not be installed yet at this moment.
+ if (!HasDefaultApp(app_id))
+ RemoveApp(app_id);
}
}
@@ -881,7 +1126,7 @@ void ArcAppListPrefs::OnTaskCreated(int32_t task_id,
const mojo::String& package_name,
const mojo::String& activity,
const mojo::String& name) {
- MayAddNonLaunchableApp(name, package_name, activity);
+ MaybeAddNonLaunchableApp(name, package_name, activity);
FOR_EACH_OBSERVER(Observer, observer_list_,
OnTaskCreated(task_id, package_name, activity));
}
@@ -952,14 +1197,25 @@ void ArcAppListPrefs::OnPackageListRefreshed(
}
std::vector<std::string> ArcAppListPrefs::GetPackagesFromPrefs() const {
+ return GetPackagesFromPrefs(true);
+}
+
+std::vector<std::string> ArcAppListPrefs::GetPackagesFromPrefs(
+ bool installed) const {
std::vector<std::string> packages;
- if (!IsArcEnabled())
+ if (!IsArcEnabled() && installed)
return packages;
const base::DictionaryValue* package_prefs =
prefs_->GetDictionary(prefs::kArcPackages);
for (base::DictionaryValue::Iterator package(*package_prefs);
!package.IsAtEnd(); package.Advance()) {
+
+ bool uninstalled = false;
+ package_prefs->GetBoolean(kSystem, &uninstalled);
+ if (installed != !uninstalled)
+ continue;
+
packages.push_back(package.key());
}
@@ -1038,6 +1294,19 @@ ArcAppListPrefs::AppInfo::AppInfo(const std::string& name,
// Complex class/struct needs an explicit out-of-line destructor
ArcAppListPrefs::AppInfo::~AppInfo() {}
+ArcAppListPrefs::DefaultAppInfo::DefaultAppInfo(const std::string& name,
+ const std::string& package_name,
+ const std::string& activity,
+ bool oem,
+ const base::FilePath app_path)
+ : name(name),
+ package_name(package_name),
+ activity(activity),
+ oem(oem),
+ app_path(app_path) {}
+
+ArcAppListPrefs::DefaultAppInfo::~DefaultAppInfo() {}
+
ArcAppListPrefs::PackageInfo::PackageInfo(const std::string& package_name,
int32_t package_version,
int64_t last_backup_android_id,

Powered by Google App Engine
This is Rietveld 408576698