13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <vector> 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/ash_switches.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ash/desktop_background/desktop_background_controller.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/multi_profile_uma.h" 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/root_window_controller.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shelf/shelf_item_delegate_manager.h" 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_model.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/shelf/shelf_widget.h" 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/shell.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h" 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/wm/window_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h" 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/values.h" 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h" 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/defaults.h" 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/extensions/app_icon_loader_impl.h" 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/extension_util.h" 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/extensions/launch_util.h" 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/favicon/favicon_tab_helper.h" 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/prefs/incognito_mode_prefs.h" 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h" 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/app_sync_ui_state.h" 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/chrome_launcher_prefs.h" 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h" 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h" 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/browser_status_monitor.h" 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h" 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.h" 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h" 4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/chrome_launcher_types.h" 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/launcher_app_tab_helper.h" 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/launcher_item_controller.h" 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h" 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h" 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/extensions/application_launch.h" 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/extensions/extension_enable_flow.h" 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h" 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/common/pref_names.h" 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/common/url_constants.h" 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/notification_service.h" 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/browser/web_contents.h" 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_util.h" 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/extension_resource.h" 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h" 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/url_pattern.h" 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "grit/ash_resources.h" 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "grit/chromium_strings.h" 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "grit/generated_resources.h" 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "grit/theme_resources.h" 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "grit/ui_resources.h" 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/base/url_util.h" 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/aura/window.h" 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/keyboard/keyboard_util.h" 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_animations.h" 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_CHROMEOS) 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/browser_process.h" 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/user_manager.h" 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/ui/ash/chrome_shell_delegate.h" 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h" 961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/ash/launcher/multi_profile_browser_status_monitor.h" 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using extensions::Extension; 1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::UnloadedExtensionInfo; 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using extension_misc::kGmailAppId; 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using content::WebContents; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// static 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeLauncherController* ChromeLauncherController::instance_ = NULL; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace { 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// This will be used as placeholder in the list of the pinned applciatons. 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Note that this is NOT a valid extension identifier so that pre M31 versions 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// will ignore it. 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kAppShelfIdPlaceholder[] = "AppShelfIDPlaceholder--------"; 11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)std::string GetPrefKeyForRootWindow(aura::Window* root_window) { 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::Display display = gfx::Screen::GetScreenFor( 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) root_window)->GetDisplayNearestWindow(root_window); 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(display.is_valid()); 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return base::Int64ToString(display.id()); 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void UpdatePerDisplayPref(PrefService* pref_service, 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window, 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* pref_key, 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& value) { 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string key = GetPrefKeyForRootWindow(root_window); 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (key.empty()) 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DictionaryPrefUpdate update(pref_service, prefs::kShelfPreferences); 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::DictionaryValue* shelf_prefs = update.Get(); 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::DictionaryValue* prefs = NULL; 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!shelf_prefs->GetDictionary(key, &prefs)) { 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs = new base::DictionaryValue(); 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) shelf_prefs->Set(key, prefs); 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs->SetStringWithoutPathExpansion(pref_key, value); 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Returns a pref value in |pref_service| for the display of |root_window|. The 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// pref value is stored in |local_path| and |path|, but |pref_service| may have 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// per-display preferences and the value can be specified by policy. Here is 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// the priority: 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// * A value managed by policy. This is a single value that applies to all 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// displays. 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// * A user-set value for the specified display. 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// * A user-set value in |local_path| or |path|, if no per-display settings are 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ever specified (see http://crbug.com/173719 for why). |local_path| is 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// preferred. See comment in |kShelfAlignment| as to why we consider two 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// prefs and why |local_path| is preferred. 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// * A value recommended by policy. This is a single value that applies to all 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// root windows. 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// * The default value for |local_path| if the value is not recommended by 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// policy. 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string GetPrefForRootWindow(PrefService* pref_service, 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window, 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* local_path, 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* path) { 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const PrefService::Preference* local_pref = 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_service->FindPreference(local_path); 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string value(pref_service->GetString(local_path)); 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (local_pref->IsManaged()) 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return value; 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string pref_key = GetPrefKeyForRootWindow(root_window); 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool has_per_display_prefs = false; 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!pref_key.empty()) { 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::DictionaryValue* shelf_prefs = pref_service->GetDictionary( 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfPreferences); 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::DictionaryValue* display_pref = NULL; 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string per_display_value; 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (shelf_prefs->GetDictionary(pref_key, &display_pref) && 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) display_pref->GetString(path, &per_display_value)) 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return per_display_value; 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If the pref for the specified display is not found, scan the whole prefs 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // and check if the prefs for other display is already specified. 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string unused_value; 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (base::DictionaryValue::Iterator iter(*shelf_prefs); 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !iter.IsAtEnd(); iter.Advance()) { 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::DictionaryValue* display_pref = NULL; 1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (iter.value().GetAsDictionary(&display_pref) && 1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) display_pref->GetString(path, &unused_value)) { 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) has_per_display_prefs = true; 1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (local_pref->IsRecommended() || !has_per_display_prefs) 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return value; 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::Value* default_value = 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_service->GetDefaultPrefValue(local_path); 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string default_string; 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default_value->GetAsString(&default_string); 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return default_string; 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// If prefs have synced and no user-set value exists at |local_path|, the value 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// from |synced_path| is copied to |local_path|. 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MaybePropagatePrefToLocal(PrefServiceSyncable* pref_service, 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* local_path, 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* synced_path) { 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!pref_service->FindPreference(local_path)->HasUserSetting() && 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_service->IsSyncing()) { 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // First time the user is using this machine, propagate from remote to 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // local. 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_service->SetString(local_path, pref_service->GetString(synced_path)); 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string GetSourceFromAppListSource(ash::LaunchSource source) { 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (source) { 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case ash::LAUNCH_FROM_APP_LIST: 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return std::string(extension_urls::kLaunchSourceAppList); 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case ash::LAUNCH_FROM_APP_LIST_SEARCH: 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return std::string(extension_urls::kLaunchSourceAppListSearch); 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) default: return std::string(); 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_CHROMEOS) 2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// A class to get events from ChromeOS when a user gets changed or added. 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class ChromeLauncherControllerUserSwitchObserverChromeOS 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : public ChromeLauncherControllerUserSwitchObserver, 2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public chromeos::UserManager::UserSessionStateObserver, 2301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) content::NotificationObserver { 231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ChromeLauncherControllerUserSwitchObserverChromeOS( 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ChromeLauncherController* controller) 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : controller_(controller) { 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(chromeos::UserManager::IsInitialized()); 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) chromeos::UserManager::Get()->AddSessionStateObserver(this); 2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // A UserAddedToSession notification can be sent before a profile is loaded. 2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Since our observers require that we have already a profile, we might have 2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // to postpone the notification until the ProfileManager lets us know that 2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the profile for that newly added user was added to the ProfileManager. 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED, 2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) content::NotificationService::AllSources()); 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual ~ChromeLauncherControllerUserSwitchObserverChromeOS() { 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) chromeos::UserManager::Get()->RemoveSessionStateObserver(this); 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // chromeos::UserManager::UserSessionStateObserver overrides: 2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual void UserAddedToSession(const chromeos::User* added_user) OVERRIDE; 2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // content::NotificationObserver overrides: 2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual void Observe(int type, 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const content::NotificationSource& source, 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Add a user to the session. 2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void AddUser(Profile* profile); 2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The owning ChromeLauncherController. 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ChromeLauncherController* controller_; 262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The notification registrar to track the Profile creations after a user got 2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // added to the session (if required). 2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) content::NotificationRegistrar registrar_; 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Users which were just added to the system, but which profiles were not yet 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // (fully) loaded. 2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::set<std::string> added_user_ids_waiting_for_profiles_; 2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerUserSwitchObserverChromeOS); 272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ChromeLauncherControllerUserSwitchObserverChromeOS::UserAddedToSession( 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const chromeos::User* active_user) { 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Profile* profile = multi_user_util::GetProfileFromUserID( 2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) active_user->email()); 2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If we do not have a profile yet, we postpone forwarding the notification 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // until it is loaded. 2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!profile) 2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) added_user_ids_waiting_for_profiles_.insert(active_user->email()); 2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AddUser(profile); 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ChromeLauncherControllerUserSwitchObserverChromeOS::Observe( 2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int type, 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const content::NotificationSource& source, 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const content::NotificationDetails& details) { 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (type == chrome::NOTIFICATION_PROFILE_ADDED && 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) !added_user_ids_waiting_for_profiles_.empty()) { 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Check if the profile is from a user which was on the waiting list. 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Profile* profile = content::Source<Profile>(source).ptr(); 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string user_id = multi_user_util::GetUserIDFromProfile(profile); 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::set<std::string>::iterator it = std::find( 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) added_user_ids_waiting_for_profiles_.begin(), 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) added_user_ids_waiting_for_profiles_.end(), 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) user_id); 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it != added_user_ids_waiting_for_profiles_.end()) { 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) added_user_ids_waiting_for_profiles_.erase(it); 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AddUser(profile->GetOriginalProfile()); 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ChromeLauncherControllerUserSwitchObserverChromeOS::AddUser( 3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Profile* profile) { 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ChromeLauncherController::ChromeLauncherController(Profile* profile, 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::ShelfModel* model) 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : model_(model), 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) item_delegate_manager_(NULL), 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_(profile), 3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_sync_ui_state_(NULL), 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ignore_persist_pinned_state_change_(false) { 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!profile_) { 323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If no profile was passed, we take the currently active profile and use it 324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // as the owner of the current desktop. 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Use the original profile as on chromeos we may get a temporary off the 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // record profile, unless in guest session (where off the record profile is 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the right one). 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* active_profile = ProfileManager::GetActiveUserProfile(); 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_ = active_profile->IsGuestSession() ? active_profile : 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) active_profile->GetOriginalProfile(); 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_sync_ui_state_ = AppSyncUIState::Get(profile_); 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (app_sync_ui_state_) 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_sync_ui_state_->AddObserver(this); 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // All profile relevant settings get bound to the current profile. 338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AttachProfile(profile_); 3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) model_->AddObserver(this); 340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // In multi profile mode we might have a window manager. We try to create it 3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // here. If the instantiation fails, the manager is not needed. 3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chrome::MultiUserWindowManager::CreateInstance(); 3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_CHROMEOS) 3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // On Chrome OS using multi profile we want to switch the content of the shelf 3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // with a user change. Note that for unit tests the instance can be NULL. 3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_OFF) { 3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) user_switch_observer_.reset( 3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new ChromeLauncherControllerUserSwitchObserverChromeOS(this)); 3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Create our v1/v2 application / browser monitors which will inform the 3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // launcher of status changes. 3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) { 3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If running in separated destkop mode, we create the multi profile version 3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // of status monitor. 3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser_status_monitor_.reset(new MultiProfileBrowserStatusMonitor(this)); 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_window_controller_.reset( 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new MultiProfileAppWindowLauncherController(this)); 3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Create our v1/v2 application / browser monitors which will inform the 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // launcher of status changes. 3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser_status_monitor_.reset(new BrowserStatusMonitor(this)); 367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_window_controller_.reset(new AppWindowLauncherController(this)); 3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#else 3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Create our v1/v2 application / browser monitors which will inform the 3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // launcher of status changes. 372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) browser_status_monitor_.reset(new BrowserStatusMonitor(this)); 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_window_controller_.reset(new AppWindowLauncherController(this)); 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Right now ash::Shell isn't created for tests. 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(mukai): Allows it to observe display change and write tests. 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ash::Shell::HasInstance()) { 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::Shell::GetInstance()->display_controller()->AddObserver(this); 3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) item_delegate_manager_ = 381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ash::Shell::GetInstance()->shelf_item_delegate_manager(); 3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch notification_registrar_.Add(this, 3850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 3860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::Source<Profile>(profile_)); 38723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) notification_registrar_.Add( 38823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) this, 38923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 39023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) content::Source<Profile>(profile_)); 3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ChromeLauncherController::~ChromeLauncherController() { 39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Reset the BrowserStatusMonitor as it has a weak pointer to this. 39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browser_status_monitor_.reset(); 39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Reset the app window controller here since it has a weak pointer to this. 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_window_controller_.reset(); 3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::set<ash::Shelf*>::iterator iter = shelves_.begin(); 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter != shelves_.end(); 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++iter) 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) (*iter)->shelf_widget()->shelf_layout_manager()->RemoveObserver(this); 4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->RemoveObserver(this); 4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (ash::Shell::HasInstance()) 4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::Shell::GetInstance()->display_controller()->RemoveObserver(this); 4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin(); 4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i != id_to_item_controller_map_.end(); ++i) { 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(i->first); 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // A "browser proxy" is not known to the model and this removal does 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // therefore not need to be propagated to the model. 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index != -1 && 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->items()[index].type != ash::TYPE_BROWSER_SHORTCUT) 4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->RemoveItemAt(index); 4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (ash::Shell::HasInstance()) 4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::Shell::GetInstance()->RemoveShellObserver(this); 4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Release all profile dependent resources. 422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ReleaseProfile(); 4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (instance_ == this) 4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) instance_ = NULL; 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Get rid of the multi user window manager instance. 4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chrome::MultiUserWindowManager::DeleteInstance(); 4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ChromeLauncherController* ChromeLauncherController::CreateInstance( 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile, 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::ShelfModel* model) { 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We do not check here for re-creation of the ChromeLauncherController since 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it appears that it might be intentional that the ChromeLauncherController 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // can be re-created. 4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) instance_ = new ChromeLauncherController(profile, model); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return instance_; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::Init() { 4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CreateBrowserShortcutLauncherItem(); 44368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateAppLaunchersFromPref(); 4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(sky): update unit test so that this test isn't necessary. 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (ash::Shell::HasInstance()) { 4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetShelfAutoHideBehaviorFromPrefs(); 4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetShelfAlignmentFromPrefs(); 4496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(OS_CHROMEOS) 4506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) SetVirtualKeyboardBehaviorFromPrefs(); 4516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif // defined(OS_CHROMEOS) 4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PrefServiceSyncable* prefs = PrefServiceSyncable::FromProfile(profile_); 4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!prefs->FindPreference(prefs::kShelfAlignmentLocal)->HasUserSetting() || 4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) !prefs->FindPreference(prefs::kShelfAutoHideBehaviorLocal)-> 4553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) HasUserSetting()) { 4563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This causes OnIsSyncingChanged to be called when the value of 4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // PrefService::IsSyncing() changes. 4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs->AddObserver(this); 4593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::Shell::GetInstance()->AddShellObserver(this); 4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ash::ShelfID ChromeLauncherController::CreateAppLauncherItem( 4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller, 4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id, 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemStatus status) { 4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(controller); 4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = 0; 4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Panels are inserted on the left so as not to push all existing panels over. 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL) 4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index = model_->item_count(); 4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return InsertAppLauncherItem(controller, 4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_id, 4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) status, 4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index, 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller->GetShelfItemType()); 4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::SetItemStatus(ash::ShelfID id, 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemStatus status) { 4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(id); 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemStatus old_status = model_->items()[index].status; 4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Since ordinary browser windows are not registered, we might get a negative 4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // index here. 4864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (index >= 0 && old_status != status) { 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem item = model_->items()[index]; 4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) item.status = status; 4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->Set(index, item); 4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetItemController( 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id, 4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller) { 4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(controller); 4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(iter != id_to_item_controller_map_.end()); 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller->set_shelf_id(id); 5004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter->second = controller; 5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Existing controller is destroyed and replaced by registering again. 502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetShelfItemDelegate(id, controller); 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::CloseLauncherItem(ash::ShelfID id) { 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(id); 5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsPinned(id)) { 5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Create a new shortcut controller. 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(iter != id_to_item_controller_map_.end()); 5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetItemStatus(id, ash::STATUS_CLOSED); 5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string app_id = iter->second->app_id(); 5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) iter->second = new AppShortcutLauncherItemController(app_id, this); 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->second->set_shelf_id(id); 5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Existing controller is destroyed and replaced by registering again. 516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetShelfItemDelegate(id, iter->second); 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemClosed(id); 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::Pin(ash::ShelfID id) { 5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(HasItemController(id)); 5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(id); 5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_GE(index, 0); 5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem item = model_->items()[index]; 5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (item.type == ash::TYPE_PLATFORM_APP || 5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) item.type == ash::TYPE_WINDOWED_APP) { 5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) item.type = ash::TYPE_APP_SHORTCUT; 5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->Set(index, item); 5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (item.type != ash::TYPE_APP_SHORTCUT) { 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CanPin()) 5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PersistPinnedState(); 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::Unpin(ash::ShelfID id) { 5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(HasItemController(id)); 5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller = id_to_item_controller_map_[id]; 54668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (controller->type() == LauncherItemController::TYPE_APP || 54768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) controller->locked()) { 54868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UnpinRunningAppInternal(model_->ItemIndexByID(id)); 5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 55068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LauncherItemClosed(id); 5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CanPin()) 5533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PersistPinnedState(); 5543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ChromeLauncherController::IsPinned(ash::ShelfID id) { 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(id); 5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index < 0) 5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType type = model_->items()[index].type; 5613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); 5623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::TogglePinned(ash::ShelfID id) { 5653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!HasItemController(id)) 5663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; // May happen if item closed with menu open. 5673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsPinned(id)) 5693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Unpin(id); 5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 5713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Pin(id); 5723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ChromeLauncherController::IsPinnable(ash::ShelfID id) const { 5753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(id); 5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index == -1) 5773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 5783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType type = model_->items()[index].type; 5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return ((type == ash::TYPE_APP_SHORTCUT || 5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) type == ash::TYPE_PLATFORM_APP || 5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) type == ash::TYPE_WINDOWED_APP) && 5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CanPin()); 5843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeLauncherController::Install(ash::ShelfID id) { 587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!HasItemController(id)) 588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string app_id = GetAppIDForShelfID(id); 591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (extensions::util::IsExtensionInstalledPermanently(app_id, profile_)) 592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LauncherItemController* controller = id_to_item_controller_map_[id]; 595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (controller->type() == LauncherItemController::TYPE_APP) { 596cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppWindowLauncherItemController* app_window_controller = 597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<AppWindowLauncherItemController*>(controller); 598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) app_window_controller->InstallApp(); 599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ChromeLauncherController::CanInstall(ash::ShelfID id) { 603cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int index = model_->ItemIndexByID(id); 604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (index == -1) 605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 607cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ash::ShelfItemType type = model_->items()[index].type; 608cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (type != ash::TYPE_PLATFORM_APP) 609cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return extensions::util::IsEphemeralApp(GetAppIDForShelfID(id), profile_); 612cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 6143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::LockV1AppWithID( 6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id) { 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = GetShelfIDForAppID(app_id); 6173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!IsPinned(id) && !IsWindowedAppInLauncher(app_id)) { 6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CreateAppShortcutLauncherItemWithType(app_id, 6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->item_count(), 6203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::TYPE_WINDOWED_APP); 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) id = GetShelfIDForAppID(app_id); 6223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 6233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(id); 6243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_[id]->lock(); 6253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 6263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::UnlockV1AppWithID(const std::string& app_id) { 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = GetShelfIDForAppID(app_id); 6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(IsPinned(id) || IsWindowedAppInLauncher(app_id)); 6303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(id); 6313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller = id_to_item_controller_map_[id]; 6323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) controller->unlock(); 6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!controller->locked() && !IsPinned(id)) 6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CloseLauncherItem(id); 6353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::Launch(ash::ShelfID id, int event_flags) { 6383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!HasItemController(id)) 6393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; // In case invoked from menu and item closed while menu up. 64068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) id_to_item_controller_map_[id]->Launch(ash::LAUNCH_FROM_UNKNOWN, event_flags); 6413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 6423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::Close(ash::ShelfID id) { 6443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!HasItemController(id)) 6453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; // May happen if menu closed. 6463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_[id]->Close(); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ChromeLauncherController::IsOpen(ash::ShelfID id) { 6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!HasItemController(id)) 651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return id_to_item_controller_map_[id]->IsOpen(); 6533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 6543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ChromeLauncherController::IsPlatformApp(ash::ShelfID id) { 6563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!HasItemController(id)) 6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 6583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string app_id = GetAppIDForShelfID(id); 6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* extension = GetExtensionForAppID(app_id); 6613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // An extension can be synced / updated at any time and therefore not be 6623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // available. 6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return extension ? extension->is_platform_app() : false; 6643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::LaunchApp(const std::string& app_id, 66768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ash::LaunchSource source, 66868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int event_flags) { 6693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |extension| could be NULL when it is being unloaded for updating. 6703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* extension = GetExtensionForAppID(app_id); 6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!extension) 6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 6733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!extensions::util::IsAppLaunchableWithoutEnabling(app_id, profile_)) { 6753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Do nothing if there is already a running enable flow. 6763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (extension_enable_flow_) 6773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 6783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension_enable_flow_.reset( 6803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new ExtensionEnableFlow(profile_, app_id, this)); 6813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension_enable_flow_->StartForNativeWindow(NULL); 6823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 6833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 6843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN) 686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (LaunchedInNativeDesktop(app_id)) 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 688cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The app will be created for the currently active profile. 691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AppLaunchParams params(profile_, 692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extension, 693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) event_flags, 694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chrome::HOST_DESKTOP_TYPE_ASH); 69568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (source != ash::LAUNCH_FROM_UNKNOWN && 69668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) app_id == extension_misc::kWebStoreAppId) { 69768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Get the corresponding source string. 69868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string source_value = GetSourceFromAppListSource(source); 69968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 70068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Set an override URL to include the source. 70168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GURL extension_url = extensions::AppLaunchInfo::GetFullLaunchURL(extension); 70268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) params.override_url = net::AppendQueryParameter( 70368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) extension_url, extension_urls::kWebstoreSourceField, source_value); 70468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 70568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OpenApplication(params); 7073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::ActivateApp(const std::string& app_id, 71068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ash::LaunchSource source, 71168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int event_flags) { 7123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If there is an existing non-shortcut controller for this app, open it. 7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = GetShelfIDForAppID(app_id); 7143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (id) { 7153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller = id_to_item_controller_map_[id]; 71668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) controller->Activate(source); 7173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 7183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Create a temporary application launcher item and use it to see if there are 7213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // running instances. 7223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<AppShortcutLauncherItemController> app_controller( 7233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new AppShortcutLauncherItemController(app_id, this)); 7243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!app_controller->GetRunningApplications().empty()) 72568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) app_controller->Activate(source); 7263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 72768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LaunchApp(app_id, source, event_flags); 7283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)extensions::LaunchType ChromeLauncherController::GetLaunchType( 7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id) { 7323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(HasItemController(id)); 7333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* extension = GetExtensionForAppID( 7353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_[id]->app_id()); 7363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // An extension can be unloaded/updated/unavailable at any time. 7383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!extension) 739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return extensions::LAUNCH_TYPE_DEFAULT; 7403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 741a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_), 742a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension); 7433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ash::ShelfID ChromeLauncherController::GetShelfIDForAppID( 7463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id) { 7473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (IDToItemControllerMap::const_iterator i = 7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_.begin(); 7493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i != id_to_item_controller_map_.end(); ++i) { 7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (i->second->type() == LauncherItemController::TYPE_APP_PANEL) 7513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; // Don't include panels 7523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (i->second->app_id() == app_id) 7533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return i->first; 7543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 7563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& ChromeLauncherController::GetAppIDForShelfID( 7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id) { 7603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(HasItemController(id)); 7613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return id_to_item_controller_map_[id]->app_id(); 7623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetAppImage(const std::string& id, 7653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const gfx::ImageSkia& image) { 7663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO: need to get this working for shortcuts. 7673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (IDToItemControllerMap::const_iterator i = 7683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_.begin(); 7693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i != id_to_item_controller_map_.end(); ++i) { 7703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller = i->second; 7713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (controller->app_id() != id) 7723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 7733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (controller->image_set_by_controller()) 7743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 7753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(i->first); 7763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index == -1) 7773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem item = model_->items()[index]; 7793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) item.image = image; 7803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->Set(index, item); 7813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // It's possible we're waiting on more than one item, so don't break. 7823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::OnAutoHideBehaviorChanged( 7861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window, 7873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::ShelfAutoHideBehavior new_behavior) { 7883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetShelfAutoHideBehaviorPrefs(new_behavior, root_window); 7893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetLauncherItemImage( 7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID shelf_id, 7933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const gfx::ImageSkia& image) { 7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int index = model_->ItemIndexByID(shelf_id); 7953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index == -1) 7963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem item = model_->items()[index]; 7983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) item.image = image; 7993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->Set(index, item); 8003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ChromeLauncherController::CanPin() const { 80358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const PrefService::Preference* pref = 80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) profile_->GetPrefs()->FindPreference(prefs::kPinnedLauncherApps); 80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return pref && pref->IsUserModifiable(); 80658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ChromeLauncherController::IsAppPinned(const std::string& app_id) { 8093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (IDToItemControllerMap::const_iterator i = 8103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_.begin(); 8113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i != id_to_item_controller_map_.end(); ++i) { 8123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsPinned(i->first) && i->second->app_id() == app_id) 8133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 8143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 8163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ChromeLauncherController::IsWindowedAppInLauncher( 8193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id) { 8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int index = model_->ItemIndexByID(GetShelfIDForAppID(app_id)); 8213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index < 0) 8223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 8233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType type = model_->items()[index].type; 8253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return type == ash::TYPE_WINDOWED_APP; 8263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::PinAppWithID(const std::string& app_id) { 8293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CanPin()) 8303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DoPinAppWithID(app_id); 8313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 8323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 8333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetLaunchType( 8365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id, 837a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extensions::LaunchType launch_type) { 8383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!HasItemController(id)) 8393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 8403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::SetLaunchType(profile_->GetExtensionService(), 842a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) id_to_item_controller_map_[id]->app_id(), 843a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) launch_type); 8443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 846424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ChromeLauncherController::UnpinAppWithID(const std::string& app_id) { 8473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CanPin()) 848424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DoUnpinAppWithID(app_id); 8493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 8503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 8513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ChromeLauncherController::IsLoggedInAsGuest() { 854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return profile_->IsGuestSession(); 8553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::CreateNewWindow() { 858a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Use the currently active user. 859a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chrome::NewEmptyWindow(profile_, chrome::HOST_DESKTOP_TYPE_ASH); 8603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::CreateNewIncognitoWindow() { 863a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Use the currently active user. 864a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chrome::NewEmptyWindow(profile_->GetOffTheRecordProfile(), 8653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) chrome::HOST_DESKTOP_TYPE_ASH); 8663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::PersistPinnedState() { 8693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (ignore_persist_pinned_state_change_) 8703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 8713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // It is a coding error to call PersistPinnedState() if the pinned apps are 8723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // not user-editable. The code should check earlier and not perform any 8733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // modification actions that trigger persisting the state. 8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!CanPin()) { 8753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED() << "Can't pin but pinned state being updated"; 8763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 8773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Mutating kPinnedLauncherApps is going to notify us and trigger us to 8793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // process the change. We don't want that to happen so remove ourselves as a 8803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // listener. 8813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_change_registrar_.Remove(prefs::kPinnedLauncherApps); 8823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 8833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps); 8843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) updater->Clear(); 8853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < model_->items().size(); ++i) { 8863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) { 8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = model_->items()[i].id; 8883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (HasItemController(id) && IsPinned(id)) { 8893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::DictionaryValue* app_value = ash::CreateAppDict( 8903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_[id]->app_id()); 8913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (app_value) 8923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) updater->Append(app_value); 8933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) { 8953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PersistChromeItemIndex(i); 89668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else if (model_->items()[i].type == ash::TYPE_APP_LIST) { 89768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::DictionaryValue* app_value = ash::CreateAppDict( 8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAppShelfIdPlaceholder); 89968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (app_value) 90068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) updater->Append(app_value); 9013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_change_registrar_.Add( 9053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kPinnedLauncherApps, 9063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 9073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Unretained(this))); 9083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 910f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ash::ShelfModel* ChromeLauncherController::model() { 9113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return model_; 9123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Profile* ChromeLauncherController::profile() { 9153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return profile_; 9163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ash::ShelfAutoHideBehavior ChromeLauncherController::GetShelfAutoHideBehavior( 9191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window) const { 9203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Don't show the shelf in app mode. 9213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (chrome::IsRunningInAppMode()) 9223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN; 9233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // See comment in |kShelfAlignment| as to why we consider two prefs. 9253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string behavior_value( 9263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetPrefForRootWindow(profile_->GetPrefs(), 9273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) root_window, 9283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfAutoHideBehaviorLocal, 9293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfAutoHideBehavior)); 9303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Note: To maintain sync compatibility with old images of chrome/chromeos 9323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the set of values that may be encountered includes the now-extinct 9333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // "Default" as well as "Never" and "Always", "Default" should now 9343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // be treated as "Never" (http://crbug.com/146773). 9353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (behavior_value == ash::kShelfAutoHideBehaviorAlways) 9363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; 9373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER; 9383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ChromeLauncherController::CanUserModifyShelfAutoHideBehavior( 9411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window) const { 94246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return profile_->GetPrefs()-> 94346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FindPreference(prefs::kShelfAutoHideBehaviorLocal)->IsUserModifiable(); 9443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::ToggleShelfAutoHideBehavior( 9471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window) { 9483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::ShelfAutoHideBehavior behavior = GetShelfAutoHideBehavior(root_window) == 9493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS ? 9503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER : 9513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; 9523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetShelfAutoHideBehaviorPrefs(behavior, root_window); 9533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 9543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::UpdateAppState(content::WebContents* contents, 9573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AppState app_state) { 9584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string app_id = app_tab_helper_->GetAppID(contents); 9593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Check if the gMail app is loaded and it matches the given content. 9613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This special treatment is needed to address crbug.com/234268. 9623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) 9633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_id = kGmailAppId; 9643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Check the old |app_id| for a tab. If the contents has changed we need to 9663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // remove it from the previous app. 9673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) { 9683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string last_app_id = web_contents_to_app_id_[contents]; 969effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (last_app_id != app_id) { 970effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ash::ShelfID id = GetShelfIDForAppID(last_app_id); 971effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (id) { 972effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Since GetAppState() will use |web_contents_to_app_id_| we remove 973effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // the connection before calling it. 974effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch web_contents_to_app_id_.erase(contents); 975effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SetItemStatus(id, GetAppState(last_app_id)); 9763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 978effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 9794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 980effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (app_state == APP_STATE_REMOVED) 981effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch web_contents_to_app_id_.erase(contents); 982effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else 983effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch web_contents_to_app_id_[contents] = app_id; 9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 985effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ash::ShelfID id = GetShelfIDForAppID(app_id); 986effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (id) { 987effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SetItemStatus(id, (app_state == APP_STATE_WINDOW_ACTIVE || 988effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch app_state == APP_STATE_ACTIVE) ? ash::STATUS_ACTIVE : 989effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch GetAppState(app_id)); 9903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ash::ShelfID ChromeLauncherController::GetShelfIDForWebContents( 994f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::WebContents* contents) { 995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(contents); 996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string app_id = app_tab_helper_->GetAppID(contents); 998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 999f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) 1000f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) app_id = kGmailAppId; 1001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = GetShelfIDForAppID(app_id); 1003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (app_id.empty() || !id) { 1005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int browser_index = model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT); 1006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return model_->items()[browser_index].id; 1007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return id; 1010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::SetRefocusURLPatternForTest(ash::ShelfID id, 10133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const GURL& url) { 10143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(HasItemController(id)); 10153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller = id_to_item_controller_map_[id]; 10163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(id); 10183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index == -1) { 10193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED() << "Invalid launcher id"; 10203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 10213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType type = model_->items()[index].type; 10243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_WINDOWED_APP) { 10253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AppShortcutLauncherItemController* app_controller = 10263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<AppShortcutLauncherItemController*>(controller); 10273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_controller->set_refocus_url(url); 10283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 10293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED() << "Invalid launcher type"; 10303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const Extension* ChromeLauncherController::GetExtensionForAppID( 10343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id) const { 10353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Some unit tests do not have a real extension. 10363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return (profile_->GetExtensionService()) ? 10373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetExtensionService()->GetInstalledExtension(app_id) : NULL; 10383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::ActivateWindowOrMinimizeIfActive( 10413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ui::BaseWindow* window, 10423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool allow_minimize) { 1043f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // In separated desktop mode we might have to teleport a window back to the 1044f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // current user. 10451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 10461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) { 10471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* native_window = window->GetNativeWindow(); 10481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::string& current_user = 1049f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) multi_user_util::GetUserIDFromProfile(profile()); 1050f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::MultiUserWindowManager* manager = 1051f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::MultiUserWindowManager::GetInstance(); 10521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!manager->IsWindowOnDesktopOfUser(native_window, current_user)) { 10530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ash::MultiProfileUMA::RecordTeleportAction( 10540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ash::MultiProfileUMA::TELEPORT_WINDOW_RETURN_BY_LAUNCHER); 10551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) manager->ShowWindowForUser(native_window, current_user); 10561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) window->Activate(); 10571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 10581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 10591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1060f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (window->IsActive() && allow_minimize) { 10623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 10633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switches::kDisableMinimizeOnSecondLauncherItemClick)) { 10643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AnimateWindow(window->GetNativeWindow(), 1065a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::WINDOW_ANIMATION_TYPE_BOUNCE); 10663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 10673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) window->Minimize(); 10683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 10703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) window->Show(); 10713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) window->Activate(); 10723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::OnShelfCreated(ash::Shelf* shelf) { 10765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelves_.insert(shelf); 10775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf->shelf_widget()->shelf_layout_manager()->AddObserver(this); 10783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::OnShelfDestroyed(ash::Shelf* shelf) { 10815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelves_.erase(shelf); 10823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // RemoveObserver is not called here, since by the time this method is called 10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Shelf is already in its destructor. 10843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1086f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ChromeLauncherController::ShelfItemAdded(int index) { 108768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // The app list launcher can get added to the shelf after we applied the 108868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // preferences. In that case the item might be at the wrong spot. As such we 108968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // call the function again. 1090a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (model_->items()[index].type == ash::TYPE_APP_LIST) 109168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateAppLaunchersFromPref(); 10923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) { 10953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1097f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ChromeLauncherController::ShelfItemMoved(int start_index, 1098f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int target_index) { 10995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ash::ShelfItem& item = model_->items()[target_index]; 110068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We remember the moved item position if it is either pinnable or 110168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // it is the app list with the alternate shelf layout. 110268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((HasItemController(item.id) && IsPinned(item.id)) || 1103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch item.type == ash::TYPE_APP_LIST) 11043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PersistPinnedState(); 11053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 11063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ChromeLauncherController::ShelfItemChanged( 11083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index, 11095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ash::ShelfItem& old_item) { 11103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 11113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ChromeLauncherController::ShelfStatusChanged() { 11133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 11143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ChromeLauncherController::ActiveUserChanged( 1116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const std::string& user_email) { 11175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Store the order of running applications for the user which gets inactive. 11185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RememberUnpinnedRunningApplicationOrder(); 1119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Coming here the default profile is already switched. All profile specific 1120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // resources get released and the new profile gets attached instead. 1121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ReleaseProfile(); 1122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // When coming here, the active user has already be changed so that we can 1123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // set it as active. 1124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AttachProfile(ProfileManager::GetActiveUserProfile()); 11251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Update the V1 applications. 11261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) browser_status_monitor_->ActiveUserChanged(user_email); 11271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Switch the running applications to the new user. 1128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_window_controller_->ActiveUserChanged(user_email); 1129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Update the user specific shell properties from the new user profile. 1130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UpdateAppLaunchersFromPref(); 1131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SetShelfAlignmentFromPrefs(); 1132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SetShelfAutoHideBehaviorFromPrefs(); 1133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SetShelfBehaviorsFromPrefs(); 11346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(OS_CHROMEOS) 11356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) SetVirtualKeyboardBehaviorFromPrefs(); 11366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif // defined(OS_CHROMEOS) 11375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Restore the order of running, but unpinned applications for the activated 11385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // user. 11395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RestoreUnpinnedRunningApplicationOrder(user_email); 11405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Inform the system tray of the change. 11415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::Shell::GetInstance()->system_tray_delegate()->ActiveUserWasChanged(); 1142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Force on-screen keyboard to reset. 1143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (keyboard::IsKeyboardEnabled()) 1144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::Shell::GetInstance()->CreateKeyboard(); 11451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 11461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 11471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ChromeLauncherController::AdditionalUserAddedToSession(Profile* profile) { 11481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Switch the running applications to the new user. 1149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_window_controller_->AdditionalUserAddedToSession(profile); 1150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 1151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 11523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::Observe( 11533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int type, 11543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const content::NotificationSource& source, 11553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const content::NotificationDetails& details) { 11563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (type) { 11570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { 11583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* extension = 11593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::Details<const Extension>(details).ptr(); 11603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsAppPinned(extension->id())) { 11613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Clear and re-fetch to ensure icon is up-to-date. 11623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_icon_loader_->ClearImage(extension->id()); 11633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_icon_loader_->FetchImage(extension->id()); 11643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 11663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateAppLaunchersFromPref(); 11673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 11683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 116923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: { 11701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const content::Details<UnloadedExtensionInfo>& unload_info(details); 11713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* extension = unload_info->extension; 11723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& id = extension->id(); 11733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Since we might have windowed apps of this type which might have 11743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // outstanding locks which needs to be removed. 11755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (GetShelfIDForAppID(id) && 11761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) unload_info->reason == UnloadedExtensionInfo::REASON_UNINSTALL) { 11773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CloseWindowedAppsFromRemovedExtension(id); 11783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 11803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsAppPinned(id)) { 11811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (unload_info->reason == UnloadedExtensionInfo::REASON_UNINSTALL) { 1182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DoUnpinAppWithID(id); 11833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_icon_loader_->ClearImage(id); 11843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 11853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_icon_loader_->UpdateImage(id); 11863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 11893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 11913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED() << "Unexpected notification type=" << type; 11923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 11943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 11953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::OnShelfAlignmentChanged( 11961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window) { 11973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* pref_value = NULL; 11983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (ash::Shell::GetInstance()->GetShelfAlignment(root_window)) { 11993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ash::SHELF_ALIGNMENT_BOTTOM: 12003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_value = ash::kShelfAlignmentBottom; 12013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 12023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ash::SHELF_ALIGNMENT_LEFT: 12033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_value = ash::kShelfAlignmentLeft; 12043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 12053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ash::SHELF_ALIGNMENT_RIGHT: 12063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_value = ash::kShelfAlignmentRight; 12073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 12083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ash::SHELF_ALIGNMENT_TOP: 12093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pref_value = ash::kShelfAlignmentTop; 12103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdatePerDisplayPref( 12133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetPrefs(), root_window, prefs::kShelfAlignment, pref_value); 12143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (root_window == ash::Shell::GetPrimaryRootWindow()) { 12163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // See comment in |kShelfAlignment| about why we have two prefs here. 12173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetPrefs()->SetString(prefs::kShelfAlignmentLocal, pref_value); 12183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetPrefs()->SetString(prefs::kShelfAlignment, pref_value); 12193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::OnDisplayConfigurationChanged() { 12233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetShelfBehaviorsFromPrefs(); 12243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::OnIsSyncingChanged() { 12273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PrefServiceSyncable* prefs = PrefServiceSyncable::FromProfile(profile_); 12283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MaybePropagatePrefToLocal(prefs, 12293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfAlignmentLocal, 12303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfAlignment); 12313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MaybePropagatePrefToLocal(prefs, 12323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfAutoHideBehaviorLocal, 12333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfAutoHideBehavior); 12343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::OnAppSyncUIStatusChanged() { 12373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (app_sync_ui_state_->status() == AppSyncUIState::STATUS_SYNCING) 1238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model_->SetStatus(ash::ShelfModel::STATUS_LOADING); 12393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else 1240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) model_->SetStatus(ash::ShelfModel::STATUS_NORMAL); 12413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::ExtensionEnableFlowFinished() { 124468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LaunchApp(extension_enable_flow_->extension_id(), 124568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ash::LAUNCH_FROM_UNKNOWN, 124668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::EF_NONE); 12473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension_enable_flow_.reset(); 12483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::ExtensionEnableFlowAborted(bool user_initiated) { 12513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension_enable_flow_.reset(); 12523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ChromeLauncherAppMenuItems ChromeLauncherController::GetApplicationList( 12555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ash::ShelfItem& item, 12563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int event_flags) { 12573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Make sure that there is a controller associated with the id and that the 12583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // extension itself is a valid application and not a panel. 12593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!HasItemController(item.id) || 12605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !GetShelfIDForAppID(id_to_item_controller_map_[item.id]->app_id())) 12613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return ChromeLauncherAppMenuItems().Pass(); 12623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return id_to_item_controller_map_[item.id]->GetApplicationList(event_flags); 12643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::vector<content::WebContents*> 12673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ChromeLauncherController::GetV1ApplicationsFromAppId(std::string app_id) { 12685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = GetShelfIDForAppID(app_id); 12693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If there is no such an item pinned to the launcher, no menu gets created. 12713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (id) { 12723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller = id_to_item_controller_map_[id]; 12733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(controller); 12743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (controller->type() == LauncherItemController::TYPE_SHORTCUT) 12753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return GetV1ApplicationsFromController(controller); 12763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return std::vector<content::WebContents*>(); 12783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::ActivateShellApp(const std::string& app_id, 12813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index) { 12825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = GetShelfIDForAppID(app_id); 12833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (id) { 12843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller = id_to_item_controller_map_[id]; 12853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (controller->type() == LauncherItemController::TYPE_APP) { 1286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AppWindowLauncherItemController* app_window_controller = 1287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<AppWindowLauncherItemController*>(controller); 1288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_window_controller->ActivateIndexedApp(index); 12893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 12923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ChromeLauncherController::IsWebContentHandledByApplication( 12943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::WebContents* web_contents, 12953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id) { 12963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if ((web_contents_to_app_id_.find(web_contents) != 12973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_contents_to_app_id_.end()) && 12983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) (web_contents_to_app_id_[web_contents] == app_id)) 12993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 13003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return (app_id == kGmailAppId && ContentCanBeHandledByGmailApp(web_contents)); 13013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 13023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ChromeLauncherController::ContentCanBeHandledByGmailApp( 13043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::WebContents* web_contents) { 13055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = GetShelfIDForAppID(kGmailAppId); 13063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (id) { 13073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const GURL url = web_contents->GetURL(); 13083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We need to extend the application matching for the gMail app beyond the 13093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // manifest file's specification. This is required because of the namespace 13103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // overlap with the offline app ("/mail/mu/"). 13113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!MatchPattern(url.path(), "/mail/mu/*") && 13123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MatchPattern(url.path(), "/mail/*") && 13133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetExtensionForAppID(kGmailAppId) && 13143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetExtensionForAppID(kGmailAppId)->OverlapsWithOrigin(url)) 13153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 13163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 13183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 13193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)gfx::Image ChromeLauncherController::GetAppListIcon( 13213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::WebContents* web_contents) const { 1322c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 13233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsIncognito(web_contents)) 1324c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return rb.GetImageNamed(IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER); 13253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FaviconTabHelper* favicon_tab_helper = 13263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FaviconTabHelper::FromWebContents(web_contents); 13273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::Image result = favicon_tab_helper->GetFavicon(); 13283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (result.IsEmpty()) 13293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return rb.GetImageNamed(IDR_DEFAULT_FAVICON); 13303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return result; 13313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 13323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 ChromeLauncherController::GetAppListTitle( 13343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::WebContents* web_contents) const { 1335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title = web_contents->GetTitle(); 13363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!title.empty()) 13373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return title; 13383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) WebContentsToAppIDMap::const_iterator iter = 13393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_contents_to_app_id_.find(web_contents); 13403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (iter != web_contents_to_app_id_.end()) { 13413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string app_id = iter->second; 13423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const extensions::Extension* extension = GetExtensionForAppID(app_id); 13433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (extension) 13445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::UTF8ToUTF16(extension->name()); 13453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE); 13473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 13483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ash::ShelfID ChromeLauncherController::CreateAppShortcutLauncherItem( 13503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id, 13513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index) { 13523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CreateAppShortcutLauncherItemWithType(app_id, 13533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index, 13543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::TYPE_APP_SHORTCUT); 13553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 13563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetAppTabHelperForTest(AppTabHelper* helper) { 13583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_tab_helper_.reset(helper); 13593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 13603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetAppIconLoaderForTest( 13623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extensions::AppIconLoader* loader) { 13633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_icon_loader_.reset(loader); 13643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 13653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const std::string& ChromeLauncherController::GetAppIdFromShelfIdForTest( 13675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id) { 13683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return id_to_item_controller_map_[id]->app_id(); 13693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 13703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChromeLauncherController::SetShelfItemDelegateManagerForTest( 1372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ash::ShelfItemDelegateManager* manager) { 13734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) item_delegate_manager_ = manager; 13744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 13754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::RememberUnpinnedRunningApplicationOrder() { 13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunningAppListIds list; 13785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < model_->item_count(); i++) { 13795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType type = model_->items()[i].type; 13805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) 13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) list.push_back(GetAppIDForShelfID(model_->items()[i].id)); 13825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_used_running_application_order_[ 13845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) multi_user_util::GetUserIDFromProfile(profile_)] = list; 13855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 13865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::RestoreUnpinnedRunningApplicationOrder( 13885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& user_id) { 13895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const RunningAppListIdMap::iterator app_id_list = 13905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) last_used_running_application_order_.find(user_id); 13915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (app_id_list == last_used_running_application_order_.end()) 13925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 13935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Find the first insertion point for running applications. 13955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int running_index = model_->FirstRunningAppIndex(); 13965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (RunningAppListIds::iterator app_id = app_id_list->second.begin(); 13975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_id != app_id_list->second.end(); ++app_id) { 13985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID shelf_id = GetShelfIDForAppID(*app_id); 13995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shelf_id) { 14005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int app_index = model_->ItemIndexByID(shelf_id); 14015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_GE(app_index, 0); 14025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType type = model_->items()[app_index].type; 14035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) { 14045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (running_index != app_index) 14055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model_->Move(running_index, app_index); 14065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) running_index++; 14075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 14085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 14095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 14105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 14115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 14125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ash::ShelfID ChromeLauncherController::CreateAppShortcutLauncherItemWithType( 14133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id, 14143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index, 14155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType shelf_item_type) { 14163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AppShortcutLauncherItemController* controller = 14173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new AppShortcutLauncherItemController(app_id, this); 14185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID shelf_id = InsertAppLauncherItem( 14195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller, app_id, ash::STATUS_CLOSED, index, shelf_item_type); 14205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return shelf_id; 14213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 14223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)LauncherItemController* ChromeLauncherController::GetLauncherItemController( 14245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ash::ShelfID id) { 14254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!HasItemController(id)) 14264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 14274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return id_to_item_controller_map_[id]; 14284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 14294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 14301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ChromeLauncherController::IsBrowserFromActiveUser(Browser* browser) { 14311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If running multi user mode with separate desktops, we have to check if the 14321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // browser is from the active user. 14331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 14341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 14351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 1436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return multi_user_util::IsProfileFromActiveUser(browser->profile()); 14371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 14381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 14395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) { 14403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 14413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(iter != id_to_item_controller_map_.end()); 14423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(iter->second); 14433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_icon_loader_->ClearImage(iter->second->app_id()); 14443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_.erase(iter); 14453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(id); 14463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // A "browser proxy" is not known to the model and this removal does 14473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // therefore not need to be propagated to the model. 14483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (index != -1) 14493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->RemoveItemAt(index); 14503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 14513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::DoPinAppWithID(const std::string& app_id) { 14533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If there is an item, do nothing and return. 14543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsAppPinned(app_id)) 14553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 14563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 14585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shelf_id) { 14593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // App item exists, pin it 14605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Pin(shelf_id); 14613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 14623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Otherwise, create a shortcut item for it. 14633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CreateAppShortcutLauncherItem(app_id, model_->item_count()); 14643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CanPin()) 14653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PersistPinnedState(); 14663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 14683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1469424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { 14705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 14715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shelf_id && IsPinned(shelf_id)) 14725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Unpin(shelf_id); 14733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 14743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int ChromeLauncherController::PinRunningAppInternal(int index, 14765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID shelf_id) { 14775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int running_index = model_->ItemIndexByID(shelf_id); 14785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem item = model_->items()[running_index]; 147968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(item.type == ash::TYPE_WINDOWED_APP || 148068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item.type == ash::TYPE_PLATFORM_APP); 148168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item.type = ash::TYPE_APP_SHORTCUT; 148268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) model_->Set(running_index, item); 1483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The |ShelfModel|'s weight system might reposition the item to a 148468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // new index, so we get the index again. 14855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) running_index = model_->ItemIndexByID(shelf_id); 148668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (running_index < index) 148768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) --index; 148868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (running_index != index) 148968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) model_->Move(running_index, index); 149068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return index; 149168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 149268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 149368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ChromeLauncherController::UnpinRunningAppInternal(int index) { 149468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_GE(index, 0); 14955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem item = model_->items()[index]; 149668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); 149768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item.type = ash::TYPE_WINDOWED_APP; 149868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such 149968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // we have to check here what this was before it got a shortcut. 150068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (HasItemController(item.id) && 150168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) id_to_item_controller_map_[item.id]->type() == 150268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LauncherItemController::TYPE_APP) 150368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) item.type = ash::TYPE_PLATFORM_APP; 150468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) model_->Set(index, item); 150568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 150668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::UpdateAppLaunchersFromPref() { 150868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // There are various functions which will trigger a |PersistPinnedState| call 150968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // like a direct call to |DoPinAppWithID|, or an indirect call to the menu 151068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // model which will use weights to re-arrange the icons to new positions. 151168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Since this function is meant to synchronize the "is state" with the 151268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // "sync state", it makes no sense to store any changes by this function back 151368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // into the pref state. Therefore we tell |persistPinnedState| to ignore any 151468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // invocations while we are running. 151568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); 151668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<std::string> pinned_apps = GetListOfPinnedAppsAndBrowser(); 151768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = 0; 15193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int max_index = model_->item_count(); 15203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 152168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // When one of the two special items cannot be moved (and we do not know where 152268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // yet), we remember the current location in one of these variables. 152368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int chrome_index = -1; 152468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int app_list_index = -1; 15253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Walk the model and |pinned_apps| from the pref lockstep, adding and 15273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // removing items as necessary. NB: This code uses plain old indexing instead 15283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // of iterators because of model mutations as part of the loop. 15293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); 15303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { 153168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Check if we have an item which we need to handle. 15323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (*pref_app_id == extension_misc::kChromeAppId || 15335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *pref_app_id == kAppShelfIdPlaceholder || 15343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IsAppPinned(*pref_app_id)) { 15353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (; index < max_index; ++index) { 15365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ash::ShelfItem& item(model_->items()[index]); 153768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool is_app_list = item.type == ash::TYPE_APP_LIST; 153868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT; 153968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome) 15403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) continue; 15413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDToItemControllerMap::const_iterator entry = 15423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_.find(item.id); 15435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((kAppShelfIdPlaceholder == *pref_app_id && is_app_list) || 154468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (extension_misc::kChromeAppId == *pref_app_id && is_chrome) || 15453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) (entry != id_to_item_controller_map_.end() && 15463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) entry->second->app_id() == *pref_app_id)) { 154768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Check if an item needs to be moved here. 154868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MoveChromeOrApplistToFinalPosition( 154968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) is_chrome, is_app_list, index, &chrome_index, &app_list_index); 15503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++pref_app_id; 15513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 15523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 155368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (is_chrome || is_app_list) { 155468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We cannot delete any of these shortcuts. As such we remember 155568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // their positions and move them later where they belong. 155668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (is_chrome) 155768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) chrome_index = index; 155868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else 155968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) app_list_index = index; 156068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // And skip the item - or exit the loop if end is reached (note that 156168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // in that case we will reduce the index again by one and this only 156268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // compensates for it). 156368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (index >= max_index - 1) 156468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 156568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ++index; 15663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 156768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Check if this is a platform or a windowed app. 156868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (item.type == ash::TYPE_APP_SHORTCUT && 156968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (id_to_item_controller_map_[item.id]->locked() || 157068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) id_to_item_controller_map_[item.id]->type() == 157168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LauncherItemController::TYPE_APP)) { 157268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Note: This will not change the amount of items (|max_index|). 157368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Even changes to the actual |index| due to item weighting 157468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // changes should be fine. 157568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UnpinRunningAppInternal(index); 157668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 157768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LauncherItemClosed(item.id); 157868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) --max_index; 157968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 15803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) --index; 15823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If the item wasn't found, that means id_to_item_controller_map_ 15853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // is out of sync. 1586d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(index <= max_index); 15873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 158868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Check if the item was already running but not yet pinned. 15895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); 15905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shelf_id) { 159168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // This app is running but not yet pinned. So pin and move it. 15925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) index = PinRunningAppInternal(index, shelf_id); 159368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 159468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // This app wasn't pinned before, insert a new entry. 15955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_id = CreateAppShortcutLauncherItem(*pref_app_id, index); 159668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ++max_index; 15975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) index = model_->ItemIndexByID(shelf_id); 159868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 15993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++pref_app_id; 16003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Remove any trailing existing items. 16043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) while (index < model_->item_count()) { 16055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ash::ShelfItem& item(model_->items()[index]); 160668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (item.type == ash::TYPE_APP_SHORTCUT) { 160768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (id_to_item_controller_map_[item.id]->locked() || 160868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) id_to_item_controller_map_[item.id]->type() == 160968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LauncherItemController::TYPE_APP) 161068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UnpinRunningAppInternal(index); 161168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else 161268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LauncherItemClosed(item.id); 161368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 161468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (item.type == ash::TYPE_BROWSER_SHORTCUT) 161568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) chrome_index = index; 161668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else if (item.type == ash::TYPE_APP_LIST) 161768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) app_list_index = index; 16183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++index; 161968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 16203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Append unprocessed items from the pref to the end of the model. 16233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { 162468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // All items but the chrome and / or app list shortcut needs to be added. 162568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool is_chrome = *pref_app_id == extension_misc::kChromeAppId; 16265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool is_app_list = *pref_app_id == kAppShelfIdPlaceholder; 162768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Coming here we know the next item which can be finalized, either the 162868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // chrome item or the app launcher. The final position is the end of the 162968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // list. The menu model will make sure that the item is grouped according 163068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // to its weight (which we do not know here). 163168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!is_chrome && !is_app_list) { 16323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DoPinAppWithID(*pref_app_id); 163368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int target_index = FindInsertionPoint(false); 16345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); 163568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int source_index = model_->ItemIndexByID(id); 163668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (source_index != target_index) 163768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) model_->Move(source_index, target_index); 163868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 163968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Needed for the old layout - the weight might force it to be lower in 164068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // rank. 164168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (app_list_index != -1 && target_index <= app_list_index) 164268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ++app_list_index; 164368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 164468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int target_index = FindInsertionPoint(is_app_list); 164568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MoveChromeOrApplistToFinalPosition( 164668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) is_chrome, is_app_list, target_index, &chrome_index, &app_list_index); 164768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 16483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 16503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetShelfAutoHideBehaviorPrefs( 16523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::ShelfAutoHideBehavior behavior, 16531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window) { 16543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* value = NULL; 16553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (behavior) { 16563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS: 16573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) value = ash::kShelfAutoHideBehaviorAlways; 16583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 16593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER: 16603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) value = ash::kShelfAutoHideBehaviorNever; 16613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 16623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN: 16633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This one should not be a valid preference option for now. We only want 16645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to completely hide it when we run in app mode - or while we temporarily 16655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // hide the shelf as part of an animation (e.g. the multi user change). 16663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 16673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdatePerDisplayPref( 16703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetPrefs(), root_window, prefs::kShelfAutoHideBehavior, value); 16713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (root_window == ash::Shell::GetPrimaryRootWindow()) { 16733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // See comment in |kShelfAlignment| about why we have two prefs here. 16743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetPrefs()->SetString(prefs::kShelfAutoHideBehaviorLocal, value); 16753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetPrefs()->SetString(prefs::kShelfAutoHideBehavior, value); 16763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 16783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { 1680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); 16813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (aura::Window::Windows::const_iterator iter = root_windows.begin(); 16833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) iter != root_windows.end(); ++iter) { 16843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::Shell::GetInstance()->SetShelfAutoHideBehavior( 16853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetShelfAutoHideBehavior(*iter), *iter); 16863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 16883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetShelfAlignmentFromPrefs() { 16903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ash::ShelfWidget::ShelfAlignmentAllowed()) 16913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 16923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); 16943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (aura::Window::Windows::const_iterator iter = root_windows.begin(); 16963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) iter != root_windows.end(); ++iter) { 16973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // See comment in |kShelfAlignment| as to why we consider two prefs. 16983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string alignment_value( 16993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetPrefForRootWindow(profile_->GetPrefs(), 17003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *iter, 17013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfAlignmentLocal, 17023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kShelfAlignment)); 17033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::ShelfAlignment alignment = ash::SHELF_ALIGNMENT_BOTTOM; 17043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (alignment_value == ash::kShelfAlignmentLeft) 17053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) alignment = ash::SHELF_ALIGNMENT_LEFT; 17063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else if (alignment_value == ash::kShelfAlignmentRight) 17073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) alignment = ash::SHELF_ALIGNMENT_RIGHT; 17083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else if (alignment_value == ash::kShelfAlignmentTop) 17093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) alignment = ash::SHELF_ALIGNMENT_TOP; 17103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ash::Shell::GetInstance()->SetShelfAlignment(alignment, *iter); 17113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 17123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 17133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::SetShelfBehaviorsFromPrefs() { 17153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetShelfAutoHideBehaviorFromPrefs(); 17163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetShelfAlignmentFromPrefs(); 17173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 17183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(OS_CHROMEOS) 17206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() { 17216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const PrefService* service = profile_->GetPrefs(); 17226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (!service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) { 17236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); 17246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } else { 17256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const bool enabled = service->GetBoolean( 17266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) prefs::kTouchVirtualKeyboardEnabled); 17276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) keyboard::SetKeyboardShowOverride( 17286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) enabled ? keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED 17296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) : keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED); 17306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 17316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 17326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif // defined(OS_CHROMEOS) 17336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1734effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochash::ShelfItemStatus ChromeLauncherController::GetAppState( 1735effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const::std::string& app_id) { 1736effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ash::ShelfItemStatus status = ash::STATUS_CLOSED; 1737effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (WebContentsToAppIDMap::iterator it = web_contents_to_app_id_.begin(); 1738effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch it != web_contents_to_app_id_.end(); 1739effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++it) { 1740effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (it->second == app_id) { 1741effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Browser* browser = chrome::FindBrowserWithWebContents(it->first); 1742c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Usually there should never be an item in our |web_contents_to_app_id_| 1743c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // list which got deleted already. However - in some situations e.g. 1744c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Browser::SwapTabContent there is temporarily no associated browser. 1745c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!browser) 1746c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch continue; 1747effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (browser->window()->IsActive()) { 1748effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return browser->tab_strip_model()->GetActiveWebContents() == it->first ? 1749effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ash::STATUS_ACTIVE : ash::STATUS_RUNNING; 1750effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 1751effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch status = ash::STATUS_RUNNING; 1752effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 1753effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 17545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1755effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return status; 17563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 17573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ash::ShelfID ChromeLauncherController::InsertAppLauncherItem( 17593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller, 17603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id, 17615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemStatus status, 17623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index, 17635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType shelf_item_type) { 17645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = model_->next_id(); 17653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(!HasItemController(id)); 17663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CHECK(controller); 17673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_[id] = controller; 17685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) controller->set_shelf_id(id); 17693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem item; 17715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item.type = shelf_item_type; 17725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu item.image = extensions::util::GetDefaultAppIcon(); 17733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1774effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ash::ShelfItemStatus new_state = GetAppState(app_id); 1775effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (new_state != ash::STATUS_CLOSED) 1776effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch status = new_state; 1777effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 17783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) item.status = status; 17793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->AddAt(index, item); 17813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_icon_loader_->FetchImage(app_id); 17833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1784a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetShelfItemDelegate(id, controller); 17854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 17863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return id; 17873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 17883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ChromeLauncherController::HasItemController(ash::ShelfID id) const { 17903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return id_to_item_controller_map_.find(id) != 17913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_to_item_controller_map_.end(); 17923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 17933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::vector<content::WebContents*> 17953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ChromeLauncherController::GetV1ApplicationsFromController( 17963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LauncherItemController* controller) { 17973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(controller->type() == LauncherItemController::TYPE_SHORTCUT); 17983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AppShortcutLauncherItemController* app_controller = 17993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<AppShortcutLauncherItemController*>(controller); 18003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return app_controller->GetRunningApplications(); 18013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 18023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 180358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BrowserShortcutLauncherItemController* 18043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ChromeLauncherController::GetBrowserShortcutLauncherItemController() { 18053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin(); 18063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i != id_to_item_controller_map_.end(); ++i) { 18073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int index = model_->ItemIndexByID(i->first); 18085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ash::ShelfItem& item = model_->items()[index]; 18093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (item.type == ash::TYPE_BROWSER_SHORTCUT) 181058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return static_cast<BrowserShortcutLauncherItemController*>(i->second); 18113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 181258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Create a LauncherItemController for the Browser shortcut if it does not 181358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // exist yet. 18145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = CreateBrowserShortcutLauncherItem(); 18153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(id_to_item_controller_map_[id]); 181658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return static_cast<BrowserShortcutLauncherItemController*>( 181758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) id_to_item_controller_map_[id]); 18183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 18193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 18205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { 18215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItem browser_shortcut; 18223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; 18233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 18243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); 18255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id = model_->next_id(); 182668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t index = GetChromeIconIndexForCreation(); 18273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) model_->AddAt(index, browser_shortcut); 18284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) id_to_item_controller_map_[id] = 18294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new BrowserShortcutLauncherItemController(this); 18305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) id_to_item_controller_map_[id]->set_shelf_id(id); 1831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. 1832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetShelfItemDelegate(id, id_to_item_controller_map_[id]); 18333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return id; 18343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 18353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 18363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::PersistChromeItemIndex(int index) { 18373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); 18383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 18393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 18403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int ChromeLauncherController::GetChromeIconIndexFromPref() const { 18413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t index = profile_->GetPrefs()->GetInteger(prefs::kShelfChromeIconIndex); 18423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::ListValue* pinned_apps_pref = 18433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) profile_->GetPrefs()->GetList(prefs::kPinnedLauncherApps); 18443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return std::max(static_cast<size_t>(0), 18453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::min(pinned_apps_pref->GetSize(), index)); 18463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 18473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 184868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ChromeLauncherController::MoveChromeOrApplistToFinalPosition( 184968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool is_chrome, 185068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool is_app_list, 185168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int target_index, 185268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int* chrome_index, 185368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int* app_list_index) { 185468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (is_chrome && *chrome_index != -1) { 185568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) model_->Move(*chrome_index, target_index); 185668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (*app_list_index != -1 && 185768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) *chrome_index < *app_list_index && 185868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) target_index > *app_list_index) 185968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) --(*app_list_index); 186068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) *chrome_index = -1; 186168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else if (is_app_list && *app_list_index != -1) { 186268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) model_->Move(*app_list_index, target_index); 186368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (*chrome_index != -1 && 186468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) *app_list_index < *chrome_index && 186568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) target_index > *chrome_index) 186668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) --(*chrome_index); 186768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) *app_list_index = -1; 186868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 186968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 187068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 187168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int ChromeLauncherController::FindInsertionPoint(bool is_app_list) { 18725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Keeping this change small to backport to M33&32 (see crbug.com/329597). 18735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(skuhne): With the removal of the legacy shelf layout we should remove 18745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the ability to move the app list item since this was never used. We should 18755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index. 1876a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (is_app_list) 18775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 18785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 187968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int i = model_->item_count() - 1; i > 0; --i) { 18805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfItemType type = model_->items()[i].type; 188168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (type == ash::TYPE_APP_SHORTCUT || 1882a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (is_app_list && type == ash::TYPE_APP_LIST) || 1883effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch type == ash::TYPE_BROWSER_SHORTCUT) { 188468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return i; 1885effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 188668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 188768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return 0; 188868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 188968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 189068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int ChromeLauncherController::GetChromeIconIndexForCreation() { 189168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We get the list of pinned apps as they currently would get pinned. 189268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Within this list the chrome icon will be the correct location. 189368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<std::string> pinned_apps = GetListOfPinnedAppsAndBrowser(); 189468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 189568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<std::string>::iterator it = 189668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::find(pinned_apps.begin(), 189768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pinned_apps.end(), 189868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string(extension_misc::kChromeAppId)); 189968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(it != pinned_apps.end()); 190068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int index = it - pinned_apps.begin(); 190168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 190268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We should do here a comparison between the is state and the "want to be" 190368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // state since some apps might be able to pin but are not yet. Instead - for 190468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // the time being we clamp against the amount of known items and wait for the 190568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since 190668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // the pinning will be done then. 190768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return std::min(model_->item_count(), index); 190868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 190968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 191068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<std::string> 191168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ChromeLauncherController::GetListOfPinnedAppsAndBrowser() { 191268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Adding the app list item to the list of items requires that the ID is not 191368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // a valid and known ID for the extension system. The ID was constructed that 191468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // way - but just to make sure... 19155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!app_tab_helper_->IsValidIDForCurrentUser(kAppShelfIdPlaceholder)); 191668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 191768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<std::string> pinned_apps; 191868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 191968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Get the new incarnation of the list. 192068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const base::ListValue* pinned_apps_pref = 192168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) profile_->GetPrefs()->GetList(prefs::kPinnedLauncherApps); 192268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 192368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Keep track of the addition of the chrome and the app list icon. 192468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool chrome_icon_added = false; 192568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool app_list_icon_added = false; 192668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_t chrome_icon_index = GetChromeIconIndexFromPref(); 192768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 192868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // See if the chrome string is already in the pinned list and remove it if 192968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // needed. 193068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Value* chrome_app = ash::CreateAppDict(extension_misc::kChromeAppId); 193168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (chrome_app) { 193268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) chrome_icon_added = pinned_apps_pref->Find(*chrome_app) != 193368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pinned_apps_pref->end(); 193468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) delete chrome_app; 193568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 193668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 193768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t index = 0; index < pinned_apps_pref->GetSize(); ++index) { 193868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We need to position the chrome icon relative to it's place in the pinned 193968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // preference list - even if an item of that list isn't shown yet. 194068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (index == chrome_icon_index && !chrome_icon_added) { 194168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pinned_apps.push_back(extension_misc::kChromeAppId); 194268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) chrome_icon_added = true; 194368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* app = NULL; 194568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string app_id; 194668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pinned_apps_pref->GetDictionary(index, &app) && 194768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id) && 194868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (std::find(pinned_apps.begin(), pinned_apps.end(), app_id) == 194968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pinned_apps.end())) { 195068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (app_id == extension_misc::kChromeAppId) { 195168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) chrome_icon_added = true; 195268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pinned_apps.push_back(extension_misc::kChromeAppId); 19535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (app_id == kAppShelfIdPlaceholder) { 195468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) app_list_icon_added = true; 19555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pinned_apps.push_back(kAppShelfIdPlaceholder); 19564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else if (app_tab_helper_->IsValidIDForCurrentUser(app_id)) { 19574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Note: In multi profile scenarios we only want to show pinnable apps 19584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // here which is correct. Running applications from the other users will 19594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // continue to run. So no need for multi profile modifications. 196068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pinned_apps.push_back(app_id); 196168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 196268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 196368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 196468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 196568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If not added yet, the chrome item will be the last item in the list. 196668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!chrome_icon_added) 196768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pinned_apps.push_back(extension_misc::kChromeAppId); 196868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 196968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If not added yet, add the app list item either at the end or at the 197068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // beginning - depending on the shelf layout. 197168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!app_list_icon_added) { 1972a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pinned_apps.insert(pinned_apps.begin(), kAppShelfIdPlaceholder); 197368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 197468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return pinned_apps; 197568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 197668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ChromeLauncherController::IsIncognito( 197868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const content::WebContents* web_contents) const { 19793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Profile* profile = 19803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 19813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return profile->IsOffTheRecord() && !profile->IsGuestSession(); 19823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 19833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 19843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( 19853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& app_id) { 19863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This function cannot rely on the controller's enumeration functionality 19873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // since the extension has already be unloaded. 19883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const BrowserList* ash_browser_list = 19893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 19903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<Browser*> browser_to_close; 19913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (BrowserList::const_reverse_iterator 19923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) it = ash_browser_list->begin_last_active(); 19933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) it != ash_browser_list->end_last_active(); ++it) { 19943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Browser* browser = *it; 19953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!browser->is_type_tabbed() && 19963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) browser->is_type_popup() && 19973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) browser->is_app() && 19983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) app_id == web_app::GetExtensionIdFromApplicationName( 19993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) browser->app_name())) { 20003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) browser_to_close.push_back(browser); 20013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 20023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 20033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) while (!browser_to_close.empty()) { 20043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TabStripModel* tab_strip = browser_to_close.back()->tab_strip_model(); 20053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE); 20063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) browser_to_close.pop_back(); 20073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 20083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 20093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2010a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ChromeLauncherController::SetShelfItemDelegate( 20115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ShelfID id, 2012a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ash::ShelfItemDelegate* item_delegate) { 20134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_GT(id, 0); 20144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(item_delegate); 20154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(item_delegate_manager_); 2016a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) item_delegate_manager_->SetShelfItemDelegate( 2017a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) id, scoped_ptr<ash::ShelfItemDelegate>(item_delegate).Pass()); 2018424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 2019d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2020d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ChromeLauncherController::AttachProfile(Profile* profile) { 2021d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) profile_ = profile; 20224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Either add the profile to the list of known profiles and make it the active 20234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // one for some functions of AppTabHelper or create a new one. 20244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!app_tab_helper_.get()) 20254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app_tab_helper_.reset(new LauncherAppTabHelper(profile_)); 20264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else 20274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app_tab_helper_->SetCurrentUser(profile_); 2028d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(skuhne): The AppIconLoaderImpl has the same problem. Each loaded 2029d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // image is associated with a profile (it's loader requires the profile). 2030d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Since icon size changes are possible, the icon could be requested to be 2031d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // reloaded. However - having it not multi profile aware would cause problems 2032d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // if the icon cache gets deleted upon user switch. 2033d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) app_icon_loader_.reset(new extensions::AppIconLoaderImpl( 2034d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) profile_, extension_misc::EXTENSION_ICON_SMALL, this)); 2035d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2036d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pref_change_registrar_.Init(profile_->GetPrefs()); 2037d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pref_change_registrar_.Add( 2038d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) prefs::kPinnedLauncherApps, 2039d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 2040d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Unretained(this))); 2041d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pref_change_registrar_.Add( 2042d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) prefs::kShelfAlignmentLocal, 2043d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs, 2044d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Unretained(this))); 2045d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pref_change_registrar_.Add( 2046d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) prefs::kShelfAutoHideBehaviorLocal, 2047d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&ChromeLauncherController:: 2048d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SetShelfAutoHideBehaviorFromPrefs, 2049d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Unretained(this))); 2050d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pref_change_registrar_.Add( 2051d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) prefs::kShelfPreferences, 2052d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&ChromeLauncherController::SetShelfBehaviorsFromPrefs, 2053d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Unretained(this))); 20546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(OS_CHROMEOS) 20556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) pref_change_registrar_.Add( 20566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) prefs::kTouchVirtualKeyboardEnabled, 20576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Bind(&ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs, 20586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Unretained(this))); 20596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif // defined(OS_CHROMEOS) 2060d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 2061d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2062d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ChromeLauncherController::ReleaseProfile() { 2063d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (app_sync_ui_state_) 2064d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) app_sync_ui_state_->RemoveObserver(this); 2065d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2066d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this); 2067d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2068d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pref_change_registrar_.RemoveAll(); 2069d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 2070