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

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

Issue 2052013002: Adding ChromeLauncherController interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@chrome_launcher_smaller_api
Patch Set: Fix method order Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "ash/ash_switches.h" 11 #include "ash/ash_switches.h"
12 #include "ash/common/shelf/shelf_item_delegate_manager.h" 12 #include "ash/common/shelf/shelf_item_delegate_manager.h"
13 #include "ash/common/shelf/shelf_model.h" 13 #include "ash/common/shelf/shelf_model.h"
14 #include "ash/common/system/tray/system_tray_delegate.h" 14 #include "ash/common/system/tray/system_tray_delegate.h"
15 #include "ash/desktop_background/desktop_background_controller.h" 15 #include "ash/desktop_background/desktop_background_controller.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 #include "ui/base/window_open_disposition.h" 97 #include "ui/base/window_open_disposition.h"
98 #include "ui/keyboard/keyboard_util.h" 98 #include "ui/keyboard/keyboard_util.h"
99 #include "ui/resources/grit/ui_resources.h" 99 #include "ui/resources/grit/ui_resources.h"
100 #include "ui/wm/core/window_animations.h" 100 #include "ui/wm/core/window_animations.h"
101 101
102 using extensions::Extension; 102 using extensions::Extension;
103 using extensions::UnloadedExtensionInfo; 103 using extensions::UnloadedExtensionInfo;
104 using extension_misc::kGmailAppId; 104 using extension_misc::kGmailAppId;
105 using content::WebContents; 105 using content::WebContents;
106 106
107 // static
108 ChromeLauncherController* ChromeLauncherController::instance_ = NULL;
109
110 namespace { 107 namespace {
111 108
112 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) { 109 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) {
113 aura::Window* root_window = 110 aura::Window* root_window =
114 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow(); 111 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
115 display::Display display = 112 display::Display display =
116 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window); 113 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
117 DCHECK(display.is_valid()); 114 DCHECK(display.is_valid());
118 return display.id(); 115 return display.id();
119 } 116 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 const size_t kPinProhibitedExtensionIdsLength = 170 const size_t kPinProhibitedExtensionIdsLength =
174 arraysize(kPinProhibitedExtensionIds); 171 arraysize(kPinProhibitedExtensionIds);
175 172
176 } // namespace 173 } // namespace
177 174
178 // A class to get events from ChromeOS when a user gets changed or added. 175 // A class to get events from ChromeOS when a user gets changed or added.
179 class ChromeLauncherControllerUserSwitchObserver 176 class ChromeLauncherControllerUserSwitchObserver
180 : public user_manager::UserManager::UserSessionStateObserver { 177 : public user_manager::UserManager::UserSessionStateObserver {
181 public: 178 public:
182 ChromeLauncherControllerUserSwitchObserver( 179 ChromeLauncherControllerUserSwitchObserver(
183 ChromeLauncherController* controller) 180 ChromeLauncherControllerImpl* controller)
184 : controller_(controller) { 181 : controller_(controller) {
185 DCHECK(user_manager::UserManager::IsInitialized()); 182 DCHECK(user_manager::UserManager::IsInitialized());
186 user_manager::UserManager::Get()->AddSessionStateObserver(this); 183 user_manager::UserManager::Get()->AddSessionStateObserver(this);
187 } 184 }
188 ~ChromeLauncherControllerUserSwitchObserver() override { 185 ~ChromeLauncherControllerUserSwitchObserver() override {
189 user_manager::UserManager::Get()->RemoveSessionStateObserver(this); 186 user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
190 } 187 }
191 188
192 // user_manager::UserManager::UserSessionStateObserver overrides: 189 // user_manager::UserManager::UserSessionStateObserver overrides:
193 void UserAddedToSession(const user_manager::User* added_user) override; 190 void UserAddedToSession(const user_manager::User* added_user) override;
194 191
195 // ChromeLauncherControllerUserSwitchObserver: 192 // ChromeLauncherControllerUserSwitchObserver:
196 void OnUserProfileReadyToSwitch(Profile* profile); 193 void OnUserProfileReadyToSwitch(Profile* profile);
197 194
198 private: 195 private:
199 // Add a user to the session. 196 // Add a user to the session.
200 void AddUser(Profile* profile); 197 void AddUser(Profile* profile);
201 198
202 // The owning ChromeLauncherController. 199 // The owning ChromeLauncherControllerImpl.
203 ChromeLauncherController* controller_; 200 ChromeLauncherControllerImpl* controller_;
204 201
205 // Users which were just added to the system, but which profiles were not yet 202 // Users which were just added to the system, but which profiles were not yet
206 // (fully) loaded. 203 // (fully) loaded.
207 std::set<std::string> added_user_ids_waiting_for_profiles_; 204 std::set<std::string> added_user_ids_waiting_for_profiles_;
208 205
209 DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerUserSwitchObserver); 206 DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerUserSwitchObserver);
210 }; 207 };
211 208
212 void ChromeLauncherControllerUserSwitchObserver::UserAddedToSession( 209 void ChromeLauncherControllerUserSwitchObserver::UserAddedToSession(
213 const user_manager::User* active_user) { 210 const user_manager::User* active_user) {
214 Profile* profile = 211 Profile* profile =
215 multi_user_util::GetProfileFromAccountId(active_user->GetAccountId()); 212 multi_user_util::GetProfileFromAccountId(active_user->GetAccountId());
216 // If we do not have a profile yet, we postpone forwarding the notification 213 // If we do not have a profile yet, we postpone forwarding the notification
217 // until it is loaded. 214 // until it is loaded.
218 if (!profile) 215 if (!profile)
219 added_user_ids_waiting_for_profiles_.insert(active_user->email()); 216 added_user_ids_waiting_for_profiles_.insert(active_user->email());
220 else 217 else
221 AddUser(profile); 218 AddUser(profile);
222 } 219 }
223 220
224 void ChromeLauncherControllerUserSwitchObserver::OnUserProfileReadyToSwitch( 221 void ChromeLauncherControllerUserSwitchObserver::OnUserProfileReadyToSwitch(
225 Profile* profile) { 222 Profile* profile) {
226 if (!added_user_ids_waiting_for_profiles_.empty()) { 223 if (!added_user_ids_waiting_for_profiles_.empty()) {
227 // Check if the profile is from a user which was on the waiting list. 224 // Check if the profile is from a user which was on the waiting list.
228 std::string user_id = 225 std::string user_id =
229 multi_user_util::GetAccountIdFromProfile(profile).GetUserEmail(); 226 multi_user_util::GetAccountIdFromProfile(profile).GetUserEmail();
230 std::set<std::string>::iterator it = std::find( 227 std::set<std::string>::iterator it =
231 added_user_ids_waiting_for_profiles_.begin(), 228 std::find(added_user_ids_waiting_for_profiles_.begin(),
232 added_user_ids_waiting_for_profiles_.end(), 229 added_user_ids_waiting_for_profiles_.end(), user_id);
233 user_id);
234 if (it != added_user_ids_waiting_for_profiles_.end()) { 230 if (it != added_user_ids_waiting_for_profiles_.end()) {
235 added_user_ids_waiting_for_profiles_.erase(it); 231 added_user_ids_waiting_for_profiles_.erase(it);
236 AddUser(profile->GetOriginalProfile()); 232 AddUser(profile->GetOriginalProfile());
237 } 233 }
238 } 234 }
239 } 235 }
240 236
241 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { 237 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) {
242 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 238 if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
243 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 239 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
244 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); 240 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile);
245 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); 241 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile());
246 } 242 }
247 243
248 ChromeLauncherController::ChromeLauncherController(Profile* profile, 244 ChromeLauncherControllerImpl::ChromeLauncherControllerImpl(
249 ash::ShelfModel* model) 245 Profile* profile,
246 ash::ShelfModel* model)
250 : model_(model), 247 : model_(model),
251 item_delegate_manager_(NULL), 248 item_delegate_manager_(NULL),
252 profile_(profile), 249 profile_(profile),
253 app_sync_ui_state_(NULL), 250 app_sync_ui_state_(NULL),
254 ignore_persist_pinned_state_change_(false) { 251 ignore_persist_pinned_state_change_(false) {
255 if (!profile_) { 252 if (!profile_) {
256 // If no profile was passed, we take the currently active profile and use it 253 // If no profile was passed, we take the currently active profile and use it
257 // as the owner of the current desktop. 254 // as the owner of the current desktop.
258 // Use the original profile as on chromeos we may get a temporary off the 255 // Use the original profile as on chromeos we may get a temporary off the
259 // record profile, unless in guest session (where off the record profile is 256 // record profile, unless in guest session (where off the record profile is
(...skipping 15 matching lines...) Expand all
275 AttachProfile(profile_); 272 AttachProfile(profile_);
276 model_->AddObserver(this); 273 model_->AddObserver(this);
277 274
278 // In multi profile mode we might have a window manager. We try to create it 275 // In multi profile mode we might have a window manager. We try to create it
279 // here. If the instantiation fails, the manager is not needed. 276 // here. If the instantiation fails, the manager is not needed.
280 chrome::MultiUserWindowManager::CreateInstance(); 277 chrome::MultiUserWindowManager::CreateInstance();
281 278
282 // On Chrome OS using multi profile we want to switch the content of the shelf 279 // On Chrome OS using multi profile we want to switch the content of the shelf
283 // with a user change. Note that for unit tests the instance can be NULL. 280 // with a user change. Note that for unit tests the instance can be NULL.
284 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 281 if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
285 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_OFF) { 282 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_OFF) {
286 user_switch_observer_.reset( 283 user_switch_observer_.reset(
287 new ChromeLauncherControllerUserSwitchObserver(this)); 284 new ChromeLauncherControllerUserSwitchObserver(this));
288 } 285 }
289 286
290 std::unique_ptr<AppWindowLauncherController> extension_app_window_controller; 287 std::unique_ptr<AppWindowLauncherController> extension_app_window_controller;
291 // Create our v1/v2 application / browser monitors which will inform the 288 // Create our v1/v2 application / browser monitors which will inform the
292 // launcher of status changes. 289 // launcher of status changes.
293 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 290 if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
294 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) { 291 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) {
295 // If running in separated destkop mode, we create the multi profile version 292 // If running in separated destkop mode, we create the multi profile version
296 // of status monitor. 293 // of status monitor.
297 browser_status_monitor_.reset(new MultiProfileBrowserStatusMonitor(this)); 294 browser_status_monitor_.reset(new MultiProfileBrowserStatusMonitor(this));
298 extension_app_window_controller.reset( 295 extension_app_window_controller.reset(
299 new MultiProfileAppWindowLauncherController(this)); 296 new MultiProfileAppWindowLauncherController(this));
300 } else { 297 } else {
301 // Create our v1/v2 application / browser monitors which will inform the 298 // Create our v1/v2 application / browser monitors which will inform the
302 // launcher of status changes. 299 // launcher of status changes.
303 browser_status_monitor_.reset(new BrowserStatusMonitor(this)); 300 browser_status_monitor_.reset(new BrowserStatusMonitor(this));
304 extension_app_window_controller.reset( 301 extension_app_window_controller.reset(
305 new ExtensionAppWindowLauncherController(this)); 302 new ExtensionAppWindowLauncherController(this));
306 } 303 }
307 app_window_controllers_.push_back(std::move(extension_app_window_controller)); 304 app_window_controllers_.push_back(std::move(extension_app_window_controller));
308 305
309 std::unique_ptr<AppWindowLauncherController> arc_app_window_controller; 306 std::unique_ptr<AppWindowLauncherController> arc_app_window_controller;
310 arc_app_window_controller.reset(new ArcAppWindowLauncherController(this)); 307 arc_app_window_controller.reset(
308 new ArcAppWindowLauncherController(this, this));
311 app_window_controllers_.push_back(std::move(arc_app_window_controller)); 309 app_window_controllers_.push_back(std::move(arc_app_window_controller));
312 310
313 // Right now ash::Shell isn't created for tests. 311 // Right now ash::Shell isn't created for tests.
314 // TODO(mukai): Allows it to observe display change and write tests. 312 // TODO(mukai): Allows it to observe display change and write tests.
315 if (ash::Shell::HasInstance()) { 313 if (ash::Shell::HasInstance()) {
316 ash::Shell::GetInstance()->window_tree_host_manager()->AddObserver(this); 314 ash::Shell::GetInstance()->window_tree_host_manager()->AddObserver(this);
317 // If it got already set, we remove the observer first again and swap the 315 // If it got already set, we remove the observer first again and swap the
318 // ItemDelegateManager. 316 // ItemDelegateManager.
319 if (item_delegate_manager_) 317 if (item_delegate_manager_)
320 item_delegate_manager_->RemoveObserver(this); 318 item_delegate_manager_->RemoveObserver(this);
321 item_delegate_manager_ = 319 item_delegate_manager_ =
322 ash::Shell::GetInstance()->shelf_item_delegate_manager(); 320 ash::Shell::GetInstance()->shelf_item_delegate_manager();
323 item_delegate_manager_->AddObserver(this); 321 item_delegate_manager_->AddObserver(this);
324 } 322 }
325 } 323 }
326 324
327 ChromeLauncherController::~ChromeLauncherController() { 325 ChromeLauncherControllerImpl::~ChromeLauncherControllerImpl() {
328 if (item_delegate_manager_) 326 if (item_delegate_manager_)
329 item_delegate_manager_->RemoveObserver(this); 327 item_delegate_manager_->RemoveObserver(this);
330 328
331 // Reset the BrowserStatusMonitor as it has a weak pointer to this. 329 // Reset the BrowserStatusMonitor as it has a weak pointer to this.
332 browser_status_monitor_.reset(); 330 browser_status_monitor_.reset();
333 331
334 // Reset the app window controllers here since it has a weak pointer to this. 332 // Reset the app window controllers here since it has a weak pointer to this.
335 app_window_controllers_.clear(); 333 app_window_controllers_.clear();
336 334
337 model_->RemoveObserver(this); 335 model_->RemoveObserver(this);
338 if (ash::Shell::HasInstance()) 336 if (ash::Shell::HasInstance())
339 ash::Shell::GetInstance()->window_tree_host_manager()->RemoveObserver(this); 337 ash::Shell::GetInstance()->window_tree_host_manager()->RemoveObserver(this);
340 for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin(); 338 for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin();
341 i != id_to_item_controller_map_.end(); ++i) { 339 i != id_to_item_controller_map_.end(); ++i) {
342 int index = model_->ItemIndexByID(i->first); 340 int index = model_->ItemIndexByID(i->first);
343 // A "browser proxy" is not known to the model and this removal does 341 // A "browser proxy" is not known to the model and this removal does
344 // therefore not need to be propagated to the model. 342 // therefore not need to be propagated to the model.
345 if (index != -1 && 343 if (index != -1 &&
346 model_->items()[index].type != ash::TYPE_BROWSER_SHORTCUT) 344 model_->items()[index].type != ash::TYPE_BROWSER_SHORTCUT)
347 model_->RemoveItemAt(index); 345 model_->RemoveItemAt(index);
348 } 346 }
349 347
350 // Release all profile dependent resources. 348 // Release all profile dependent resources.
351 ReleaseProfile(); 349 ReleaseProfile();
352 if (instance_ == this)
353 instance_ = NULL;
354 350
355 // Get rid of the multi user window manager instance. 351 // Get rid of the multi user window manager instance.
356 chrome::MultiUserWindowManager::DeleteInstance(); 352 chrome::MultiUserWindowManager::DeleteInstance();
357 } 353 }
358 354
359 // static 355 // static
360 ChromeLauncherController* ChromeLauncherController::CreateInstance( 356 ChromeLauncherControllerImpl* ChromeLauncherControllerImpl::CreateInstance(
361 Profile* profile, 357 Profile* profile,
362 ash::ShelfModel* model) { 358 ash::ShelfModel* model) {
363 // We do not check here for re-creation of the ChromeLauncherController since 359 // We do not check here for re-creation of the ChromeLauncherControllerImpl
364 // it appears that it might be intentional that the ChromeLauncherController 360 // since it appears that it might be intentional that
365 // can be re-created. 361 // ChromeLauncherControllerImpl can be re-created.
366 instance_ = new ChromeLauncherController(profile, model); 362 ChromeLauncherControllerImpl* instance =
367 return instance_; 363 new ChromeLauncherControllerImpl(profile, model);
364 ChromeLauncherController::SetInstance(instance);
365 return instance;
368 } 366 }
369 367
370 void ChromeLauncherController::Init() { 368 void ChromeLauncherControllerImpl::Init() {
371 CreateBrowserShortcutLauncherItem(); 369 CreateBrowserShortcutLauncherItem();
372 UpdateAppLaunchersFromPref(); 370 UpdateAppLaunchersFromPref();
373 371
374 // TODO(sky): update unit test so that this test isn't necessary. 372 // TODO(sky): update unit test so that this test isn't necessary.
375 if (ash::Shell::HasInstance()) 373 if (ash::Shell::HasInstance())
376 SetVirtualKeyboardBehaviorFromPrefs(); 374 SetVirtualKeyboardBehaviorFromPrefs();
377 375
378 prefs_observer_ = 376 prefs_observer_ =
379 ash::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_); 377 ash::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_);
380 } 378 }
381 379
382 ash::ShelfID ChromeLauncherController::CreateAppLauncherItem( 380 ash::ShelfID ChromeLauncherControllerImpl::CreateAppLauncherItem(
383 LauncherItemController* controller, 381 LauncherItemController* controller,
384 const std::string& app_id, 382 const std::string& app_id,
385 ash::ShelfItemStatus status) { 383 ash::ShelfItemStatus status) {
386 CHECK(controller); 384 CHECK(controller);
387 int index = 0; 385 int index = 0;
388 // Panels are inserted on the left so as not to push all existing panels over. 386 // Panels are inserted on the left so as not to push all existing panels over.
389 if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL) 387 if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL)
390 index = model_->item_count(); 388 index = model_->item_count();
391 return InsertAppLauncherItem(controller, 389 return InsertAppLauncherItem(controller, app_id, status, index,
392 app_id,
393 status,
394 index,
395 controller->GetShelfItemType()); 390 controller->GetShelfItemType());
396 } 391 }
397 392
398 void ChromeLauncherController::SetItemStatus(ash::ShelfID id, 393 void ChromeLauncherControllerImpl::SetItemStatus(ash::ShelfID id,
399 ash::ShelfItemStatus status) { 394 ash::ShelfItemStatus status) {
400 int index = model_->ItemIndexByID(id); 395 int index = model_->ItemIndexByID(id);
401 ash::ShelfItemStatus old_status = model_->items()[index].status; 396 ash::ShelfItemStatus old_status = model_->items()[index].status;
402 // Since ordinary browser windows are not registered, we might get a negative 397 // Since ordinary browser windows are not registered, we might get a negative
403 // index here. 398 // index here.
404 if (index >= 0 && old_status != status) { 399 if (index >= 0 && old_status != status) {
405 ash::ShelfItem item = model_->items()[index]; 400 ash::ShelfItem item = model_->items()[index];
406 item.status = status; 401 item.status = status;
407 model_->Set(index, item); 402 model_->Set(index, item);
408 } 403 }
409 } 404 }
410 405
411 void ChromeLauncherController::SetItemController( 406 void ChromeLauncherControllerImpl::SetItemController(
412 ash::ShelfID id, 407 ash::ShelfID id,
413 LauncherItemController* controller) { 408 LauncherItemController* controller) {
414 CHECK(controller); 409 CHECK(controller);
415 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 410 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
416 CHECK(iter != id_to_item_controller_map_.end()); 411 CHECK(iter != id_to_item_controller_map_.end());
417 controller->set_shelf_id(id); 412 controller->set_shelf_id(id);
418 iter->second = controller; 413 iter->second = controller;
419 // Existing controller is destroyed and replaced by registering again. 414 // Existing controller is destroyed and replaced by registering again.
420 SetShelfItemDelegate(id, controller); 415 SetShelfItemDelegate(id, controller);
421 } 416 }
422 417
423 void ChromeLauncherController::CloseLauncherItem(ash::ShelfID id) { 418 void ChromeLauncherControllerImpl::CloseLauncherItem(ash::ShelfID id) {
424 CHECK(id); 419 CHECK(id);
425 if (IsPinned(id)) { 420 if (IsPinned(id)) {
426 // Create a new shortcut controller. 421 // Create a new shortcut controller.
427 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 422 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
428 CHECK(iter != id_to_item_controller_map_.end()); 423 CHECK(iter != id_to_item_controller_map_.end());
429 SetItemStatus(id, ash::STATUS_CLOSED); 424 SetItemStatus(id, ash::STATUS_CLOSED);
430 std::string app_id = iter->second->app_id(); 425 std::string app_id = iter->second->app_id();
431 iter->second = AppShortcutLauncherItemController::Create(app_id, this); 426 iter->second = AppShortcutLauncherItemController::Create(app_id, this);
432 iter->second->set_shelf_id(id); 427 iter->second->set_shelf_id(id);
433 // Existing controller is destroyed and replaced by registering again. 428 // Existing controller is destroyed and replaced by registering again.
434 SetShelfItemDelegate(id, iter->second); 429 SetShelfItemDelegate(id, iter->second);
435 } else { 430 } else {
436 LauncherItemClosed(id); 431 LauncherItemClosed(id);
437 } 432 }
438 } 433 }
439 434
440 AppListControllerDelegate::Pinnable ChromeLauncherController::GetPinnable( 435 AppListControllerDelegate::Pinnable ChromeLauncherControllerImpl::GetPinnable(
msw 2016/06/10 22:44:38 nit: the order of definitions should match the ord
mfomitchev 2016/06/10 23:29:09 Yeah, I also didn't want to move code around in th
msw 2016/06/10 23:42:51 Acknowledged.
441 const std::string& app_id) { 436 const std::string& app_id) {
442 for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) { 437 for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) {
443 if (kPinProhibitedExtensionIds[i] == app_id) 438 if (kPinProhibitedExtensionIds[i] == app_id)
444 return AppListControllerDelegate::NO_PIN; 439 return AppListControllerDelegate::NO_PIN;
445 } 440 }
446 441
447 const base::ListValue* pref = 442 const base::ListValue* pref =
448 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); 443 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
449 if (!pref) 444 if (!pref)
450 return AppListControllerDelegate::PIN_EDITABLE; 445 return AppListControllerDelegate::PIN_EDITABLE;
451 446
452 // Pinned ARC apps policy defines the package name of the apps, that must 447 // Pinned ARC apps policy defines the package name of the apps, that must
453 // be pinned. All the launch activities of any package in policy are pinned. 448 // be pinned. All the launch activities of any package in policy are pinned.
454 // In turn the input parameter to this function is app_id, which 449 // In turn the input parameter to this function is app_id, which
455 // is 32 chars hash. In case of ARC app this is a hash of 450 // is 32 chars hash. In case of ARC app this is a hash of
456 // (package name + activity). This means that we must identify the package 451 // (package name + activity). This means that we must identify the package
457 // from the hash, and check if this package is pinned by policy. 452 // from the hash, and check if this package is pinned by policy.
458 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(profile()); 453 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(GetProfile());
459 std::string arc_app_packege_name; 454 std::string arc_app_packege_name;
460 if (arc_prefs) { 455 if (arc_prefs) {
461 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = 456 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
462 arc_prefs->GetApp(app_id); 457 arc_prefs->GetApp(app_id);
463 if (app_info) 458 if (app_info)
464 arc_app_packege_name = app_info->package_name; 459 arc_app_packege_name = app_info->package_name;
465 } 460 }
466 461
467 for (size_t index = 0; index < pref->GetSize(); ++index) { 462 for (size_t index = 0; index < pref->GetSize(); ++index) {
468 const base::DictionaryValue* app = nullptr; 463 const base::DictionaryValue* app = nullptr;
469 std::string app_id_or_package; 464 std::string app_id_or_package;
470 if (pref->GetDictionary(index, &app) && 465 if (pref->GetDictionary(index, &app) &&
471 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_or_package) && 466 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_or_package) &&
472 (app_id == app_id_or_package || 467 (app_id == app_id_or_package ||
473 arc_app_packege_name == app_id_or_package)) { 468 arc_app_packege_name == app_id_or_package)) {
474 return AppListControllerDelegate::PIN_FIXED; 469 return AppListControllerDelegate::PIN_FIXED;
475 } 470 }
476 } 471 }
477 return AppListControllerDelegate::PIN_EDITABLE; 472 return AppListControllerDelegate::PIN_EDITABLE;
478 } 473 }
479 474
480 void ChromeLauncherController::Pin(ash::ShelfID id) { 475 void ChromeLauncherControllerImpl::Pin(ash::ShelfID id) {
481 DCHECK(HasShelfIDToAppIDMapping(id)); 476 DCHECK(HasShelfIDToAppIDMapping(id));
482 477
483 int index = model_->ItemIndexByID(id); 478 int index = model_->ItemIndexByID(id);
484 DCHECK_GE(index, 0); 479 DCHECK_GE(index, 0);
485 480
486 ash::ShelfItem item = model_->items()[index]; 481 ash::ShelfItem item = model_->items()[index];
487 482
488 if (item.type == ash::TYPE_PLATFORM_APP || 483 if (item.type == ash::TYPE_PLATFORM_APP ||
489 item.type == ash::TYPE_WINDOWED_APP) { 484 item.type == ash::TYPE_WINDOWED_APP) {
490 item.type = ash::TYPE_APP_SHORTCUT; 485 item.type = ash::TYPE_APP_SHORTCUT;
491 model_->Set(index, item); 486 model_->Set(index, item);
492 } else if (item.type != ash::TYPE_APP_SHORTCUT) { 487 } else if (item.type != ash::TYPE_APP_SHORTCUT) {
493 return; 488 return;
494 } 489 }
495 490
496 if (GetLauncherItemController(id)->CanPin()) 491 if (GetLauncherItemController(id)->CanPin())
497 PersistPinnedState(); 492 PersistPinnedState();
498 } 493 }
499 494
500 void ChromeLauncherController::Unpin(ash::ShelfID id) { 495 void ChromeLauncherControllerImpl::Unpin(ash::ShelfID id) {
501 LauncherItemController* controller = GetLauncherItemController(id); 496 LauncherItemController* controller = GetLauncherItemController(id);
502 CHECK(controller); 497 CHECK(controller);
503 const bool can_pin = controller->CanPin(); 498 const bool can_pin = controller->CanPin();
504 499
505 if (controller->type() == LauncherItemController::TYPE_APP || 500 if (controller->type() == LauncherItemController::TYPE_APP ||
506 controller->locked()) { 501 controller->locked()) {
507 UnpinRunningAppInternal(model_->ItemIndexByID(id)); 502 UnpinRunningAppInternal(model_->ItemIndexByID(id));
508 } else { 503 } else {
509 LauncherItemClosed(id); 504 LauncherItemClosed(id);
510 } 505 }
511 if (can_pin) 506 if (can_pin)
512 PersistPinnedState(); 507 PersistPinnedState();
513 } 508 }
514 509
515 bool ChromeLauncherController::IsPinned(ash::ShelfID id) { 510 bool ChromeLauncherControllerImpl::IsPinned(ash::ShelfID id) {
516 int index = model_->ItemIndexByID(id); 511 int index = model_->ItemIndexByID(id);
517 if (index < 0) 512 if (index < 0)
518 return false; 513 return false;
519 ash::ShelfItemType type = model_->items()[index].type; 514 ash::ShelfItemType type = model_->items()[index].type;
520 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); 515 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT);
521 } 516 }
522 517
523 void ChromeLauncherController::TogglePinned(ash::ShelfID id) { 518 void ChromeLauncherControllerImpl::TogglePinned(ash::ShelfID id) {
524 if (!HasShelfIDToAppIDMapping(id)) 519 if (!HasShelfIDToAppIDMapping(id))
525 return; // May happen if item closed with menu open. 520 return; // May happen if item closed with menu open.
526 521
527 if (IsPinned(id)) 522 if (IsPinned(id))
528 Unpin(id); 523 Unpin(id);
529 else 524 else
530 Pin(id); 525 Pin(id);
531 } 526 }
532 527
533 bool ChromeLauncherController::IsPinnable(ash::ShelfID id) const { 528 bool ChromeLauncherControllerImpl::IsPinnable(ash::ShelfID id) const {
534 int index = model_->ItemIndexByID(id); 529 int index = model_->ItemIndexByID(id);
535 if (index == -1) 530 if (index == -1)
536 return false; 531 return false;
537 532
538 ash::ShelfItemType type = model_->items()[index].type; 533 ash::ShelfItemType type = model_->items()[index].type;
539 std::string app_id; 534 std::string app_id;
540 return ((type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_PLATFORM_APP || 535 return ((type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_PLATFORM_APP ||
541 type == ash::TYPE_WINDOWED_APP) && 536 type == ash::TYPE_WINDOWED_APP) &&
542 item_delegate_manager_->GetShelfItemDelegate(id)->CanPin()); 537 item_delegate_manager_->GetShelfItemDelegate(id)->CanPin());
543 } 538 }
544 539
545 void ChromeLauncherController::LockV1AppWithID(const std::string& app_id) { 540 void ChromeLauncherControllerImpl::LockV1AppWithID(const std::string& app_id) {
546 ash::ShelfID id = GetShelfIDForAppID(app_id); 541 ash::ShelfID id = GetShelfIDForAppID(app_id);
547 if (!IsPinned(id) && !IsWindowedAppInLauncher(app_id)) { 542 if (!IsPinned(id) && !IsWindowedAppInLauncher(app_id)) {
548 CreateAppShortcutLauncherItemWithType(app_id, 543 CreateAppShortcutLauncherItemWithType(app_id, model_->item_count(),
549 model_->item_count(),
550 ash::TYPE_WINDOWED_APP); 544 ash::TYPE_WINDOWED_APP);
551 id = GetShelfIDForAppID(app_id); 545 id = GetShelfIDForAppID(app_id);
552 } 546 }
553 CHECK(id); 547 CHECK(id);
554 id_to_item_controller_map_[id]->lock(); 548 id_to_item_controller_map_[id]->lock();
555 } 549 }
556 550
557 void ChromeLauncherController::UnlockV1AppWithID(const std::string& app_id) { 551 void ChromeLauncherControllerImpl::UnlockV1AppWithID(
552 const std::string& app_id) {
558 ash::ShelfID id = GetShelfIDForAppID(app_id); 553 ash::ShelfID id = GetShelfIDForAppID(app_id);
559 CHECK(id); 554 CHECK(id);
560 CHECK(IsPinned(id) || IsWindowedAppInLauncher(app_id)); 555 CHECK(IsPinned(id) || IsWindowedAppInLauncher(app_id));
561 LauncherItemController* controller = id_to_item_controller_map_[id]; 556 LauncherItemController* controller = id_to_item_controller_map_[id];
562 controller->unlock(); 557 controller->unlock();
563 if (!controller->locked() && !IsPinned(id)) 558 if (!controller->locked() && !IsPinned(id))
564 CloseLauncherItem(id); 559 CloseLauncherItem(id);
565 } 560 }
566 561
567 void ChromeLauncherController::Launch(ash::ShelfID id, int event_flags) { 562 void ChromeLauncherControllerImpl::Launch(ash::ShelfID id, int event_flags) {
568 LauncherItemController* controller = GetLauncherItemController(id); 563 LauncherItemController* controller = GetLauncherItemController(id);
569 if (!controller) 564 if (!controller)
570 return; // In case invoked from menu and item closed while menu up. 565 return; // In case invoked from menu and item closed while menu up.
571 controller->Launch(ash::LAUNCH_FROM_UNKNOWN, event_flags); 566 controller->Launch(ash::LAUNCH_FROM_UNKNOWN, event_flags);
572 } 567 }
573 568
574 void ChromeLauncherController::Close(ash::ShelfID id) { 569 void ChromeLauncherControllerImpl::Close(ash::ShelfID id) {
575 LauncherItemController* controller = GetLauncherItemController(id); 570 LauncherItemController* controller = GetLauncherItemController(id);
576 if (!controller) 571 if (!controller)
577 return; // May happen if menu closed. 572 return; // May happen if menu closed.
578 controller->Close(); 573 controller->Close();
579 } 574 }
580 575
581 bool ChromeLauncherController::IsOpen(ash::ShelfID id) { 576 bool ChromeLauncherControllerImpl::IsOpen(ash::ShelfID id) {
582 LauncherItemController* controller = GetLauncherItemController(id); 577 LauncherItemController* controller = GetLauncherItemController(id);
583 if (!controller) 578 if (!controller)
584 return false; 579 return false;
585 return controller->IsOpen(); 580 return controller->IsOpen();
586 } 581 }
587 582
588 bool ChromeLauncherController::IsPlatformApp(ash::ShelfID id) { 583 bool ChromeLauncherControllerImpl::IsPlatformApp(ash::ShelfID id) {
589 if (!HasShelfIDToAppIDMapping(id)) 584 if (!HasShelfIDToAppIDMapping(id))
590 return false; 585 return false;
591 586
592 std::string app_id = GetAppIDForShelfID(id); 587 std::string app_id = GetAppIDForShelfID(id);
593 const Extension* extension = GetExtensionForAppID(app_id); 588 const Extension* extension = GetExtensionForAppID(app_id);
594 // An extension can be synced / updated at any time and therefore not be 589 // An extension can be synced / updated at any time and therefore not be
595 // available. 590 // available.
596 return extension ? extension->is_platform_app() : false; 591 return extension ? extension->is_platform_app() : false;
597 } 592 }
598 593
599 void ChromeLauncherController::LaunchApp(const std::string& app_id, 594 void ChromeLauncherControllerImpl::LaunchApp(const std::string& app_id,
600 ash::LaunchSource source, 595 ash::LaunchSource source,
601 int event_flags) { 596 int event_flags) {
602 launcher_controller_helper_->LaunchApp(app_id, source, event_flags); 597 launcher_controller_helper_->LaunchApp(app_id, source, event_flags);
603 } 598 }
604 599
605 void ChromeLauncherController::ActivateApp(const std::string& app_id, 600 void ChromeLauncherControllerImpl::ActivateApp(const std::string& app_id,
606 ash::LaunchSource source, 601 ash::LaunchSource source,
607 int event_flags) { 602 int event_flags) {
608 // If there is an existing non-shortcut controller for this app, open it. 603 // If there is an existing non-shortcut controller for this app, open it.
609 ash::ShelfID id = GetShelfIDForAppID(app_id); 604 ash::ShelfID id = GetShelfIDForAppID(app_id);
610 if (id) { 605 if (id) {
611 LauncherItemController* controller = GetLauncherItemController(id); 606 LauncherItemController* controller = GetLauncherItemController(id);
612 controller->Activate(source); 607 controller->Activate(source);
613 return; 608 return;
614 } 609 }
615 610
616 // Create a temporary application launcher item and use it to see if there are 611 // Create a temporary application launcher item and use it to see if there are
617 // running instances. 612 // running instances.
618 std::unique_ptr<AppShortcutLauncherItemController> app_controller( 613 std::unique_ptr<AppShortcutLauncherItemController> app_controller(
619 AppShortcutLauncherItemController::Create(app_id, this)); 614 AppShortcutLauncherItemController::Create(app_id, this));
620 if (!app_controller->GetRunningApplications().empty()) 615 if (!app_controller->GetRunningApplications().empty())
621 app_controller->Activate(source); 616 app_controller->Activate(source);
622 else 617 else
623 LaunchApp(app_id, source, event_flags); 618 LaunchApp(app_id, source, event_flags);
624 } 619 }
625 620
626 extensions::LaunchType ChromeLauncherController::GetLaunchType( 621 extensions::LaunchType ChromeLauncherControllerImpl::GetLaunchType(
627 ash::ShelfID id) { 622 ash::ShelfID id) {
628 const Extension* extension = GetExtensionForAppID(GetAppIDForShelfID(id)); 623 const Extension* extension = GetExtensionForAppID(GetAppIDForShelfID(id));
629 624
630 // An extension can be unloaded/updated/unavailable at any time. 625 // An extension can be unloaded/updated/unavailable at any time.
631 if (!extension) 626 if (!extension)
632 return extensions::LAUNCH_TYPE_DEFAULT; 627 return extensions::LAUNCH_TYPE_DEFAULT;
633 628
634 return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_), 629 return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_),
635 extension); 630 extension);
636 } 631 }
637 632
638 ash::ShelfID ChromeLauncherController::GetShelfIDForAppID( 633 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID(
639 const std::string& app_id) { 634 const std::string& app_id) {
640 for (IDToItemControllerMap::const_iterator i = 635 for (IDToItemControllerMap::const_iterator i =
641 id_to_item_controller_map_.begin(); 636 id_to_item_controller_map_.begin();
642 i != id_to_item_controller_map_.end(); ++i) { 637 i != id_to_item_controller_map_.end(); ++i) {
643 if (i->second->type() == LauncherItemController::TYPE_APP_PANEL) 638 if (i->second->type() == LauncherItemController::TYPE_APP_PANEL)
644 continue; // Don't include panels 639 continue; // Don't include panels
645 if (i->second->app_id() == app_id) 640 if (i->second->app_id() == app_id)
646 return i->first; 641 return i->first;
647 } 642 }
648 return 0; 643 return 0;
649 } 644 }
650 645
651 bool ChromeLauncherController::HasShelfIDToAppIDMapping(ash::ShelfID id) const { 646 bool ChromeLauncherControllerImpl::HasShelfIDToAppIDMapping(
647 ash::ShelfID id) const {
652 return id_to_item_controller_map_.find(id) != 648 return id_to_item_controller_map_.find(id) !=
653 id_to_item_controller_map_.end(); 649 id_to_item_controller_map_.end();
654 } 650 }
655 651
656 const std::string& ChromeLauncherController::GetAppIDForShelfID( 652 const std::string& ChromeLauncherControllerImpl::GetAppIDForShelfID(
657 ash::ShelfID id) { 653 ash::ShelfID id) {
658 LauncherItemController* controller = GetLauncherItemController(id); 654 LauncherItemController* controller = GetLauncherItemController(id);
659 return controller ? controller->app_id() : base::EmptyString(); 655 return controller ? controller->app_id() : base::EmptyString();
660 } 656 }
661 657
662 void ChromeLauncherController::OnAppImageUpdated(const std::string& id, 658 void ChromeLauncherControllerImpl::OnAppImageUpdated(
663 const gfx::ImageSkia& image) { 659 const std::string& id,
660 const gfx::ImageSkia& image) {
664 // TODO: need to get this working for shortcuts. 661 // TODO: need to get this working for shortcuts.
665 for (IDToItemControllerMap::const_iterator i = 662 for (IDToItemControllerMap::const_iterator i =
666 id_to_item_controller_map_.begin(); 663 id_to_item_controller_map_.begin();
667 i != id_to_item_controller_map_.end(); ++i) { 664 i != id_to_item_controller_map_.end(); ++i) {
668 LauncherItemController* controller = i->second; 665 LauncherItemController* controller = i->second;
669 if (controller->app_id() != id) 666 if (controller->app_id() != id)
670 continue; 667 continue;
671 if (controller->image_set_by_controller()) 668 if (controller->image_set_by_controller())
672 continue; 669 continue;
673 int index = model_->ItemIndexByID(i->first); 670 int index = model_->ItemIndexByID(i->first);
674 if (index == -1) 671 if (index == -1)
675 continue; 672 continue;
676 ash::ShelfItem item = model_->items()[index]; 673 ash::ShelfItem item = model_->items()[index];
677 item.image = image; 674 item.image = image;
678 model_->Set(index, item); 675 model_->Set(index, item);
679 // It's possible we're waiting on more than one item, so don't break. 676 // It's possible we're waiting on more than one item, so don't break.
680 } 677 }
681 } 678 }
682 679
683 void ChromeLauncherController::SetLauncherItemImage( 680 void ChromeLauncherControllerImpl::SetLauncherItemImage(
684 ash::ShelfID shelf_id, 681 ash::ShelfID shelf_id,
685 const gfx::ImageSkia& image) { 682 const gfx::ImageSkia& image) {
686 int index = model_->ItemIndexByID(shelf_id); 683 int index = model_->ItemIndexByID(shelf_id);
687 if (index == -1) 684 if (index == -1)
688 return; 685 return;
689 ash::ShelfItem item = model_->items()[index]; 686 ash::ShelfItem item = model_->items()[index];
690 item.image = image; 687 item.image = image;
691 model_->Set(index, item); 688 model_->Set(index, item);
692 } 689 }
693 690
694 bool ChromeLauncherController::IsAppPinned(const std::string& app_id) { 691 bool ChromeLauncherControllerImpl::IsAppPinned(const std::string& app_id) {
695 for (IDToItemControllerMap::const_iterator i = 692 for (IDToItemControllerMap::const_iterator i =
696 id_to_item_controller_map_.begin(); 693 id_to_item_controller_map_.begin();
697 i != id_to_item_controller_map_.end(); ++i) { 694 i != id_to_item_controller_map_.end(); ++i) {
698 if (IsPinned(i->first) && i->second->app_id() == app_id) 695 if (IsPinned(i->first) && i->second->app_id() == app_id)
699 return true; 696 return true;
700 } 697 }
701 return false; 698 return false;
702 } 699 }
703 700
704 bool ChromeLauncherController::IsWindowedAppInLauncher( 701 bool ChromeLauncherControllerImpl::IsWindowedAppInLauncher(
705 const std::string& app_id) { 702 const std::string& app_id) {
706 int index = model_->ItemIndexByID(GetShelfIDForAppID(app_id)); 703 int index = model_->ItemIndexByID(GetShelfIDForAppID(app_id));
707 if (index < 0) 704 if (index < 0)
708 return false; 705 return false;
709 706
710 ash::ShelfItemType type = model_->items()[index].type; 707 ash::ShelfItemType type = model_->items()[index].type;
711 return type == ash::TYPE_WINDOWED_APP; 708 return type == ash::TYPE_WINDOWED_APP;
712 } 709 }
713 710
714 void ChromeLauncherController::PinAppWithID(const std::string& app_id) { 711 void ChromeLauncherControllerImpl::PinAppWithID(const std::string& app_id) {
715 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) 712 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
716 DoPinAppWithID(app_id); 713 DoPinAppWithID(app_id);
717 else 714 else
718 NOTREACHED(); 715 NOTREACHED();
719 } 716 }
720 717
721 void ChromeLauncherController::SetLaunchType( 718 void ChromeLauncherControllerImpl::SetLaunchType(
722 ash::ShelfID id, 719 ash::ShelfID id,
723 extensions::LaunchType launch_type) { 720 extensions::LaunchType launch_type) {
724 LauncherItemController* controller = GetLauncherItemController(id); 721 LauncherItemController* controller = GetLauncherItemController(id);
725 if (!controller) 722 if (!controller)
726 return; 723 return;
727 724
728 extensions::SetLaunchType(profile_, controller->app_id(), launch_type); 725 extensions::SetLaunchType(profile_, controller->app_id(), launch_type);
729 } 726 }
730 727
731 void ChromeLauncherController::UnpinAppWithID(const std::string& app_id) { 728 void ChromeLauncherControllerImpl::UnpinAppWithID(const std::string& app_id) {
732 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) 729 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
733 DoUnpinAppWithID(app_id); 730 DoUnpinAppWithID(app_id);
734 else 731 else
735 NOTREACHED(); 732 NOTREACHED();
736 } 733 }
737 734
738 void ChromeLauncherController::OnSetShelfItemDelegate( 735 void ChromeLauncherControllerImpl::OnSetShelfItemDelegate(
739 ash::ShelfID id, 736 ash::ShelfID id,
740 ash::ShelfItemDelegate* item_delegate) { 737 ash::ShelfItemDelegate* item_delegate) {
741 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we 738 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
742 // get into this state in the first place. 739 // get into this state in the first place.
743 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 740 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
744 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second) 741 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second)
745 return; 742 return;
746 LOG(ERROR) << "Unexpected change of shelf item id: " << id; 743 LOG(ERROR) << "Unexpected change of shelf item id: " << id;
747 id_to_item_controller_map_.erase(iter); 744 id_to_item_controller_map_.erase(iter);
748 } 745 }
749 746
750 void ChromeLauncherController::PersistPinnedState() { 747 void ChromeLauncherControllerImpl::PersistPinnedState() {
751 if (ignore_persist_pinned_state_change_) 748 if (ignore_persist_pinned_state_change_)
752 return; 749 return;
753 // It is a coding error to call PersistPinnedState() if the pinned apps are 750 // It is a coding error to call PersistPinnedState() if the pinned apps are
754 // not user-editable. The code should check earlier and not perform any 751 // not user-editable. The code should check earlier and not perform any
755 // modification actions that trigger persisting the state. 752 // modification actions that trigger persisting the state.
756 // Mutating kPinnedLauncherApps is going to notify us and trigger us to 753 // Mutating kPinnedLauncherApps is going to notify us and trigger us to
757 // process the change. We don't want that to happen so remove ourselves as a 754 // process the change. We don't want that to happen so remove ourselves as a
758 // listener. 755 // listener.
759 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps); 756 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps);
760 { 757 {
761 std::unique_ptr<const base::ListValue> pinned_apps_pref = 758 std::unique_ptr<const base::ListValue> pinned_apps_pref =
762 profile_->GetPrefs() 759 profile_->GetPrefs()
763 ->GetList(prefs::kPinnedLauncherApps) 760 ->GetList(prefs::kPinnedLauncherApps)
764 ->CreateDeepCopy(); 761 ->CreateDeepCopy();
765 762
766 const base::ListValue* policy_pinned_apps_pref = 763 const base::ListValue* policy_pinned_apps_pref =
767 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); 764 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
768 765
769 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps); 766 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps);
770 updater->Clear(); 767 updater->Clear();
771 for (size_t i = 0; i < model_->items().size(); ++i) { 768 for (size_t i = 0; i < model_->items().size(); ++i) {
772 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) { 769 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) {
773 ash::ShelfID id = model_->items()[i].id; 770 ash::ShelfID id = model_->items()[i].id;
774 LauncherItemController* controller = GetLauncherItemController(id); 771 LauncherItemController* controller = GetLauncherItemController(id);
775 // Don't persist pinning state for apps that are handled internally and 772 // Don't persist pinning state for apps that are handled internally and
776 // have pinnable state AppListControllerDelegate::NO_PIN. 773 // have pinnable state AppListControllerDelegate::NO_PIN.
777 if (controller && IsPinned(id) && 774 if (controller && IsPinned(id) &&
778 GetPinnable(controller->app_id()) != 775 GetPinnable(controller->app_id()) !=
779 AppListControllerDelegate::NO_PIN) { 776 AppListControllerDelegate::NO_PIN) {
780 base::DictionaryValue* app_value = ash::CreateAppDict( 777 base::DictionaryValue* app_value =
781 controller->app_id()); 778 ash::CreateAppDict(controller->app_id());
782 if (app_value) { 779 if (app_value) {
783 if (!IsAppForUserPinned(controller->app_id(), 780 if (!IsAppForUserPinned(controller->app_id(),
784 pinned_apps_pref.get(), 781 pinned_apps_pref.get(),
785 policy_pinned_apps_pref)) 782 policy_pinned_apps_pref))
786 app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true); 783 app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true);
787 updater->Append(app_value); 784 updater->Append(app_value);
788 } 785 }
789 } 786 }
790 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) { 787 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) {
791 PersistChromeItemIndex(i); 788 PersistChromeItemIndex(i);
792 } else if (model_->items()[i].type == ash::TYPE_APP_LIST) { 789 } else if (model_->items()[i].type == ash::TYPE_APP_LIST) {
793 base::DictionaryValue* app_value = 790 base::DictionaryValue* app_value =
794 ash::CreateAppDict(ash::kPinnedAppsPlaceholder); 791 ash::CreateAppDict(ash::kPinnedAppsPlaceholder);
795 if (app_value) 792 if (app_value)
796 updater->Append(app_value); 793 updater->Append(app_value);
797 } 794 }
798 } 795 }
799 } 796 }
800 pref_change_registrar_.Add( 797 pref_change_registrar_.Add(
801 prefs::kPinnedLauncherApps, 798 prefs::kPinnedLauncherApps,
802 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 799 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
803 base::Unretained(this))); 800 base::Unretained(this)));
804 } 801 }
805 802
806 Profile* ChromeLauncherController::profile() { 803 Profile* ChromeLauncherControllerImpl::GetProfile() {
807 return profile_; 804 return profile_;
808 } 805 }
809 806
810 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, 807 void ChromeLauncherControllerImpl::UpdateAppState(
811 AppState app_state) { 808 content::WebContents* contents,
809 AppState app_state) {
812 std::string app_id = launcher_controller_helper_->GetAppID(contents); 810 std::string app_id = launcher_controller_helper_->GetAppID(contents);
813 811
814 // Check if the gMail app is loaded and it matches the given content. 812 // Check if the gMail app is loaded and it matches the given content.
815 // This special treatment is needed to address crbug.com/234268. 813 // This special treatment is needed to address crbug.com/234268.
816 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) 814 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents))
817 app_id = kGmailAppId; 815 app_id = kGmailAppId;
818 816
819 // Check the old |app_id| for a tab. If the contents has changed we need to 817 // Check the old |app_id| for a tab. If the contents has changed we need to
820 // remove it from the previous app. 818 // remove it from the previous app.
821 if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) { 819 if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) {
(...skipping 10 matching lines...) Expand all
832 } 830 }
833 831
834 if (app_state == APP_STATE_REMOVED) 832 if (app_state == APP_STATE_REMOVED)
835 web_contents_to_app_id_.erase(contents); 833 web_contents_to_app_id_.erase(contents);
836 else 834 else
837 web_contents_to_app_id_[contents] = app_id; 835 web_contents_to_app_id_[contents] = app_id;
838 836
839 ash::ShelfID id = GetShelfIDForAppID(app_id); 837 ash::ShelfID id = GetShelfIDForAppID(app_id);
840 if (id) { 838 if (id) {
841 SetItemStatus(id, (app_state == APP_STATE_WINDOW_ACTIVE || 839 SetItemStatus(id, (app_state == APP_STATE_WINDOW_ACTIVE ||
842 app_state == APP_STATE_ACTIVE) ? ash::STATUS_ACTIVE : 840 app_state == APP_STATE_ACTIVE)
843 GetAppState(app_id)); 841 ? ash::STATUS_ACTIVE
842 : GetAppState(app_id));
844 } 843 }
845 } 844 }
846 845
847 ash::ShelfID ChromeLauncherController::GetShelfIDForWebContents( 846 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForWebContents(
848 content::WebContents* contents) { 847 content::WebContents* contents) {
849 DCHECK(contents); 848 DCHECK(contents);
850 849
851 std::string app_id = launcher_controller_helper_->GetAppID(contents); 850 std::string app_id = launcher_controller_helper_->GetAppID(contents);
852 851
853 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents)) 852 if (app_id.empty() && ContentCanBeHandledByGmailApp(contents))
854 app_id = kGmailAppId; 853 app_id = kGmailAppId;
855 854
856 ash::ShelfID id = GetShelfIDForAppID(app_id); 855 ash::ShelfID id = GetShelfIDForAppID(app_id);
857 856
858 if (app_id.empty() || !id) { 857 if (app_id.empty() || !id) {
859 int browser_index = model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT); 858 int browser_index = model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT);
860 return model_->items()[browser_index].id; 859 return model_->items()[browser_index].id;
861 } 860 }
862 861
863 return id; 862 return id;
864 } 863 }
865 864
866 void ChromeLauncherController::SetRefocusURLPatternForTest(ash::ShelfID id, 865 void ChromeLauncherControllerImpl::SetRefocusURLPatternForTest(
867 const GURL& url) { 866 ash::ShelfID id,
867 const GURL& url) {
868 LauncherItemController* controller = GetLauncherItemController(id); 868 LauncherItemController* controller = GetLauncherItemController(id);
869 DCHECK(controller); 869 DCHECK(controller);
870 870
871 int index = model_->ItemIndexByID(id); 871 int index = model_->ItemIndexByID(id);
872 if (index == -1) { 872 if (index == -1) {
873 NOTREACHED() << "Invalid launcher id"; 873 NOTREACHED() << "Invalid launcher id";
874 return; 874 return;
875 } 875 }
876 876
877 ash::ShelfItemType type = model_->items()[index].type; 877 ash::ShelfItemType type = model_->items()[index].type;
878 if (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_WINDOWED_APP) { 878 if (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_WINDOWED_APP) {
879 AppShortcutLauncherItemController* app_controller = 879 AppShortcutLauncherItemController* app_controller =
880 static_cast<AppShortcutLauncherItemController*>(controller); 880 static_cast<AppShortcutLauncherItemController*>(controller);
881 app_controller->set_refocus_url(url); 881 app_controller->set_refocus_url(url);
882 } else { 882 } else {
883 NOTREACHED() << "Invalid launcher type"; 883 NOTREACHED() << "Invalid launcher type";
884 } 884 }
885 } 885 }
886 886
887 const Extension* ChromeLauncherController::GetExtensionForAppID( 887 const Extension* ChromeLauncherControllerImpl::GetExtensionForAppID(
888 const std::string& app_id) const { 888 const std::string& app_id) const {
889 return extensions::ExtensionRegistry::Get(profile_)->GetExtensionById( 889 return extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
890 app_id, extensions::ExtensionRegistry::EVERYTHING); 890 app_id, extensions::ExtensionRegistry::EVERYTHING);
891 } 891 }
892 892
893 ash::ShelfItemDelegate::PerformedAction 893 ash::ShelfItemDelegate::PerformedAction
894 ChromeLauncherController::ActivateWindowOrMinimizeIfActive( 894 ChromeLauncherControllerImpl::ActivateWindowOrMinimizeIfActive(
895 ui::BaseWindow* window, 895 ui::BaseWindow* window,
896 bool allow_minimize) { 896 bool allow_minimize) {
897 // In separated desktop mode we might have to teleport a window back to the 897 // In separated desktop mode we might have to teleport a window back to the
898 // current user. 898 // current user.
899 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == 899 if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
900 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) { 900 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) {
901 aura::Window* native_window = window->GetNativeWindow(); 901 aura::Window* native_window = window->GetNativeWindow();
902 const AccountId& current_account_id = 902 const AccountId& current_account_id =
903 multi_user_util::GetAccountIdFromProfile(profile()); 903 multi_user_util::GetAccountIdFromProfile(GetProfile());
904 chrome::MultiUserWindowManager* manager = 904 chrome::MultiUserWindowManager* manager =
905 chrome::MultiUserWindowManager::GetInstance(); 905 chrome::MultiUserWindowManager::GetInstance();
906 if (!manager->IsWindowOnDesktopOfUser(native_window, current_account_id)) { 906 if (!manager->IsWindowOnDesktopOfUser(native_window, current_account_id)) {
907 ash::MultiProfileUMA::RecordTeleportAction( 907 ash::MultiProfileUMA::RecordTeleportAction(
908 ash::MultiProfileUMA::TELEPORT_WINDOW_RETURN_BY_LAUNCHER); 908 ash::MultiProfileUMA::TELEPORT_WINDOW_RETURN_BY_LAUNCHER);
909 manager->ShowWindowForUser(native_window, current_account_id); 909 manager->ShowWindowForUser(native_window, current_account_id);
910 window->Activate(); 910 window->Activate();
911 return ash::ShelfItemDelegate::kExistingWindowActivated; 911 return ash::ShelfItemDelegate::kExistingWindowActivated;
912 } 912 }
913 } 913 }
914 914
915 if (window->IsActive() && allow_minimize) { 915 if (window->IsActive() && allow_minimize) {
916 window->Minimize(); 916 window->Minimize();
917 return ash::ShelfItemDelegate::kNoAction; 917 return ash::ShelfItemDelegate::kNoAction;
918 } 918 }
919 919
920 window->Show(); 920 window->Show();
921 window->Activate(); 921 window->Activate();
922 return ash::ShelfItemDelegate::kExistingWindowActivated; 922 return ash::ShelfItemDelegate::kExistingWindowActivated;
923 } 923 }
924 924
925 void ChromeLauncherController::OnShelfCreated(ash::Shelf* shelf) { 925 ArcAppDeferredLauncherController*
926 ChromeLauncherControllerImpl::GetArcDeferredLauncher() {
927 return arc_deferred_launcher_.get();
928 }
929
930 void ChromeLauncherControllerImpl::OnShelfCreated(ash::Shelf* shelf) {
926 PrefService* prefs = profile_->GetPrefs(); 931 PrefService* prefs = profile_->GetPrefs();
927 const int64_t display = GetDisplayIDForShelf(shelf); 932 const int64_t display = GetDisplayIDForShelf(shelf);
928 933
929 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(prefs, display)); 934 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(prefs, display));
930 935
931 if (ash::ShelfWidget::ShelfAlignmentAllowed()) 936 if (ash::ShelfWidget::ShelfAlignmentAllowed())
932 shelf->SetAlignment(ash::GetShelfAlignmentPref(prefs, display)); 937 shelf->SetAlignment(ash::GetShelfAlignmentPref(prefs, display));
933 } 938 }
934 939
935 void ChromeLauncherController::OnShelfDestroyed(ash::Shelf* shelf) {} 940 void ChromeLauncherControllerImpl::OnShelfDestroyed(ash::Shelf* shelf) {}
936 941
937 void ChromeLauncherController::OnShelfAlignmentChanged(ash::Shelf* shelf) { 942 void ChromeLauncherControllerImpl::OnShelfAlignmentChanged(ash::Shelf* shelf) {
938 ash::SetShelfAlignmentPref(profile_->GetPrefs(), GetDisplayIDForShelf(shelf), 943 ash::SetShelfAlignmentPref(profile_->GetPrefs(), GetDisplayIDForShelf(shelf),
939 shelf->alignment()); 944 shelf->alignment());
940 } 945 }
941 946
942 void ChromeLauncherController::OnShelfAutoHideBehaviorChanged( 947 void ChromeLauncherControllerImpl::OnShelfAutoHideBehaviorChanged(
943 ash::Shelf* shelf) { 948 ash::Shelf* shelf) {
944 ash::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), 949 ash::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(),
945 GetDisplayIDForShelf(shelf), 950 GetDisplayIDForShelf(shelf),
946 shelf->auto_hide_behavior()); 951 shelf->auto_hide_behavior());
947 } 952 }
948 953
949 void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {} 954 void ChromeLauncherControllerImpl::OnShelfAutoHideStateChanged(
950
951 void ChromeLauncherController::OnShelfVisibilityStateChanged(
952 ash::Shelf* shelf) {} 955 ash::Shelf* shelf) {}
953 956
954 void ChromeLauncherController::ShelfItemAdded(int index) { 957 void ChromeLauncherControllerImpl::OnShelfVisibilityStateChanged(
958 ash::Shelf* shelf) {}
959
960 void ChromeLauncherControllerImpl::ShelfItemAdded(int index) {
955 // The app list launcher can get added to the shelf after we applied the 961 // The app list launcher can get added to the shelf after we applied the
956 // preferences. In that case the item might be at the wrong spot. As such we 962 // preferences. In that case the item might be at the wrong spot. As such we
957 // call the function again. 963 // call the function again.
958 if (model_->items()[index].type == ash::TYPE_APP_LIST) 964 if (model_->items()[index].type == ash::TYPE_APP_LIST)
959 UpdateAppLaunchersFromPref(); 965 UpdateAppLaunchersFromPref();
960 } 966 }
961 967
962 void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) { 968 void ChromeLauncherControllerImpl::ShelfItemRemoved(int index,
969 ash::ShelfID id) {
963 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we 970 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
964 // get into this state in the first place. 971 // get into this state in the first place.
965 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 972 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
966 if (iter == id_to_item_controller_map_.end()) 973 if (iter == id_to_item_controller_map_.end())
967 return; 974 return;
968 975
969 LOG(ERROR) << "Unexpected change of shelf item id: " << id; 976 LOG(ERROR) << "Unexpected change of shelf item id: " << id;
970 977
971 id_to_item_controller_map_.erase(iter); 978 id_to_item_controller_map_.erase(iter);
972 } 979 }
973 980
974 void ChromeLauncherController::ShelfItemMoved(int start_index, 981 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index,
975 int target_index) { 982 int target_index) {
976 const ash::ShelfItem& item = model_->items()[target_index]; 983 const ash::ShelfItem& item = model_->items()[target_index];
977 // We remember the moved item position if it is either pinnable or 984 // We remember the moved item position if it is either pinnable or
978 // it is the app list with the alternate shelf layout. 985 // it is the app list with the alternate shelf layout.
979 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) || 986 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) ||
980 item.type == ash::TYPE_APP_LIST) 987 item.type == ash::TYPE_APP_LIST)
981 PersistPinnedState(); 988 PersistPinnedState();
982 } 989 }
983 990
984 void ChromeLauncherController::ShelfItemChanged( 991 void ChromeLauncherControllerImpl::ShelfItemChanged(
985 int index, 992 int index,
986 const ash::ShelfItem& old_item) {} 993 const ash::ShelfItem& old_item) {}
987 994
988 void ChromeLauncherController::ActiveUserChanged( 995 void ChromeLauncherControllerImpl::ActiveUserChanged(
989 const std::string& user_email) { 996 const std::string& user_email) {
990 // Store the order of running applications for the user which gets inactive. 997 // Store the order of running applications for the user which gets inactive.
991 RememberUnpinnedRunningApplicationOrder(); 998 RememberUnpinnedRunningApplicationOrder();
992 // Coming here the default profile is already switched. All profile specific 999 // Coming here the default profile is already switched. All profile specific
993 // resources get released and the new profile gets attached instead. 1000 // resources get released and the new profile gets attached instead.
994 ReleaseProfile(); 1001 ReleaseProfile();
995 // When coming here, the active user has already be changed so that we can 1002 // When coming here, the active user has already be changed so that we can
996 // set it as active. 1003 // set it as active.
997 AttachProfile(ProfileManager::GetActiveUserProfile()); 1004 AttachProfile(ProfileManager::GetActiveUserProfile());
998 // Update the V1 applications. 1005 // Update the V1 applications.
999 browser_status_monitor_->ActiveUserChanged(user_email); 1006 browser_status_monitor_->ActiveUserChanged(user_email);
1000 // Switch the running applications to the new user. 1007 // Switch the running applications to the new user.
1001 for (auto& controller : app_window_controllers_) 1008 for (auto& controller : app_window_controllers_)
1002 controller->ActiveUserChanged(user_email); 1009 controller->ActiveUserChanged(user_email);
1003 // Update the user specific shell properties from the new user profile. 1010 // Update the user specific shell properties from the new user profile.
1004 UpdateAppLaunchersFromPref(); 1011 UpdateAppLaunchersFromPref();
1005 SetShelfBehaviorsFromPrefs(); 1012 SetShelfBehaviorsFromPrefs();
1006 SetVirtualKeyboardBehaviorFromPrefs(); 1013 SetVirtualKeyboardBehaviorFromPrefs();
1007 1014
1008 // Restore the order of running, but unpinned applications for the activated 1015 // Restore the order of running, but unpinned applications for the activated
1009 // user. 1016 // user.
1010 RestoreUnpinnedRunningApplicationOrder(user_email); 1017 RestoreUnpinnedRunningApplicationOrder(user_email);
1011 // Inform the system tray of the change. 1018 // Inform the system tray of the change.
1012 ash::Shell::GetInstance()->system_tray_delegate()->ActiveUserWasChanged(); 1019 ash::Shell::GetInstance()->system_tray_delegate()->ActiveUserWasChanged();
1013 // Force on-screen keyboard to reset. 1020 // Force on-screen keyboard to reset.
1014 if (keyboard::IsKeyboardEnabled()) 1021 if (keyboard::IsKeyboardEnabled())
1015 ash::Shell::GetInstance()->CreateKeyboard(); 1022 ash::Shell::GetInstance()->CreateKeyboard();
1016 } 1023 }
1017 1024
1018 void ChromeLauncherController::AdditionalUserAddedToSession(Profile* profile) { 1025 void ChromeLauncherControllerImpl::AdditionalUserAddedToSession(
1026 Profile* profile) {
1019 // Switch the running applications to the new user. 1027 // Switch the running applications to the new user.
1020 for (auto& controller : app_window_controllers_) 1028 for (auto& controller : app_window_controllers_)
1021 controller->AdditionalUserAddedToSession(profile); 1029 controller->AdditionalUserAddedToSession(profile);
1022 } 1030 }
1023 1031
1024 void ChromeLauncherController::OnAppInstalled( 1032 void ChromeLauncherControllerImpl::OnAppInstalled(
1025 content::BrowserContext* browser_context, 1033 content::BrowserContext* browser_context,
1026 const std::string& app_id) { 1034 const std::string& app_id) {
1027 if (IsAppPinned(app_id)) { 1035 if (IsAppPinned(app_id)) {
1028 // Clear and re-fetch to ensure icon is up-to-date. 1036 // Clear and re-fetch to ensure icon is up-to-date.
1029 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1037 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1030 if (app_icon_loader) { 1038 if (app_icon_loader) {
1031 app_icon_loader->ClearImage(app_id); 1039 app_icon_loader->ClearImage(app_id);
1032 app_icon_loader->FetchImage(app_id); 1040 app_icon_loader->FetchImage(app_id);
1033 } 1041 }
1034 } 1042 }
1035 1043
1036 UpdateAppLaunchersFromPref(); 1044 UpdateAppLaunchersFromPref();
1037 } 1045 }
1038 1046
1039 void ChromeLauncherController::OnAppUpdated( 1047 void ChromeLauncherControllerImpl::OnAppUpdated(
1040 content::BrowserContext* browser_context, 1048 content::BrowserContext* browser_context,
1041 const std::string& app_id) { 1049 const std::string& app_id) {
1042 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1050 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1043 if (app_icon_loader) 1051 if (app_icon_loader)
1044 app_icon_loader->UpdateImage(app_id); 1052 app_icon_loader->UpdateImage(app_id);
1045 } 1053 }
1046 1054
1047 void ChromeLauncherController::OnAppUninstalled( 1055 void ChromeLauncherControllerImpl::OnAppUninstalled(
1048 content::BrowserContext* browser_context, 1056 content::BrowserContext* browser_context,
1049 const std::string& app_id) { 1057 const std::string& app_id) {
1050 // Since we might have windowed apps of this type which might have 1058 // Since we might have windowed apps of this type which might have
1051 // outstanding locks which needs to be removed. 1059 // outstanding locks which needs to be removed.
1052 const Profile* profile = Profile::FromBrowserContext(browser_context); 1060 const Profile* profile = Profile::FromBrowserContext(browser_context);
1053 if (GetShelfIDForAppID(app_id)) 1061 if (GetShelfIDForAppID(app_id))
1054 CloseWindowedAppsFromRemovedExtension(app_id, profile); 1062 CloseWindowedAppsFromRemovedExtension(app_id, profile);
1055 1063
1056 if (IsAppPinned(app_id)) { 1064 if (IsAppPinned(app_id)) {
1057 if (profile == profile_) 1065 if (profile == profile_)
1058 DoUnpinAppWithID(app_id); 1066 DoUnpinAppWithID(app_id);
1059 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1067 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1060 if (app_icon_loader) 1068 if (app_icon_loader)
1061 app_icon_loader->ClearImage(app_id); 1069 app_icon_loader->ClearImage(app_id);
1062 } 1070 }
1063 } 1071 }
1064 1072
1065 void ChromeLauncherController::OnDisplayConfigurationChanged() { 1073 void ChromeLauncherControllerImpl::OnDisplayConfigurationChanged() {
1066 SetShelfBehaviorsFromPrefs(); 1074 SetShelfBehaviorsFromPrefs();
1067 } 1075 }
1068 1076
1069 void ChromeLauncherController::OnAppSyncUIStatusChanged() { 1077 void ChromeLauncherControllerImpl::OnAppSyncUIStatusChanged() {
1070 if (app_sync_ui_state_->status() == AppSyncUIState::STATUS_SYNCING) 1078 if (app_sync_ui_state_->status() == AppSyncUIState::STATUS_SYNCING)
1071 model_->set_status(ash::ShelfModel::STATUS_LOADING); 1079 model_->set_status(ash::ShelfModel::STATUS_LOADING);
1072 else 1080 else
1073 model_->set_status(ash::ShelfModel::STATUS_NORMAL); 1081 model_->set_status(ash::ShelfModel::STATUS_NORMAL);
1074 } 1082 }
1075 1083
1076 ChromeLauncherAppMenuItems ChromeLauncherController::GetApplicationList( 1084 ChromeLauncherAppMenuItems ChromeLauncherControllerImpl::GetApplicationList(
1077 const ash::ShelfItem& item, 1085 const ash::ShelfItem& item,
1078 int event_flags) { 1086 int event_flags) {
1079 // Make sure that there is a controller associated with the id and that the 1087 // Make sure that there is a controller associated with the id and that the
1080 // extension itself is a valid application and not a panel. 1088 // extension itself is a valid application and not a panel.
1081 LauncherItemController* controller = GetLauncherItemController(item.id); 1089 LauncherItemController* controller = GetLauncherItemController(item.id);
1082 if (!controller || !GetShelfIDForAppID(controller->app_id())) 1090 if (!controller || !GetShelfIDForAppID(controller->app_id()))
1083 return ChromeLauncherAppMenuItems(); 1091 return ChromeLauncherAppMenuItems();
1084 1092
1085 return controller->GetApplicationList(event_flags); 1093 return controller->GetApplicationList(event_flags);
1086 } 1094 }
1087 1095
1088 std::vector<content::WebContents*> 1096 std::vector<content::WebContents*>
1089 ChromeLauncherController::GetV1ApplicationsFromAppId( 1097 ChromeLauncherControllerImpl::GetV1ApplicationsFromAppId(
1090 const std::string& app_id) { 1098 const std::string& app_id) {
1091 ash::ShelfID id = GetShelfIDForAppID(app_id); 1099 ash::ShelfID id = GetShelfIDForAppID(app_id);
1092 1100
1093 // If there is no such an item pinned to the launcher, no menu gets created. 1101 // If there is no such an item pinned to the launcher, no menu gets created.
1094 if (id) { 1102 if (id) {
1095 LauncherItemController* controller = GetLauncherItemController(id); 1103 LauncherItemController* controller = GetLauncherItemController(id);
1096 DCHECK(controller); 1104 DCHECK(controller);
1097 if (controller->type() == LauncherItemController::TYPE_SHORTCUT) 1105 if (controller->type() == LauncherItemController::TYPE_SHORTCUT)
1098 return GetV1ApplicationsFromController(controller); 1106 return GetV1ApplicationsFromController(controller);
1099 } 1107 }
1100 return std::vector<content::WebContents*>(); 1108 return std::vector<content::WebContents*>();
1101 } 1109 }
1102 1110
1103 void ChromeLauncherController::ActivateShellApp(const std::string& app_id, 1111 void ChromeLauncherControllerImpl::ActivateShellApp(const std::string& app_id,
1104 int index) { 1112 int index) {
1105 ash::ShelfID id = GetShelfIDForAppID(app_id); 1113 ash::ShelfID id = GetShelfIDForAppID(app_id);
1106 if (id) { 1114 if (id) {
1107 LauncherItemController* controller = GetLauncherItemController(id); 1115 LauncherItemController* controller = GetLauncherItemController(id);
1108 if (controller && controller->type() == LauncherItemController::TYPE_APP) { 1116 if (controller && controller->type() == LauncherItemController::TYPE_APP) {
1109 AppWindowLauncherItemController* app_window_controller = 1117 AppWindowLauncherItemController* app_window_controller =
1110 static_cast<AppWindowLauncherItemController*>(controller); 1118 static_cast<AppWindowLauncherItemController*>(controller);
1111 app_window_controller->ActivateIndexedApp(index); 1119 app_window_controller->ActivateIndexedApp(index);
1112 } 1120 }
1113 } 1121 }
1114 } 1122 }
1115 1123
1116 bool ChromeLauncherController::IsWebContentHandledByApplication( 1124 bool ChromeLauncherControllerImpl::IsWebContentHandledByApplication(
1117 content::WebContents* web_contents, 1125 content::WebContents* web_contents,
1118 const std::string& app_id) { 1126 const std::string& app_id) {
1119 if ((web_contents_to_app_id_.find(web_contents) != 1127 if ((web_contents_to_app_id_.find(web_contents) !=
1120 web_contents_to_app_id_.end()) && 1128 web_contents_to_app_id_.end()) &&
1121 (web_contents_to_app_id_[web_contents] == app_id)) 1129 (web_contents_to_app_id_[web_contents] == app_id))
1122 return true; 1130 return true;
1123 return (app_id == kGmailAppId && ContentCanBeHandledByGmailApp(web_contents)); 1131 return (app_id == kGmailAppId && ContentCanBeHandledByGmailApp(web_contents));
1124 } 1132 }
1125 1133
1126 bool ChromeLauncherController::ContentCanBeHandledByGmailApp( 1134 bool ChromeLauncherControllerImpl::ContentCanBeHandledByGmailApp(
1127 content::WebContents* web_contents) { 1135 content::WebContents* web_contents) {
1128 ash::ShelfID id = GetShelfIDForAppID(kGmailAppId); 1136 ash::ShelfID id = GetShelfIDForAppID(kGmailAppId);
1129 if (id) { 1137 if (id) {
1130 const GURL url = web_contents->GetURL(); 1138 const GURL url = web_contents->GetURL();
1131 // We need to extend the application matching for the gMail app beyond the 1139 // We need to extend the application matching for the gMail app beyond the
1132 // manifest file's specification. This is required because of the namespace 1140 // manifest file's specification. This is required because of the namespace
1133 // overlap with the offline app ("/mail/mu/"). 1141 // overlap with the offline app ("/mail/mu/").
1134 if (!base::MatchPattern(url.path(), "/mail/mu/*") && 1142 if (!base::MatchPattern(url.path(), "/mail/mu/*") &&
1135 base::MatchPattern(url.path(), "/mail/*") && 1143 base::MatchPattern(url.path(), "/mail/*") &&
1136 GetExtensionForAppID(kGmailAppId) && 1144 GetExtensionForAppID(kGmailAppId) &&
1137 GetExtensionForAppID(kGmailAppId)->OverlapsWithOrigin(url)) 1145 GetExtensionForAppID(kGmailAppId)->OverlapsWithOrigin(url))
1138 return true; 1146 return true;
1139 } 1147 }
1140 return false; 1148 return false;
1141 } 1149 }
1142 1150
1143 gfx::Image ChromeLauncherController::GetAppListIcon( 1151 gfx::Image ChromeLauncherControllerImpl::GetAppListIcon(
1144 content::WebContents* web_contents) const { 1152 content::WebContents* web_contents) const {
1145 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1153 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1146 if (IsIncognito(web_contents)) 1154 if (IsIncognito(web_contents))
1147 return rb.GetImageNamed(IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER); 1155 return rb.GetImageNamed(IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER);
1148 favicon::FaviconDriver* favicon_driver = 1156 favicon::FaviconDriver* favicon_driver =
1149 favicon::ContentFaviconDriver::FromWebContents(web_contents); 1157 favicon::ContentFaviconDriver::FromWebContents(web_contents);
1150 gfx::Image result = favicon_driver->GetFavicon(); 1158 gfx::Image result = favicon_driver->GetFavicon();
1151 if (result.IsEmpty()) 1159 if (result.IsEmpty())
1152 return rb.GetImageNamed(IDR_DEFAULT_FAVICON); 1160 return rb.GetImageNamed(IDR_DEFAULT_FAVICON);
1153 return result; 1161 return result;
1154 } 1162 }
1155 1163
1156 base::string16 ChromeLauncherController::GetAppListTitle( 1164 base::string16 ChromeLauncherControllerImpl::GetAppListTitle(
1157 content::WebContents* web_contents) const { 1165 content::WebContents* web_contents) const {
1158 base::string16 title = web_contents->GetTitle(); 1166 base::string16 title = web_contents->GetTitle();
1159 if (!title.empty()) 1167 if (!title.empty())
1160 return title; 1168 return title;
1161 WebContentsToAppIDMap::const_iterator iter = 1169 WebContentsToAppIDMap::const_iterator iter =
1162 web_contents_to_app_id_.find(web_contents); 1170 web_contents_to_app_id_.find(web_contents);
1163 if (iter != web_contents_to_app_id_.end()) { 1171 if (iter != web_contents_to_app_id_.end()) {
1164 std::string app_id = iter->second; 1172 std::string app_id = iter->second;
1165 const extensions::Extension* extension = GetExtensionForAppID(app_id); 1173 const extensions::Extension* extension = GetExtensionForAppID(app_id);
1166 if (extension) 1174 if (extension)
1167 return base::UTF8ToUTF16(extension->name()); 1175 return base::UTF8ToUTF16(extension->name());
1168 } 1176 }
1169 return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE); 1177 return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
1170 } 1178 }
1171 1179
1172 ash::ShelfID ChromeLauncherController::CreateAppShortcutLauncherItem( 1180 ash::ShelfID ChromeLauncherControllerImpl::CreateAppShortcutLauncherItem(
1173 const std::string& app_id, 1181 const std::string& app_id,
1174 int index) { 1182 int index) {
1175 return CreateAppShortcutLauncherItemWithType(app_id, 1183 return CreateAppShortcutLauncherItemWithType(app_id, index,
1176 index,
1177 ash::TYPE_APP_SHORTCUT); 1184 ash::TYPE_APP_SHORTCUT);
1178 } 1185 }
1179 1186
1180 void ChromeLauncherController::SetLauncherControllerHelperForTest( 1187 void ChromeLauncherControllerImpl::SetLauncherControllerHelperForTest(
1181 LauncherControllerHelper* helper) { 1188 LauncherControllerHelper* helper) {
1182 launcher_controller_helper_.reset(helper); 1189 launcher_controller_helper_.reset(helper);
1183 } 1190 }
1184 1191
1185 void ChromeLauncherController::SetAppIconLoadersForTest( 1192 void ChromeLauncherControllerImpl::SetAppIconLoadersForTest(
1186 std::vector<std::unique_ptr<AppIconLoader>>& loaders) { 1193 std::vector<std::unique_ptr<AppIconLoader>>& loaders) {
1187 app_icon_loaders_.clear(); 1194 app_icon_loaders_.clear();
1188 for (auto& loader : loaders) 1195 for (auto& loader : loaders)
1189 app_icon_loaders_.push_back(std::move(loader)); 1196 app_icon_loaders_.push_back(std::move(loader));
1190 } 1197 }
1191 1198
1192 const std::string& ChromeLauncherController::GetAppIdFromShelfIdForTest( 1199 const std::string& ChromeLauncherControllerImpl::GetAppIdFromShelfIdForTest(
1193 ash::ShelfID id) { 1200 ash::ShelfID id) {
1194 return id_to_item_controller_map_[id]->app_id(); 1201 return id_to_item_controller_map_[id]->app_id();
1195 } 1202 }
1196 1203
1197 bool ChromeLauncherController::GetAppIDForShelfIDConst( 1204 bool ChromeLauncherControllerImpl::GetAppIDForShelfIDConst(
1198 ash::ShelfID id, 1205 ash::ShelfID id,
1199 std::string* app_id) const { 1206 std::string* app_id) const {
1200 auto app = id_to_item_controller_map_.find(id); 1207 auto app = id_to_item_controller_map_.find(id);
1201 if (app == id_to_item_controller_map_.end()) { 1208 if (app == id_to_item_controller_map_.end()) {
1202 return false; 1209 return false;
1203 } else { 1210 } else {
1204 *app_id = app->second->app_id(); 1211 *app_id = app->second->app_id();
1205 return true; 1212 return true;
1206 } 1213 }
1207 } 1214 }
1208 1215
1209 void ChromeLauncherController::SetShelfItemDelegateManagerForTest( 1216 void ChromeLauncherControllerImpl::SetShelfItemDelegateManagerForTest(
1210 ash::ShelfItemDelegateManager* manager) { 1217 ash::ShelfItemDelegateManager* manager) {
1211 if (item_delegate_manager_) 1218 if (item_delegate_manager_)
1212 item_delegate_manager_->RemoveObserver(this); 1219 item_delegate_manager_->RemoveObserver(this);
1213 1220
1214 item_delegate_manager_ = manager; 1221 item_delegate_manager_ = manager;
1215 1222
1216 if (item_delegate_manager_) 1223 if (item_delegate_manager_)
1217 item_delegate_manager_->AddObserver(this); 1224 item_delegate_manager_->AddObserver(this);
1218 } 1225 }
1219 1226
1220 void ChromeLauncherController::RememberUnpinnedRunningApplicationOrder() { 1227 void ChromeLauncherControllerImpl::RememberUnpinnedRunningApplicationOrder() {
1221 RunningAppListIds list; 1228 RunningAppListIds list;
1222 for (int i = 0; i < model_->item_count(); i++) { 1229 for (int i = 0; i < model_->item_count(); i++) {
1223 ash::ShelfItemType type = model_->items()[i].type; 1230 ash::ShelfItemType type = model_->items()[i].type;
1224 if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) 1231 if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP)
1225 list.push_back(GetAppIDForShelfID(model_->items()[i].id)); 1232 list.push_back(GetAppIDForShelfID(model_->items()[i].id));
1226 } 1233 }
1227 const std::string user_email = 1234 const std::string user_email =
1228 multi_user_util::GetAccountIdFromProfile(profile_).GetUserEmail(); 1235 multi_user_util::GetAccountIdFromProfile(profile_).GetUserEmail();
1229 last_used_running_application_order_[user_email] = list; 1236 last_used_running_application_order_[user_email] = list;
1230 } 1237 }
1231 1238
1232 void ChromeLauncherController::RestoreUnpinnedRunningApplicationOrder( 1239 void ChromeLauncherControllerImpl::RestoreUnpinnedRunningApplicationOrder(
1233 const std::string& user_id) { 1240 const std::string& user_id) {
1234 const RunningAppListIdMap::iterator app_id_list = 1241 const RunningAppListIdMap::iterator app_id_list =
1235 last_used_running_application_order_.find(user_id); 1242 last_used_running_application_order_.find(user_id);
1236 if (app_id_list == last_used_running_application_order_.end()) 1243 if (app_id_list == last_used_running_application_order_.end())
1237 return; 1244 return;
1238 1245
1239 // Find the first insertion point for running applications. 1246 // Find the first insertion point for running applications.
1240 int running_index = model_->FirstRunningAppIndex(); 1247 int running_index = model_->FirstRunningAppIndex();
1241 for (RunningAppListIds::iterator app_id = app_id_list->second.begin(); 1248 for (RunningAppListIds::iterator app_id = app_id_list->second.begin();
1242 app_id != app_id_list->second.end(); ++app_id) { 1249 app_id != app_id_list->second.end(); ++app_id) {
1243 ash::ShelfID shelf_id = GetShelfIDForAppID(*app_id); 1250 ash::ShelfID shelf_id = GetShelfIDForAppID(*app_id);
1244 if (shelf_id) { 1251 if (shelf_id) {
1245 int app_index = model_->ItemIndexByID(shelf_id); 1252 int app_index = model_->ItemIndexByID(shelf_id);
1246 DCHECK_GE(app_index, 0); 1253 DCHECK_GE(app_index, 0);
1247 ash::ShelfItemType type = model_->items()[app_index].type; 1254 ash::ShelfItemType type = model_->items()[app_index].type;
1248 if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) { 1255 if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) {
1249 if (running_index != app_index) 1256 if (running_index != app_index)
1250 model_->Move(running_index, app_index); 1257 model_->Move(running_index, app_index);
1251 running_index++; 1258 running_index++;
1252 } 1259 }
1253 } 1260 }
1254 } 1261 }
1255 } 1262 }
1256 1263
1257 ash::ShelfID ChromeLauncherController::CreateAppShortcutLauncherItemWithType( 1264 ash::ShelfID
1265 ChromeLauncherControllerImpl::CreateAppShortcutLauncherItemWithType(
1258 const std::string& app_id, 1266 const std::string& app_id,
1259 int index, 1267 int index,
1260 ash::ShelfItemType shelf_item_type) { 1268 ash::ShelfItemType shelf_item_type) {
1261 AppShortcutLauncherItemController* controller = 1269 AppShortcutLauncherItemController* controller =
1262 AppShortcutLauncherItemController::Create(app_id, this); 1270 AppShortcutLauncherItemController::Create(app_id, this);
1263 ash::ShelfID shelf_id = InsertAppLauncherItem( 1271 ash::ShelfID shelf_id = InsertAppLauncherItem(
1264 controller, app_id, ash::STATUS_CLOSED, index, shelf_item_type); 1272 controller, app_id, ash::STATUS_CLOSED, index, shelf_item_type);
1265 return shelf_id; 1273 return shelf_id;
1266 } 1274 }
1267 1275
1268 LauncherItemController* ChromeLauncherController::GetLauncherItemController( 1276 LauncherItemController* ChromeLauncherControllerImpl::GetLauncherItemController(
1269 const ash::ShelfID id) { 1277 const ash::ShelfID id) {
1270 if (!HasShelfIDToAppIDMapping(id)) 1278 if (!HasShelfIDToAppIDMapping(id))
1271 return NULL; 1279 return NULL;
1272 return id_to_item_controller_map_[id]; 1280 return id_to_item_controller_map_[id];
1273 } 1281 }
1274 1282
1275 bool ChromeLauncherController::IsBrowserFromActiveUser(Browser* browser) { 1283 bool ChromeLauncherControllerImpl::IsBrowserFromActiveUser(Browser* browser) {
1276 // If running multi user mode with separate desktops, we have to check if the 1284 // If running multi user mode with separate desktops, we have to check if the
1277 // browser is from the active user. 1285 // browser is from the active user.
1278 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 1286 if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
1279 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 1287 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
1280 return true; 1288 return true;
1281 return multi_user_util::IsProfileFromActiveUser(browser->profile()); 1289 return multi_user_util::IsProfileFromActiveUser(browser->profile());
1282 } 1290 }
1283 1291
1284 bool ChromeLauncherController::ShelfBoundsChangesProbablyWithUser( 1292 bool ChromeLauncherControllerImpl::ShelfBoundsChangesProbablyWithUser(
1285 ash::Shelf* shelf, 1293 ash::Shelf* shelf,
1286 const std::string& user_id) const { 1294 const std::string& user_id) const {
1287 Profile* other_profile = multi_user_util::GetProfileFromAccountId( 1295 Profile* other_profile = multi_user_util::GetProfileFromAccountId(
1288 AccountId::FromUserEmail(user_id)); 1296 AccountId::FromUserEmail(user_id));
1289 if (other_profile == profile_) 1297 if (other_profile == profile_)
1290 return false; 1298 return false;
1291 1299
1292 // Note: The Auto hide state from preferences is not the same as the actual 1300 // Note: The Auto hide state from preferences is not the same as the actual
1293 // visibility of the shelf. Depending on all the various states (full screen, 1301 // visibility of the shelf. Depending on all the various states (full screen,
1294 // no window on desktop, multi user, ..) the shelf could be shown - or not. 1302 // no window on desktop, multi user, ..) the shelf could be shown - or not.
1295 PrefService* prefs = profile_->GetPrefs(); 1303 PrefService* prefs = profile_->GetPrefs();
1296 PrefService* other_prefs = other_profile->GetPrefs(); 1304 PrefService* other_prefs = other_profile->GetPrefs();
1297 const int64_t display = GetDisplayIDForShelf(shelf); 1305 const int64_t display = GetDisplayIDForShelf(shelf);
1298 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 1306 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
1299 ash::GetShelfAutoHideBehaviorPref(prefs, display); 1307 ash::GetShelfAutoHideBehaviorPref(prefs, display);
1300 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == 1308 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
1301 ash::GetShelfAutoHideBehaviorPref(other_prefs, display); 1309 ash::GetShelfAutoHideBehaviorPref(other_prefs, display);
1302 1310
1303 return currently_shown != other_shown || 1311 return currently_shown != other_shown ||
1304 ash::GetShelfAlignmentPref(prefs, display) != 1312 ash::GetShelfAlignmentPref(prefs, display) !=
1305 ash::GetShelfAlignmentPref(other_prefs, display); 1313 ash::GetShelfAlignmentPref(other_prefs, display);
1306 } 1314 }
1307 1315
1308 void ChromeLauncherController::OnUserProfileReadyToSwitch(Profile* profile) { 1316 void ChromeLauncherControllerImpl::OnUserProfileReadyToSwitch(
1317 Profile* profile) {
1309 if (user_switch_observer_.get()) 1318 if (user_switch_observer_.get())
1310 user_switch_observer_->OnUserProfileReadyToSwitch(profile); 1319 user_switch_observer_->OnUserProfileReadyToSwitch(profile);
1311 } 1320 }
1312 1321
1313 void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) { 1322 void ChromeLauncherControllerImpl::LauncherItemClosed(ash::ShelfID id) {
1314 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); 1323 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
1315 CHECK(iter != id_to_item_controller_map_.end()); 1324 CHECK(iter != id_to_item_controller_map_.end());
1316 CHECK(iter->second); 1325 CHECK(iter->second);
1317 const std::string& app_id = iter->second->app_id(); 1326 const std::string& app_id = iter->second->app_id();
1318 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id); 1327 AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
1319 if (app_icon_loader) 1328 if (app_icon_loader)
1320 app_icon_loader->ClearImage(app_id); 1329 app_icon_loader->ClearImage(app_id);
1321 id_to_item_controller_map_.erase(iter); 1330 id_to_item_controller_map_.erase(iter);
1322 int index = model_->ItemIndexByID(id); 1331 int index = model_->ItemIndexByID(id);
1323 // A "browser proxy" is not known to the model and this removal does 1332 // A "browser proxy" is not known to the model and this removal does
1324 // therefore not need to be propagated to the model. 1333 // therefore not need to be propagated to the model.
1325 if (index != -1) 1334 if (index != -1)
1326 model_->RemoveItemAt(index); 1335 model_->RemoveItemAt(index);
1327 } 1336 }
1328 1337
1329 void ChromeLauncherController::DoPinAppWithID(const std::string& app_id) { 1338 void ChromeLauncherControllerImpl::DoPinAppWithID(const std::string& app_id) {
1330 // If there is an item, do nothing and return. 1339 // If there is an item, do nothing and return.
1331 if (IsAppPinned(app_id)) 1340 if (IsAppPinned(app_id))
1332 return; 1341 return;
1333 1342
1334 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 1343 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
1335 if (shelf_id) { 1344 if (shelf_id) {
1336 // App item exists, pin it 1345 // App item exists, pin it
1337 Pin(shelf_id); 1346 Pin(shelf_id);
1338 } else { 1347 } else {
1339 // Otherwise, create a shortcut item for it. 1348 // Otherwise, create a shortcut item for it.
1340 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); 1349 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count());
1341 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) 1350 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
1342 PersistPinnedState(); 1351 PersistPinnedState();
1343 } 1352 }
1344 } 1353 }
1345 1354
1346 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { 1355 void ChromeLauncherControllerImpl::DoUnpinAppWithID(const std::string& app_id) {
1347 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); 1356 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
1348 if (shelf_id && IsPinned(shelf_id)) 1357 if (shelf_id && IsPinned(shelf_id))
1349 Unpin(shelf_id); 1358 Unpin(shelf_id);
1350 } 1359 }
1351 1360
1352 int ChromeLauncherController::PinRunningAppInternal(int index, 1361 int ChromeLauncherControllerImpl::PinRunningAppInternal(int index,
1353 ash::ShelfID shelf_id) { 1362 ash::ShelfID shelf_id) {
1354 int running_index = model_->ItemIndexByID(shelf_id); 1363 int running_index = model_->ItemIndexByID(shelf_id);
1355 ash::ShelfItem item = model_->items()[running_index]; 1364 ash::ShelfItem item = model_->items()[running_index];
1356 DCHECK(item.type == ash::TYPE_WINDOWED_APP || 1365 DCHECK(item.type == ash::TYPE_WINDOWED_APP ||
1357 item.type == ash::TYPE_PLATFORM_APP); 1366 item.type == ash::TYPE_PLATFORM_APP);
1358 item.type = ash::TYPE_APP_SHORTCUT; 1367 item.type = ash::TYPE_APP_SHORTCUT;
1359 model_->Set(running_index, item); 1368 model_->Set(running_index, item);
1360 // The |ShelfModel|'s weight system might reposition the item to a 1369 // The |ShelfModel|'s weight system might reposition the item to a
1361 // new index, so we get the index again. 1370 // new index, so we get the index again.
1362 running_index = model_->ItemIndexByID(shelf_id); 1371 running_index = model_->ItemIndexByID(shelf_id);
1363 if (running_index < index) 1372 if (running_index < index)
1364 --index; 1373 --index;
1365 if (running_index != index) 1374 if (running_index != index)
1366 model_->Move(running_index, index); 1375 model_->Move(running_index, index);
1367 return index; 1376 return index;
1368 } 1377 }
1369 1378
1370 void ChromeLauncherController::UnpinRunningAppInternal(int index) { 1379 void ChromeLauncherControllerImpl::UnpinRunningAppInternal(int index) {
1371 DCHECK_GE(index, 0); 1380 DCHECK_GE(index, 0);
1372 ash::ShelfItem item = model_->items()[index]; 1381 ash::ShelfItem item = model_->items()[index];
1373 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); 1382 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT);
1374 item.type = ash::TYPE_WINDOWED_APP; 1383 item.type = ash::TYPE_WINDOWED_APP;
1375 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such 1384 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such
1376 // we have to check here what this was before it got a shortcut. 1385 // we have to check here what this was before it got a shortcut.
1377 LauncherItemController* controller = GetLauncherItemController(item.id); 1386 LauncherItemController* controller = GetLauncherItemController(item.id);
1378 if (controller && controller->type() == LauncherItemController::TYPE_APP) 1387 if (controller && controller->type() == LauncherItemController::TYPE_APP)
1379 item.type = ash::TYPE_PLATFORM_APP; 1388 item.type = ash::TYPE_PLATFORM_APP;
1380 model_->Set(index, item); 1389 model_->Set(index, item);
1381 } 1390 }
1382 1391
1383 void ChromeLauncherController::UpdateAppLaunchersFromPref() { 1392 void ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref() {
1384 // There are various functions which will trigger a |PersistPinnedState| call 1393 // There are various functions which will trigger a |PersistPinnedState| call
1385 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu 1394 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu
1386 // model which will use weights to re-arrange the icons to new positions. 1395 // model which will use weights to re-arrange the icons to new positions.
1387 // Since this function is meant to synchronize the "is state" with the 1396 // Since this function is meant to synchronize the "is state" with the
1388 // "sync state", it makes no sense to store any changes by this function back 1397 // "sync state", it makes no sense to store any changes by this function back
1389 // into the pref state. Therefore we tell |persistPinnedState| to ignore any 1398 // into the pref state. Therefore we tell |persistPinnedState| to ignore any
1390 // invocations while we are running. 1399 // invocations while we are running.
1391 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); 1400 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true);
1392 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( 1401 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs(
1393 profile_->GetPrefs(), launcher_controller_helper_.get()); 1402 profile_->GetPrefs(), launcher_controller_helper_.get());
(...skipping 19 matching lines...) Expand all
1413 const ash::ShelfItem& item(model_->items()[index]); 1422 const ash::ShelfItem& item(model_->items()[index]);
1414 bool is_app_list = item.type == ash::TYPE_APP_LIST; 1423 bool is_app_list = item.type == ash::TYPE_APP_LIST;
1415 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT; 1424 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT;
1416 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome) 1425 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome)
1417 continue; 1426 continue;
1418 LauncherItemController* controller = GetLauncherItemController(item.id); 1427 LauncherItemController* controller = GetLauncherItemController(item.id);
1419 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) || 1428 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) ||
1420 (extension_misc::kChromeAppId == *pref_app_id && is_chrome) || 1429 (extension_misc::kChromeAppId == *pref_app_id && is_chrome) ||
1421 (controller && controller->app_id() == *pref_app_id)) { 1430 (controller && controller->app_id() == *pref_app_id)) {
1422 // Check if an item needs to be moved here. 1431 // Check if an item needs to be moved here.
1423 MoveChromeOrApplistToFinalPosition( 1432 MoveChromeOrApplistToFinalPosition(is_chrome, is_app_list, index,
1424 is_chrome, is_app_list, index, &chrome_index, &app_list_index); 1433 &chrome_index, &app_list_index);
1425 ++pref_app_id; 1434 ++pref_app_id;
1426 break; 1435 break;
1427 } else { 1436 } else {
1428 if (is_chrome || is_app_list) { 1437 if (is_chrome || is_app_list) {
1429 // We cannot delete any of these shortcuts. As such we remember 1438 // We cannot delete any of these shortcuts. As such we remember
1430 // their positions and move them later where they belong. 1439 // their positions and move them later where they belong.
1431 if (is_chrome) 1440 if (is_chrome)
1432 chrome_index = index; 1441 chrome_index = index;
1433 else 1442 else
1434 app_list_index = index; 1443 app_list_index = index;
1435 // And skip the item - or exit the loop if end is reached (note that 1444 // And skip the item - or exit the loop if end is reached (note that
1436 // in that case we will reduce the index again by one and this only 1445 // in that case we will reduce the index again by one and this only
1437 // compensates for it). 1446 // compensates for it).
1438 if (index >= max_index - 1) 1447 if (index >= max_index - 1)
1439 break; 1448 break;
1440 ++index; 1449 ++index;
1441 } else { 1450 } else {
1442 // Check if this is a platform or a windowed app. 1451 // Check if this is a platform or a windowed app.
1443 if (item.type == ash::TYPE_APP_SHORTCUT && 1452 if (item.type == ash::TYPE_APP_SHORTCUT && controller &&
1444 controller &&
1445 (controller->locked() || 1453 (controller->locked() ||
1446 controller->type() == LauncherItemController::TYPE_APP)) { 1454 controller->type() == LauncherItemController::TYPE_APP)) {
1447 // Note: This will not change the amount of items (|max_index|). 1455 // Note: This will not change the amount of items (|max_index|).
1448 // Even changes to the actual |index| due to item weighting 1456 // Even changes to the actual |index| due to item weighting
1449 // changes should be fine. 1457 // changes should be fine.
1450 UnpinRunningAppInternal(index); 1458 UnpinRunningAppInternal(index);
1451 } else { 1459 } else {
1452 if (controller) 1460 if (controller)
1453 LauncherItemClosed(item.id); 1461 LauncherItemClosed(item.id);
1454 --max_index; 1462 --max_index;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 int source_index = model_->ItemIndexByID(id); 1522 int source_index = model_->ItemIndexByID(id);
1515 if (source_index != target_index) 1523 if (source_index != target_index)
1516 model_->Move(source_index, target_index); 1524 model_->Move(source_index, target_index);
1517 1525
1518 // Needed for the old layout - the weight might force it to be lower in 1526 // Needed for the old layout - the weight might force it to be lower in
1519 // rank. 1527 // rank.
1520 if (app_list_index != -1 && target_index <= app_list_index) 1528 if (app_list_index != -1 && target_index <= app_list_index)
1521 ++app_list_index; 1529 ++app_list_index;
1522 } else { 1530 } else {
1523 int target_index = FindInsertionPoint(is_app_list); 1531 int target_index = FindInsertionPoint(is_app_list);
1524 MoveChromeOrApplistToFinalPosition( 1532 MoveChromeOrApplistToFinalPosition(is_chrome, is_app_list, target_index,
1525 is_chrome, is_app_list, target_index, &chrome_index, &app_list_index); 1533 &chrome_index, &app_list_index);
1526 } 1534 }
1527 } 1535 }
1528 } 1536 }
1529 1537
1530 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { 1538 void ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs() {
1531 for (auto* window : ash::Shell::GetAllRootWindows()) { 1539 for (auto* window : ash::Shell::GetAllRootWindows()) {
1532 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1540 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1533 if (shelf) { 1541 if (shelf) {
1534 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( 1542 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(
1535 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); 1543 profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
1536 } 1544 }
1537 } 1545 }
1538 } 1546 }
1539 1547
1540 void ChromeLauncherController::SetShelfAlignmentFromPrefs() { 1548 void ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs() {
1541 if (!ash::ShelfWidget::ShelfAlignmentAllowed()) 1549 if (!ash::ShelfWidget::ShelfAlignmentAllowed())
1542 return; 1550 return;
1543 1551
1544 for (auto* window : ash::Shell::GetAllRootWindows()) { 1552 for (auto* window : ash::Shell::GetAllRootWindows()) {
1545 ash::Shelf* shelf = ash::Shelf::ForWindow(window); 1553 ash::Shelf* shelf = ash::Shelf::ForWindow(window);
1546 if (shelf) { 1554 if (shelf) {
1547 shelf->SetAlignment(ash::GetShelfAlignmentPref( 1555 shelf->SetAlignment(ash::GetShelfAlignmentPref(
1548 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); 1556 profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
1549 } 1557 }
1550 } 1558 }
1551 } 1559 }
1552 1560
1553 void ChromeLauncherController::SetShelfBehaviorsFromPrefs() { 1561 void ChromeLauncherControllerImpl::SetShelfBehaviorsFromPrefs() {
1554 SetShelfAutoHideBehaviorFromPrefs(); 1562 SetShelfAutoHideBehaviorFromPrefs();
1555 SetShelfAlignmentFromPrefs(); 1563 SetShelfAlignmentFromPrefs();
1556 } 1564 }
1557 1565
1558 void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() { 1566 void ChromeLauncherControllerImpl::SetVirtualKeyboardBehaviorFromPrefs() {
1559 const PrefService* service = profile_->GetPrefs(); 1567 const PrefService* service = profile_->GetPrefs();
1560 const bool was_enabled = keyboard::IsKeyboardEnabled(); 1568 const bool was_enabled = keyboard::IsKeyboardEnabled();
1561 if (!service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) { 1569 if (!service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) {
1562 keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE); 1570 keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE);
1563 } else { 1571 } else {
1564 const bool enable = service->GetBoolean( 1572 const bool enable =
1565 prefs::kTouchVirtualKeyboardEnabled); 1573 service->GetBoolean(prefs::kTouchVirtualKeyboardEnabled);
1566 keyboard::SetKeyboardShowOverride( 1574 keyboard::SetKeyboardShowOverride(
1567 enable ? keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED 1575 enable ? keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED
1568 : keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED); 1576 : keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED);
1569 } 1577 }
1570 const bool is_enabled = keyboard::IsKeyboardEnabled(); 1578 const bool is_enabled = keyboard::IsKeyboardEnabled();
1571 if (was_enabled && !is_enabled) 1579 if (was_enabled && !is_enabled)
1572 ash::Shell::GetInstance()->DeactivateKeyboard(); 1580 ash::Shell::GetInstance()->DeactivateKeyboard();
1573 else if (is_enabled && !was_enabled) 1581 else if (is_enabled && !was_enabled)
1574 ash::Shell::GetInstance()->CreateKeyboard(); 1582 ash::Shell::GetInstance()->CreateKeyboard();
1575 } 1583 }
1576 1584
1577 ash::ShelfItemStatus ChromeLauncherController::GetAppState( 1585 ash::ShelfItemStatus ChromeLauncherControllerImpl::GetAppState(
1578 const std::string& app_id) { 1586 const std::string& app_id) {
1579 ash::ShelfItemStatus status = ash::STATUS_CLOSED; 1587 ash::ShelfItemStatus status = ash::STATUS_CLOSED;
1580 for (WebContentsToAppIDMap::iterator it = web_contents_to_app_id_.begin(); 1588 for (WebContentsToAppIDMap::iterator it = web_contents_to_app_id_.begin();
1581 it != web_contents_to_app_id_.end(); 1589 it != web_contents_to_app_id_.end(); ++it) {
1582 ++it) {
1583 if (it->second == app_id) { 1590 if (it->second == app_id) {
1584 Browser* browser = chrome::FindBrowserWithWebContents(it->first); 1591 Browser* browser = chrome::FindBrowserWithWebContents(it->first);
1585 // Usually there should never be an item in our |web_contents_to_app_id_| 1592 // Usually there should never be an item in our |web_contents_to_app_id_|
1586 // list which got deleted already. However - in some situations e.g. 1593 // list which got deleted already. However - in some situations e.g.
1587 // Browser::SwapTabContent there is temporarily no associated browser. 1594 // Browser::SwapTabContent there is temporarily no associated browser.
1588 if (!browser) 1595 if (!browser)
1589 continue; 1596 continue;
1590 if (browser->window()->IsActive()) { 1597 if (browser->window()->IsActive()) {
1591 return browser->tab_strip_model()->GetActiveWebContents() == it->first ? 1598 return browser->tab_strip_model()->GetActiveWebContents() == it->first
1592 ash::STATUS_ACTIVE : ash::STATUS_RUNNING; 1599 ? ash::STATUS_ACTIVE
1600 : ash::STATUS_RUNNING;
1593 } else { 1601 } else {
1594 status = ash::STATUS_RUNNING; 1602 status = ash::STATUS_RUNNING;
1595 } 1603 }
1596 } 1604 }
1597 } 1605 }
1598 return status; 1606 return status;
1599 } 1607 }
1600 1608
1601 ash::ShelfID ChromeLauncherController::InsertAppLauncherItem( 1609 ash::ShelfID ChromeLauncherControllerImpl::InsertAppLauncherItem(
1602 LauncherItemController* controller, 1610 LauncherItemController* controller,
1603 const std::string& app_id, 1611 const std::string& app_id,
1604 ash::ShelfItemStatus status, 1612 ash::ShelfItemStatus status,
1605 int index, 1613 int index,
1606 ash::ShelfItemType shelf_item_type) { 1614 ash::ShelfItemType shelf_item_type) {
1607 ash::ShelfID id = model_->next_id(); 1615 ash::ShelfID id = model_->next_id();
1608 CHECK(!HasShelfIDToAppIDMapping(id)); 1616 CHECK(!HasShelfIDToAppIDMapping(id));
1609 CHECK(controller); 1617 CHECK(controller);
1610 id_to_item_controller_map_[id] = controller; 1618 id_to_item_controller_map_[id] = controller;
1611 controller->set_shelf_id(id); 1619 controller->set_shelf_id(id);
(...skipping 15 matching lines...) Expand all
1627 app_icon_loader->FetchImage(app_id); 1635 app_icon_loader->FetchImage(app_id);
1628 app_icon_loader->UpdateImage(app_id); 1636 app_icon_loader->UpdateImage(app_id);
1629 } 1637 }
1630 1638
1631 SetShelfItemDelegate(id, controller); 1639 SetShelfItemDelegate(id, controller);
1632 1640
1633 return id; 1641 return id;
1634 } 1642 }
1635 1643
1636 std::vector<content::WebContents*> 1644 std::vector<content::WebContents*>
1637 ChromeLauncherController::GetV1ApplicationsFromController( 1645 ChromeLauncherControllerImpl::GetV1ApplicationsFromController(
1638 LauncherItemController* controller) { 1646 LauncherItemController* controller) {
1639 DCHECK(controller->type() == LauncherItemController::TYPE_SHORTCUT); 1647 DCHECK(controller->type() == LauncherItemController::TYPE_SHORTCUT);
1640 AppShortcutLauncherItemController* app_controller = 1648 AppShortcutLauncherItemController* app_controller =
1641 static_cast<AppShortcutLauncherItemController*>(controller); 1649 static_cast<AppShortcutLauncherItemController*>(controller);
1642 return app_controller->GetRunningApplications(); 1650 return app_controller->GetRunningApplications();
1643 } 1651 }
1644 1652
1645 BrowserShortcutLauncherItemController* 1653 BrowserShortcutLauncherItemController*
1646 ChromeLauncherController::GetBrowserShortcutLauncherItemController() { 1654 ChromeLauncherControllerImpl::GetBrowserShortcutLauncherItemController() {
1647 for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin(); 1655 for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin();
1648 i != id_to_item_controller_map_.end(); ++i) { 1656 i != id_to_item_controller_map_.end(); ++i) {
1649 int index = model_->ItemIndexByID(i->first); 1657 int index = model_->ItemIndexByID(i->first);
1650 const ash::ShelfItem& item = model_->items()[index]; 1658 const ash::ShelfItem& item = model_->items()[index];
1651 if (item.type == ash::TYPE_BROWSER_SHORTCUT) 1659 if (item.type == ash::TYPE_BROWSER_SHORTCUT)
1652 return static_cast<BrowserShortcutLauncherItemController*>(i->second); 1660 return static_cast<BrowserShortcutLauncherItemController*>(i->second);
1653 } 1661 }
1654 NOTREACHED() 1662 NOTREACHED()
1655 << "There should be always be a BrowserShortcutLauncherItemController."; 1663 << "There should be always be a BrowserShortcutLauncherItemController.";
1656 return nullptr; 1664 return nullptr;
1657 } 1665 }
1658 1666
1659 ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { 1667 ash::ShelfID ChromeLauncherControllerImpl::CreateBrowserShortcutLauncherItem() {
1660 ash::ShelfItem browser_shortcut; 1668 ash::ShelfItem browser_shortcut;
1661 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; 1669 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT;
1662 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1670 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1663 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); 1671 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32);
1664 ash::ShelfID id = model_->next_id(); 1672 ash::ShelfID id = model_->next_id();
1665 size_t index = GetChromeIconIndexForCreation(); 1673 size_t index = GetChromeIconIndexForCreation();
1666 model_->AddAt(index, browser_shortcut); 1674 model_->AddAt(index, browser_shortcut);
1667 id_to_item_controller_map_[id] = 1675 id_to_item_controller_map_[id] =
1668 new BrowserShortcutLauncherItemController(this, model_); 1676 new BrowserShortcutLauncherItemController(this, model_);
1669 id_to_item_controller_map_[id]->set_shelf_id(id); 1677 id_to_item_controller_map_[id]->set_shelf_id(id);
1670 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. 1678 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController.
1671 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); 1679 SetShelfItemDelegate(id, id_to_item_controller_map_[id]);
1672 return id; 1680 return id;
1673 } 1681 }
1674 1682
1675 void ChromeLauncherController::PersistChromeItemIndex(int index) { 1683 void ChromeLauncherControllerImpl::PersistChromeItemIndex(int index) {
1676 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); 1684 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index);
1677 } 1685 }
1678 1686
1679 void ChromeLauncherController::MoveChromeOrApplistToFinalPosition( 1687 void ChromeLauncherControllerImpl::MoveChromeOrApplistToFinalPosition(
1680 bool is_chrome, 1688 bool is_chrome,
1681 bool is_app_list, 1689 bool is_app_list,
1682 int target_index, 1690 int target_index,
1683 int* chrome_index, 1691 int* chrome_index,
1684 int* app_list_index) { 1692 int* app_list_index) {
1685 if (is_chrome && *chrome_index != -1) { 1693 if (is_chrome && *chrome_index != -1) {
1686 model_->Move(*chrome_index, target_index); 1694 model_->Move(*chrome_index, target_index);
1687 if (*app_list_index != -1 && 1695 if (*app_list_index != -1 && *chrome_index < *app_list_index &&
1688 *chrome_index < *app_list_index &&
1689 target_index > *app_list_index) 1696 target_index > *app_list_index)
1690 --(*app_list_index); 1697 --(*app_list_index);
1691 *chrome_index = -1; 1698 *chrome_index = -1;
1692 } else if (is_app_list && *app_list_index != -1) { 1699 } else if (is_app_list && *app_list_index != -1) {
1693 model_->Move(*app_list_index, target_index); 1700 model_->Move(*app_list_index, target_index);
1694 if (*chrome_index != -1 && 1701 if (*chrome_index != -1 && *app_list_index < *chrome_index &&
1695 *app_list_index < *chrome_index &&
1696 target_index > *chrome_index) 1702 target_index > *chrome_index)
1697 --(*chrome_index); 1703 --(*chrome_index);
1698 *app_list_index = -1; 1704 *app_list_index = -1;
1699 } 1705 }
1700 } 1706 }
1701 1707
1702 int ChromeLauncherController::FindInsertionPoint(bool is_app_list) { 1708 int ChromeLauncherControllerImpl::FindInsertionPoint(bool is_app_list) {
1703 // Keeping this change small to backport to M33&32 (see crbug.com/329597). 1709 // Keeping this change small to backport to M33&32 (see crbug.com/329597).
1704 // TODO(skuhne): With the removal of the legacy shelf layout we should remove 1710 // TODO(skuhne): With the removal of the legacy shelf layout we should remove
1705 // the ability to move the app list item since this was never used. We should 1711 // the ability to move the app list item since this was never used. We should
1706 // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index. 1712 // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index.
1707 if (is_app_list) 1713 if (is_app_list)
1708 return 0; 1714 return 0;
1709 1715
1710 for (int i = model_->item_count() - 1; i > 0; --i) { 1716 for (int i = model_->item_count() - 1; i > 0; --i) {
1711 ash::ShelfItemType type = model_->items()[i].type; 1717 ash::ShelfItemType type = model_->items()[i].type;
1712 if (type == ash::TYPE_APP_SHORTCUT || 1718 if (type == ash::TYPE_APP_SHORTCUT ||
1713 (is_app_list && type == ash::TYPE_APP_LIST) || 1719 (is_app_list && type == ash::TYPE_APP_LIST) ||
1714 type == ash::TYPE_BROWSER_SHORTCUT) { 1720 type == ash::TYPE_BROWSER_SHORTCUT) {
1715 return i; 1721 return i;
1716 } 1722 }
1717 } 1723 }
1718 return 0; 1724 return 0;
1719 } 1725 }
1720 1726
1721 int ChromeLauncherController::GetChromeIconIndexForCreation() { 1727 int ChromeLauncherControllerImpl::GetChromeIconIndexForCreation() {
1722 // We get the list of pinned apps as they currently would get pinned. 1728 // We get the list of pinned apps as they currently would get pinned.
1723 // Within this list the chrome icon will be the correct location. 1729 // Within this list the chrome icon will be the correct location.
1724 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( 1730 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs(
1725 profile_->GetPrefs(), launcher_controller_helper_.get()); 1731 profile_->GetPrefs(), launcher_controller_helper_.get());
1726 1732
1727 std::vector<std::string>::iterator it = 1733 std::vector<std::string>::iterator it =
1728 std::find(pinned_apps.begin(), 1734 std::find(pinned_apps.begin(), pinned_apps.end(),
1729 pinned_apps.end(),
1730 std::string(extension_misc::kChromeAppId)); 1735 std::string(extension_misc::kChromeAppId));
1731 DCHECK(it != pinned_apps.end()); 1736 DCHECK(it != pinned_apps.end());
1732 int index = it - pinned_apps.begin(); 1737 int index = it - pinned_apps.begin();
1733 1738
1734 // We should do here a comparison between the is state and the "want to be" 1739 // We should do here a comparison between the is state and the "want to be"
1735 // state since some apps might be able to pin but are not yet. Instead - for 1740 // state since some apps might be able to pin but are not yet. Instead - for
1736 // the time being we clamp against the amount of known items and wait for the 1741 // the time being we clamp against the amount of known items and wait for the
1737 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since 1742 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since
1738 // the pinning will be done then. 1743 // the pinning will be done then.
1739 return std::min(model_->item_count(), index); 1744 return std::min(model_->item_count(), index);
1740 } 1745 }
1741 1746
1742 bool ChromeLauncherController::IsIncognito( 1747 bool ChromeLauncherControllerImpl::IsIncognito(
1743 const content::WebContents* web_contents) const { 1748 const content::WebContents* web_contents) const {
1744 const Profile* profile = 1749 const Profile* profile =
1745 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 1750 Profile::FromBrowserContext(web_contents->GetBrowserContext());
1746 return profile->IsOffTheRecord() && !profile->IsGuestSession() && 1751 return profile->IsOffTheRecord() && !profile->IsGuestSession() &&
1747 !profile->IsSystemProfile(); 1752 !profile->IsSystemProfile();
1748 } 1753 }
1749 1754
1750 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( 1755 void ChromeLauncherControllerImpl::CloseWindowedAppsFromRemovedExtension(
1751 const std::string& app_id, 1756 const std::string& app_id,
1752 const Profile* profile) { 1757 const Profile* profile) {
1753 // This function cannot rely on the controller's enumeration functionality 1758 // This function cannot rely on the controller's enumeration functionality
1754 // since the extension has already be unloaded. 1759 // since the extension has already be unloaded.
1755 const BrowserList* browser_list = BrowserList::GetInstance(); 1760 const BrowserList* browser_list = BrowserList::GetInstance();
1756 std::vector<Browser*> browser_to_close; 1761 std::vector<Browser*> browser_to_close;
1757 for (BrowserList::const_reverse_iterator it = 1762 for (BrowserList::const_reverse_iterator it =
1758 browser_list->begin_last_active(); 1763 browser_list->begin_last_active();
1759 it != browser_list->end_last_active(); ++it) { 1764 it != browser_list->end_last_active(); ++it) {
1760 Browser* browser = *it; 1765 Browser* browser = *it;
1761 if (!browser->is_type_tabbed() && browser->is_type_popup() && 1766 if (!browser->is_type_tabbed() && browser->is_type_popup() &&
1762 browser->is_app() && 1767 browser->is_app() &&
1763 app_id == 1768 app_id ==
1764 web_app::GetExtensionIdFromApplicationName(browser->app_name()) && 1769 web_app::GetExtensionIdFromApplicationName(browser->app_name()) &&
1765 profile == browser->profile()) { 1770 profile == browser->profile()) {
1766 browser_to_close.push_back(browser); 1771 browser_to_close.push_back(browser);
1767 } 1772 }
1768 } 1773 }
1769 while (!browser_to_close.empty()) { 1774 while (!browser_to_close.empty()) {
1770 TabStripModel* tab_strip = browser_to_close.back()->tab_strip_model(); 1775 TabStripModel* tab_strip = browser_to_close.back()->tab_strip_model();
1771 tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE); 1776 tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
1772 browser_to_close.pop_back(); 1777 browser_to_close.pop_back();
1773 } 1778 }
1774 } 1779 }
1775 1780
1776 void ChromeLauncherController::SetShelfItemDelegate( 1781 void ChromeLauncherControllerImpl::SetShelfItemDelegate(
1777 ash::ShelfID id, 1782 ash::ShelfID id,
1778 ash::ShelfItemDelegate* item_delegate) { 1783 ash::ShelfItemDelegate* item_delegate) {
1779 DCHECK_GT(id, 0); 1784 DCHECK_GT(id, 0);
1780 DCHECK(item_delegate); 1785 DCHECK(item_delegate);
1781 DCHECK(item_delegate_manager_); 1786 DCHECK(item_delegate_manager_);
1782 item_delegate_manager_->SetShelfItemDelegate( 1787 item_delegate_manager_->SetShelfItemDelegate(
1783 id, std::unique_ptr<ash::ShelfItemDelegate>(item_delegate)); 1788 id, std::unique_ptr<ash::ShelfItemDelegate>(item_delegate));
1784 } 1789 }
1785 1790
1786 void ChromeLauncherController::AttachProfile(Profile* profile) { 1791 void ChromeLauncherControllerImpl::AttachProfile(Profile* profile) {
1787 profile_ = profile; 1792 profile_ = profile;
1788 // Either add the profile to the list of known profiles and make it the active 1793 // Either add the profile to the list of known profiles and make it the active
1789 // one for some functions of LauncherControllerHelper or create a new one. 1794 // one for some functions of LauncherControllerHelper or create a new one.
1790 if (!launcher_controller_helper_.get()) 1795 if (!launcher_controller_helper_.get())
1791 launcher_controller_helper_.reset(new LauncherControllerHelper(profile_)); 1796 launcher_controller_helper_.reset(new LauncherControllerHelper(profile_));
1792 else 1797 else
1793 launcher_controller_helper_->SetCurrentUser(profile_); 1798 launcher_controller_helper_->SetCurrentUser(profile_);
1794 // TODO(skuhne): The AppIconLoaderImpl has the same problem. Each loaded 1799 // TODO(skuhne): The AppIconLoaderImpl has the same problem. Each loaded
1795 // image is associated with a profile (its loader requires the profile). 1800 // image is associated with a profile (its loader requires the profile).
1796 // Since icon size changes are possible, the icon could be requested to be 1801 // Since icon size changes are possible, the icon could be requested to be
1797 // reloaded. However - having it not multi profile aware would cause problems 1802 // reloaded. However - having it not multi profile aware would cause problems
1798 // if the icon cache gets deleted upon user switch. 1803 // if the icon cache gets deleted upon user switch.
1799 std::unique_ptr<AppIconLoader> extension_app_icon_loader( 1804 std::unique_ptr<AppIconLoader> extension_app_icon_loader(
1800 new extensions::ExtensionAppIconLoader( 1805 new extensions::ExtensionAppIconLoader(
1801 profile_, extension_misc::EXTENSION_ICON_SMALL, this)); 1806 profile_, extension_misc::EXTENSION_ICON_SMALL, this));
1802 app_icon_loaders_.push_back(std::move(extension_app_icon_loader)); 1807 app_icon_loaders_.push_back(std::move(extension_app_icon_loader));
1803 1808
1804 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { 1809 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
1805 DCHECK(arc_deferred_launcher()); 1810 DCHECK(arc_deferred_launcher_.get());
1806 std::unique_ptr<AppIconLoader> arc_app_icon_loader( 1811 std::unique_ptr<AppIconLoader> arc_app_icon_loader(
1807 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, 1812 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL,
1808 arc_deferred_launcher(), this)); 1813 arc_deferred_launcher_.get(), this));
1809 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); 1814 app_icon_loaders_.push_back(std::move(arc_app_icon_loader));
1810 } 1815 }
1811 1816
1812 pref_change_registrar_.Init(profile_->GetPrefs()); 1817 pref_change_registrar_.Init(profile_->GetPrefs());
1813 pref_change_registrar_.Add( 1818 pref_change_registrar_.Add(
1814 prefs::kPinnedLauncherApps, 1819 prefs::kPinnedLauncherApps,
1815 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 1820 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
1816 base::Unretained(this))); 1821 base::Unretained(this)));
1817 pref_change_registrar_.Add( 1822 pref_change_registrar_.Add(
1818 prefs::kPolicyPinnedLauncherApps, 1823 prefs::kPolicyPinnedLauncherApps,
1819 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, 1824 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref,
1820 base::Unretained(this))); 1825 base::Unretained(this)));
1821 pref_change_registrar_.Add( 1826 pref_change_registrar_.Add(
1822 prefs::kShelfAlignmentLocal, 1827 prefs::kShelfAlignmentLocal,
1823 base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs, 1828 base::Bind(&ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs,
1824 base::Unretained(this))); 1829 base::Unretained(this)));
1825 pref_change_registrar_.Add( 1830 pref_change_registrar_.Add(
1826 prefs::kShelfAutoHideBehaviorLocal, 1831 prefs::kShelfAutoHideBehaviorLocal,
1827 base::Bind(&ChromeLauncherController:: 1832 base::Bind(
1828 SetShelfAutoHideBehaviorFromPrefs, 1833 &ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs,
1829 base::Unretained(this))); 1834 base::Unretained(this)));
1830 pref_change_registrar_.Add( 1835 pref_change_registrar_.Add(
1831 prefs::kShelfPreferences, 1836 prefs::kShelfPreferences,
1832 base::Bind(&ChromeLauncherController::SetShelfBehaviorsFromPrefs, 1837 base::Bind(&ChromeLauncherControllerImpl::SetShelfBehaviorsFromPrefs,
1833 base::Unretained(this))); 1838 base::Unretained(this)));
1834 pref_change_registrar_.Add( 1839 pref_change_registrar_.Add(
1835 prefs::kTouchVirtualKeyboardEnabled, 1840 prefs::kTouchVirtualKeyboardEnabled,
1836 base::Bind(&ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs, 1841 base::Bind(
1837 base::Unretained(this))); 1842 &ChromeLauncherControllerImpl::SetVirtualKeyboardBehaviorFromPrefs,
1843 base::Unretained(this)));
1838 1844
1839 std::unique_ptr<LauncherAppUpdater> extension_app_updater( 1845 std::unique_ptr<LauncherAppUpdater> extension_app_updater(
1840 new LauncherExtensionAppUpdater(this, profile_)); 1846 new LauncherExtensionAppUpdater(this, profile_));
1841 app_updaters_.push_back(std::move(extension_app_updater)); 1847 app_updaters_.push_back(std::move(extension_app_updater));
1842 1848
1843 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { 1849 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
1844 std::unique_ptr<LauncherAppUpdater> arc_app_updater( 1850 std::unique_ptr<LauncherAppUpdater> arc_app_updater(
1845 new LauncherArcAppUpdater(this, profile_)); 1851 new LauncherArcAppUpdater(this, profile_));
1846 app_updaters_.push_back(std::move(arc_app_updater)); 1852 app_updaters_.push_back(std::move(arc_app_updater));
1847 } 1853 }
1848 } 1854 }
1849 1855
1850 void ChromeLauncherController::ReleaseProfile() { 1856 void ChromeLauncherControllerImpl::ReleaseProfile() {
1851 if (app_sync_ui_state_) 1857 if (app_sync_ui_state_)
1852 app_sync_ui_state_->RemoveObserver(this); 1858 app_sync_ui_state_->RemoveObserver(this);
1853 1859
1854 app_updaters_.clear(); 1860 app_updaters_.clear();
1855 1861
1856 prefs_observer_.reset(); 1862 prefs_observer_.reset();
1857 1863
1858 pref_change_registrar_.RemoveAll(); 1864 pref_change_registrar_.RemoveAll();
1859 } 1865 }
1860 1866
1861 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( 1867 AppIconLoader* ChromeLauncherControllerImpl::GetAppIconLoaderForApp(
1862 const std::string& app_id) { 1868 const std::string& app_id) {
1863 for (const auto& app_icon_loader : app_icon_loaders_) { 1869 for (const auto& app_icon_loader : app_icon_loaders_) {
1864 if (app_icon_loader->CanLoadImageForApp(app_id)) 1870 if (app_icon_loader->CanLoadImageForApp(app_id))
1865 return app_icon_loader.get(); 1871 return app_icon_loader.get();
1866 } 1872 }
1867 1873
1868 return nullptr; 1874 return nullptr;
1869 } 1875 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698