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

Side by Side Diff: chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc

Issue 1881263002: Generalize support for per-display shelf prefs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup. Created 4 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/launcher/chrome_launcher_controller.h" 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "ash/ash_switches.h" 11 #include "ash/ash_switches.h"
12 #include "ash/desktop_background/desktop_background_controller.h" 12 #include "ash/desktop_background/desktop_background_controller.h"
13 #include "ash/multi_profile_uma.h" 13 #include "ash/multi_profile_uma.h"
14 #include "ash/root_window_controller.h" 14 #include "ash/root_window_controller.h"
15 #include "ash/shelf/shelf.h" 15 #include "ash/shelf/shelf.h"
16 #include "ash/shelf/shelf_item_delegate_manager.h" 16 #include "ash/shelf/shelf_item_delegate_manager.h"
17 #include "ash/shelf/shelf_model.h" 17 #include "ash/shelf/shelf_model.h"
18 #include "ash/shell.h" 18 #include "ash/shell.h"
19 #include "ash/system/tray/system_tray_delegate.h" 19 #include "ash/system/tray/system_tray_delegate.h"
20 #include "ash/wm/window_util.h" 20 #include "ash/wm/window_util.h"
21 #include "base/command_line.h" 21 #include "base/command_line.h"
22 #include "base/macros.h" 22 #include "base/macros.h"
23 #include "base/strings/pattern.h" 23 #include "base/strings/pattern.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
26 #include "base/strings/utf_string_conversions.h" 25 #include "base/strings/utf_string_conversions.h"
27 #include "base/values.h" 26 #include "base/values.h"
28 #include "build/build_config.h" 27 #include "build/build_config.h"
29 #include "chrome/browser/app_mode/app_mode_utils.h"
30 #include "chrome/browser/chrome_notification_types.h" 28 #include "chrome/browser/chrome_notification_types.h"
31 #include "chrome/browser/defaults.h" 29 #include "chrome/browser/defaults.h"
32 #include "chrome/browser/extensions/extension_app_icon_loader.h" 30 #include "chrome/browser/extensions/extension_app_icon_loader.h"
33 #include "chrome/browser/extensions/extension_util.h" 31 #include "chrome/browser/extensions/extension_util.h"
34 #include "chrome/browser/extensions/launch_util.h" 32 #include "chrome/browser/extensions/launch_util.h"
35 #include "chrome/browser/prefs/incognito_mode_prefs.h" 33 #include "chrome/browser/prefs/incognito_mode_prefs.h"
36 #include "chrome/browser/prefs/pref_service_syncable_util.h" 34 #include "chrome/browser/prefs/pref_service_syncable_util.h"
37 #include "chrome/browser/profiles/profile.h" 35 #include "chrome/browser/profiles/profile.h"
38 #include "chrome/browser/profiles/profile_manager.h" 36 #include "chrome/browser/profiles/profile_manager.h"
39 #include "chrome/browser/ui/ash/app_sync_ui_state.h" 37 #include "chrome/browser/ui/ash/app_sync_ui_state.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 // static 115 // static
118 ChromeLauncherController* ChromeLauncherController::instance_ = NULL; 116 ChromeLauncherController* ChromeLauncherController::instance_ = NULL;
119 117
120 namespace { 118 namespace {
121 119
122 // This will be used as placeholder in the list of the pinned applciatons. 120 // This will be used as placeholder in the list of the pinned applciatons.
123 // Note that this is NOT a valid extension identifier so that pre M31 versions 121 // Note that this is NOT a valid extension identifier so that pre M31 versions
124 // will ignore it. 122 // will ignore it.
125 const char kAppShelfIdPlaceholder[] = "AppShelfIDPlaceholder--------"; 123 const char kAppShelfIdPlaceholder[] = "AppShelfIDPlaceholder--------";
126 124
127 std::string GetPrefKeyForRootWindow(aura::Window* root_window) { 125 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) {
126 aura::Window* root_window =
127 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
128 gfx::Display display = 128 gfx::Display display =
129 gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_window); 129 gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
130 DCHECK(display.is_valid()); 130 DCHECK(display.is_valid());
131 131 return display.id();
132 return base::Int64ToString(display.id());
133 }
134
135 void UpdatePerDisplayPref(PrefService* pref_service,
136 aura::Window* root_window,
137 const char* pref_key,
138 const std::string& value) {
139 std::string key = GetPrefKeyForRootWindow(root_window);
140 if (key.empty())
141 return;
142
143 DictionaryPrefUpdate update(pref_service, prefs::kShelfPreferences);
144 base::DictionaryValue* shelf_prefs = update.Get();
145 base::DictionaryValue* prefs = NULL;
146 if (!shelf_prefs->GetDictionary(key, &prefs)) {
147 prefs = new base::DictionaryValue();
148 shelf_prefs->Set(key, prefs);
149 }
150 prefs->SetStringWithoutPathExpansion(pref_key, value);
151 }
152
153 // Returns a pref value in |pref_service| for the display of |root_window|. The
154 // pref value is stored in |local_path| and |path|, but |pref_service| may have
155 // per-display preferences and the value can be specified by policy. Here is
156 // the priority:
157 // * A value managed by policy. This is a single value that applies to all
158 // displays.
159 // * A user-set value for the specified display.
160 // * A user-set value in |local_path| or |path|, if no per-display settings are
161 // ever specified (see http://crbug.com/173719 for why). |local_path| is
162 // preferred. See comment in |kShelfAlignment| as to why we consider two
163 // prefs and why |local_path| is preferred.
164 // * A value recommended by policy. This is a single value that applies to all
165 // root windows.
166 // * The default value for |local_path| if the value is not recommended by
167 // policy.
168 std::string GetPrefForRootWindow(PrefService* pref_service,
169 aura::Window* root_window,
170 const char* local_path,
171 const char* path) {
172 const PrefService::Preference* local_pref =
173 pref_service->FindPreference(local_path);
174 const std::string value(pref_service->GetString(local_path));
175 if (local_pref->IsManaged())
176 return value;
177
178 std::string pref_key = GetPrefKeyForRootWindow(root_window);
179 bool has_per_display_prefs = false;
180 if (!pref_key.empty()) {
181 const base::DictionaryValue* shelf_prefs = pref_service->GetDictionary(
182 prefs::kShelfPreferences);
183 const base::DictionaryValue* display_pref = NULL;
184 std::string per_display_value;
185 if (shelf_prefs->GetDictionary(pref_key, &display_pref) &&
186 display_pref->GetString(path, &per_display_value))
187 return per_display_value;
188
189 // If the pref for the specified display is not found, scan the whole prefs
190 // and check if the prefs for other display is already specified.
191 std::string unused_value;
192 for (base::DictionaryValue::Iterator iter(*shelf_prefs);
193 !iter.IsAtEnd(); iter.Advance()) {
194 const base::DictionaryValue* display_pref = NULL;
195 if (iter.value().GetAsDictionary(&display_pref) &&
196 display_pref->GetString(path, &unused_value)) {
197 has_per_display_prefs = true;
198 break;
199 }
200 }
201 }
202
203 if (local_pref->IsRecommended() || !has_per_display_prefs)
204 return value;
205
206 const base::Value* default_value =
207 pref_service->GetDefaultPrefValue(local_path);
208 std::string default_string;
209 default_value->GetAsString(&default_string);
210 return default_string;
211 }
212
213 // Gets the shelf auto hide behavior from prefs for a root window.
214 ash::ShelfAutoHideBehavior GetShelfAutoHideBehaviorFromPrefs(
215 Profile* profile,
216 aura::Window* root_window) {
217 DCHECK(profile);
218
219 // Don't show the shelf in app mode.
220 if (chrome::IsRunningInAppMode())
221 return ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN;
222
223 // See comment in |kShelfAlignment| as to why we consider two prefs.
224 return ash::AutoHideBehaviorFromPref(GetPrefForRootWindow(
225 profile->GetPrefs(), root_window, prefs::kShelfAutoHideBehaviorLocal,
226 prefs::kShelfAutoHideBehavior));
227 }
228
229 // Gets the shelf alignment from prefs for a root window.
230 ash::ShelfAlignment GetShelfAlignmentFromPrefs(Profile* profile,
231 aura::Window* root_window) {
232 DCHECK(profile);
233
234 // See comment in |kShelfAlignment| as to why we consider two prefs.
235 return ash::AlignmentFromPref(GetPrefForRootWindow(
236 profile->GetPrefs(), root_window, prefs::kShelfAlignmentLocal,
237 prefs::kShelfAlignment));
238 } 132 }
239 133
240 // If prefs have synced and no user-set value exists at |local_path|, the value 134 // If prefs have synced and no user-set value exists at |local_path|, the value
241 // from |synced_path| is copied to |local_path|. 135 // from |synced_path| is copied to |local_path|.
242 void MaybePropagatePrefToLocal( 136 void MaybePropagatePrefToLocal(
243 syncable_prefs::PrefServiceSyncable* pref_service, 137 syncable_prefs::PrefServiceSyncable* pref_service,
244 const char* local_path, 138 const char* local_path,
245 const char* synced_path) { 139 const char* synced_path) {
246 if (!pref_service->FindPreference(local_path)->HasUserSetting() && 140 if (!pref_service->FindPreference(local_path)->HasUserSetting() &&
247 pref_service->IsSyncing()) { 141 pref_service->IsSyncing()) {
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 window->Minimize(); 1009 window->Minimize();
1116 return ash::ShelfItemDelegate::kNoAction; 1010 return ash::ShelfItemDelegate::kNoAction;
1117 } 1011 }
1118 1012
1119 window->Show(); 1013 window->Show();
1120 window->Activate(); 1014 window->Activate();
1121 return ash::ShelfItemDelegate::kExistingWindowActivated; 1015 return ash::ShelfItemDelegate::kExistingWindowActivated;
1122 } 1016 }
1123 1017
1124 void ChromeLauncherController::OnShelfCreated(ash::Shelf* shelf) { 1018 void ChromeLauncherController::OnShelfCreated(ash::Shelf* shelf) {
1125 aura::Window* root_window = 1019 const int64_t display = GetDisplayIDForShelf(shelf);
1126 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
1127
1128 shelf->SetAutoHideBehavior( 1020 shelf->SetAutoHideBehavior(
1129 GetShelfAutoHideBehaviorFromPrefs(profile_, root_window)); 1021 ash::GetShelfAutoHideBehaviorPref(profile_, display));
1130 1022
1131 if (ash::ShelfWidget::ShelfAlignmentAllowed()) 1023 if (ash::ShelfWidget::ShelfAlignmentAllowed())
1132 shelf->SetAlignment(GetShelfAlignmentFromPrefs(profile_, root_window)); 1024 shelf->SetAlignment(ash::GetShelfAlignmentPref(profile_, display));
1133 } 1025 }
1134 1026
1135 void ChromeLauncherController::OnShelfDestroyed(ash::Shelf* shelf) {} 1027 void ChromeLauncherController::OnShelfDestroyed(ash::Shelf* shelf) {}
1136 1028
1137 void ChromeLauncherController::OnShelfAlignmentChanged(ash::Shelf* shelf) { 1029 void ChromeLauncherController::OnShelfAlignmentChanged(ash::Shelf* shelf) {
1138 const char* value = ash::AlignmentToPref(shelf->GetAlignment()); 1030 ash::SetShelfAlignmentPref(profile_, GetDisplayIDForShelf(shelf),
1139 aura::Window* root_window = 1031 shelf->GetAlignment());
1140 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
1141
1142 UpdatePerDisplayPref(profile_->GetPrefs(), root_window,
1143 prefs::kShelfAlignment, value);
1144
1145 if (root_window == ash::Shell::GetPrimaryRootWindow()) {
1146 // See comment in |kShelfAlignment| about why we have two prefs here.
1147 profile_->GetPrefs()->SetString(prefs::kShelfAlignmentLocal, value);
1148 profile_->GetPrefs()->SetString(prefs::kShelfAlignment, value);
1149 }
1150 } 1032 }
1151 1033
1152 void ChromeLauncherController::OnShelfAutoHideBehaviorChanged( 1034 void ChromeLauncherController::OnShelfAutoHideBehaviorChanged(
1153 ash::Shelf* shelf) { 1035 ash::Shelf* shelf) {
1154 const char* value = ash::AutoHideBehaviorToPref(shelf->GetAutoHideBehavior()); 1036 ash::SetShelfAutoHideBehaviorPref(profile_, GetDisplayIDForShelf(shelf),
1155 if (!value) 1037 shelf->auto_hide_behavior());
1156 return;
1157
1158 aura::Window* root_window =
1159 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
1160
1161 UpdatePerDisplayPref(profile_->GetPrefs(), root_window,
1162 prefs::kShelfAutoHideBehavior, value);
1163
1164 if (root_window == ash::Shell::GetPrimaryRootWindow()) {
1165 // See comment in |kShelfAlignment| about why we have two prefs here.
1166 profile_->GetPrefs()->SetString(prefs::kShelfAutoHideBehaviorLocal, value);
1167 profile_->GetPrefs()->SetString(prefs::kShelfAutoHideBehavior, value);
1168 }
1169 } 1038 }
1170 1039
1171 void ChromeLauncherController::ShelfItemAdded(int index) { 1040 void ChromeLauncherController::ShelfItemAdded(int index) {
1172 // The app list launcher can get added to the shelf after we applied the 1041 // The app list launcher can get added to the shelf after we applied the
1173 // preferences. In that case the item might be at the wrong spot. As such we 1042 // preferences. In that case the item might be at the wrong spot. As such we
1174 // call the function again. 1043 // call the function again.
1175 if (model_->items()[index].type == ash::TYPE_APP_LIST) 1044 if (model_->items()[index].type == ash::TYPE_APP_LIST)
1176 UpdateAppLaunchersFromPref(); 1045 UpdateAppLaunchersFromPref();
1177 } 1046 }
1178 1047
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 bool ChromeLauncherController::IsBrowserFromActiveUser(Browser* browser) { 1385 bool ChromeLauncherController::IsBrowserFromActiveUser(Browser* browser) {
1517 // If running multi user mode with separate desktops, we have to check if the 1386 // If running multi user mode with separate desktops, we have to check if the
1518 // browser is from the active user. 1387 // browser is from the active user.
1519 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 1388 if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
1520 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 1389 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
1521 return true; 1390 return true;
1522 return multi_user_util::IsProfileFromActiveUser(browser->profile()); 1391 return multi_user_util::IsProfileFromActiveUser(browser->profile());
1523 } 1392 }
1524 1393
1525 bool ChromeLauncherController::ShelfBoundsChangesProbablyWithUser( 1394 bool ChromeLauncherController::ShelfBoundsChangesProbablyWithUser(
1526 aura::Window* root_window, 1395 ash::Shelf* shelf,
1527 const std::string& user_id) const { 1396 const std::string& user_id) const {
1528 Profile* other_profile = multi_user_util::GetProfileFromAccountId( 1397 Profile* other_profile = multi_user_util::GetProfileFromAccountId(
1529 AccountId::FromUserEmail(user_id)); 1398 AccountId::FromUserEmail(user_id));
1530 if (other_profile == profile_) 1399 if (other_profile == profile_)
1531 return false; 1400 return false;
1532 1401
1533 // Note: The Auto hide state from preferences is not the same as the actual 1402 // Note: The Auto hide state from preferences is not the same as the actual
1534 // visibility of the shelf. Depending on all the various states (full screen, 1403 // visibility of the shelf. Depending on all the various states (full screen,
1535 // no window on desktop, multi user, ..) the shelf could be shown - or not. 1404 // no window on desktop, multi user, ..) the shelf could be shown - or not.
1405 const int64_t display = GetDisplayIDForShelf(shelf);
1536 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 1406 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
1537 GetShelfAutoHideBehaviorFromPrefs(profile_, root_window); 1407 ash::GetShelfAutoHideBehaviorPref(profile_, display);
1538 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 1408 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
1539 GetShelfAutoHideBehaviorFromPrefs(other_profile, root_window); 1409 ash::GetShelfAutoHideBehaviorPref(other_profile, display);
1540 1410
1541 return currently_shown != other_shown || 1411 return currently_shown != other_shown ||
1542 GetShelfAlignmentFromPrefs(profile_, root_window) != 1412 ash::GetShelfAlignmentPref(profile_, display) !=
1543 GetShelfAlignmentFromPrefs(other_profile, root_window); 1413 ash::GetShelfAlignmentPref(other_profile, display);
1544 } 1414 }
1545 1415
1546 void ChromeLauncherController::OnUserProfileReadyToSwitch(Profile* profile) { 1416 void ChromeLauncherController::OnUserProfileReadyToSwitch(Profile* profile) {
1547 #if defined(OS_CHROMEOS) 1417 #if defined(OS_CHROMEOS)
1548 if (user_switch_observer_.get()) 1418 if (user_switch_observer_.get())
1549 user_switch_observer_->OnUserProfileReadyToSwitch(profile); 1419 user_switch_observer_->OnUserProfileReadyToSwitch(profile);
1550 #endif 1420 #endif
1551 } 1421 }
1552 1422
1553 void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) { 1423 void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 MoveChromeOrApplistToFinalPosition( 1633 MoveChromeOrApplistToFinalPosition(
1764 is_chrome, is_app_list, target_index, &chrome_index, &app_list_index); 1634 is_chrome, is_app_list, target_index, &chrome_index, &app_list_index);
1765 } 1635 }
1766 } 1636 }
1767 } 1637 }
1768 1638
1769 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { 1639 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() {
1770 for (auto* window : ash::Shell::GetAllRootWindows()) { 1640 for (auto* window : ash::Shell::GetAllRootWindows()) {
1771 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1641 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1772 if (shelf) { 1642 if (shelf) {
1773 shelf->SetAutoHideBehavior( 1643 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(
1774 GetShelfAutoHideBehaviorFromPrefs(profile_, window)); 1644 profile_, GetDisplayIDForShelf(shelf)));
1775 } 1645 }
1776 } 1646 }
1777 } 1647 }
1778 1648
1779 void ChromeLauncherController::SetShelfAlignmentFromPrefs() { 1649 void ChromeLauncherController::SetShelfAlignmentFromPrefs() {
1780 if (!ash::ShelfWidget::ShelfAlignmentAllowed()) 1650 if (!ash::ShelfWidget::ShelfAlignmentAllowed())
1781 return; 1651 return;
1782 1652
1783 for (auto* window : ash::Shell::GetAllRootWindows()) { 1653 for (auto* window : ash::Shell::GetAllRootWindows()) {
1784 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1654 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1785 if (shelf) 1655 if (shelf) {
1786 shelf->SetAlignment(GetShelfAlignmentFromPrefs(profile_, window)); 1656 shelf->SetAlignment(
1657 ash::GetShelfAlignmentPref(profile_, GetDisplayIDForShelf(shelf)));
1658 }
1787 } 1659 }
1788 } 1660 }
1789 1661
1790 void ChromeLauncherController::SetShelfBehaviorsFromPrefs() { 1662 void ChromeLauncherController::SetShelfBehaviorsFromPrefs() {
1791 SetShelfAutoHideBehaviorFromPrefs(); 1663 SetShelfAutoHideBehaviorFromPrefs();
1792 SetShelfAlignmentFromPrefs(); 1664 SetShelfAlignmentFromPrefs();
1793 } 1665 }
1794 1666
1795 #if defined(OS_CHROMEOS) 1667 #if defined(OS_CHROMEOS)
1796 void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() { 1668 void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() {
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
2187 2059
2188 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( 2060 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp(
2189 const std::string& app_id) { 2061 const std::string& app_id) {
2190 for (const auto& app_icon_loader : app_icon_loaders_) { 2062 for (const auto& app_icon_loader : app_icon_loaders_) {
2191 if (app_icon_loader->CanLoadImageForApp(app_id)) 2063 if (app_icon_loader->CanLoadImageForApp(app_id))
2192 return app_icon_loader.get(); 2064 return app_icon_loader.get();
2193 } 2065 }
2194 2066
2195 return nullptr; 2067 return nullptr;
2196 } 2068 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698