OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" | 5 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/strings/string_number_conversions.h" |
12 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/app_mode/app_mode_utils.h" |
13 #include "chrome/common/extensions/extension_constants.h" | 15 #include "chrome/common/extensions/extension_constants.h" |
14 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
15 #include "components/pref_registry/pref_registry_syncable.h" | 17 #include "components/pref_registry/pref_registry_syncable.h" |
| 18 #include "components/prefs/pref_service.h" |
| 19 #include "components/prefs/scoped_user_pref_update.h" |
| 20 #include "ui/gfx/screen.h" |
| 21 |
| 22 namespace ash { |
16 | 23 |
17 namespace { | 24 namespace { |
18 | 25 |
19 // App ID of default pinned apps. | 26 // App ID of default pinned apps. |
20 const char* kDefaultPinnedApps[] = { | 27 const char* kDefaultPinnedApps[] = { |
21 extension_misc::kGmailAppId, | 28 extension_misc::kGmailAppId, |
22 extension_misc::kGoogleDocAppId, | 29 extension_misc::kGoogleDocAppId, |
23 extension_misc::kYoutubeAppId, | 30 extension_misc::kYoutubeAppId, |
24 }; | 31 }; |
25 | 32 |
26 base::ListValue* CreateDefaultPinnedAppsList() { | 33 base::ListValue* CreateDefaultPinnedAppsList() { |
27 std::unique_ptr<base::ListValue> apps(new base::ListValue); | 34 std::unique_ptr<base::ListValue> apps(new base::ListValue); |
28 for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) | 35 for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) |
29 apps->Append(ash::CreateAppDict(kDefaultPinnedApps[i])); | 36 apps->Append(CreateAppDict(kDefaultPinnedApps[i])); |
30 | 37 |
31 return apps.release(); | 38 return apps.release(); |
32 } | 39 } |
33 | 40 |
| 41 // Returns the preference value for the display with the given |display_id|. |
| 42 // The pref value is stored in |local_path| and |path|, but the pref service may |
| 43 // have per-display preferences and the value can be specified by policy. |
| 44 // Here is the priority: |
| 45 // * A value managed by policy. This is a single value that applies to all |
| 46 // displays. |
| 47 // * A user-set value for the specified display. |
| 48 // * A user-set value in |local_path| or |path|, if no per-display settings are |
| 49 // ever specified (see http://crbug.com/173719 for why). |local_path| is |
| 50 // preferred. See comment in |kShelfAlignment| as to why we consider two |
| 51 // prefs and why |local_path| is preferred. |
| 52 // * A value recommended by policy. This is a single value that applies to all |
| 53 // root windows. |
| 54 // * The default value for |local_path| if the value is not recommended by |
| 55 // policy. |
| 56 std::string GetPerDisplayPref(PrefService* prefs, |
| 57 int64_t display_id, |
| 58 const char* local_path, |
| 59 const char* path) { |
| 60 const PrefService::Preference* local_pref = prefs->FindPreference(local_path); |
| 61 const std::string value(prefs->GetString(local_path)); |
| 62 if (local_pref->IsManaged()) |
| 63 return value; |
| 64 |
| 65 std::string pref_key = base::Int64ToString(display_id); |
| 66 bool has_per_display_prefs = false; |
| 67 if (!pref_key.empty()) { |
| 68 const base::DictionaryValue* shelf_prefs = |
| 69 prefs->GetDictionary(prefs::kShelfPreferences); |
| 70 const base::DictionaryValue* display_pref = nullptr; |
| 71 std::string per_display_value; |
| 72 if (shelf_prefs->GetDictionary(pref_key, &display_pref) && |
| 73 display_pref->GetString(path, &per_display_value)) |
| 74 return per_display_value; |
| 75 |
| 76 // If the pref for the specified display is not found, scan the whole prefs |
| 77 // and check if the prefs for other display is already specified. |
| 78 std::string unused_value; |
| 79 for (base::DictionaryValue::Iterator iter(*shelf_prefs); !iter.IsAtEnd(); |
| 80 iter.Advance()) { |
| 81 const base::DictionaryValue* display_pref = nullptr; |
| 82 if (iter.value().GetAsDictionary(&display_pref) && |
| 83 display_pref->GetString(path, &unused_value)) { |
| 84 has_per_display_prefs = true; |
| 85 break; |
| 86 } |
| 87 } |
| 88 } |
| 89 |
| 90 if (local_pref->IsRecommended() || !has_per_display_prefs) |
| 91 return value; |
| 92 |
| 93 const base::Value* default_value = prefs->GetDefaultPrefValue(local_path); |
| 94 std::string default_string; |
| 95 default_value->GetAsString(&default_string); |
| 96 return default_string; |
| 97 } |
| 98 |
| 99 // Sets the preference value for the display with the given |display_id|. |
| 100 void SetPerDisplayPref(PrefService* prefs, |
| 101 int64_t display_id, |
| 102 const char* pref_key, |
| 103 const std::string& value) { |
| 104 if (display_id < 0) |
| 105 return; |
| 106 |
| 107 DictionaryPrefUpdate update(prefs, prefs::kShelfPreferences); |
| 108 base::DictionaryValue* shelf_prefs = update.Get(); |
| 109 base::DictionaryValue* pref_dictionary = nullptr; |
| 110 std::string key = base::Int64ToString(display_id); |
| 111 if (!shelf_prefs->GetDictionary(key, &pref_dictionary)) { |
| 112 pref_dictionary = new base::DictionaryValue(); |
| 113 shelf_prefs->Set(key, pref_dictionary); |
| 114 } |
| 115 pref_dictionary->SetStringWithoutPathExpansion(pref_key, value); |
| 116 } |
| 117 |
| 118 ShelfAlignment AlignmentFromPref(const std::string& value) { |
| 119 if (value == kShelfAlignmentLeft) |
| 120 return SHELF_ALIGNMENT_LEFT; |
| 121 else if (value == kShelfAlignmentRight) |
| 122 return SHELF_ALIGNMENT_RIGHT; |
| 123 // Default to bottom. |
| 124 return SHELF_ALIGNMENT_BOTTOM; |
| 125 } |
| 126 |
| 127 const char* AlignmentToPref(ShelfAlignment alignment) { |
| 128 switch (alignment) { |
| 129 case SHELF_ALIGNMENT_BOTTOM: |
| 130 return kShelfAlignmentBottom; |
| 131 case SHELF_ALIGNMENT_LEFT: |
| 132 return kShelfAlignmentLeft; |
| 133 case SHELF_ALIGNMENT_RIGHT: |
| 134 return kShelfAlignmentRight; |
| 135 } |
| 136 NOTREACHED(); |
| 137 return nullptr; |
| 138 } |
| 139 |
| 140 ShelfAutoHideBehavior AutoHideBehaviorFromPref(const std::string& value) { |
| 141 // Note: To maintain sync compatibility with old images of chrome/chromeos |
| 142 // the set of values that may be encountered includes the now-extinct |
| 143 // "Default" as well as "Never" and "Always", "Default" should now |
| 144 // be treated as "Never" (http://crbug.com/146773). |
| 145 if (value == kShelfAutoHideBehaviorAlways) |
| 146 return SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; |
| 147 return SHELF_AUTO_HIDE_BEHAVIOR_NEVER; |
| 148 } |
| 149 |
| 150 const char* AutoHideBehaviorToPref(ShelfAutoHideBehavior behavior) { |
| 151 switch (behavior) { |
| 152 case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS: |
| 153 return kShelfAutoHideBehaviorAlways; |
| 154 case SHELF_AUTO_HIDE_BEHAVIOR_NEVER: |
| 155 return kShelfAutoHideBehaviorNever; |
| 156 case SHELF_AUTO_HIDE_ALWAYS_HIDDEN: |
| 157 // This one should not be a valid preference option for now. We only want |
| 158 // to completely hide it when we run in app mode - or while we temporarily |
| 159 // hide the shelf as part of an animation (e.g. the multi user change). |
| 160 return nullptr; |
| 161 } |
| 162 NOTREACHED(); |
| 163 return nullptr; |
| 164 } |
| 165 |
34 } // namespace | 166 } // namespace |
35 | 167 |
36 namespace ash { | |
37 | |
38 const char kPinnedAppsPrefAppIDPath[] = "id"; | 168 const char kPinnedAppsPrefAppIDPath[] = "id"; |
39 const char kPinnedAppsPrefPinnedByPolicy[] = "pinned_by_policy"; | 169 const char kPinnedAppsPrefPinnedByPolicy[] = "pinned_by_policy"; |
40 | 170 |
41 const char kShelfAutoHideBehaviorAlways[] = "Always"; | 171 const char kShelfAutoHideBehaviorAlways[] = "Always"; |
42 const char kShelfAutoHideBehaviorNever[] = "Never"; | 172 const char kShelfAutoHideBehaviorNever[] = "Never"; |
43 | 173 |
44 const char kShelfAlignmentBottom[] = "Bottom"; | 174 const char kShelfAlignmentBottom[] = "Bottom"; |
45 const char kShelfAlignmentLeft[] = "Left"; | 175 const char kShelfAlignmentLeft[] = "Left"; |
46 const char kShelfAlignmentRight[] = "Right"; | 176 const char kShelfAlignmentRight[] = "Right"; |
47 | 177 |
(...skipping 22 matching lines...) Expand all Loading... |
70 registry->RegisterIntegerPref(prefs::kLogoutDialogDurationMs, 20000); | 200 registry->RegisterIntegerPref(prefs::kLogoutDialogDurationMs, 20000); |
71 registry->RegisterBooleanPref(prefs::kShowLogoutButtonInTray, false); | 201 registry->RegisterBooleanPref(prefs::kShowLogoutButtonInTray, false); |
72 } | 202 } |
73 | 203 |
74 base::DictionaryValue* CreateAppDict(const std::string& app_id) { | 204 base::DictionaryValue* CreateAppDict(const std::string& app_id) { |
75 std::unique_ptr<base::DictionaryValue> app_value(new base::DictionaryValue); | 205 std::unique_ptr<base::DictionaryValue> app_value(new base::DictionaryValue); |
76 app_value->SetString(kPinnedAppsPrefAppIDPath, app_id); | 206 app_value->SetString(kPinnedAppsPrefAppIDPath, app_id); |
77 return app_value.release(); | 207 return app_value.release(); |
78 } | 208 } |
79 | 209 |
80 ash::ShelfAlignment AlignmentFromPref(const std::string& value) { | 210 ShelfAutoHideBehavior GetShelfAutoHideBehaviorPref(PrefService* prefs, |
81 if (value == ash::kShelfAlignmentLeft) | 211 int64_t display_id) { |
82 return ash::SHELF_ALIGNMENT_LEFT; | 212 DCHECK_GE(display_id, 0); |
83 else if (value == ash::kShelfAlignmentRight) | 213 |
84 return ash::SHELF_ALIGNMENT_RIGHT; | 214 // Don't show the shelf in app mode. |
85 // Default to bottom. | 215 if (chrome::IsRunningInAppMode()) |
86 return ash::SHELF_ALIGNMENT_BOTTOM; | 216 return SHELF_AUTO_HIDE_ALWAYS_HIDDEN; |
| 217 |
| 218 // See comment in |kShelfAlignment| as to why we consider two prefs. |
| 219 return AutoHideBehaviorFromPref( |
| 220 GetPerDisplayPref(prefs, display_id, prefs::kShelfAutoHideBehaviorLocal, |
| 221 prefs::kShelfAutoHideBehavior)); |
87 } | 222 } |
88 | 223 |
89 const char* AlignmentToPref(ash::ShelfAlignment alignment) { | 224 void SetShelfAutoHideBehaviorPref(PrefService* prefs, |
90 switch (alignment) { | 225 int64_t display_id, |
91 case ash::SHELF_ALIGNMENT_BOTTOM: | 226 ShelfAutoHideBehavior behavior) { |
92 return ash::kShelfAlignmentBottom; | 227 DCHECK_GE(display_id, 0); |
93 case ash::SHELF_ALIGNMENT_LEFT: | 228 |
94 return ash::kShelfAlignmentLeft; | 229 const char* value = AutoHideBehaviorToPref(behavior); |
95 case ash::SHELF_ALIGNMENT_RIGHT: | 230 if (!value) |
96 return ash::kShelfAlignmentRight; | 231 return; |
| 232 |
| 233 SetPerDisplayPref(prefs, display_id, prefs::kShelfAutoHideBehavior, value); |
| 234 if (display_id == gfx::Screen::GetScreen()->GetPrimaryDisplay().id()) { |
| 235 // See comment in |kShelfAlignment| about why we have two prefs here. |
| 236 prefs->SetString(prefs::kShelfAutoHideBehaviorLocal, value); |
| 237 prefs->SetString(prefs::kShelfAutoHideBehavior, value); |
97 } | 238 } |
98 NOTREACHED(); | |
99 return nullptr; | |
100 } | 239 } |
101 | 240 |
102 ash::ShelfAutoHideBehavior AutoHideBehaviorFromPref(const std::string& value) { | 241 ShelfAlignment GetShelfAlignmentPref(PrefService* prefs, int64_t display_id) { |
103 // Note: To maintain sync compatibility with old images of chrome/chromeos | 242 DCHECK_GE(display_id, 0); |
104 // the set of values that may be encountered includes the now-extinct | 243 |
105 // "Default" as well as "Never" and "Always", "Default" should now | 244 // See comment in |kShelfAlignment| as to why we consider two prefs. |
106 // be treated as "Never" (http://crbug.com/146773). | 245 return AlignmentFromPref(GetPerDisplayPref( |
107 if (value == ash::kShelfAutoHideBehaviorAlways) | 246 prefs, display_id, prefs::kShelfAlignmentLocal, prefs::kShelfAlignment)); |
108 return ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; | |
109 return ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER; | |
110 } | 247 } |
111 | 248 |
112 const char* AutoHideBehaviorToPref(ash::ShelfAutoHideBehavior behavior) { | 249 void SetShelfAlignmentPref(PrefService* prefs, |
113 switch (behavior) { | 250 int64_t display_id, |
114 case ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS: | 251 ShelfAlignment alignment) { |
115 return ash::kShelfAutoHideBehaviorAlways; | 252 DCHECK_GE(display_id, 0); |
116 case ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER: | 253 |
117 return ash::kShelfAutoHideBehaviorNever; | 254 const char* value = AlignmentToPref(alignment); |
118 case ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN: | 255 SetPerDisplayPref(prefs, display_id, prefs::kShelfAlignment, value); |
119 // This one should not be a valid preference option for now. We only want | 256 if (display_id == gfx::Screen::GetScreen()->GetPrimaryDisplay().id()) { |
120 // to completely hide it when we run in app mode - or while we temporarily | 257 // See comment in |kShelfAlignment| as to why we consider two prefs. |
121 // hide the shelf as part of an animation (e.g. the multi user change). | 258 prefs->SetString(prefs::kShelfAlignmentLocal, value); |
122 return nullptr; | 259 prefs->SetString(prefs::kShelfAlignment, value); |
123 } | 260 } |
124 NOTREACHED(); | |
125 return nullptr; | |
126 } | 261 } |
127 | 262 |
128 } // namespace ash | 263 } // namespace ash |
OLD | NEW |