2df5f060c057af35e32df374a2f251abf89cf932
[platform/framework/web/crosswalk.git] / src / chrome / android / java / src / org / chromium / chrome / browser / sync / DelayedSyncController.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.sync;
6
7 import android.accounts.Account;
8 import android.content.ContentResolver;
9 import android.content.Context;
10 import android.content.SharedPreferences;
11 import android.os.AsyncTask;
12 import android.os.Bundle;
13 import android.preference.PreferenceManager;
14 import android.util.Log;
15
16 import com.google.common.annotations.VisibleForTesting;
17
18 import org.chromium.base.ApplicationStatus;
19 import org.chromium.sync.notifier.SyncStatusHelper;
20 import org.chromium.sync.signin.AccountManagerHelper;
21
22 /**
23  * A class for controlling when a sync should be performed immediately, and when it should be
24  * delayed until Chrome comes to the foreground again.
25  */
26 public class DelayedSyncController {
27     private static final String TAG = "DelayedSyncController";
28     private static final String DELAYED_ACCOUNT_NAME = "delayed_account";
29
30     private static class LazyHolder {
31         private static final DelayedSyncController INSTANCE = new DelayedSyncController();
32     }
33
34     public static DelayedSyncController getInstance() {
35         return LazyHolder.INSTANCE;
36     }
37
38     @VisibleForTesting
39     DelayedSyncController() {}
40
41     /**
42      * Resume any syncs that were delayed while Chromium was backgrounded.
43      */
44     public boolean resumeDelayedSyncs(final Context context) {
45         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
46         String accountName = prefs.getString(DELAYED_ACCOUNT_NAME, null);
47         if (accountName == null) {
48             Log.d(TAG, "No delayed sync.");
49             return false;
50         } else {
51             Log.d(TAG, "Handling delayed sync.");
52             Account account = AccountManagerHelper.createAccountFromName(accountName);
53             requestSyncOnBackgroundThread(context, account);
54             return true;
55         }
56     }
57
58     /**
59      * Calls ContentResolver.requestSync() in a separate thread as it performs some blocking
60      * IO operations.
61      */
62     @VisibleForTesting
63     void requestSyncOnBackgroundThread(final Context context, final Account account) {
64         new AsyncTask<Void, Void, Void>() {
65             @Override
66             protected Void doInBackground(Void... unused) {
67                 String contractAuthority =
68                         SyncStatusHelper.get(context).getContractAuthority();
69                 ContentResolver.requestSync(account, contractAuthority, new Bundle());
70                 return null;
71             }
72         }.execute();
73     }
74
75     /**
76      * Stores preferences to indicate that an invalidation has arrived, but dropped on the floor.
77      */
78     void setDelayedSync(Context ctx, String accountName) {
79         SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(ctx).edit();
80         editor.putString(DELAYED_ACCOUNT_NAME, accountName);
81         editor.apply();
82     }
83
84     /**
85      * If there is a delayed sync, it will be cleared.
86      */
87     @VisibleForTesting
88     void clearDelayedSyncs(Context context) {
89         setDelayedSync(context, null);
90     }
91
92     @VisibleForTesting
93     boolean shouldPerformSync(Context ctx, Bundle extras, Account account) {
94         boolean manualSync = isManualSync(extras);
95
96         if (manualSync || ApplicationStatus.hasVisibleActivities()) {
97             clearDelayedSyncs(ctx);
98             return true;
99         } else {
100             Log.d(TAG, "Delaying sync.");
101             setDelayedSync(ctx, account.name);
102             return false;
103         }
104     }
105
106     private static boolean isManualSync(Bundle extras) {
107         boolean manualSync = false;
108         if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)) {
109             manualSync = true;
110             Log.d(TAG, "Manual sync requested.");
111         }
112         return manualSync;
113     }
114 }