1 // Copyright 2014 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.
5 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_USERS_WALLPAPER_WALLPAPER_MANAGER_H_
6 #define CHROME_BROWSER_CHROMEOS_LOGIN_USERS_WALLPAPER_WALLPAPER_MANAGER_H_
12 #include "ash/desktop_background/desktop_background_controller.h"
13 #include "base/files/file_path.h"
14 #include "base/memory/ref_counted_memory.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/observer_list.h"
18 #include "base/threading/sequenced_worker_pool.h"
19 #include "base/time/time.h"
20 #include "chrome/browser/chromeos/login/users/avatar/user_image_loader.h"
21 #include "chrome/browser/chromeos/settings/cros_settings.h"
22 #include "components/user_manager/user.h"
23 #include "components/user_manager/user_image/user_image.h"
24 #include "content/public/browser/notification_observer.h"
25 #include "content/public/browser/notification_registrar.h"
26 #include "third_party/icu/source/i18n/unicode/timezone.h"
27 #include "ui/gfx/image/image_skia.h"
29 class PrefRegistrySimple;
33 class SequencedTaskRunner;
36 namespace user_manager {
43 struct WallpaperInfo {
44 // Either file name of migrated wallpaper including first directory level
45 // (corresponding to user id hash) or online wallpaper URL.
47 ash::WallpaperLayout layout;
48 user_manager::User::WallpaperType type;
50 bool operator==(const WallpaperInfo& other) {
51 return (location == other.location) && (layout == other.layout) &&
56 class MovableOnDestroyCallback;
57 typedef scoped_ptr<MovableOnDestroyCallback> MovableOnDestroyCallbackHolder;
59 class WallpaperManagerBrowserTest;
61 // Name of wallpaper sequence token.
62 extern const char kWallpaperSequenceTokenName[];
64 // File path suffices of resized small or large wallpaper.
65 // TODO(bshe): Use the same sub folder system as custom wallpapers use.
67 extern const char kSmallWallpaperSuffix[];
68 extern const char kLargeWallpaperSuffix[];
70 // Directory names of custom wallpapers.
71 extern const char kSmallWallpaperSubDir[];
72 extern const char kLargeWallpaperSubDir[];
73 extern const char kOriginalWallpaperSubDir[];
74 extern const char kThumbnailWallpaperSubDir[];
76 // The width and height of small/large resolution wallpaper. When screen size is
77 // smaller than |kSmallWallpaperMaxWidth| and |kSmallWallpaperMaxHeight|, the
78 // small resolution wallpaper should be used. Otherwise, use the large
79 // resolution wallpaper.
80 extern const int kSmallWallpaperMaxWidth;
81 extern const int kSmallWallpaperMaxHeight;
82 extern const int kLargeWallpaperMaxWidth;
83 extern const int kLargeWallpaperMaxHeight;
85 // The width and height of wallpaper thumbnails.
86 extern const int kWallpaperThumbnailWidth;
87 extern const int kWallpaperThumbnailHeight;
89 // This singleton class maintains wallpapers for users who have logged into this
91 class WallpaperManager: public content::NotificationObserver {
93 enum WallpaperResolution {
94 WALLPAPER_RESOLUTION_LARGE,
95 WALLPAPER_RESOLUTION_SMALL
101 explicit TestApi(WallpaperManager* wallpaper_manager);
104 base::FilePath current_wallpaper_path();
106 bool GetWallpaperFromCache(const std::string& user_id,
107 gfx::ImageSkia* image);
109 void SetWallpaperCache(const std::string& user_id,
110 const gfx::ImageSkia& image);
112 void ClearDisposableWallpaperCache();
115 WallpaperManager* wallpaper_manager_; // not owned
117 DISALLOW_COPY_AND_ASSIGN(TestApi);
120 // This should be public to allow access from functions in anonymous
122 class CustomizedWallpaperRescaledFiles;
126 virtual ~Observer() {}
127 virtual void OnWallpaperAnimationFinished(const std::string& user_id) = 0;
128 virtual void OnUpdateWallpaperForTesting() {}
129 virtual void OnPendingListEmptyForTesting() {}
132 // This is "wallpaper either scheduled to load, or loading right now".
134 // While enqueued, it defines moment in the future, when it will be loaded.
135 // Enqueued but not started request might be updated by subsequent load
136 // request. Therefore it's created empty, and updated being enqueued.
138 // PendingWallpaper is owned by WallpaperManager, but reference to this object
139 // is passed to other threads by PostTask() calls, therefore it is
140 // RefCountedThreadSafe.
141 class PendingWallpaper : public base::RefCountedThreadSafe<PendingWallpaper> {
143 // Do LoadWallpaper() - image not found in cache.
144 PendingWallpaper(const base::TimeDelta delay, const std::string& user_id);
146 // There are 4 cases in SetUserWallpaper:
147 // 1) gfx::ImageSkia is found in cache.
148 // - Schedule task to (probably) resize it and install:
149 // call ash::Shell::GetInstance()->desktop_background_controller()->
150 // SetCustomWallpaper(user_wallpaper, layout);
151 // 2) WallpaperInfo is found in cache
152 // - need to LoadWallpaper(), resize and install.
153 // 3) wallpaper path is not NULL, load image URL, then resize, etc...
154 // 4) SetDefaultWallpaper (either on some error, or when user is new).
155 void ResetSetWallpaperImage(const gfx::ImageSkia& image,
156 const WallpaperInfo& info);
157 void ResetLoadWallpaper(const WallpaperInfo& info);
158 void ResetSetCustomWallpaper(const WallpaperInfo& info,
159 const base::FilePath& wallpaper_path);
160 void ResetSetDefaultWallpaper();
163 friend class base::RefCountedThreadSafe<PendingWallpaper>;
167 // All Reset*() methods use SetMode() to set object to new state.
168 void SetMode(const gfx::ImageSkia& image,
169 const WallpaperInfo& info,
170 const base::FilePath& wallpaper_path,
171 const bool is_default);
173 // This method is usually triggered by timer to actually load request.
174 void ProcessRequest();
176 // This method is called by callback, when load request is finished.
177 void OnWallpaperSet();
179 std::string user_id_;
181 gfx::ImageSkia user_wallpaper_;
182 base::FilePath wallpaper_path_;
184 // Load default wallpaper instead of user image.
187 // This is "on destroy" callback that will call OnWallpaperSet() when
188 // image will be loaded.
189 MovableOnDestroyCallbackHolder on_finish_;
190 base::OneShotTimer<WallpaperManager::PendingWallpaper> timer;
192 // Load start time to calculate duration.
193 base::Time started_load_at_;
195 DISALLOW_COPY_AND_ASSIGN(PendingWallpaper);
199 virtual ~WallpaperManager();
201 // Get pointer to singleton WallpaperManager instance, create it if necessary.
202 static WallpaperManager* Get();
204 // Registers wallpaper manager preferences.
205 static void RegisterPrefs(PrefRegistrySimple* registry);
207 // Resizes |image| to a resolution which is nearest to |preferred_width| and
208 // |preferred_height| while respecting the |layout| choice. |output_skia| is
209 // optional (may be NULL). Returns true on success.
210 static bool ResizeImage(const gfx::ImageSkia& image,
211 ash::WallpaperLayout layout,
213 int preferred_height,
214 scoped_refptr<base::RefCountedBytes>* output,
215 gfx::ImageSkia* output_skia);
217 // Resizes |image| to a resolution which is nearest to |preferred_width| and
218 // |preferred_height| while respecting the |layout| choice and saves the
219 // resized wallpaper to |path|. |output_skia| is optional (may be
220 // NULL). Returns true on success.
221 static bool ResizeAndSaveWallpaper(const gfx::ImageSkia& image,
222 const base::FilePath& path,
223 ash::WallpaperLayout layout,
225 int preferred_height,
226 gfx::ImageSkia* output_skia);
228 // Returns the appropriate wallpaper resolution for all root windows.
229 static WallpaperResolution GetAppropriateResolution();
231 // Returns custom wallpaper path. Append |sub_dir|, |user_id_hash| and |file|
232 // to custom wallpaper directory.
233 static base::FilePath GetCustomWallpaperPath(const char* sub_dir,
234 const std::string& user_id_hash,
235 const std::string& file);
237 void SetCommandLineForTesting(base::CommandLine* command_line);
239 // Indicates imminent shutdown, allowing the WallpaperManager to remove any
240 // observers it has registered.
243 // Adds PowerManagerClient, TimeZoneSettings and CrosSettings observers.
246 // Loads wallpaper asynchronously if the current wallpaper is not the
247 // wallpaper of logged in user.
248 void EnsureLoggedInUserWallpaperLoaded();
250 // Gets wallpaper information of logged in user.
251 bool GetLoggedInUserWallpaperInfo(WallpaperInfo* info);
253 // Initializes wallpaper. If logged in, loads user's wallpaper. If not logged
254 // in, uses a solid color wallpaper. If logged in as a stub user, uses an
256 void InitializeWallpaper();
258 // NotificationObserver overrides:
259 virtual void Observe(int type,
260 const content::NotificationSource& source,
261 const content::NotificationDetails& details) override;
263 // Removes all |user_id| related wallpaper info and saved wallpapers.
264 void RemoveUserWallpaperInfo(const std::string& user_id);
266 // Calls SetCustomWallpaper() with |user_id_hash| received from cryptohome.
267 void SetCustomWallpaperOnSanitizedUsername(const std::string& user_id,
268 const gfx::ImageSkia& image,
269 bool update_wallpaper,
270 bool cryptohome_success,
271 const std::string& user_id_hash);
273 // Saves custom wallpaper to file, post task to generate thumbnail and updates
274 // local state preferences. If |update_wallpaper| is false, don't change
275 // wallpaper but only update cache.
276 void SetCustomWallpaper(const std::string& user_id,
277 const std::string& user_id_hash,
278 const std::string& file,
279 ash::WallpaperLayout layout,
280 user_manager::User::WallpaperType type,
281 const gfx::ImageSkia& image,
282 bool update_wallpaper);
284 // Use given files as new default wallpaper.
285 // Reloads current wallpaper, if old default was loaded.
286 // Current value of default_wallpaper_image_ is destroyed.
287 // Sets default_wallpaper_image_ either to |small_wallpaper_image| or
288 // |large_wallpaper_image| depending on GetAppropriateResolution().
289 void SetDefaultWallpaperPath(
290 const base::FilePath& customized_default_wallpaper_file_small,
291 scoped_ptr<gfx::ImageSkia> small_wallpaper_image,
292 const base::FilePath& customized_default_wallpaper_file_large,
293 scoped_ptr<gfx::ImageSkia> large_wallpaper_image);
295 // Sets wallpaper to default wallpaper (asynchronously with zero delay).
296 void SetDefaultWallpaperNow(const std::string& user_id);
298 // Sets wallpaper to default wallpaper (asynchronously with default delay).
299 void SetDefaultWallpaperDelayed(const std::string& user_id);
301 // Sets selected wallpaper information for |user_id| and saves it to Local
302 // State if |is_persistent| is true.
303 void SetUserWallpaperInfo(const std::string& user_id,
304 const WallpaperInfo& info,
307 // Sets |user_id|'s wallpaper (asynchronously with zero delay).
308 void SetUserWallpaperNow(const std::string& user_id);
310 // Sets |user_id|'s wallpaper (asynchronously with default delay).
311 void SetUserWallpaperDelayed(const std::string& user_id);
313 // Sets wallpaper to |image| (asynchronously with zero delay). If
314 // |update_wallpaper| is false, skip change wallpaper but only update cache.
315 void SetWallpaperFromImageSkia(const std::string& user_id,
316 const gfx::ImageSkia& image,
317 ash::WallpaperLayout layout,
318 bool update_wallpaper);
320 // Updates current wallpaper. It may switch the size of wallpaper based on the
321 // current display's resolution. (asynchronously with zero delay)
322 void UpdateWallpaper(bool clear_cache);
324 // Adds given observer to the list.
325 void AddObserver(Observer* observer);
327 // Removes given observer from the list.
328 void RemoveObserver(Observer* observer);
330 // Returns whether a wallpaper policy is enforced for |user_id|.
331 bool IsPolicyControlled(const std::string& user_id) const;
333 // Called when a wallpaper policy has been set for |user_id|. Blocks user
334 // from changing the wallpaper.
335 void OnPolicySet(const std::string& policy, const std::string& user_id);
337 // Called when the wallpaper policy has been cleared for |user_id|.
338 void OnPolicyCleared(const std::string& policy, const std::string& user_id);
340 // Called when the policy-set wallpaper has been fetched. Initiates decoding
341 // of the JPEG |data| with a callback to SetPolicyControlledWallpaper().
342 void OnPolicyFetched(const std::string& policy,
343 const std::string& user_id,
344 scoped_ptr<std::string> data);
346 // This is called from CustomizationDocument.
347 // |resized_directory| is the directory where resized versions are stored and
349 void SetCustomizedDefaultWallpaper(const GURL& wallpaper_url,
350 const base::FilePath& downloaded_file,
351 const base::FilePath& resized_directory);
353 // Returns queue size.
354 size_t GetPendingListSizeForTesting() const;
357 friend class TestApi;
358 friend class PendingWallpaper;
359 friend class WallpaperManagerBrowserTest;
360 friend class WallpaperManagerBrowserTestDefaultWallpaper;
361 friend class WallpaperManagerPolicyTest;
363 typedef std::map<std::string, gfx::ImageSkia> CustomWallpaperMap;
366 // Saves original custom wallpaper to |path| (absolute path) on filesystem
367 // and starts resizing operation of the custom wallpaper if necessary.
368 static void SaveCustomWallpaper(const std::string& user_id_hash,
369 const base::FilePath& path,
370 ash::WallpaperLayout layout,
371 scoped_ptr<gfx::ImageSkia> image);
373 // Moves custom wallpapers from |user_id| directory to |user_id_hash|
375 static void MoveCustomWallpapersOnWorker(
376 const std::string& user_id,
377 const std::string& user_id_hash,
378 base::WeakPtr<WallpaperManager> weak_ptr);
380 // Gets |user_id|'s custom wallpaper at |wallpaper_path|. Falls back on
381 // original custom wallpaper. When |update_wallpaper| is true, sets wallpaper
382 // to the loaded wallpaper. Must run on wallpaper sequenced worker thread.
383 static void GetCustomWallpaperInternal(
384 const std::string& user_id,
385 const WallpaperInfo& info,
386 const base::FilePath& wallpaper_path,
387 bool update_wallpaper,
388 MovableOnDestroyCallbackHolder on_finish,
389 base::WeakPtr<WallpaperManager> weak_ptr);
391 // Resize and save customized default wallpaper.
392 static void ResizeCustomizedDefaultWallpaper(
393 scoped_ptr<gfx::ImageSkia> image,
394 const user_manager::UserImage::RawImage& raw_image,
395 const CustomizedWallpaperRescaledFiles* rescaled_files,
397 gfx::ImageSkia* small_wallpaper_image,
398 gfx::ImageSkia* large_wallpaper_image);
400 // Initialize wallpaper for the specified user to default and saves this
401 // settings in local state.
402 void InitInitialUserWallpaper(const std::string& user_id, bool is_persistent);
404 // Set wallpaper to |user_image| controlled by policy. (Takes a UserImage
405 // because that's the callback interface provided by UserImageLoader.)
406 void SetPolicyControlledWallpaper(const std::string& user_id,
407 const user_manager::UserImage& user_image);
409 // Gets encoded wallpaper from cache. Returns true if success.
410 bool GetWallpaperFromCache(const std::string& user_id, gfx::ImageSkia* image);
412 // The number of wallpapers have loaded. For test only.
413 int loaded_wallpapers() const { return loaded_wallpapers_; }
415 // Cache some (or all) logged in users' wallpapers to memory at login
416 // screen. It should not compete with first wallpaper loading when boot
417 // up/initialize login WebUI page.
418 // There are two ways the first wallpaper might be loaded:
419 // 1. Loaded on boot. Login WebUI waits for it.
420 // 2. When flag --disable-boot-animation is passed. Login WebUI is loaded
421 // right away and in 500ms after. Wallpaper started to load.
422 // For case 2, should_cache_wallpaper_ is used to indicate if we need to
423 // cache wallpapers on wallpaper animation finished. The cache operation
424 // should be only executed once.
425 void CacheUsersWallpapers();
427 // Caches |user_id|'s wallpaper to memory.
428 void CacheUserWallpaper(const std::string& user_id);
430 // Clears disposable ONLINE and CUSTOM wallpaper cache. At multi profile
431 // world, logged in users' wallpaper cache is not disposable.
432 void ClearDisposableWallpaperCache();
434 // Clears all obsolete wallpaper prefs from old version wallpaper pickers.
435 void ClearObsoleteWallpaperPrefs();
437 // Deletes all |user_id| related custom wallpapers and directories.
438 void DeleteUserWallpapers(const std::string& user_id,
439 const std::string& path_to_file);
441 // Gets the CommandLine representing the current process's command line.
442 base::CommandLine* GetCommandLine();
444 // Initialize wallpaper of registered device after device policy is trusted.
445 // Note that before device is enrolled, it proceeds with untrusted setting.
446 void InitializeRegisteredDeviceWallpaper();
448 // Loads |user_id|'s wallpaper. When |update_wallpaper| is true, sets
449 // wallpaper to the loaded wallpaper.
450 void LoadWallpaper(const std::string& user_id,
451 const WallpaperInfo& info,
452 bool update_wallpaper,
453 MovableOnDestroyCallbackHolder on_finish);
455 // Called when the original custom wallpaper is moved to the new place.
456 // Updates the corresponding user wallpaper info.
457 void MoveCustomWallpapersSuccess(const std::string& user_id,
458 const std::string& user_id_hash);
460 // Moves custom wallpaper to a new place. Email address was used as directory
461 // name in the old system, this is not safe. New directory system uses
462 // user_id_hash instead of user_id. This must be called after user_id_hash is
464 void MoveLoggedInUserCustomWallpaper();
466 // Gets wallpaper information of |user_id| from Local State or memory. Returns
467 // false if wallpaper information is not found.
468 bool GetUserWallpaperInfo(const std::string& user_id,
469 WallpaperInfo* info) const;
471 // Sets wallpaper to the decoded wallpaper if |update_wallpaper| is true.
472 // Otherwise, cache wallpaper to memory if not logged in. (Takes a UserImage
473 // because that's the callback interface provided by UserImageLoader.)
474 void OnWallpaperDecoded(const std::string& user_id,
475 ash::WallpaperLayout layout,
476 bool update_wallpaper,
477 MovableOnDestroyCallbackHolder on_finish,
478 const user_manager::UserImage& user_image);
480 // Creates new PendingWallpaper request (or updates currently pending).
481 void ScheduleSetUserWallpaper(const std::string& user_id, bool delayed);
483 // Sets wallpaper to default.
484 void DoSetDefaultWallpaper(
485 const std::string& user_id,
486 MovableOnDestroyCallbackHolder on_finish);
488 // Starts to load wallpaper at |wallpaper_path|. If |wallpaper_path| is the
489 // same as |current_wallpaper_path_|, do nothing. Must be called on UI thread.
490 void StartLoad(const std::string& user_id,
491 const WallpaperInfo& info,
492 bool update_wallpaper,
493 const base::FilePath& wallpaper_path,
494 MovableOnDestroyCallbackHolder on_finish);
496 // After completed load operation, update average load time.
497 void SaveLastLoadTime(const base::TimeDelta elapsed);
499 // Notify all registered observers.
500 void NotifyAnimationFinished();
502 // Returns modifiable PendingWallpaper.
503 // Returns pending_inactive_ or creates new PendingWallpaper if necessary.
504 PendingWallpaper* GetPendingWallpaper(const std::string& user_id,
507 // This is called by PendingWallpaper when load is finished.
508 void RemovePendingWallpaperFromList(PendingWallpaper* pending);
510 // Calculate delay for next wallpaper load.
511 // It is usually average wallpaper load time.
512 // If last wallpaper load happened long ago, timeout should be reduced by
513 // the time passed after last wallpaper load. So usual user experience results
515 base::TimeDelta GetWallpaperLoadDelay() const;
517 // This is called after we check that supplied default wallpaper files exist.
518 void SetCustomizedDefaultWallpaperAfterCheck(
519 const GURL& wallpaper_url,
520 const base::FilePath& downloaded_file,
521 scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files);
523 // Starts rescaling of customized wallpaper.
524 void OnCustomizedDefaultWallpaperDecoded(
525 const GURL& wallpaper_url,
526 scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files,
527 const user_manager::UserImage& user_image);
529 // Check the result of ResizeCustomizedDefaultWallpaper and finally
530 // apply Customized Default Wallpaper.
531 void OnCustomizedDefaultWallpaperResized(
532 const GURL& wallpaper_url,
533 scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files,
534 scoped_ptr<bool> success,
535 scoped_ptr<gfx::ImageSkia> small_wallpaper_image,
536 scoped_ptr<gfx::ImageSkia> large_wallpaper_image);
538 // Init |*default_*_wallpaper_file_| from given command line and
539 // clear |default_wallpaper_image_|.
540 void SetDefaultWallpaperPathsFromCommandLine(base::CommandLine* command_line);
542 // Sets wallpaper to decoded default.
543 void OnDefaultWallpaperDecoded(const base::FilePath& path,
544 const ash::WallpaperLayout layout,
545 scoped_ptr<user_manager::UserImage>* result,
546 MovableOnDestroyCallbackHolder on_finish,
547 const user_manager::UserImage& user_image);
549 // Start decoding given default wallpaper.
550 void StartLoadAndSetDefaultWallpaper(
551 const base::FilePath& path,
552 const ash::WallpaperLayout layout,
553 MovableOnDestroyCallbackHolder on_finish,
554 scoped_ptr<user_manager::UserImage>* result_out);
556 // Returns wallpaper subdirectory name for current resolution.
557 const char* GetCustomWallpaperSubdirForCurrentResolution();
559 // Init default_wallpaper_image_ with 1x1 image of default color.
560 void CreateSolidDefaultWallpaper();
562 // The number of loaded wallpapers.
563 int loaded_wallpapers_;
565 // Sequence token associated with wallpaper operations.
566 base::SequencedWorkerPool::SequenceToken sequence_token_;
568 // Wallpaper sequenced task runner.
569 scoped_refptr<base::SequencedTaskRunner> task_runner_;
571 // The file path of current loaded/loading custom/online wallpaper.
572 base::FilePath current_wallpaper_path_;
574 // Loads user wallpaper from its file.
575 scoped_refptr<UserImageLoader> wallpaper_loader_;
577 // Logged-in user wallpaper information.
578 WallpaperInfo current_user_wallpaper_info_;
580 // If non-NULL, used in place of the real command line.
581 base::CommandLine* command_line_for_testing_;
583 // Caches wallpapers of users. Accessed only on UI thread.
584 CustomWallpaperMap wallpaper_cache_;
586 // The last selected user on user pod row.
587 std::string last_selected_user_;
589 bool should_cache_wallpaper_;
591 scoped_ptr<CrosSettings::ObserverSubscription>
592 show_user_name_on_signin_subscription_;
594 content::NotificationRegistrar registrar_;
596 ObserverList<Observer> observers_;
598 // These members are for the scheduler:
600 // When last load attempt finished.
601 base::Time last_load_finished_at_;
603 // last N wallpaper loads times.
604 std::deque<base::TimeDelta> last_load_times_;
606 // Pointer to last inactive (waiting) entry of 'loading_' list.
607 // NULL when there is no inactive request.
608 PendingWallpaper* pending_inactive_;
610 // Owns PendingWallpaper.
611 // PendingWallpaper deletes itself from here on load complete.
612 // All pending will be finally deleted on destroy.
613 typedef std::vector<scoped_refptr<PendingWallpaper> > PendingList;
614 PendingList loading_;
616 base::FilePath default_small_wallpaper_file_;
617 base::FilePath default_large_wallpaper_file_;
619 base::FilePath guest_small_wallpaper_file_;
620 base::FilePath guest_large_wallpaper_file_;
622 // Current decoded default image is stored in cache.
623 scoped_ptr<user_manager::UserImage> default_wallpaper_image_;
625 base::WeakPtrFactory<WallpaperManager> weak_factory_;
627 DISALLOW_COPY_AND_ASSIGN(WallpaperManager);
630 } // namespace chromeos
632 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_USERS_WALLPAPER_WALLPAPER_MANAGER_H_