Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/gcore/ConnectedTask.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java_staging/src/org/chromium/chrome/browser/gcore/ConnectedTask.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/gcore/ConnectedTask.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/gcore/ConnectedTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..39fcfe73b4930a646c69b5903b0b7d042489e52d
--- /dev/null
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/gcore/ConnectedTask.java
@@ -0,0 +1,136 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.gcore;
+
+import org.chromium.base.Log;
+import org.chromium.base.TraceEvent;
+import org.chromium.base.VisibleForTesting;
+import org.chromium.base.annotations.NoSideEffects;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Base class for tasks which connects to Google Play Services using given GoogleApiClient,
+ * performs action specified in doWhenConnected method, disconnects the client and cleans up
+ * by invoking cleanUp method.
+ *
+ * <p>
+ * Using the same client for tasks running in more than one thread is a serious error, as
+ * the state can then be modified while other threads are still using the client. The
+ * recommended way to use these tasks is with a {@link java.util.concurrent.ThreadPoolExecutor}
+ * having a pool size of 1.
+ * </p>
+ * <p>
+ * This class waits {@link #CONNECTION_TIMEOUT_MS} milliseconds for connection to be established.
+ * If connection is unsuccessful then it will retry after {@link #CONNECTION_RETRY_TIME_MS}
+ * milliseconds as long as Google Play Services is available. Number of retries is limited to
+ * {@link #RETRY_NUMBER_LIMIT}.
+ * </p>
+ *
+ * @param <T> type of {@link ChromeGoogleApiClient} to use for the tasks
+ */
+public abstract class ConnectedTask<T extends ChromeGoogleApiClient> implements Runnable {
+ private static final String TAG = Log.makeTag("GCore");
+
+ public static final long CONNECTION_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5);
+ public static final long CONNECTION_RETRY_TIME_MS = TimeUnit.SECONDS.toMillis(10);
+ public static final int RETRY_NUMBER_LIMIT = 5;
+
+ private final T mClient;
+ private int mRetryNumber;
+
+ /**
+ * Used for logging and tracing.
+ * <ul>
+ * <li>Log format: "{logPrefix}| {{@link #getName()}} {message}"</li>
+ * <li>Trace format: "ConnectedTask:{logPrefix}:{traceEventName}"</li>
+ * </ul>
+ */
+ private final String mLogPrefix;
+
+ /**
+ * @param client
+ * @param logPrefix used for logging and tracing.
+ */
+ public ConnectedTask(T client, String logPrefix) {
+ assert logPrefix != null;
+ mClient = client;
+ mLogPrefix = logPrefix;
+ }
+
+ /** Creates a connected task with an empty log prefix. */
+ @VisibleForTesting
+ public ConnectedTask(T client) {
+ this(client, "");
+ }
+
+ /**
+ * Executed with client connected to Google Play Services.
+ * This method is intended to be overridden by a subclass.
+ */
+ protected abstract void doWhenConnected(T client);
+
+ /**
+ * Returns a name of a task. Implementations should not have side effects
+ * as we want to have the logging related calls removed.
+ */
+ @NoSideEffects
+ protected abstract String getName();
+
+ /**
+ * Executed after doWhenConnected was done and client was disconnected.
+ * May also be executed when Google Play Services is no longer available, which means connection
+ * was unsuccessful and won't be retried.
+ * This method is intended to be overridden by a subclass.
+ */
+ protected void cleanUp() {}
+
+ /**
+ * Executed if the connection was unsuccessful.
+ * This method is intended to be overridden by a subclass.
+ */
+ protected void connectionFailed() {}
+
+ @Override
+ @VisibleForTesting
+ public final void run() {
+ TraceEvent.begin("GCore:" + mLogPrefix + ":run");
+ try {
+ Log.d(TAG, "%s:%s started", mLogPrefix, getName());
+ if (mClient.connectWithTimeout(CONNECTION_TIMEOUT_MS)) {
+ try {
+ Log.d(TAG, "%s:%s connected", mLogPrefix, getName());
+ doWhenConnected(mClient);
+ Log.d(TAG, "%s:%s finished", mLogPrefix, getName());
+ } finally {
+ mClient.disconnect();
+ Log.d(TAG, "%s:%s disconnected", mLogPrefix, getName());
+ cleanUp();
+ Log.d(TAG, "%s:%s cleaned up", mLogPrefix, getName());
+ }
+ } else {
+ mRetryNumber++;
+ if (mRetryNumber < RETRY_NUMBER_LIMIT && mClient.isGooglePlayServicesAvailable()) {
+ Log.d(TAG, "%s:%s calling retry", mLogPrefix, getName());
+ retry(this, CONNECTION_RETRY_TIME_MS);
+ } else {
+ connectionFailed();
+ Log.d(TAG, "%s:%s number of retries exceeded", mLogPrefix, getName());
+ cleanUp();
+ Log.d(TAG, "%s:%s cleaned up", mLogPrefix, getName());
+ }
+ }
+ } catch (RuntimeException e) {
+ Log.e(TAG, "%s:%s runtime exception %s: %s", mLogPrefix, getName(),
+ e.getClass().getName(), e.getMessage());
+ throw e;
+ } finally {
+ TraceEvent.end("GCore:" + mLogPrefix + ":run");
+ }
+ }
+
+ /** Method to implement to determine how to run the retry task. */
+ protected abstract void retry(Runnable task, long delayMs);
+}

Powered by Google App Engine
This is Rietveld 408576698