1 // Copyright 2015 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_UI_APP_LIST_CHROME_APP_LIST_ITEM_H_
6 #define CHROME_BROWSER_UI_APP_LIST_CHROME_APP_LIST_ITEM_H_
7 
8 #include <memory>
9 #include <string>
10 #include <utility>
11 
12 #include "ash/public/cpp/app_list/app_list_types.h"
13 #include "chrome/browser/ui/app_list/app_context_menu.h"
14 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
15 #include "ui/gfx/image/image_skia.h"
16 
17 class AppListControllerDelegate;
18 class AppListModelUpdater;
19 class Profile;
20 
21 namespace extensions {
22 class AppSorting;
23 }  // namespace extensions
24 
25 namespace ui {
26 class SimpleMenuModel;
27 }  // namespace ui
28 
29 // Base class of all chrome app list items.
30 class ChromeAppListItem {
31  public:
32   class TestApi {
33    public:
34     explicit TestApi(ChromeAppListItem* item);
35     ~TestApi() = default;
36 
37     void SetFolderId(const std::string& folder_id);
38     void SetPosition(const syncer::StringOrdinal& position);
39 
40    private:
41     ChromeAppListItem* const item_;
42   };
43 
44   ChromeAppListItem(Profile* profile,
45                     const std::string& app_id,
46                     AppListModelUpdater* model_updater);
47   ChromeAppListItem(const ChromeAppListItem&) = delete;
48   ChromeAppListItem& operator=(const ChromeAppListItem&) = delete;
49   virtual ~ChromeAppListItem();
50 
51   // AppListControllerDelegate is not properly implemented in tests. Use mock
52   // |controller| for unit_tests.
53   static void OverrideAppListControllerDelegateForTesting(
54       AppListControllerDelegate* controller);
55 
56   static gfx::ImageSkia CreateDisabledIcon(const gfx::ImageSkia& icon);
57 
id()58   const std::string& id() const { return metadata_->id; }
folder_id()59   const std::string& folder_id() const { return metadata_->folder_id; }
position()60   const syncer::StringOrdinal& position() const { return metadata_->position; }
name()61   const std::string& name() const { return metadata_->name; }
is_folder()62   bool is_folder() const { return metadata_->is_folder; }
is_persistent()63   bool is_persistent() const { return metadata_->is_persistent; }
icon()64   const gfx::ImageSkia& icon() const { return metadata_->icon; }
is_page_break()65   bool is_page_break() const { return metadata_->is_page_break; }
66 
67   void SetMetadata(std::unique_ptr<ash::AppListItemMetadata> metadata);
68   std::unique_ptr<ash::AppListItemMetadata> CloneMetadata() const;
69 
70   // The following methods set Chrome side data here, and call model updater
71   // interfaces that talk to ash directly.
72   void SetIcon(const gfx::ImageSkia& icon);
73   void SetName(const std::string& name);
74   void SetNameAndShortName(const std::string& name,
75                            const std::string& short_name);
76   void SetFolderId(const std::string& folder_id);
77   void SetPosition(const syncer::StringOrdinal& position);
78   void SetIsPageBreak(bool is_page_break);
79   void SetIsPersistent(bool is_persistent);
80 
81   // The following methods won't make changes to Ash and it should be called
82   // by this item itself or the model updater.
83   void SetChromeFolderId(const std::string& folder_id);
84   void SetChromeIsFolder(bool is_folder);
85   void SetChromeName(const std::string& name);
86   void SetChromePosition(const syncer::StringOrdinal& position);
87 
88   // Call |Activate()| and dismiss launcher if necessary.
89   void PerformActivate(int event_flags);
90 
91   // Activates (opens) the item. Does nothing by default.
92   virtual void Activate(int event_flags);
93 
94   // Returns a static const char* identifier for the subclass (defaults to "").
95   // Pointers can be compared for quick type checking.
96   virtual const char* GetItemType() const;
97 
98   // Returns the context menu model in |callback| for this item. NULL if there
99   // is currently no menu for the item (e.g. during install). Note |callback|
100   // takes the ownership of the returned menu model.
101   using GetMenuModelCallback =
102       base::OnceCallback<void(std::unique_ptr<ui::SimpleMenuModel>)>;
103   virtual void GetContextMenuModel(GetMenuModelCallback callback);
104 
105   // Returns true iff this item was badged because it's an extension app that
106   // has its Android analog installed.
107   virtual bool IsBadged() const;
108 
109   bool CompareForTest(const ChromeAppListItem* other) const;
110 
111   std::string ToDebugString() const;
112 
113   // Set the default position if it exists. Otherwise set the first available
114   // position in the app list if |model_updater| is not null.
115   void SetDefaultPositionIfApplicable(AppListModelUpdater* model_updater);
116 
117  protected:
118   ChromeAppListItem(Profile* profile, const std::string& app_id);
119 
profile()120   Profile* profile() const { return profile_; }
121 
122   extensions::AppSorting* GetAppSorting();
123 
124   AppListControllerDelegate* GetController();
125 
model_updater()126   AppListModelUpdater* model_updater() { return model_updater_; }
set_model_updater(AppListModelUpdater * model_updater)127   void set_model_updater(AppListModelUpdater* model_updater) {
128     model_updater_ = model_updater;
129   }
130 
131   // Updates item position and name from |sync_item|. |sync_item| must be valid.
132   void UpdateFromSync(
133       const app_list::AppListSyncableService::SyncItem* sync_item);
134 
135   // Get the context menu of a certain app. This could be different for
136   // different kinds of items.
137   virtual app_list::AppContextMenu* GetAppContextMenu();
138 
139   void MaybeDismissAppList();
140 
141  private:
142   std::unique_ptr<ash::AppListItemMetadata> metadata_;
143   Profile* profile_;
144   AppListModelUpdater* model_updater_ = nullptr;
145 };
146 
147 #endif  // CHROME_BROWSER_UI_APP_LIST_CHROME_APP_LIST_ITEM_H_
148