Provide a callback for Component Updater OnDemand calls.

The idea here is that there is no good way for a client to know
when a subsequent OnDemand call can be issued without getting
an Error::ERROR_UPDATE_IN_PROGRESS. This issue showed up when writing a
browser test for an unrelated component updater feature.

This change is mostly mechanical, especially for the existing users
of the OnDemand interface. All existing call sites pass a null callback
as an argument, therefore no new code paths are introduced with this change.

BUG=639180

Review-Url: https://codereview.chromium.org/2261533003
Cr-Commit-Position: refs/heads/master@{#413178}
diff --git a/components/component_updater/component_updater_service.cc b/components/component_updater/component_updater_service.cc
index 4964bb0..1f6684c1 100644
--- a/components/component_updater/component_updater_service.cc
+++ b/components/component_updater/component_updater_service.cc
@@ -239,13 +239,19 @@
   callback.Run();  // Unblock the request if the request can't be throttled.
 }
 
-bool CrxUpdateService::OnDemandUpdate(const std::string& id) {
+void CrxUpdateService::OnDemandUpdate(const std::string& id,
+                                      CompletionCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  if (!GetComponent(id))
-    return false;
+  if (!GetComponent(id)) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::Bind(callback,
+                   update_client::Error::ERROR_UPDATE_INVALID_ARGUMENT));
+    return;
+  }
 
-  return OnDemandUpdateInternal(id);
+  OnDemandUpdateInternal(id, callback);
 }
 
 bool CrxUpdateService::OnDemandUpdateWithCooldown(const std::string& id) {
@@ -261,21 +267,20 @@
       return false;
   }
 
-  return OnDemandUpdateInternal(id);
+  OnDemandUpdateInternal(id, CompletionCallback());
+  return true;
 }
 
-bool CrxUpdateService::OnDemandUpdateInternal(const std::string& id) {
+void CrxUpdateService::OnDemandUpdateInternal(const std::string& id,
+                                              CompletionCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.Calls", UPDATE_TYPE_MANUAL,
                             UPDATE_TYPE_COUNT);
-
   update_client_->Install(
       id, base::Bind(&CrxUpdateService::OnUpdate, base::Unretained(this)),
       base::Bind(&CrxUpdateService::OnUpdateComplete, base::Unretained(this),
-                 base::TimeTicks::Now()));
-
-  return true;
+                 callback, base::TimeTicks::Now()));
 }
 
 bool CrxUpdateService::CheckForUpdates() {
@@ -301,7 +306,7 @@
         unsecure_ids,
         base::Bind(&CrxUpdateService::OnUpdate, base::Unretained(this)),
         base::Bind(&CrxUpdateService::OnUpdateComplete, base::Unretained(this),
-                   base::TimeTicks::Now()));
+                   CompletionCallback(), base::TimeTicks::Now()));
   }
 
   if (!secure_ids.empty()) {
@@ -309,7 +314,7 @@
         secure_ids,
         base::Bind(&CrxUpdateService::OnUpdate, base::Unretained(this)),
         base::Bind(&CrxUpdateService::OnUpdateComplete, base::Unretained(this),
-                   base::TimeTicks::Now()));
+                   CompletionCallback(), base::TimeTicks::Now()));
   }
 
   return true;
@@ -354,7 +359,8 @@
   }
 }
 
-void CrxUpdateService::OnUpdateComplete(const base::TimeTicks& start_time,
+void CrxUpdateService::OnUpdateComplete(CompletionCallback callback,
+                                        const base::TimeTicks& start_time,
                                         int error) {
   DCHECK(thread_checker_.CalledOnValidThread());
   VLOG(1) << "Update completed with error " << error;
@@ -370,6 +376,11 @@
         DoUnregisterComponent(*component);
     }
   }
+
+  if (!callback.is_null()) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  base::Bind(callback, error));
+  }
 }
 
 void CrxUpdateService::OnEvent(Events event, const std::string& id) {