1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.chrome.browser.invalidation;
7 import android.accounts.Account;
8 import android.content.Context;
9 import android.content.Intent;
11 import org.chromium.base.ApplicationState;
12 import org.chromium.base.ApplicationStatus;
13 import org.chromium.base.CalledByNative;
14 import org.chromium.base.VisibleForTesting;
15 import org.chromium.sync.internal_api.pub.base.ModelType;
16 import org.chromium.sync.notifier.InvalidationClientNameProvider;
17 import org.chromium.sync.notifier.InvalidationIntentProtocol;
18 import org.chromium.sync.notifier.InvalidationPreferences;
19 import org.chromium.sync.notifier.InvalidationService;
20 import org.chromium.sync.notifier.SyncStatusHelper;
25 * Controller used to send start, stop, and registration-change commands to the invalidation
26 * client library used by Sync.
28 public class InvalidationController implements ApplicationStatus.ApplicationStateListener {
29 private static final Object LOCK = new Object();
31 private static InvalidationController sInstance;
33 private final Context mContext;
36 * Sets the types for which the client should register for notifications.
38 * @param account Account of the user.
39 * @param allTypes If {@code true}, registers for all types, and {@code types} is ignored
40 * @param types Set of types for which to register. Ignored if {@code allTypes == true}.
42 public void setRegisteredTypes(Account account, boolean allTypes, Set<ModelType> types) {
43 Intent registerIntent =
44 InvalidationIntentProtocol.createRegisterIntent(account, allTypes, types);
45 registerIntent.setClass(mContext, InvalidationService.class);
46 mContext.startService(registerIntent);
50 * Reads all stored preferences and calls
51 * {@link #setRegisteredTypes(android.accounts.Account, boolean, java.util.Set)} with the stored
52 * values, refreshing the set of types with {@code types}. It can be used on startup of Chrome
53 * to ensure we always have a set of registrations consistent with the native code.
54 * @param types Set of types for which to register.
56 public void refreshRegisteredTypes(Set<ModelType> types) {
57 InvalidationPreferences invalidationPreferences = new InvalidationPreferences(mContext);
58 Set<String> savedSyncedTypes = invalidationPreferences.getSavedSyncedTypes();
59 Account account = invalidationPreferences.getSavedSyncedAccount();
60 boolean allTypes = savedSyncedTypes != null &&
61 savedSyncedTypes.contains(ModelType.ALL_TYPES_TYPE);
62 setRegisteredTypes(account, allTypes, types);
66 * Sets object ids for which the client should register for notification. This is intended for
67 * registering non-Sync types; Sync types are registered with {@code setRegisteredTypes}.
69 * @param objectSources The sources of the objects.
70 * @param objectNames The names of the objects.
73 public void setRegisteredObjectIds(int[] objectSources, String[] objectNames) {
74 InvalidationPreferences invalidationPreferences = new InvalidationPreferences(mContext);
75 Account account = invalidationPreferences.getSavedSyncedAccount();
76 Intent registerIntent =
77 InvalidationIntentProtocol.createRegisterIntent(
78 account, objectSources, objectNames);
79 registerIntent.setClass(mContext, InvalidationService.class);
80 mContext.startService(registerIntent);
84 * Starts the invalidation client.
87 Intent intent = new Intent(mContext, InvalidationService.class);
88 mContext.startService(intent);
92 * Stops the invalidation client.
95 Intent intent = new Intent(mContext, InvalidationService.class);
96 intent.putExtra(InvalidationIntentProtocol.EXTRA_STOP, true);
97 mContext.startService(intent);
101 * Returns the instance that will use {@code context} to issue intents.
103 * Calling this method will create the instance if it does not yet exist.
106 public static InvalidationController get(Context context) {
107 synchronized (LOCK) {
108 if (sInstance == null) {
109 sInstance = new InvalidationController(context);
116 * Creates an instance using {@code context} to send intents.
119 InvalidationController(Context context) {
120 Context appContext = context.getApplicationContext();
121 if (appContext == null) throw new NullPointerException("Unable to get application context");
122 mContext = appContext;
123 ApplicationStatus.registerApplicationStateListener(this);
127 public void onApplicationStateChange(int newState) {
128 if (SyncStatusHelper.get(mContext).isSyncEnabled()) {
129 if (newState == ApplicationState.HAS_RUNNING_ACTIVITIES) {
131 } else if (newState == ApplicationState.HAS_PAUSED_ACTIVITIES) {
138 * Fetches the Invalidator client name.
140 * Note that there is a naming discrepancy here. In C++, we refer to the invalidation client
141 * identifier that is unique for every invalidation client instance in an account as the client
142 * ID. In Java, we call it the client name.
145 public byte[] getInvalidatorClientId() {
146 return InvalidationClientNameProvider.get().getInvalidatorClientName();