Index: chrome/browser/ui/ash/chrome_launcher_prefs.cc |
diff --git a/chrome/browser/ui/ash/chrome_launcher_prefs.cc b/chrome/browser/ui/ash/chrome_launcher_prefs.cc |
index b437cd32af6eac8421c6805aa6d51d1223b42ece..2b8084fbeac5bc243ec491d74829b6f0839b44dc 100644 |
--- a/chrome/browser/ui/ash/chrome_launcher_prefs.cc |
+++ b/chrome/browser/ui/ash/chrome_launcher_prefs.cc |
@@ -9,10 +9,18 @@ |
#include <memory> |
#include "base/macros.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/values.h" |
+#include "chrome/browser/app_mode/app_mode_utils.h" |
+#include "chrome/browser/profiles/profile.h" |
#include "chrome/common/extensions/extension_constants.h" |
#include "chrome/common/pref_names.h" |
#include "components/pref_registry/pref_registry_syncable.h" |
+#include "components/prefs/pref_service.h" |
+#include "components/prefs/scoped_user_pref_update.h" |
+#include "ui/gfx/screen.h" |
+ |
+namespace ash { |
namespace { |
@@ -26,14 +34,140 @@ const char* kDefaultPinnedApps[] = { |
base::ListValue* CreateDefaultPinnedAppsList() { |
std::unique_ptr<base::ListValue> apps(new base::ListValue); |
for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) |
- apps->Append(ash::CreateAppDict(kDefaultPinnedApps[i])); |
+ apps->Append(CreateAppDict(kDefaultPinnedApps[i])); |
return apps.release(); |
} |
-} // namespace |
+// Returns |profile|'s pref value for the display with the given |display_id|. |
+// The pref value is stored in |local_path| and |path|, but the pref service may |
+// have per-display preferences and the value can be specified by policy. |
+// Here is the priority: |
+// * A value managed by policy. This is a single value that applies to all |
+// displays. |
+// * A user-set value for the specified display. |
+// * A user-set value in |local_path| or |path|, if no per-display settings are |
+// ever specified (see http://crbug.com/173719 for why). |local_path| is |
+// preferred. See comment in |kShelfAlignment| as to why we consider two |
+// prefs and why |local_path| is preferred. |
+// * A value recommended by policy. This is a single value that applies to all |
+// root windows. |
+// * The default value for |local_path| if the value is not recommended by |
+// policy. |
+std::string GetPerDisplayPref(Profile* profile, |
+ int64_t display_id, |
+ const char* local_path, |
+ const char* path) { |
+ PrefService* pref_service = profile->GetPrefs(); |
+ const PrefService::Preference* local_pref = |
+ pref_service->FindPreference(local_path); |
+ const std::string value(pref_service->GetString(local_path)); |
+ if (local_pref->IsManaged()) |
+ return value; |
-namespace ash { |
+ std::string pref_key = base::Int64ToString(display_id); |
+ bool has_per_display_prefs = false; |
+ if (!pref_key.empty()) { |
+ const base::DictionaryValue* shelf_prefs = |
+ pref_service->GetDictionary(prefs::kShelfPreferences); |
+ const base::DictionaryValue* display_pref = nullptr; |
+ std::string per_display_value; |
+ if (shelf_prefs->GetDictionary(pref_key, &display_pref) && |
+ display_pref->GetString(path, &per_display_value)) |
+ return per_display_value; |
+ |
+ // If the pref for the specified display is not found, scan the whole prefs |
+ // and check if the prefs for other display is already specified. |
+ std::string unused_value; |
+ for (base::DictionaryValue::Iterator iter(*shelf_prefs); !iter.IsAtEnd(); |
+ iter.Advance()) { |
+ const base::DictionaryValue* display_pref = nullptr; |
+ if (iter.value().GetAsDictionary(&display_pref) && |
+ display_pref->GetString(path, &unused_value)) { |
+ has_per_display_prefs = true; |
+ break; |
+ } |
+ } |
+ } |
+ |
+ if (local_pref->IsRecommended() || !has_per_display_prefs) |
+ return value; |
+ |
+ const base::Value* default_value = |
+ pref_service->GetDefaultPrefValue(local_path); |
+ std::string default_string; |
+ default_value->GetAsString(&default_string); |
+ return default_string; |
+} |
+ |
+// Sets |profile|'s pref value for the display with the given |display_id|. |
+void SetPerDisplayPref(Profile* profile, |
+ int64_t display_id, |
+ const char* pref_key, |
+ const std::string& value) { |
+ if (display_id < 0) |
+ return; |
+ |
+ DictionaryPrefUpdate update(profile->GetPrefs(), prefs::kShelfPreferences); |
+ base::DictionaryValue* shelf_prefs = update.Get(); |
+ base::DictionaryValue* prefs = nullptr; |
+ std::string key = base::Int64ToString(display_id); |
+ if (!shelf_prefs->GetDictionary(key, &prefs)) { |
+ prefs = new base::DictionaryValue(); |
+ shelf_prefs->Set(key, prefs); |
+ } |
+ prefs->SetStringWithoutPathExpansion(pref_key, value); |
+} |
+ |
+ShelfAlignment AlignmentFromPref(const std::string& value) { |
+ if (value == kShelfAlignmentLeft) |
+ return SHELF_ALIGNMENT_LEFT; |
+ else if (value == kShelfAlignmentRight) |
+ return SHELF_ALIGNMENT_RIGHT; |
+ // Default to bottom. |
+ return SHELF_ALIGNMENT_BOTTOM; |
+} |
+ |
+const char* AlignmentToPref(ShelfAlignment alignment) { |
+ switch (alignment) { |
+ case SHELF_ALIGNMENT_BOTTOM: |
+ return kShelfAlignmentBottom; |
+ case SHELF_ALIGNMENT_LEFT: |
+ return kShelfAlignmentLeft; |
+ case SHELF_ALIGNMENT_RIGHT: |
+ return kShelfAlignmentRight; |
+ } |
+ NOTREACHED(); |
+ return nullptr; |
+} |
+ |
+ShelfAutoHideBehavior AutoHideBehaviorFromPref(const std::string& value) { |
+ // Note: To maintain sync compatibility with old images of chrome/chromeos |
+ // the set of values that may be encountered includes the now-extinct |
+ // "Default" as well as "Never" and "Always", "Default" should now |
+ // be treated as "Never" (http://crbug.com/146773). |
+ if (value == kShelfAutoHideBehaviorAlways) |
+ return SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; |
+ return SHELF_AUTO_HIDE_BEHAVIOR_NEVER; |
+} |
+ |
+const char* AutoHideBehaviorToPref(ShelfAutoHideBehavior behavior) { |
+ switch (behavior) { |
+ case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS: |
+ return kShelfAutoHideBehaviorAlways; |
+ case SHELF_AUTO_HIDE_BEHAVIOR_NEVER: |
+ return kShelfAutoHideBehaviorNever; |
+ case SHELF_AUTO_HIDE_ALWAYS_HIDDEN: |
+ // This one should not be a valid preference option for now. We only want |
+ // to completely hide it when we run in app mode - or while we temporarily |
+ // hide the shelf as part of an animation (e.g. the multi user change). |
+ return nullptr; |
+ } |
+ NOTREACHED(); |
+ return nullptr; |
+} |
+ |
+} // namespace |
const char kPinnedAppsPrefAppIDPath[] = "id"; |
const char kPinnedAppsPrefPinnedByPolicy[] = "pinned_by_policy"; |
@@ -77,52 +211,62 @@ base::DictionaryValue* CreateAppDict(const std::string& app_id) { |
return app_value.release(); |
} |
-ash::ShelfAlignment AlignmentFromPref(const std::string& value) { |
- if (value == ash::kShelfAlignmentLeft) |
- return ash::SHELF_ALIGNMENT_LEFT; |
- else if (value == ash::kShelfAlignmentRight) |
- return ash::SHELF_ALIGNMENT_RIGHT; |
- // Default to bottom. |
- return ash::SHELF_ALIGNMENT_BOTTOM; |
+ShelfAutoHideBehavior GetShelfAutoHideBehaviorPref(Profile* profile, |
+ int64_t display_id) { |
+ DCHECK(profile); |
+ DCHECK_GE(display_id, 0); |
+ |
+ // Don't show the shelf in app mode. |
+ if (chrome::IsRunningInAppMode()) |
+ return SHELF_AUTO_HIDE_ALWAYS_HIDDEN; |
+ |
+ // See comment in |kShelfAlignment| as to why we consider two prefs. |
+ return AutoHideBehaviorFromPref( |
+ GetPerDisplayPref(profile, display_id, prefs::kShelfAutoHideBehaviorLocal, |
+ prefs::kShelfAutoHideBehavior)); |
} |
-const char* AlignmentToPref(ash::ShelfAlignment alignment) { |
- switch (alignment) { |
- case ash::SHELF_ALIGNMENT_BOTTOM: |
- return ash::kShelfAlignmentBottom; |
- case ash::SHELF_ALIGNMENT_LEFT: |
- return ash::kShelfAlignmentLeft; |
- case ash::SHELF_ALIGNMENT_RIGHT: |
- return ash::kShelfAlignmentRight; |
+void SetShelfAutoHideBehaviorPref(Profile* profile, |
+ int64_t display_id, |
+ ShelfAutoHideBehavior behavior) { |
+ DCHECK(profile); |
+ DCHECK_GE(display_id, 0); |
+ |
+ const char* value = AutoHideBehaviorToPref(behavior); |
+ if (!value) |
+ return; |
+ |
+ SetPerDisplayPref(profile, display_id, prefs::kShelfAutoHideBehavior, value); |
+ if (display_id == gfx::Screen::GetScreen()->GetPrimaryDisplay().id()) { |
+ // See comment in |kShelfAlignment| about why we have two prefs here. |
+ profile->GetPrefs()->SetString(prefs::kShelfAutoHideBehaviorLocal, value); |
+ profile->GetPrefs()->SetString(prefs::kShelfAutoHideBehavior, value); |
} |
- NOTREACHED(); |
- return nullptr; |
} |
-ash::ShelfAutoHideBehavior AutoHideBehaviorFromPref(const std::string& value) { |
- // Note: To maintain sync compatibility with old images of chrome/chromeos |
- // the set of values that may be encountered includes the now-extinct |
- // "Default" as well as "Never" and "Always", "Default" should now |
- // be treated as "Never" (http://crbug.com/146773). |
- if (value == ash::kShelfAutoHideBehaviorAlways) |
- return ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; |
- return ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER; |
+ShelfAlignment GetShelfAlignmentPref(Profile* profile, int64_t display_id) { |
+ DCHECK(profile); |
+ DCHECK_GE(display_id, 0); |
+ |
+ // See comment in |kShelfAlignment| as to why we consider two prefs. |
+ return AlignmentFromPref(GetPerDisplayPref(profile, display_id, |
+ prefs::kShelfAlignmentLocal, |
+ prefs::kShelfAlignment)); |
} |
-const char* AutoHideBehaviorToPref(ash::ShelfAutoHideBehavior behavior) { |
- switch (behavior) { |
- case ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS: |
- return ash::kShelfAutoHideBehaviorAlways; |
- case ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER: |
- return ash::kShelfAutoHideBehaviorNever; |
- case ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN: |
- // This one should not be a valid preference option for now. We only want |
- // to completely hide it when we run in app mode - or while we temporarily |
- // hide the shelf as part of an animation (e.g. the multi user change). |
- return nullptr; |
+void SetShelfAlignmentPref(Profile* profile, |
+ int64_t display_id, |
+ ShelfAlignment alignment) { |
+ DCHECK(profile); |
+ DCHECK_GE(display_id, 0); |
+ |
+ const char* value = AlignmentToPref(alignment); |
+ SetPerDisplayPref(profile, display_id, prefs::kShelfAlignment, value); |
+ if (display_id == gfx::Screen::GetScreen()->GetPrimaryDisplay().id()) { |
+ // See comment in |kShelfAlignment| as to why we consider two prefs. |
+ profile->GetPrefs()->SetString(prefs::kShelfAlignmentLocal, value); |
+ profile->GetPrefs()->SetString(prefs::kShelfAlignment, value); |
} |
- NOTREACHED(); |
- return nullptr; |
} |
} // namespace ash |