Chromium Code Reviews| Index: sync/android/java/src/org/chromium/sync/notifier/InvalidationController.java |
| diff --git a/sync/android/java/src/org/chromium/sync/notifier/InvalidationController.java b/sync/android/java/src/org/chromium/sync/notifier/InvalidationController.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9d5483e650893fd146e4f60ec8de3cdb029f5d2d |
| --- /dev/null |
| +++ b/sync/android/java/src/org/chromium/sync/notifier/InvalidationController.java |
| @@ -0,0 +1,180 @@ |
| +// Copyright (c) 2013 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.sync.notifier; |
| + |
| +import android.accounts.Account; |
| +import android.content.Context; |
| +import android.content.Intent; |
| +import android.content.pm.ApplicationInfo; |
| +import android.content.pm.PackageManager; |
| +import android.content.pm.PackageManager.NameNotFoundException; |
| +import android.util.Log; |
| + |
| +import com.google.common.base.Preconditions; |
| +import com.google.common.collect.Lists; |
| + |
| +import org.chromium.sync.ModelType; |
| + |
| +import java.util.Set; |
| + |
| +import javax.annotation.Nullable; |
| + |
| +/** |
| + * Controller used to send start, stop, and registration-change commands to the invalidation |
| + * client library used by Sync. |
| + */ |
| +public class InvalidationController { |
| + /** |
| + * Constants and utility methods to create the intents used to communicate between the |
| + * controller and the invalidation client library. |
| + */ |
| + public static class IntentProtocol { |
| + /** |
| + * Action set on register intents. |
| + */ |
| + public static final String ACTION_REGISTER = |
| + "org.chromium.sync.notifier.ACTION_REGISTER_TYPES"; |
| + /** |
|
Yaron
2013/01/10 19:29:40
Nit: missing ws above
nyquist
2013/01/10 22:01:42
Done.
|
| + * Special syncable type that lets us know to sync all types. |
| + */ |
| + public static final String ALL_TYPES_TYPE = "ALL_TYPES"; |
| + |
| + /** |
| + * Parcelable-valued intent extra containing the account of the user. |
| + */ |
| + public static final String EXTRA_ACCOUNT = "account"; |
| + |
| + /** |
| + * String-list-valued intent extra of the syncable types to sync. |
| + */ |
| + public static final String EXTRA_REGISTERED_TYPES = "registered_types"; |
| + |
| + /** |
| + * Boolean-valued intent extra indicating that the service should be stopped. |
| + */ |
| + public static final String EXTRA_STOP = "stop"; |
| + |
| + /** |
| + * Create an Intent that will start the invalidation listener service and |
| + * register for the specified types. |
| + */ |
| + public static Intent createRegisterIntent(Account account, |
| + boolean allTypes, Set<ModelType> types) { |
| + Intent registerIntent = new Intent(ACTION_REGISTER); |
| + String[] selectedTypesArray; |
| + if (allTypes) { |
| + selectedTypesArray = new String[]{ALL_TYPES_TYPE}; |
| + } else { |
| + selectedTypesArray = new String[types.size()]; |
| + int pos = 0; |
| + for (ModelType type : types) { |
| + selectedTypesArray[pos++] = type.name(); |
| + } |
| + } |
| + registerIntent.putStringArrayListExtra(EXTRA_REGISTERED_TYPES, |
| + Lists.newArrayList(selectedTypesArray)); |
| + registerIntent.putExtra(EXTRA_ACCOUNT, account); |
| + return registerIntent; |
| + } |
| + |
| + private IntentProtocol() { |
| + // Disallow instantiation. |
| + } |
| + } |
| + |
| + /** |
| + * Name of the manifest application metadata property specifying the name of the class |
| + * implementing the invalidation client. |
| + */ |
| + private static final String IMPL_CLASS_MANIFEST_PROPERTY = |
|
Yaron
2013/01/10 19:29:40
nit: IMPLEMENTING_CLASS_NAME? Seems like the brevi
nyquist
2013/01/10 22:01:42
Done.
|
| + "org.chromium.sync.notifier.IMPL_CLASS_NAME"; |
| + |
| + /** |
| + * Logging tag. |
| + */ |
| + private static final String TAG = InvalidationController.class.getSimpleName(); |
| + |
| + private final Context context; |
| + |
| + /** |
| + * Sets the types for which the client should register for notifications. |
| + * |
| + * @param account Account of the user. |
| + * @param allTypes If {@code true}, registers for all types, and {@code types} is ignored |
| + * @param types Set of types for which to register. Ignored if {@code allTypes == true}. |
| + */ |
| + public void setRegisteredTypes(Account account, boolean allTypes, Set<ModelType> types) { |
| + Intent registerIntent = IntentProtocol.createRegisterIntent(account, allTypes, types); |
| + setDestinationClassName(registerIntent); |
| + context.startService(registerIntent); |
| + } |
| + |
| + /** |
| + * Starts the invalidation client. |
| + */ |
| + public void start() { |
| + Intent intent = setDestinationClassName(new Intent()); |
| + context.startService(intent); |
| + } |
| + |
| + /** |
| + * Stops the invalidation client. |
| + */ |
| + public void stop() { |
| + Intent intent = setDestinationClassName(new Intent()); |
| + intent.putExtra(IntentProtocol.EXTRA_STOP, true); |
| + context.startService(intent); |
| + } |
| + |
| + /** |
| + * Returns the contract authority to use when requesting sync. |
| + */ |
| + public String getContractAuthority() { |
| + return context.getPackageName(); |
| + } |
| + |
| + /** |
| + * Returns a new instance that will use {@code context} to issue intents. |
| + */ |
| + public static InvalidationController newInstance(Context context) { |
| + return new InvalidationController(context); |
| + } |
| + |
| + /** |
| + * Creates an instance using {@code context} to send intents. |
| + */ |
| + private InvalidationController(Context context) { |
| + this.context = Preconditions.checkNotNull(context.getApplicationContext()); |
| + } |
| + |
| + /** |
| + * Sets the destination class name of {@code intent} to the value given by the manifest |
| + * property named {@link #IMPL_CLASS_MANIFEST_PROPERTY}. If no such property exists or its |
| + * value is null, takes no action. |
| + * |
| + * @return {@code intent} |
| + */ |
| + private Intent setDestinationClassName(Intent intent) { |
| + @Nullable ApplicationInfo appInfo; |
|
Yaron
2013/01/10 19:29:40
We don't really make use of @Nullable elsewhere so
nyquist
2013/01/10 22:01:42
Done.
|
| + try { |
| + // Fetch application info and read the appropriate metadata element. |
| + appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), |
| + PackageManager.GET_META_DATA); |
| + @Nullable String className = null; |
|
Yaron
2013/01/10 19:29:40
same
nyquist
2013/01/10 22:01:42
Done.
|
| + if (appInfo.metaData != null) { |
| + className = appInfo.metaData.getString(IMPL_CLASS_MANIFEST_PROPERTY); |
| + } |
| + if (className == null) { |
| + Log.wtf(TAG, "No value for " + IMPL_CLASS_MANIFEST_PROPERTY |
| + + " in manifest; sync notifications will not work"); |
| + } else { |
| + intent.setClassName(context, className); |
| + } |
| + } catch (NameNotFoundException exception) { |
| + Log.e(TAG, "Cannot read own application info", exception); |
|
Yaron
2013/01/10 19:29:40
THis is also a wtf moment?
nyquist
2013/01/10 22:01:42
Done.
|
| + } |
| + return intent; |
| + } |
| +} |