Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / android / java / src / org / chromium / chrome / browser / invalidation / InvalidationController.java
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.
4
5 package org.chromium.chrome.browser.invalidation;
6
7 import android.accounts.Account;
8 import android.content.Context;
9 import android.content.Intent;
10
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;
21
22 import java.util.Set;
23
24 /**
25  * Controller used to send start, stop, and registration-change commands to the invalidation
26  * client library used by Sync.
27  */
28 public class InvalidationController implements ApplicationStatus.ApplicationStateListener {
29     private static final Object LOCK = new Object();
30
31     private static InvalidationController sInstance;
32
33     private final Context mContext;
34
35     /**
36      * Sets the types for which the client should register for notifications.
37      *
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}.
41      */
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);
47     }
48
49     /**
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.
55      */
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);
63     }
64
65     /**
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}.
68      *
69      * @param objectSources The sources of the objects.
70      * @param objectNames   The names of the objects.
71      */
72     @CalledByNative
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);
81     }
82
83     /**
84      * Starts the invalidation client.
85      */
86     public void start() {
87         Intent intent = new Intent(mContext, InvalidationService.class);
88         mContext.startService(intent);
89     }
90
91     /**
92      * Stops the invalidation client.
93      */
94     public void stop() {
95         Intent intent = new Intent(mContext, InvalidationService.class);
96         intent.putExtra(InvalidationIntentProtocol.EXTRA_STOP, true);
97         mContext.startService(intent);
98     }
99
100     /**
101      * Returns the instance that will use {@code context} to issue intents.
102      *
103      * Calling this method will create the instance if it does not yet exist.
104      */
105     @CalledByNative
106     public static InvalidationController get(Context context) {
107         synchronized (LOCK) {
108             if (sInstance == null) {
109                 sInstance = new InvalidationController(context);
110             }
111             return sInstance;
112         }
113     }
114
115     /**
116      * Creates an instance using {@code context} to send intents.
117      */
118     @VisibleForTesting
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);
124     }
125
126     @Override
127     public void onApplicationStateChange(int newState) {
128         if (SyncStatusHelper.get(mContext).isSyncEnabled()) {
129             if (newState == ApplicationState.HAS_RUNNING_ACTIVITIES) {
130                 start();
131             } else if (newState == ApplicationState.HAS_PAUSED_ACTIVITIES) {
132                 stop();
133             }
134         }
135     }
136
137     /**
138      * Fetches the Invalidator client name.
139      *
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.
143      */
144     @CalledByNative
145     public byte[] getInvalidatorClientId() {
146         return InvalidationClientNameProvider.get().getInvalidatorClientName();
147     }
148 }