Home | History | Annotate | Download | only in app_list
      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_UI_APP_LIST_APP_LIST_SYNCABLE_SERVICE_H_
      6 #define CHROME_BROWSER_UI_APP_LIST_APP_LIST_SYNCABLE_SERVICE_H_
      7 
      8 #include <map>
      9 
     10 #include "base/memory/scoped_ptr.h"
     11 #include "chrome/browser/sync/glue/sync_start_util.h"
     12 #include "components/keyed_service/core/keyed_service.h"
     13 #include "content/public/browser/notification_observer.h"
     14 #include "content/public/browser/notification_registrar.h"
     15 #include "sync/api/string_ordinal.h"
     16 #include "sync/api/sync_change.h"
     17 #include "sync/api/sync_change_processor.h"
     18 #include "sync/api/sync_error_factory.h"
     19 #include "sync/api/syncable_service.h"
     20 #include "sync/protocol/app_list_specifics.pb.h"
     21 
     22 class DriveAppProvider;
     23 class ExtensionAppModelBuilder;
     24 class Profile;
     25 
     26 namespace extensions {
     27 class ExtensionSystem;
     28 }
     29 
     30 namespace sync_pb {
     31 class AppListSpecifics;
     32 }
     33 
     34 namespace app_list {
     35 
     36 class AppListFolderItem;
     37 class AppListItem;
     38 class AppListModel;
     39 
     40 // Keyed Service that owns, stores, and syncs an AppListModel for a profile.
     41 class AppListSyncableService : public syncer::SyncableService,
     42                                public KeyedService,
     43                                public content::NotificationObserver {
     44  public:
     45   struct SyncItem {
     46     SyncItem(const std::string& id,
     47              sync_pb::AppListSpecifics::AppListItemType type);
     48     ~SyncItem();
     49     const std::string item_id;
     50     sync_pb::AppListSpecifics::AppListItemType item_type;
     51     std::string item_name;
     52     std::string parent_id;
     53     syncer::StringOrdinal page_ordinal;
     54     syncer::StringOrdinal item_ordinal;
     55 
     56     std::string ToString() const;
     57   };
     58 
     59   // Populates the model when |extension_system| is ready.
     60   AppListSyncableService(Profile* profile,
     61                          extensions::ExtensionSystem* extension_system);
     62 
     63   virtual ~AppListSyncableService();
     64 
     65   // Adds |item| to |sync_items_| and |model_|. If a sync item already exists,
     66   // updates the existing sync item instead.
     67   void AddItem(scoped_ptr<AppListItem> app_item);
     68 
     69   // Removes sync item matching |id|.
     70   void RemoveItem(const std::string& id);
     71 
     72   // Called when properties of an item may have changed, e.g. default/oem state.
     73   void UpdateItem(AppListItem* app_item);
     74 
     75   // Returns the existing sync item matching |id| or NULL.
     76   const SyncItem* GetSyncItem(const std::string& id) const;
     77 
     78   // Sets the name of the folder for OEM apps.
     79   void SetOemFolderName(const std::string& name);
     80 
     81   Profile* profile() { return profile_; }
     82   AppListModel* model() { return model_.get(); }
     83   size_t GetNumSyncItemsForTest() const { return sync_items_.size(); }
     84   const std::string& GetOemFolderNameForTest() const {
     85     return oem_folder_name_;
     86   }
     87 
     88   // syncer::SyncableService
     89   virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
     90       syncer::ModelType type,
     91       const syncer::SyncDataList& initial_sync_data,
     92       scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
     93       scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE;
     94   virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
     95   virtual syncer::SyncDataList GetAllSyncData(
     96       syncer::ModelType type) const OVERRIDE;
     97   virtual syncer::SyncError ProcessSyncChanges(
     98       const tracked_objects::Location& from_here,
     99       const syncer::SyncChangeList& change_list) OVERRIDE;
    100 
    101  private:
    102   class ModelObserver;
    103   typedef std::map<std::string, SyncItem*> SyncItemMap;
    104 
    105   // KeyedService
    106   virtual void Shutdown() OVERRIDE;
    107 
    108   // content::NotificationObserver
    109   virtual void Observe(int type,
    110                        const content::NotificationSource& source,
    111                        const content::NotificationDetails& details) OVERRIDE;
    112 
    113   // Builds the model once ExtensionService is ready.
    114   void BuildModel();
    115 
    116   // Returns true if sync has restarted, otherwise runs |flare_|.
    117   bool SyncStarted();
    118 
    119   // If |app_item| matches an existing sync item, returns it. Otherwise adds
    120   // |app_item| to |sync_items_| and returns the new item. If |app_item| is
    121   // invalid returns NULL.
    122   SyncItem* FindOrAddSyncItem(AppListItem* app_item);
    123 
    124   // Creates a sync item for |app_item| and sends an ADD SyncChange event.
    125   SyncItem* CreateSyncItemFromAppItem(AppListItem* app_item);
    126 
    127   // If a sync item for |app_item| already exists, update |app_item| from the
    128   // sync item, otherwise create a new sync item from |app_item|.
    129   void AddOrUpdateFromSyncItem(AppListItem* app_item);
    130 
    131   // Either uninstalling a default app or remove the REMOVE_DEFAULT sync item.
    132   // Returns true if the app is removed. Otherwise deletes the existing sync
    133   // item and returns false.
    134   bool RemoveDefaultApp(AppListItem* item, SyncItem* sync_item);
    135 
    136   // Deletes a sync item from |sync_items_| and sends a DELETE action.
    137   void DeleteSyncItem(SyncItem* sync_item);
    138 
    139   // Updates existing entry in |sync_items_| from |app_item|.
    140   void UpdateSyncItem(AppListItem* app_item);
    141 
    142   // Removes sync item matching |id|.
    143   void RemoveSyncItem(const std::string& id);
    144 
    145   // Updates folder items that may get created during initial sync.
    146   void ResolveFolderPositions();
    147 
    148   // Removes any empty SyncItem folders and deletes them from sync. Called
    149   // after a sync item is removed (which may result in an empty folder).
    150   void PruneEmptySyncFolders();
    151 
    152   // Creates or updates a SyncItem from |specifics|. Returns true if a new item
    153   // was created.
    154   bool ProcessSyncItemSpecifics(const sync_pb::AppListSpecifics& specifics);
    155 
    156   // Handles a newly created sync item (e.g. creates a new AppItem and adds it
    157   // to the model or uninstalls a deleted default item.
    158   void ProcessNewSyncItem(SyncItem* sync_item);
    159 
    160   // Handles an existing sync item.
    161   void ProcessExistingSyncItem(SyncItem* sync_item);
    162 
    163   // Updates |app_item| from |sync_item| (e.g. updates item positions).
    164   void UpdateAppItemFromSyncItem(const SyncItem* sync_item,
    165                                  AppListItem* app_item);
    166 
    167   // Sends ADD or CHANGED for sync item.
    168   void SendSyncChange(SyncItem* sync_item,
    169                       syncer::SyncChange::SyncChangeType sync_change_type);
    170 
    171   // Returns an existing SyncItem corresponding to |item_id| or NULL.
    172   SyncItem* FindSyncItem(const std::string& item_id);
    173 
    174   // Creates a new sync item for |item_id|.
    175   SyncItem* CreateSyncItem(
    176       const std::string& item_id,
    177       sync_pb::AppListSpecifics::AppListItemType item_type);
    178 
    179   // Deletes a SyncItem matching |specifics|.
    180   void DeleteSyncItemSpecifics(const sync_pb::AppListSpecifics& specifics);
    181 
    182   // Creates the OEM folder and sets its name if necessary. Returns the OEM
    183   // folder id.
    184   std::string FindOrCreateOemFolder();
    185 
    186   // Gets the location for the OEM folder. Called when the folder is first
    187   // created.
    188   syncer::StringOrdinal GetOemFolderPos();
    189 
    190   // Returns true if an extension matching |id| exists and was installed by
    191   // an OEM (extension->was_installed_by_oem() is true).
    192   bool AppIsOem(const std::string& id);
    193 
    194   Profile* profile_;
    195   extensions::ExtensionSystem* extension_system_;
    196   content::NotificationRegistrar registrar_;
    197   scoped_ptr<AppListModel> model_;
    198   scoped_ptr<ModelObserver> model_observer_;
    199   scoped_ptr<ExtensionAppModelBuilder> apps_builder_;
    200   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
    201   scoped_ptr<syncer::SyncErrorFactory> sync_error_handler_;
    202   SyncItemMap sync_items_;
    203   syncer::SyncableService::StartSyncFlare flare_;
    204   bool first_app_list_sync_;
    205   std::string oem_folder_name_;
    206 
    207   // Provides integration with Drive apps.
    208   scoped_ptr<DriveAppProvider> drive_app_provider_;
    209 
    210   DISALLOW_COPY_AND_ASSIGN(AppListSyncableService);
    211 };
    212 
    213 }  // namespace app_list
    214 
    215 #endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SYNCABLE_SERVICE_H_
    216