#include "base/command_line.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/extensions/app_icon_loader_impl.h"
-#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/launch_util.h"
#include "chrome/browser/favicon/favicon_tab_helper.h"
#include "chrome/browser/ui/ash/app_sync_ui_state.h"
#include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
#include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h"
+#include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h"
+#include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
#include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h"
#include "chrome/browser/ui/ash/launcher/browser_status_monitor.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_types.h"
#include "chrome/browser/ui/ash/launcher/launcher_app_tab_helper.h"
#include "chrome/browser/ui/ash/launcher/launcher_item_controller.h"
-#include "chrome/browser/ui/ash/launcher/shell_window_launcher_controller.h"
-#include "chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
-#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "chrome/grit/generated_resources.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
+#include "extensions/browser/extension_util.h"
+#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_resource.h"
+#include "extensions/common/manifest_handlers/icons_handler.h"
#include "extensions/common/url_pattern.h"
#include "grit/ash_resources.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
-#include "grit/ui_resources.h"
#include "net/base/url_util.h"
-#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
+#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/l10n/l10n_util.h"
-#include "ui/views/corewm/window_animations.h"
+#include "ui/keyboard/keyboard_util.h"
+#include "ui/resources/grit/ui_resources.h"
+#include "ui/wm/core/window_animations.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/ui/ash/chrome_shell_delegate.h"
+#include "chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h"
#include "chrome/browser/ui/ash/launcher/multi_profile_browser_status_monitor.h"
-#include "chrome/browser/ui/ash/launcher/multi_profile_shell_window_launcher_controller.h"
+#include "components/user_manager/user_manager.h"
#endif
using extensions::Extension;
return default_string;
}
+// Gets the shelf auto hide behavior from prefs for a root window.
+ash::ShelfAutoHideBehavior GetShelfAutoHideBehaviorFromPrefs(
+ Profile* profile,
+ aura::Window* root_window) {
+ // Don't show the shelf in app mode.
+ if (chrome::IsRunningInAppMode())
+ return ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN;
+
+ // See comment in |kShelfAlignment| as to why we consider two prefs.
+ const std::string behavior_value(
+ GetPrefForRootWindow(profile->GetPrefs(),
+ root_window,
+ prefs::kShelfAutoHideBehaviorLocal,
+ prefs::kShelfAutoHideBehavior));
+
+ // Note: To maintain sync compatibility with old images of chrome/chromeos
+ // the set of values that may be encountered includes the now-extinct
+ // "Default" as well as "Never" and "Always", "Default" should now
+ // be treated as "Never" (http://crbug.com/146773).
+ if (behavior_value == ash::kShelfAutoHideBehaviorAlways)
+ return ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
+ return ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER;
+}
+
+// Gets the shelf alignment from prefs for a root window.
+ash::ShelfAlignment GetShelfAlignmentFromPrefs(Profile* profile,
+ aura::Window* root_window) {
+ // See comment in |kShelfAlignment| as to why we consider two prefs.
+ const std::string alignment_value(
+ GetPrefForRootWindow(profile->GetPrefs(),
+ root_window,
+ prefs::kShelfAlignmentLocal,
+ prefs::kShelfAlignment));
+ if (alignment_value == ash::kShelfAlignmentLeft)
+ return ash::SHELF_ALIGNMENT_LEFT;
+ else if (alignment_value == ash::kShelfAlignmentRight)
+ return ash::SHELF_ALIGNMENT_RIGHT;
+ else if (alignment_value == ash::kShelfAlignmentTop)
+ return ash::SHELF_ALIGNMENT_TOP;
+ return ash::SHELF_ALIGNMENT_BOTTOM;
+}
+
// If prefs have synced and no user-set value exists at |local_path|, the value
// from |synced_path| is copied to |local_path|.
void MaybePropagatePrefToLocal(PrefServiceSyncable* pref_service,
// A class to get events from ChromeOS when a user gets changed or added.
class ChromeLauncherControllerUserSwitchObserverChromeOS
: public ChromeLauncherControllerUserSwitchObserver,
- public chromeos::UserManager::UserSessionStateObserver,
+ public user_manager::UserManager::UserSessionStateObserver,
content::NotificationObserver {
public:
ChromeLauncherControllerUserSwitchObserverChromeOS(
ChromeLauncherController* controller)
: controller_(controller) {
- DCHECK(chromeos::UserManager::IsInitialized());
- chromeos::UserManager::Get()->AddSessionStateObserver(this);
+ DCHECK(user_manager::UserManager::IsInitialized());
+ user_manager::UserManager::Get()->AddSessionStateObserver(this);
// A UserAddedToSession notification can be sent before a profile is loaded.
// Since our observers require that we have already a profile, we might have
// to postpone the notification until the ProfileManager lets us know that
content::NotificationService::AllSources());
}
virtual ~ChromeLauncherControllerUserSwitchObserverChromeOS() {
- chromeos::UserManager::Get()->RemoveSessionStateObserver(this);
+ user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
}
- // chromeos::UserManager::UserSessionStateObserver overrides:
- virtual void UserAddedToSession(const chromeos::User* added_user) OVERRIDE;
+ // user_manager::UserManager::UserSessionStateObserver overrides:
+ virtual void UserAddedToSession(
+ const user_manager::User* added_user) override;
// content::NotificationObserver overrides:
virtual void Observe(int type,
const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
+ const content::NotificationDetails& details) override;
private:
// Add a user to the session.
};
void ChromeLauncherControllerUserSwitchObserverChromeOS::UserAddedToSession(
- const chromeos::User* active_user) {
+ const user_manager::User* active_user) {
Profile* profile = multi_user_util::GetProfileFromUserID(
active_user->email());
// If we do not have a profile yet, we postpone forwarding the notification
// If running in separated destkop mode, we create the multi profile version
// of status monitor.
browser_status_monitor_.reset(new MultiProfileBrowserStatusMonitor(this));
- shell_window_controller_.reset(
- new MultiProfileShellWindowLauncherController(this));
+ app_window_controller_.reset(
+ new MultiProfileAppWindowLauncherController(this));
} else {
// Create our v1/v2 application / browser monitors which will inform the
// launcher of status changes.
browser_status_monitor_.reset(new BrowserStatusMonitor(this));
- shell_window_controller_.reset(new ShellWindowLauncherController(this));
+ app_window_controller_.reset(new AppWindowLauncherController(this));
}
#else
// Create our v1/v2 application / browser monitors which will inform the
// launcher of status changes.
browser_status_monitor_.reset(new BrowserStatusMonitor(this));
- shell_window_controller_.reset(new ShellWindowLauncherController(this));
+ app_window_controller_.reset(new AppWindowLauncherController(this));
#endif
// Right now ash::Shell isn't created for tests.
item_delegate_manager_ =
ash::Shell::GetInstance()->shelf_item_delegate_manager();
}
-
- notification_registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_LOADED,
- content::Source<Profile>(profile_));
- notification_registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_UNLOADED,
- content::Source<Profile>(profile_));
}
ChromeLauncherController::~ChromeLauncherController() {
// Reset the BrowserStatusMonitor as it has a weak pointer to this.
browser_status_monitor_.reset();
- // Reset the shell window controller here since it has a weak pointer to this.
- shell_window_controller_.reset();
+ // Reset the app window controller here since it has a weak pointer to this.
+ app_window_controller_.reset();
for (std::set<ash::Shelf*>::iterator iter = shelves_.begin();
iter != shelves_.end();
if (ash::Shell::HasInstance()) {
SetShelfAutoHideBehaviorFromPrefs();
SetShelfAlignmentFromPrefs();
+#if defined(OS_CHROMEOS)
+ SetVirtualKeyboardBehaviorFromPrefs();
+#endif // defined(OS_CHROMEOS)
PrefServiceSyncable* prefs = PrefServiceSyncable::FromProfile(profile_);
if (!prefs->FindPreference(prefs::kShelfAlignmentLocal)->HasUserSetting() ||
!prefs->FindPreference(prefs::kShelfAutoHideBehaviorLocal)->
CanPin());
}
+void ChromeLauncherController::Install(ash::ShelfID id) {
+ if (!HasItemController(id))
+ return;
+
+ std::string app_id = GetAppIDForShelfID(id);
+ if (extensions::util::IsExtensionInstalledPermanently(app_id, profile_))
+ return;
+
+ LauncherItemController* controller = id_to_item_controller_map_[id];
+ if (controller->type() == LauncherItemController::TYPE_APP) {
+ AppWindowLauncherItemController* app_window_controller =
+ static_cast<AppWindowLauncherItemController*>(controller);
+ app_window_controller->InstallApp();
+ }
+}
+
+bool ChromeLauncherController::CanInstall(ash::ShelfID id) {
+ int index = model_->ItemIndexByID(id);
+ if (index == -1)
+ return false;
+
+ ash::ShelfItemType type = model_->items()[index].type;
+ if (type != ash::TYPE_PLATFORM_APP)
+ return false;
+
+ return extensions::util::IsEphemeralApp(GetAppIDForShelfID(id), profile_);
+}
+
void ChromeLauncherController::LockV1AppWithID(
const std::string& app_id) {
ash::ShelfID id = GetShelfIDForAppID(app_id);
return;
}
+#if defined(OS_WIN)
if (LaunchedInNativeDesktop(app_id))
return;
+#endif
// The app will be created for the currently active profile.
AppLaunchParams params(profile_,
event_flags,
chrome::HOST_DESKTOP_TYPE_ASH);
if (source != ash::LAUNCH_FROM_UNKNOWN &&
- app_id == extension_misc::kWebStoreAppId) {
+ app_id == extensions::kWebStoreAppId) {
// Get the corresponding source string.
std::string source_value = GetSourceFromAppListSource(source);
extension_url, extension_urls::kWebstoreSourceField, source_value);
}
+ params.source = (source == ash::LAUNCH_FROM_UNKNOWN)
+ ? extensions::SOURCE_UNTRACKED
+ : extensions::SOURCE_APP_LAUNCHER;
+
OpenApplication(params);
}
if (!extension)
return extensions::LAUNCH_TYPE_DEFAULT;
- return extensions::GetLaunchType(
- profile_->GetExtensionService()->extension_prefs(),
- extension);
+ return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_),
+ extension);
}
ash::ShelfID ChromeLauncherController::GetShelfIDForAppID(
if (!HasItemController(id))
return;
- extensions::SetLaunchType(profile_->GetExtensionService(),
- id_to_item_controller_map_[id]->app_id(),
- launch_type);
+ extensions::SetLaunchType(
+ extensions::ExtensionSystem::Get(profile_)->extension_service(),
+ id_to_item_controller_map_[id]->app_id(),
+ launch_type);
}
void ChromeLauncherController::UnpinAppWithID(const std::string& app_id) {
ash::ShelfAutoHideBehavior ChromeLauncherController::GetShelfAutoHideBehavior(
aura::Window* root_window) const {
- // Don't show the shelf in app mode.
- if (chrome::IsRunningInAppMode())
- return ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN;
-
- // See comment in |kShelfAlignment| as to why we consider two prefs.
- const std::string behavior_value(
- GetPrefForRootWindow(profile_->GetPrefs(),
- root_window,
- prefs::kShelfAutoHideBehaviorLocal,
- prefs::kShelfAutoHideBehavior));
-
- // Note: To maintain sync compatibility with old images of chrome/chromeos
- // the set of values that may be encountered includes the now-extinct
- // "Default" as well as "Never" and "Always", "Default" should now
- // be treated as "Never" (http://crbug.com/146773).
- if (behavior_value == ash::kShelfAutoHideBehaviorAlways)
- return ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
- return ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER;
+ return GetShelfAutoHideBehaviorFromPrefs(profile_, root_window);
}
bool ChromeLauncherController::CanUserModifyShelfAutoHideBehavior(
return;
}
-void ChromeLauncherController::RemoveTabFromRunningApp(
- WebContents* tab,
- const std::string& app_id) {
- web_contents_to_app_id_.erase(tab);
- // BrowserShortcutLauncherItemController::UpdateBrowserItemState() will update
- // the state when no application is associated with the tab.
- if (app_id.empty())
- return;
-
- AppIDToWebContentsListMap::iterator i_app_id =
- app_id_to_web_contents_list_.find(app_id);
- if (i_app_id != app_id_to_web_contents_list_.end()) {
- WebContentsList* tab_list = &i_app_id->second;
- tab_list->remove(tab);
- ash::ShelfItemStatus status = ash::STATUS_RUNNING;
- if (tab_list->empty()) {
- app_id_to_web_contents_list_.erase(i_app_id);
- status = ash::STATUS_CLOSED;
- }
- ash::ShelfID id = GetShelfIDForAppID(app_id);
- if (id)
- SetItemStatus(id, status);
- }
-}
-
void ChromeLauncherController::UpdateAppState(content::WebContents* contents,
AppState app_state) {
std::string app_id = app_tab_helper_->GetAppID(contents);
// remove it from the previous app.
if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) {
std::string last_app_id = web_contents_to_app_id_[contents];
- if (last_app_id != app_id)
- RemoveTabFromRunningApp(contents, last_app_id);
- }
-
- web_contents_to_app_id_[contents] = app_id;
-
- if (app_state == APP_STATE_REMOVED) {
- // The tab has gone away.
- RemoveTabFromRunningApp(contents, app_id);
- } else if (!app_id.empty()) {
- WebContentsList& tab_list(app_id_to_web_contents_list_[app_id]);
- WebContentsList::const_iterator i_tab =
- std::find(tab_list.begin(), tab_list.end(), contents);
-
- if (i_tab == tab_list.end())
- tab_list.push_back(contents);
-
- if (app_state == APP_STATE_INACTIVE || app_state == APP_STATE_ACTIVE) {
- if (i_tab != tab_list.begin()) {
- // Going to running state, but wasn't the front tab, indicating that a
- // new tab has already become active.
- return;
+ if (last_app_id != app_id) {
+ ash::ShelfID id = GetShelfIDForAppID(last_app_id);
+ if (id) {
+ // Since GetAppState() will use |web_contents_to_app_id_| we remove
+ // the connection before calling it.
+ web_contents_to_app_id_.erase(contents);
+ SetItemStatus(id, GetAppState(last_app_id));
}
}
+ }
- if (app_state == APP_STATE_ACTIVE || app_state == APP_STATE_WINDOW_ACTIVE) {
- tab_list.remove(contents);
- tab_list.push_front(contents);
- }
+ if (app_state == APP_STATE_REMOVED)
+ web_contents_to_app_id_.erase(contents);
+ else
+ web_contents_to_app_id_[contents] = app_id;
- ash::ShelfID id = GetShelfIDForAppID(app_id);
- if (id) {
- // If the window is active, mark the app as active.
- SetItemStatus(id, app_state == APP_STATE_WINDOW_ACTIVE ?
- ash::STATUS_ACTIVE : ash::STATUS_RUNNING);
- }
+ ash::ShelfID id = GetShelfIDForAppID(app_id);
+ if (id) {
+ SetItemStatus(id, (app_state == APP_STATE_WINDOW_ACTIVE ||
+ app_state == APP_STATE_ACTIVE) ? ash::STATUS_ACTIVE :
+ GetAppState(app_id));
}
}
const Extension* ChromeLauncherController::GetExtensionForAppID(
const std::string& app_id) const {
- // Some unit tests do not have a real extension.
- return (profile_->GetExtensionService()) ?
- profile_->GetExtensionService()->GetInstalledExtension(app_id) : NULL;
+ return extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
+ app_id, extensions::ExtensionRegistry::EVERYTHING);
}
void ChromeLauncherController::ActivateWindowOrMinimizeIfActive(
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableMinimizeOnSecondLauncherItemClick)) {
AnimateWindow(window->GetNativeWindow(),
- views::corewm::WINDOW_ANIMATION_TYPE_BOUNCE);
+ wm::WINDOW_ANIMATION_TYPE_BOUNCE);
} else {
window->Minimize();
}
// The app list launcher can get added to the shelf after we applied the
// preferences. In that case the item might be at the wrong spot. As such we
// call the function again.
- if (model_->items()[index].type == ash::TYPE_APP_LIST &&
- ash::switches::UseAlternateShelfLayout())
+ if (model_->items()[index].type == ash::TYPE_APP_LIST)
UpdateAppLaunchersFromPref();
}
// We remember the moved item position if it is either pinnable or
// it is the app list with the alternate shelf layout.
if ((HasItemController(item.id) && IsPinned(item.id)) ||
- (ash::switches::UseAlternateShelfLayout() &&
- item.type == ash::TYPE_APP_LIST))
+ item.type == ash::TYPE_APP_LIST)
PersistPinnedState();
}
// Update the V1 applications.
browser_status_monitor_->ActiveUserChanged(user_email);
// Switch the running applications to the new user.
- shell_window_controller_->ActiveUserChanged(user_email);
+ app_window_controller_->ActiveUserChanged(user_email);
// Update the user specific shell properties from the new user profile.
UpdateAppLaunchersFromPref();
SetShelfAlignmentFromPrefs();
SetShelfAutoHideBehaviorFromPrefs();
SetShelfBehaviorsFromPrefs();
+#if defined(OS_CHROMEOS)
+ SetVirtualKeyboardBehaviorFromPrefs();
+#endif // defined(OS_CHROMEOS)
// Restore the order of running, but unpinned applications for the activated
// user.
RestoreUnpinnedRunningApplicationOrder(user_email);
// Inform the system tray of the change.
ash::Shell::GetInstance()->system_tray_delegate()->ActiveUserWasChanged();
+ // Force on-screen keyboard to reset.
+ if (keyboard::IsKeyboardEnabled())
+ ash::Shell::GetInstance()->CreateKeyboard();
}
void ChromeLauncherController::AdditionalUserAddedToSession(Profile* profile) {
// Switch the running applications to the new user.
- shell_window_controller_->AdditionalUserAddedToSession(profile);
+ app_window_controller_->AdditionalUserAddedToSession(profile);
}
-void ChromeLauncherController::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- switch (type) {
- case chrome::NOTIFICATION_EXTENSION_LOADED: {
- const Extension* extension =
- content::Details<const Extension>(details).ptr();
- if (IsAppPinned(extension->id())) {
- // Clear and re-fetch to ensure icon is up-to-date.
- app_icon_loader_->ClearImage(extension->id());
- app_icon_loader_->FetchImage(extension->id());
- }
+void ChromeLauncherController::OnExtensionLoaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ if (IsAppPinned(extension->id())) {
+ // Clear and re-fetch to ensure icon is up-to-date.
+ app_icon_loader_->ClearImage(extension->id());
+ app_icon_loader_->FetchImage(extension->id());
+ }
- UpdateAppLaunchersFromPref();
- break;
- }
- case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
- const content::Details<UnloadedExtensionInfo>& unload_info(details);
- const Extension* extension = unload_info->extension;
- const std::string& id = extension->id();
- // Since we might have windowed apps of this type which might have
- // outstanding locks which needs to be removed.
- if (GetShelfIDForAppID(id) &&
- unload_info->reason == UnloadedExtensionInfo::REASON_UNINSTALL) {
- CloseWindowedAppsFromRemovedExtension(id);
- }
+ UpdateAppLaunchersFromPref();
+}
- if (IsAppPinned(id)) {
- if (unload_info->reason == UnloadedExtensionInfo::REASON_UNINSTALL) {
- DoUnpinAppWithID(id);
- app_icon_loader_->ClearImage(id);
- } else {
- app_icon_loader_->UpdateImage(id);
- }
+void ChromeLauncherController::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) {
+ const std::string& id = extension->id();
+ const Profile* profile = Profile::FromBrowserContext(browser_context);
+
+ // Since we might have windowed apps of this type which might have
+ // outstanding locks which needs to be removed.
+ if (GetShelfIDForAppID(id) &&
+ reason == UnloadedExtensionInfo::REASON_UNINSTALL) {
+ CloseWindowedAppsFromRemovedExtension(id, profile);
+ }
+
+ if (IsAppPinned(id)) {
+ if (reason == UnloadedExtensionInfo::REASON_UNINSTALL) {
+ if (profile == profile_) {
+ DoUnpinAppWithID(id);
}
- break;
+ app_icon_loader_->ClearImage(id);
+ } else {
+ app_icon_loader_->UpdateImage(id);
}
- default:
- NOTREACHED() << "Unexpected notification type=" << type;
}
}
}
}
-void ChromeLauncherController::OnDisplayConfigurationChanging() {
-}
-
void ChromeLauncherController::OnDisplayConfigurationChanged() {
SetShelfBehaviorsFromPrefs();
}
if (id) {
LauncherItemController* controller = id_to_item_controller_map_[id];
if (controller->type() == LauncherItemController::TYPE_APP) {
- ShellWindowLauncherItemController* shell_window_controller =
- static_cast<ShellWindowLauncherItemController*>(controller);
- shell_window_controller->ActivateIndexedApp(index);
+ AppWindowLauncherItemController* app_window_controller =
+ static_cast<AppWindowLauncherItemController*>(controller);
+ app_window_controller->ActivateIndexedApp(index);
}
}
}
gfx::Image ChromeLauncherController::GetAppListIcon(
content::WebContents* web_contents) const {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
if (IsIncognito(web_contents))
- return rb.GetImageNamed(IDR_AURA_LAUNCHER_LIST_INCOGNITO_BROWSER);
+ return rb.GetImageNamed(IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER);
FaviconTabHelper* favicon_tab_helper =
FaviconTabHelper::FromWebContents(web_contents);
gfx::Image result = favicon_tab_helper->GetFavicon();
return multi_user_util::IsProfileFromActiveUser(browser->profile());
}
+bool ChromeLauncherController::ShelfBoundsChangesProbablyWithUser(
+ aura::Window* root_window,
+ const std::string& user_id) const {
+ Profile* other_profile = multi_user_util::GetProfileFromUserID(user_id);
+ DCHECK_NE(other_profile, profile_);
+
+ // Note: The Auto hide state from preferences is not the same as the actual
+ // visibility of the shelf. Depending on all the various states (full screen,
+ // no window on desktop, multi user, ..) the shelf could be shown - or not.
+ bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
+ GetShelfAutoHideBehaviorFromPrefs(profile_, root_window);
+ bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
+ GetShelfAutoHideBehaviorFromPrefs(other_profile, root_window);
+
+ return currently_shown != other_shown ||
+ GetShelfAlignmentFromPrefs(profile_, root_window) !=
+ GetShelfAlignmentFromPrefs(other_profile, root_window);
+}
+
void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) {
IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
CHECK(iter != id_to_item_controller_map_.end());
for (aura::Window::Windows::const_iterator iter = root_windows.begin();
iter != root_windows.end(); ++iter) {
- // See comment in |kShelfAlignment| as to why we consider two prefs.
- const std::string alignment_value(
- GetPrefForRootWindow(profile_->GetPrefs(),
- *iter,
- prefs::kShelfAlignmentLocal,
- prefs::kShelfAlignment));
- ash::ShelfAlignment alignment = ash::SHELF_ALIGNMENT_BOTTOM;
- if (alignment_value == ash::kShelfAlignmentLeft)
- alignment = ash::SHELF_ALIGNMENT_LEFT;
- else if (alignment_value == ash::kShelfAlignmentRight)
- alignment = ash::SHELF_ALIGNMENT_RIGHT;
- else if (alignment_value == ash::kShelfAlignmentTop)
- alignment = ash::SHELF_ALIGNMENT_TOP;
- ash::Shell::GetInstance()->SetShelfAlignment(alignment, *iter);
+ ash::Shell::GetInstance()->SetShelfAlignment(
+ GetShelfAlignmentFromPrefs(profile_, *iter), *iter);
}
}
SetShelfAlignmentFromPrefs();
}
-WebContents* ChromeLauncherController::GetLastActiveWebContents(
- const std::string& app_id) {
- AppIDToWebContentsListMap::iterator i =
- app_id_to_web_contents_list_.find(app_id);
- if (i == app_id_to_web_contents_list_.end())
- return NULL;
+#if defined(OS_CHROMEOS)
+void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() {
+ const PrefService* service = profile_->GetPrefs();
+ const bool was_enabled = keyboard::IsKeyboardEnabled();
+ if (!service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) {
+ keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE);
+ } else {
+ const bool enable = service->GetBoolean(
+ prefs::kTouchVirtualKeyboardEnabled);
+ keyboard::SetKeyboardShowOverride(
+ enable ? keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED
+ : keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED);
+ }
+ const bool is_enabled = keyboard::IsKeyboardEnabled();
+ if (was_enabled && !is_enabled)
+ ash::Shell::GetInstance()->DeactivateKeyboard();
+ else if (is_enabled && !was_enabled)
+ ash::Shell::GetInstance()->CreateKeyboard();
+}
+#endif // defined(OS_CHROMEOS)
- // There are many crash records (crbug.com/341250) which indicate that the
- // app_id_to_web_contents_list_ contains deleted content entries - so there
- // must be a way that the content does not get properly updated. To fix
- // M33 and M34 we filter out the invalid items here, but this should be
- // addressed by a later patch correctly. Looking at the code however, the
- // real culprit is possibly BrowserStatusMonitor::UpdateAppItemState which
- // does not call "UpdateAppState(.., APP_STATE_REMOVED)" because due to a
- // Browser::SwapTabContent operation it isn't able to get the browser. I
- // think that the real patch is to call anyway when APP_STATE_REMOVED is
- // requested, but for a backport that seems risky.
- WebContentsList* list = &i->second;
- while (!list->empty()) {
- WebContents* contents = *list->begin();
- if (chrome::FindBrowserWithWebContents(contents))
- return contents;
- list->erase(list->begin());
- // This might not be necessary, but since we do not know why the lists
- // diverged we also erase it since it cannot be correct either.
- web_contents_to_app_id_.erase(contents);
+ash::ShelfItemStatus ChromeLauncherController::GetAppState(
+ const std::string& app_id) {
+ ash::ShelfItemStatus status = ash::STATUS_CLOSED;
+ for (WebContentsToAppIDMap::iterator it = web_contents_to_app_id_.begin();
+ it != web_contents_to_app_id_.end();
+ ++it) {
+ if (it->second == app_id) {
+ Browser* browser = chrome::FindBrowserWithWebContents(it->first);
+ // Usually there should never be an item in our |web_contents_to_app_id_|
+ // list which got deleted already. However - in some situations e.g.
+ // Browser::SwapTabContent there is temporarily no associated browser.
+ if (!browser)
+ continue;
+ if (browser->window()->IsActive()) {
+ return browser->tab_strip_model()->GetActiveWebContents() == it->first ?
+ ash::STATUS_ACTIVE : ash::STATUS_RUNNING;
+ } else {
+ status = ash::STATUS_RUNNING;
+ }
+ }
}
- app_id_to_web_contents_list_.erase(app_id);
- return NULL;
+ return status;
}
ash::ShelfID ChromeLauncherController::InsertAppLauncherItem(
ash::ShelfItem item;
item.type = shelf_item_type;
- item.image = extensions::IconsInfo::GetDefaultAppIcon();
-
- WebContents* active_tab = GetLastActiveWebContents(app_id);
- if (active_tab) {
- Browser* browser = chrome::FindBrowserWithWebContents(active_tab);
- DCHECK(browser);
- if (browser->window()->IsActive())
- status = ash::STATUS_ACTIVE;
- else
- status = ash::STATUS_RUNNING;
- }
+ item.image = extensions::util::GetDefaultAppIcon();
+
+ ash::ShelfItemStatus new_state = GetAppState(app_id);
+ if (new_state != ash::STATUS_CLOSED)
+ status = new_state;
+
item.status = status;
model_->AddAt(index, item);
}
int ChromeLauncherController::FindInsertionPoint(bool is_app_list) {
- bool alternate = ash::switches::UseAlternateShelfLayout();
// Keeping this change small to backport to M33&32 (see crbug.com/329597).
// TODO(skuhne): With the removal of the legacy shelf layout we should remove
// the ability to move the app list item since this was never used. We should
// instead ask the ShelfModel::ValidateInsertionIndex or similir for an index.
- if (is_app_list && alternate)
+ if (is_app_list)
return 0;
for (int i = model_->item_count() - 1; i > 0; --i) {
ash::ShelfItemType type = model_->items()[i].type;
if (type == ash::TYPE_APP_SHORTCUT ||
- ((is_app_list || alternate) && type == ash::TYPE_APP_LIST) ||
- type == ash::TYPE_BROWSER_SHORTCUT ||
- type == ash::TYPE_WINDOWED_APP)
+ (is_app_list && type == ash::TYPE_APP_LIST) ||
+ type == ash::TYPE_BROWSER_SHORTCUT) {
return i;
+ }
}
return 0;
}
// If not added yet, add the app list item either at the end or at the
// beginning - depending on the shelf layout.
if (!app_list_icon_added) {
- if (ash::switches::UseAlternateShelfLayout())
- pinned_apps.insert(pinned_apps.begin(), kAppShelfIdPlaceholder);
- else
- pinned_apps.push_back(kAppShelfIdPlaceholder);
+ pinned_apps.insert(pinned_apps.begin(), kAppShelfIdPlaceholder);
}
return pinned_apps;
}
}
void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension(
- const std::string& app_id) {
+ const std::string& app_id,
+ const Profile* profile) {
// This function cannot rely on the controller's enumeration functionality
// since the extension has already be unloaded.
const BrowserList* ash_browser_list =
it = ash_browser_list->begin_last_active();
it != ash_browser_list->end_last_active(); ++it) {
Browser* browser = *it;
- if (!browser->is_type_tabbed() &&
- browser->is_type_popup() &&
+ if (!browser->is_type_tabbed() && browser->is_type_popup() &&
browser->is_app() &&
- app_id == web_app::GetExtensionIdFromApplicationName(
- browser->app_name())) {
+ app_id ==
+ web_app::GetExtensionIdFromApplicationName(browser->app_name()) &&
+ profile == browser->profile()) {
browser_to_close.push_back(browser);
}
}
prefs::kShelfPreferences,
base::Bind(&ChromeLauncherController::SetShelfBehaviorsFromPrefs,
base::Unretained(this)));
+#if defined(OS_CHROMEOS)
+ pref_change_registrar_.Add(
+ prefs::kTouchVirtualKeyboardEnabled,
+ base::Bind(&ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs,
+ base::Unretained(this)));
+#endif // defined(OS_CHROMEOS)
+
+ extensions::ExtensionRegistry::Get(profile_)->AddObserver(this);
}
void ChromeLauncherController::ReleaseProfile() {
if (app_sync_ui_state_)
app_sync_ui_state_->RemoveObserver(this);
+ extensions::ExtensionRegistry::Get(profile_)->RemoveObserver(this);
+
PrefServiceSyncable::FromProfile(profile_)->RemoveObserver(this);
pref_change_registrar_.RemoveAll();