Adding the creation_flags back to pending_extension_info.
Add a unit test to cover the case when an external extension
is updated before being installed and make sure it retains
the creation flags.

BUG=627522

Review-Url: https://codereview.chromium.org/2146963004
Cr-Commit-Position: refs/heads/master@{#405856}
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 773f349..bb578e1 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -546,6 +546,7 @@
       installer->set_expected_version(expected_version,
                                       false /* fail_install_if_unexpected */);
     }
+    creation_flags = pending_extension_info->creation_flags();
     if (pending_extension_info->mark_acknowledged())
       external_install_manager_->AcknowledgeExternalExtension(id);
   } else if (extension) {
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 471cd5d7..7cdb68c 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -3018,6 +3018,7 @@
       &IsExtension,
       kGoodIsFromSync,
       Manifest::INTERNAL,
+      Extension::NO_FLAGS,
       false,
       kGoodRemoteInstall);
   UpdateExtension(good->id(), path, ENABLED);
@@ -4181,6 +4182,36 @@
 }
 #endif
 
+TEST_F(ExtensionServiceTest, UpdatingPendingExternalExtensionWithFlags) {
+  // Regression test for crbug.com/627522
+  const char kPrefFromBookmark[] = "from_bookmark";
+
+  InitializeEmptyExtensionService();
+
+  base::FilePath path = data_dir().AppendASCII("good.crx");
+  service()->set_extensions_enabled(true);
+
+  // Register and install an external extension.
+  std::unique_ptr<Version> version(new Version("1.0.0.0"));
+  content::WindowedNotificationObserver observer(
+      extensions::NOTIFICATION_CRX_INSTALLER_DONE,
+      content::NotificationService::AllSources());
+  std::unique_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile(
+      good_crx, std::move(version), path, Manifest::EXTERNAL_PREF,
+      Extension::FROM_BOOKMARK, false /* mark_acknowledged */,
+      false /* install_immediately */));
+  ASSERT_TRUE(service()->OnExternalExtensionFileFound(*info));
+  EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
+
+  // Upgrade to version 2.0, the flag should be preserved.
+  path = data_dir().AppendASCII("good2.crx");
+  UpdateExtension(good_crx, path, ENABLED);
+  ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
+  const Extension* extension = service()->GetExtensionById(good_crx, false);
+  ASSERT_TRUE(extension);
+  ASSERT_TRUE(extension->from_bookmark());
+}
+
 // Tests disabling extensions
 TEST_F(ExtensionServiceTest, DisableExtension) {
   InitializeEmptyExtensionService();
diff --git a/chrome/browser/extensions/pending_extension_info.cc b/chrome/browser/extensions/pending_extension_info.cc
index 7c6aed8..1a034ca 100644
--- a/chrome/browser/extensions/pending_extension_info.cc
+++ b/chrome/browser/extensions/pending_extension_info.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/extensions/pending_extension_info.h"
-
 #include "base/logging.h"
+#include "chrome/browser/extensions/pending_extension_info.h"
+#include "extensions/common/extension.h"
 
 namespace extensions {
 
@@ -16,6 +16,7 @@
     ShouldAllowInstallPredicate should_allow_install,
     bool is_from_sync,
     Manifest::Location install_source,
+    int creation_flags,
     bool mark_acknowledged,
     bool remote_install)
     : id_(id),
@@ -25,6 +26,7 @@
       should_allow_install_(should_allow_install),
       is_from_sync_(is_from_sync),
       install_source_(install_source),
+      creation_flags_(creation_flags),
       mark_acknowledged_(mark_acknowledged),
       remote_install_(remote_install) {
 }
@@ -34,6 +36,7 @@
       should_allow_install_(NULL),
       is_from_sync_(true),
       install_source_(Manifest::INVALID_LOCATION),
+      creation_flags_(Extension::NO_FLAGS),
       mark_acknowledged_(false),
       remote_install_(false) {
 }
diff --git a/chrome/browser/extensions/pending_extension_info.h b/chrome/browser/extensions/pending_extension_info.h
index 8bfcdaa..9d4e939 100644
--- a/chrome/browser/extensions/pending_extension_info.h
+++ b/chrome/browser/extensions/pending_extension_info.h
@@ -34,6 +34,7 @@
                        ShouldAllowInstallPredicate should_allow_install,
                        bool is_from_sync,
                        Manifest::Location install_source,
+                       int creation_flags,
                        bool mark_acknowledged,
                        bool remote_install);
 
@@ -63,6 +64,7 @@
   }
   bool is_from_sync() const { return is_from_sync_; }
   Manifest::Location install_source() const { return install_source_; }
+  int creation_flags() const { return creation_flags_; }
   bool mark_acknowledged() const { return mark_acknowledged_; }
   bool remote_install() const { return remote_install_; }
 
@@ -87,6 +89,7 @@
 
   bool is_from_sync_;  // This update check was initiated from sync.
   Manifest::Location install_source_;
+  int creation_flags_;
   bool mark_acknowledged_;
   bool remote_install_;
 
diff --git a/chrome/browser/extensions/pending_extension_manager.cc b/chrome/browser/extensions/pending_extension_manager.cc
index 601bc3a..9014cc9 100644
--- a/chrome/browser/extensions/pending_extension_manager.cc
+++ b/chrome/browser/extensions/pending_extension_manager.cc
@@ -120,6 +120,7 @@
                           should_allow_install,
                           kIsFromSync,
                           kSyncLocation,
+                          Extension::NO_FLAGS,
                           kMarkAcknowledged,
                           remote_install);
 }
@@ -149,6 +150,7 @@
                           should_allow_install,
                           kIsFromSync,
                           kManifestLocation,
+                          Extension::NO_FLAGS,
                           kMarkAcknowledged,
                           kRemoteInstall);
 }
@@ -189,6 +191,7 @@
                           &AlwaysInstall,
                           kIsFromSync,
                           location,
+                          creation_flags,
                           mark_acknowledged,
                           kRemoteInstall);
 }
@@ -215,6 +218,7 @@
                           &AlwaysInstall,
                           kIsFromSync,
                           install_source,
+                          creation_flags,
                           mark_acknowledged,
                           kRemoteInstall);
 }
@@ -248,6 +252,7 @@
     PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
     bool is_from_sync,
     Manifest::Location install_source,
+    int creation_flags,
     bool mark_acknowledged,
     bool remote_install) {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -259,6 +264,7 @@
                             should_allow_install,
                             is_from_sync,
                             install_source,
+                            creation_flags,
                             mark_acknowledged,
                             remote_install);
 
diff --git a/chrome/browser/extensions/pending_extension_manager.h b/chrome/browser/extensions/pending_extension_manager.h
index 8097264..627077b1 100644
--- a/chrome/browser/extensions/pending_extension_manager.h
+++ b/chrome/browser/extensions/pending_extension_manager.h
@@ -126,6 +126,7 @@
       PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
       bool is_from_sync,
       Manifest::Location install_source,
+      int creation_flags,
       bool mark_acknowledged,
       bool remote_install);
 
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index 60c10a6..267f75a 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -436,6 +436,7 @@
                              should_allow_install,
                              kIsFromSync,
                              Manifest::INTERNAL,
+                             Extension::NO_FLAGS,
                              kMarkAcknowledged,
                              kRemoteInstall));
   }
@@ -1192,6 +1193,7 @@
                                &ShouldAlwaysInstall,
                                kIsFromSync,
                                Manifest::INTERNAL,
+                               Extension::NO_FLAGS,
                                kMarkAcknowledged,
                                kRemoteInstall));
     }