| Index: chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc | 
| diff --git a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..f80798514732b4004aa8d978397371e47a25f939 | 
| --- /dev/null | 
| +++ b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.cc | 
| @@ -0,0 +1,87 @@ | 
| +// Copyright 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include <chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_launcher.h> | 
| + | 
| +#include "ash/wm/window_util.h" | 
| +#include "chrome/browser/ui/app_list/arc/arc_app_utils.h" | 
| +#include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" | 
| +#include "ui/aura/env.h" | 
| + | 
| +namespace chromeos { | 
| + | 
| +ArcKioskAppLauncher::ArcKioskAppLauncher(content::BrowserContext* context, | 
| +                                         const std::string& app_id) | 
| +    : app_id_(app_id) { | 
| +  prefs_ = ArcAppListPrefs::Get(context); | 
| +  prefs_->AddObserver(this); | 
| +  aura::Env::GetInstance()->AddObserver(this); | 
| +  // Launching the app by app id in landscape mode. | 
| +  arc::LaunchApp(context, app_id_); | 
| +} | 
| + | 
| +ArcKioskAppLauncher::~ArcKioskAppLauncher() { | 
| +  StopObserving(); | 
| +} | 
| + | 
| +void ArcKioskAppLauncher::OnTaskCreated(int32_t task_id, | 
| +                                        const std::string& package_name, | 
| +                                        const std::string& activity) { | 
| +  std::unique_ptr<ArcAppListPrefs::AppInfo> app = prefs_->GetApp(app_id_); | 
| +  if (!app || app->package_name != package_name || app->activity != activity) | 
| +    return; | 
| +  task_id_ = task_id; | 
| +  // The app window may have been created already. | 
| +  for (aura::Window* window : windows_) { | 
| +    if (CheckWindow(window)) | 
| +      break; | 
| +  } | 
| +} | 
| + | 
| +void ArcKioskAppLauncher::OnWindowInitialized(aura::Window* window) { | 
| +  // The |window|’s task ID is not set yet. We need to observe | 
| +  // the window until the |kApplicationIdKey| property is set. | 
| +  window->AddObserver(this); | 
| +  windows_.insert(window); | 
| +} | 
| + | 
| +void ArcKioskAppLauncher::OnWindowPropertyChanged(aura::Window* window, | 
| +                                                  const void* key, | 
| +                                                  intptr_t old) { | 
| +  // If we do not know yet what task ID to look for, do nothing. | 
| +  // Existing windows will be revisited the moment the task ID | 
| +  // becomes known. | 
| +  if (task_id_ == -1) | 
| +    return; | 
| + | 
| +  // We are only interested in changes to |kApplicationIdKey|, | 
| +  // but that constant is not accessible outside shell_surface.cc. | 
| +  // So we react to all property changes. | 
| +  CheckWindow(window); | 
| +} | 
| + | 
| +void ArcKioskAppLauncher::OnWindowDestroying(aura::Window* window) { | 
| +  window->RemoveObserver(this); | 
| +  windows_.erase(window); | 
| +} | 
| + | 
| +bool ArcKioskAppLauncher::CheckWindow(aura::Window* const window) { | 
| +  DCHECK_GE(task_id_, 0); | 
| +  if (ArcAppWindowLauncherController::GetWindowTaskId(window) != task_id_) | 
| +    return false; | 
| +  // Stop observing as target window is already found. | 
| +  StopObserving(); | 
| +  ash::wm::PinWindow(window, true /* trusted */); | 
| +  return true; | 
| +} | 
| + | 
| +void ArcKioskAppLauncher::StopObserving() { | 
| +  aura::Env::GetInstance()->RemoveObserver(this); | 
| +  for (auto* window : windows_) | 
| +    window->RemoveObserver(this); | 
| +  windows_.clear(); | 
| +  prefs_->RemoveObserver(this); | 
| +} | 
| + | 
| +}  // namespace chromeos | 
|  |