Home | History | Annotate | Download | only in gcm
      1 // Copyright (c) 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_SERVICES_GCM_GCM_PROFILE_SERVICE_H_
      6 #define CHROME_BROWSER_SERVICES_GCM_GCM_PROFILE_SERVICE_H_
      7 
      8 #include <map>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/callback.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/gtest_prod_util.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
     17 #include "content/public/browser/notification_observer.h"
     18 #include "content/public/browser/notification_registrar.h"
     19 #include "google_apis/gcm/gcm_client.h"
     20 
     21 class Profile;
     22 
     23 namespace base {
     24 class Value;
     25 }
     26 
     27 namespace extensions {
     28 class Extension;
     29 }
     30 
     31 namespace user_prefs {
     32 class PrefRegistrySyncable;
     33 }
     34 
     35 namespace gcm {
     36 
     37 class GCMEventRouter;
     38 class GCMProfileServiceTest;
     39 
     40 // Acts as a bridge between GCM API and GCMClient layer. It is profile based.
     41 class GCMProfileService : public BrowserContextKeyedService,
     42                           public content::NotificationObserver {
     43  public:
     44   typedef base::Callback<void(const std::string& registration_id,
     45                               GCMClient::Result result)> RegisterCallback;
     46   typedef base::Callback<void(const std::string& message_id,
     47                               GCMClient::Result result)> SendCallback;
     48 
     49   // For testing purpose.
     50   class TestingDelegate {
     51    public:
     52     virtual GCMEventRouter* GetEventRouter() const = 0;
     53     virtual void CheckInFinished(const GCMClient::CheckInInfo& checkin_info,
     54                                  GCMClient::Result result) = 0;
     55     virtual void LoadingFromPersistentStoreFinished() = 0;
     56   };
     57 
     58   // Returns true if the GCM support is enabled.
     59   static bool IsGCMEnabled();
     60 
     61   // Register profile-specific prefs for GCM.
     62   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
     63 
     64   explicit GCMProfileService(Profile* profile);
     65   // Constructor for testing purpose.
     66   GCMProfileService(Profile* profile, TestingDelegate* testing_delegate);
     67   virtual ~GCMProfileService();
     68 
     69   // Registers |sender_id| for an app. A registration ID will be returned by
     70   // the GCM server.
     71   // |app_id|: application ID.
     72   // |cert|: SHA-1 of public key of the application, in base16 format.
     73   // |sender_ids|: list of IDs of the servers that are allowed to send the
     74   //               messages to the application. These IDs are assigned by the
     75   //               Google API Console.
     76   // |callback|: to be called once the asynchronous operation is done.
     77   virtual void Register(const std::string& app_id,
     78                         const std::vector<std::string>& sender_ids,
     79                         const std::string& cert,
     80                         RegisterCallback callback);
     81 
     82   // Sends a message to a given receiver.
     83   // |app_id|: application ID.
     84   // |receiver_id|: registration ID of the receiver party.
     85   // |message|: message to be sent.
     86   // |callback|: to be called once the asynchronous operation is done.
     87   virtual void Send(const std::string& app_id,
     88                     const std::string& receiver_id,
     89                     const GCMClient::OutgoingMessage& message,
     90                     SendCallback callback);
     91 
     92  protected:
     93   // Flag that could be set by the testing code to enable GCM. Otherwise,
     94   // tests from official build will fail.
     95   static bool enable_gcm_for_testing_;
     96 
     97  private:
     98   friend class GCMProfileServiceTest;
     99   friend class GCMProfileServiceRegisterTest;
    100   FRIEND_TEST_ALL_PREFIXES(GCMProfileServiceTest, CheckInFromPrefsStore);
    101   FRIEND_TEST_ALL_PREFIXES(GCMProfileServiceTest, CheckOut);
    102   FRIEND_TEST_ALL_PREFIXES(GCMProfileServiceRegisterTest, Unregister);
    103 
    104   class IOWorker;
    105 
    106   struct RegistrationInfo {
    107     RegistrationInfo();
    108     ~RegistrationInfo();
    109 
    110     std::vector<std::string> sender_ids;
    111     std::string registration_id;
    112   };
    113 
    114   // Overridden from content::NotificationObserver:
    115   virtual void Observe(int type,
    116                        const content::NotificationSource& source,
    117                        const content::NotificationDetails& details) OVERRIDE;
    118 
    119   void Init();
    120 
    121   // Allows a signed-in user to use the GCM. If the check-in info can be found
    122   // in the prefs store, use it directly. Otherwise, a check-in communication
    123   // will be made with the GCM.
    124   void AddUser();
    125 
    126   // Stops the user from using the GCM after the user signs out. This simply
    127   // removes the cached and persisted check-in info.
    128   void RemoveUser();
    129 
    130   // Unregisters an app from using the GCM after it has been uninstalled.
    131   void Unregister(const std::string& app_id);
    132 
    133   void CheckInFinished(GCMClient::CheckInInfo checkin_info,
    134                        GCMClient::Result result);
    135   void RegisterFinished(std::string app_id,
    136                         std::string registration_id,
    137                         GCMClient::Result result);
    138   void SendFinished(std::string app_id,
    139                     std::string message_id,
    140                     GCMClient::Result result);
    141   void MessageReceived(std::string app_id,
    142                        GCMClient::IncomingMessage message);
    143   void MessagesDeleted(std::string app_id);
    144   void MessageSendError(std::string app_id,
    145                         std::string message_id,
    146                         GCMClient::Result result);
    147 
    148   // Returns the event router to fire the event for the given app.
    149   GCMEventRouter* GetEventRouter(const std::string& app_id);
    150 
    151   // Used to persist registration info into the app's state store.
    152   void DeleteRegistrationInfo(const std::string& app_id);
    153   void WriteRegistrationInfo(const std::string& app_id);
    154   void ReadRegistrationInfo(const std::string& app_id);
    155   void ReadRegistrationInfoFinished(std::string app_id,
    156                                     scoped_ptr<base::Value> value);
    157   bool ParsePersistedRegistrationInfo(scoped_ptr<base::Value> value,
    158                                       RegistrationInfo* registration_info);
    159 
    160   // Returns the key used to identify the registration info saved into the
    161   // app's state store. Used for testing purpose.
    162   static const char* GetPersistentRegisterKeyForTesting();
    163 
    164   // The profile which owns this object.
    165   Profile* profile_;
    166 
    167   // The username of the signed-in profile.
    168   std::string username_;
    169 
    170   content::NotificationRegistrar registrar_;
    171 
    172   // For all the work occured in IO thread.
    173   scoped_refptr<IOWorker> io_worker_;
    174 
    175   // Callback map (from app_id to callback) for Register.
    176   std::map<std::string, RegisterCallback> register_callbacks_;
    177 
    178   // Callback map (from <app_id, message_id> to callback) for Send.
    179   std::map<std::pair<std::string, std::string>, SendCallback> send_callbacks_;
    180 
    181   // Map from app_id to registration info (sender ids & registration ID).
    182   typedef std::map<std::string, RegistrationInfo> RegistrationInfoMap;
    183   RegistrationInfoMap registration_info_map_;
    184 
    185   // Event router to talk with JS API.
    186   scoped_ptr<GCMEventRouter> js_event_router_;
    187 
    188   // For testing purpose.
    189   TestingDelegate* testing_delegate_;
    190 
    191   // Used to pass a weak pointer to the IO worker.
    192   base::WeakPtrFactory<GCMProfileService> weak_ptr_factory_;
    193 
    194   DISALLOW_COPY_AND_ASSIGN(GCMProfileService);
    195 };
    196 
    197 }  // namespace gcm
    198 
    199 #endif  // CHROME_BROWSER_SERVICES_GCM_GCM_PROFILE_SERVICE_H_
    200