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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_APP_MANAGER_H_
6#define CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_APP_MANAGER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/callback_forward.h"
13#include "base/lazy_instance.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/scoped_vector.h"
16#include "base/observer_list.h"
17#include "chrome/browser/chromeos/app_mode/kiosk_app_data_delegate.h"
18#include "chrome/browser/chromeos/extensions/external_cache.h"
19#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
20#include "chrome/browser/chromeos/settings/cros_settings.h"
21#include "ui/gfx/image/image_skia.h"
22
23class PrefRegistrySimple;
24class Profile;
25
26namespace base {
27class RefCountedString;
28}
29
30namespace extensions {
31class Extension;
32class ExternalLoader;
33}
34
35namespace chromeos {
36
37class KioskAppData;
38class KioskAppExternalLoader;
39class KioskAppManagerObserver;
40class KioskExternalUpdater;
41
42// KioskAppManager manages cached app data.
43class KioskAppManager : public KioskAppDataDelegate,
44                        public ExternalCache::Delegate {
45 public:
46  enum ConsumerKioskAutoLaunchStatus {
47    // Consumer kiosk mode auto-launch feature can be enabled on this machine.
48    CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE,
49    // Consumer kiosk auto-launch feature is enabled on this machine.
50    CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED,
51    // Consumer kiosk mode auto-launch feature is disabled and cannot any longer
52    // be enabled on this machine.
53    CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED,
54  };
55
56  typedef base::Callback<void(bool success)> EnableKioskAutoLaunchCallback;
57  typedef base::Callback<void(ConsumerKioskAutoLaunchStatus status)>
58      GetConsumerKioskAutoLaunchStatusCallback;
59
60  // Struct to hold app info returned from GetApps() call.
61  struct App {
62    App(const KioskAppData& data, bool is_extension_pending);
63    App();
64    ~App();
65
66    std::string app_id;
67    std::string user_id;
68    std::string name;
69    gfx::ImageSkia icon;
70    bool is_loading;
71  };
72  typedef std::vector<App> Apps;
73
74  // Name of a dictionary that holds kiosk app info in Local State.
75  // Sample layout:
76  //   "kiosk": {
77  //     "auto_login_enabled": true  //
78  //   }
79  static const char kKioskDictionaryName[];
80  static const char kKeyApps[];
81  static const char kKeyAutoLoginState[];
82
83  // Sub directory under DIR_USER_DATA to store cached icon files.
84  static const char kIconCacheDir[];
85
86  // Sub directory under DIR_USER_DATA to store cached crx files.
87  static const char kCrxCacheDir[];
88
89  // Sub directory under DIR_USER_DATA to store unpacked crx file for validating
90  // its signature.
91  static const char kCrxUnpackDir[];
92
93  // Gets the KioskAppManager instance, which is lazily created on first call..
94  static KioskAppManager* Get();
95
96  // Prepares for shutdown and calls CleanUp() if needed.
97  static void Shutdown();
98
99  // Registers kiosk app entries in local state.
100  static void RegisterPrefs(PrefRegistrySimple* registry);
101
102  // Initiates reading of consumer kiosk mode auto-launch status.
103  void GetConsumerKioskAutoLaunchStatus(
104      const GetConsumerKioskAutoLaunchStatusCallback& callback);
105
106  // Enables consumer kiosk mode app auto-launch feature. Upon completion,
107  // |callback| will be invoked with outcome of this operation.
108  void EnableConsumerKioskAutoLaunch(
109      const EnableKioskAutoLaunchCallback& callback);
110
111  // Returns true if this device is consumer kiosk auto launch enabled.
112  bool IsConsumerKioskDeviceWithAutoLaunch();
113
114  // Returns auto launcher app id or an empty string if there is none.
115  std::string GetAutoLaunchApp() const;
116
117  // Sets |app_id| as the app to auto launch at start up.
118  void SetAutoLaunchApp(const std::string& app_id);
119
120  // Returns true if there is a pending auto-launch request.
121  bool IsAutoLaunchRequested() const;
122
123  // Returns true if owner/policy enabled auto launch.
124  bool IsAutoLaunchEnabled() const;
125
126  // Enable auto launch setter.
127  void SetEnableAutoLaunch(bool value);
128
129  // Adds/removes a kiosk app by id. When removed, all locally cached data
130  // will be removed as well.
131  void AddApp(const std::string& app_id);
132  void RemoveApp(const std::string& app_id);
133
134  // Gets info of all apps that have no meta data load error.
135  void GetApps(Apps* apps) const;
136
137  // Gets app data for the given app id. Returns true if |app_id| is known and
138  // |app| is populated. Otherwise, return false.
139  bool GetApp(const std::string& app_id, App* app) const;
140
141  // Gets the raw icon data for the given app id. Returns NULL if |app_id|
142  // is unknown.
143  const base::RefCountedString* GetAppRawIcon(const std::string& app_id) const;
144
145  // Gets whether the bailout shortcut is disabled.
146  bool GetDisableBailoutShortcut() const;
147
148  // Clears locally cached app data.
149  void ClearAppData(const std::string& app_id);
150
151  // Updates app data from the |app| in |profile|. |app| is provided to cover
152  // the case of app update case where |app| is the new version and is not
153  // finished installing (e.g. because old version is still running). Otherwise,
154  // |app| could be NULL and the current installed app in |profile| will be
155  // used.
156  void UpdateAppDataFromProfile(const std::string& app_id,
157                                Profile* profile,
158                                const extensions::Extension* app);
159
160  void RetryFailedAppDataFetch();
161
162  // Returns true if the app is found in cache.
163  bool HasCachedCrx(const std::string& app_id) const;
164
165  // Gets the path and version of the cached crx with |app_id|.
166  // Returns true if the app is found in cache.
167  bool GetCachedCrx(const std::string& app_id,
168                    base::FilePath* file_path,
169                    std::string* version) const;
170
171  void AddObserver(KioskAppManagerObserver* observer);
172  void RemoveObserver(KioskAppManagerObserver* observer);
173
174  // Creates extensions::ExternalLoader for installing kiosk apps during their
175  // first time launch.
176  extensions::ExternalLoader* CreateExternalLoader();
177
178  // Installs kiosk app with |id| from cache.
179  void InstallFromCache(const std::string& id);
180
181  void UpdateExternalCache();
182
183  // Monitors kiosk external update from usb stick.
184  void MonitorKioskExternalUpdate();
185
186  // Invoked when kiosk app cache has been updated.
187  void OnKioskAppCacheUpdated(const std::string& app_id);
188
189  // Invoked when kiosk app updating from usb stick has been completed.
190  // |success| indicates if all the updates are completed successfully.
191  void OnKioskAppExternalUpdateComplete(bool success);
192
193  // Installs the validated external extension into cache.
194  void PutValidatedExternalExtension(
195      const std::string& app_id,
196      const base::FilePath& crx_path,
197      const std::string& version,
198      const ExternalCache::PutExternalExtensionCallback& callback);
199
200  bool external_loader_created() const { return external_loader_created_; }
201
202 private:
203  friend struct base::DefaultLazyInstanceTraits<KioskAppManager>;
204  friend struct base::DefaultDeleter<KioskAppManager>;
205  friend class KioskAppManagerTest;
206  friend class KioskTest;
207  friend class KioskUpdateTest;
208
209  enum AutoLoginState {
210    AUTOLOGIN_NONE      = 0,
211    AUTOLOGIN_REQUESTED = 1,
212    AUTOLOGIN_APPROVED  = 2,
213    AUTOLOGIN_REJECTED  = 3,
214  };
215
216  KioskAppManager();
217  virtual ~KioskAppManager();
218
219  // Stop all data loading and remove its dependency on CrosSettings.
220  void CleanUp();
221
222  // Gets KioskAppData for the given app id.
223  const KioskAppData* GetAppData(const std::string& app_id) const;
224  KioskAppData* GetAppDataMutable(const std::string& app_id);
225
226  // Updates app data |apps_| based on CrosSettings.
227  void UpdateAppData();
228
229  // KioskAppDataDelegate overrides:
230  virtual void GetKioskAppIconCacheDir(base::FilePath* cache_dir) OVERRIDE;
231  virtual void OnKioskAppDataChanged(const std::string& app_id) OVERRIDE;
232  virtual void OnKioskAppDataLoadFailure(const std::string& app_id) OVERRIDE;
233
234  // ExternalCache::Delegate:
235  virtual void OnExtensionListsUpdated(
236      const base::DictionaryValue* prefs) OVERRIDE;
237  virtual void OnExtensionLoadedInCache(const std::string& id) OVERRIDE;
238  virtual void OnExtensionDownloadFailed(
239      const std::string& id,
240      extensions::ExtensionDownloaderDelegate::Error error) OVERRIDE;
241
242  // Callback for EnterpriseInstallAttributes::LockDevice() during
243  // EnableConsumerModeKiosk() call.
244  void OnLockDevice(
245      const EnableKioskAutoLaunchCallback& callback,
246      policy::EnterpriseInstallAttributes::LockResult result);
247
248  // Callback for EnterpriseInstallAttributes::ReadImmutableAttributes() during
249  // GetConsumerKioskModeStatus() call.
250  void OnReadImmutableAttributes(
251      const GetConsumerKioskAutoLaunchStatusCallback& callback);
252
253  // Callback for reading handling checks of the owner public.
254  void OnOwnerFileChecked(
255      const GetConsumerKioskAutoLaunchStatusCallback& callback,
256      bool* owner_present);
257
258  // Reads/writes auto login state from/to local state.
259  AutoLoginState GetAutoLoginState() const;
260  void SetAutoLoginState(AutoLoginState state);
261
262  void GetCrxCacheDir(base::FilePath* cache_dir);
263  void GetCrxUnpackDir(base::FilePath* unpack_dir);
264
265  // True if machine ownership is already established.
266  bool ownership_established_;
267  ScopedVector<KioskAppData> apps_;
268  std::string auto_launch_app_id_;
269  ObserverList<KioskAppManagerObserver, true> observers_;
270
271  scoped_ptr<CrosSettings::ObserverSubscription>
272      local_accounts_subscription_;
273  scoped_ptr<CrosSettings::ObserverSubscription>
274      local_account_auto_login_id_subscription_;
275
276  scoped_ptr<ExternalCache> external_cache_;
277  scoped_ptr<KioskExternalUpdater> usb_stick_updater_;
278
279  // The extension external loader for installing kiosk app.
280  bool external_loader_created_;
281  base::WeakPtr<KioskAppExternalLoader> external_loader_;
282
283  DISALLOW_COPY_AND_ASSIGN(KioskAppManager);
284};
285
286}  // namespace chromeos
287
288#endif  // CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_APP_MANAGER_H_
289