summaryrefslogtreecommitdiffstats
path: root/core/java/android/webkit/WebSyncManager.java
blob: ded17ed518c781196aa6cd3435def8ce969fad2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.webkit;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;

abstract class WebSyncManager implements Runnable {
    // message code for sync message
    private static final int SYNC_MESSAGE = 101;
    // time delay in millisec for a sync (now) message
    private static int SYNC_NOW_INTERVAL = 100; // 100 millisec
    // time delay in millisec for a sync (later) message
    private static int SYNC_LATER_INTERVAL = 5 * 60 * 1000; // 5 minutes
    // thread for syncing
    private Thread mSyncThread;
    // Name of thread
    private String mThreadName;
    // handler of the sync thread
    protected Handler mHandler;
    // database for the persistent storage
    protected WebViewDatabase mDataBase;
    // Ref count for calls to start/stop sync
    private int mStartSyncRefCount;
    // log tag
    protected static final String LOGTAG = "websync";

    private class SyncHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == SYNC_MESSAGE) {
                if (WebView.LOGV_ENABLED) {
                    Log.v(LOGTAG, "*** WebSyncManager sync ***");
                }
                syncFromRamToFlash();

                // send a delayed message to request sync later
                Message newmsg = obtainMessage(SYNC_MESSAGE);
                sendMessageDelayed(newmsg, SYNC_LATER_INTERVAL);
            }
        }
    }

    protected WebSyncManager(Context context, String name) {
        mThreadName = name;
        if (context != null) {
            mDataBase = WebViewDatabase.getInstance(context);
            mSyncThread = new Thread(this);
            mSyncThread.setName(mThreadName);
            mSyncThread.start();
        } else {
            throw new IllegalStateException(
                    "WebSyncManager can't be created without context");
        }
    }

    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("doesn't implement Cloneable");
    }

    public void run() {
        // prepare Looper for sync handler
        Looper.prepare();
        mHandler = new SyncHandler();
        onSyncInit();
        // lower the priority after onSyncInit() is done
       Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

        Message msg = mHandler.obtainMessage(SYNC_MESSAGE);
        mHandler.sendMessageDelayed(msg, SYNC_LATER_INTERVAL);

        Looper.loop();
    }

    /**
     * sync() forces sync manager to sync now
     */
    public void sync() {
        if (WebView.LOGV_ENABLED) {
            Log.v(LOGTAG, "*** WebSyncManager sync ***");
        }
        if (mHandler == null) {
            return;
        }
        mHandler.removeMessages(SYNC_MESSAGE);
        Message msg = mHandler.obtainMessage(SYNC_MESSAGE);
        mHandler.sendMessageDelayed(msg, SYNC_NOW_INTERVAL);
    }

    /**
     * resetSync() resets sync manager's timer
     */
    public void resetSync() {
        if (WebView.LOGV_ENABLED) {
            Log.v(LOGTAG, "*** WebSyncManager resetSync ***");
        }
        if (mHandler == null) {
            return;
        }
        mHandler.removeMessages(SYNC_MESSAGE);
        Message msg = mHandler.obtainMessage(SYNC_MESSAGE);
        mHandler.sendMessageDelayed(msg, SYNC_LATER_INTERVAL);
    }

    /**
     * startSync() requests sync manager to start sync
     */
    public void startSync() {
        if (WebView.LOGV_ENABLED) {
            Log.v(LOGTAG, "***  WebSyncManager startSync ***, Ref count:" + 
                    mStartSyncRefCount);
        }
        if (mHandler == null) {
            return;
        }
        if (++mStartSyncRefCount == 1) {
            Message msg = mHandler.obtainMessage(SYNC_MESSAGE);
            mHandler.sendMessageDelayed(msg, SYNC_LATER_INTERVAL);
        }
    }

    /**
     * stopSync() requests sync manager to stop sync. remove any SYNC_MESSAGE in
     * the queue to break the sync loop
     */
    public void stopSync() {
        if (WebView.LOGV_ENABLED) {
            Log.v(LOGTAG, "*** WebSyncManager stopSync ***, Ref count:" + 
                    mStartSyncRefCount);
        }
        if (mHandler == null) {
            return;
        }
        if (--mStartSyncRefCount == 0) {
            mHandler.removeMessages(SYNC_MESSAGE);
        }
    }

    protected void onSyncInit() {
    }

    abstract void syncFromRamToFlash();
}