Remove Instance ID and token data when an app with gcm permission is
uninstalled

BUG=477084
TEST=test updated
[email protected]

Review URL: https://codereview.chromium.org/1158563007

Cr-Commit-Position: refs/heads/master@{#331721}
diff --git a/chrome/browser/extensions/extension_gcm_app_handler.cc b/chrome/browser/extensions/extension_gcm_app_handler.cc
index 6a9f275..c07bd54 100644
--- a/chrome/browser/extensions/extension_gcm_app_handler.cc
+++ b/chrome/browser/extensions/extension_gcm_app_handler.cc
@@ -136,11 +136,17 @@
     const Extension* extension,
     extensions::UninstallReason reason) {
   if (IsGCMPermissionEnabled(extension)) {
-    GetGCMDriver()->Unregister(
+    // Let's first remove InstanceID data. GCM unregistration will be triggered
+    // after the asynchronous call is returned in OnDeleteTokensCompleted.
+    gcm::InstanceIDHandler* instance_id_handler =
+        GetGCMDriver()->GetInstanceIDHandler();
+    DCHECK(instance_id_handler);
+    instance_id_handler->DeleteAllTokensForApp(
         extension->id(),
-        base::Bind(&ExtensionGCMAppHandler::OnUnregisterCompleted,
+        base::Bind(&ExtensionGCMAppHandler::OnDeleteTokensCompleted,
                    weak_factory_.GetWeakPtr(),
                    extension->id()));
+    instance_id_handler->RemoveInstanceIDData(extension->id());
   }
 }
 
@@ -161,6 +167,15 @@
   RemoveAppHandler(app_id);
 }
 
+void ExtensionGCMAppHandler::OnDeleteTokensCompleted(
+    const std::string& app_id, gcm::GCMClient::Result result) {
+  GetGCMDriver()->Unregister(
+      app_id,
+      base::Bind(&ExtensionGCMAppHandler::OnUnregisterCompleted,
+                 weak_factory_.GetWeakPtr(),
+                  app_id));
+}
+
 void ExtensionGCMAppHandler::AddAppHandler(const std::string& app_id) {
   GetGCMDriver()->AddAppHandler(app_id, this);
 }
diff --git a/chrome/browser/extensions/extension_gcm_app_handler.h b/chrome/browser/extensions/extension_gcm_app_handler.h
index 3e2c00f..3f361ba 100644
--- a/chrome/browser/extensions/extension_gcm_app_handler.h
+++ b/chrome/browser/extensions/extension_gcm_app_handler.h
@@ -60,12 +60,14 @@
   // Could be overridden by testing purpose.
   virtual void OnUnregisterCompleted(const std::string& app_id,
                                      gcm::GCMClient::Result result);
+  virtual void OnDeleteTokensCompleted(const std::string& app_id,
+                                       gcm::GCMClient::Result result);
   virtual void AddAppHandler(const std::string& app_id);
   virtual void RemoveAppHandler(const std::string& app_id);
 
   gcm::GCMDriver* GetGCMDriver() const;
 
-private:
+ private:
   friend class BrowserContextKeyedAPIFactory<ExtensionGCMAppHandler>;
 
   // ExtensionRegistryObserver implementation.
diff --git a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc
index 5355ee0..4669ea3 100644
--- a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc
+++ b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc
@@ -132,6 +132,7 @@
       : ExtensionGCMAppHandler(profile),
         waiter_(waiter),
         unregistration_result_(gcm::GCMClient::UNKNOWN_ERROR),
+        delete_tokens_result_(gcm::GCMClient::UNKNOWN_ERROR),
         app_handler_count_drop_to_zero_(false) {
   }
 
@@ -153,6 +154,12 @@
     waiter_->SignalCompleted();
   }
 
+  void OnDeleteTokensCompleted(const std::string& app_id,
+                               gcm::GCMClient::Result result) override {
+    delete_tokens_result_ = result;
+    ExtensionGCMAppHandler::OnDeleteTokensCompleted(app_id, result);
+  }
+
   void RemoveAppHandler(const std::string& app_id) override {
     ExtensionGCMAppHandler::RemoveAppHandler(app_id);
     if (!GetGCMDriver()->app_handlers().size())
@@ -162,6 +169,9 @@
   gcm::GCMClient::Result unregistration_result() const {
     return unregistration_result_;
   }
+  gcm::GCMClient::Result delete_tokens_result() const {
+    return delete_tokens_result_;
+  }
   bool app_handler_count_drop_to_zero() const {
     return app_handler_count_drop_to_zero_;
   }
@@ -169,6 +179,7 @@
  private:
   Waiter* waiter_;
   gcm::GCMClient::Result unregistration_result_;
+  gcm::GCMClient::Result delete_tokens_result_;
   bool app_handler_count_drop_to_zero_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeExtensionGCMAppHandler);
@@ -418,9 +429,11 @@
   waiter()->WaitUntilCompleted();
   EXPECT_EQ(gcm::GCMClient::SUCCESS, registration_result());
 
-  // Unregistration should be triggered when the extension is uninstalled.
+  // Both token deletion and unregistration should be triggered when the
+  // extension is uninstalled.
   UninstallExtension(extension.get());
   waiter()->WaitUntilCompleted();
+  EXPECT_EQ(gcm::GCMClient::SUCCESS, gcm_app_handler()->delete_tokens_result());
   EXPECT_EQ(gcm::GCMClient::SUCCESS,
             gcm_app_handler()->unregistration_result());
 }