Bug 849072 - Persist tab state with a delayed de-bounced background handler callback. r=rnewman,nalexander

This commit is contained in:
Jamie Hewland 2013-05-19 14:18:49 -07:00
parent 8ff870575b
commit 653da06f63

View File

@ -19,6 +19,7 @@ import android.content.ContentResolver;
import android.database.ContentObserver;
import android.graphics.Color;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import java.util.ArrayList;
@ -57,9 +58,7 @@ public class Tabs implements GeckoEventListener {
public static final int LOADURL_DESKTOP = 32;
public static final int LOADURL_BACKGROUND = 64;
private static final int SCORE_INCREMENT_TAB_LOCATION_CHANGE = 5;
private static final int SCORE_INCREMENT_TAB_SELECTED = 10;
private static final int SCORE_THRESHOLD = 30;
private static final long PERSIST_TABS_AFTER_MILLISECONDS = 1000 * 5;
private static AtomicInteger sTabId = new AtomicInteger(0);
private volatile boolean mInitialTabsAdded;
@ -67,6 +66,16 @@ public class Tabs implements GeckoEventListener {
private GeckoApp mActivity;
private ContentObserver mContentObserver;
private final Runnable mPersistTabsRunnable = new Runnable() {
@Override
public void run() {
boolean syncIsSetup = SyncAccounts.syncAccountsExist(getActivity());
if (syncIsSetup) {
TabsAccessor.persistLocalTabs(getContentResolver(), getTabsInOrder());
}
}
};
private Tabs() {
registerEventListener("Session:RestoreEnd");
registerEventListener("SessionHistory:New");
@ -122,6 +131,8 @@ public class Tabs implements GeckoEventListener {
// requires us to keep it around (see
// https://bugzilla.mozilla.org/show_bug.cgi?id=844407).
public synchronized void detachFromActivity(GeckoApp activity) {
ThreadUtils.getBackgroundHandler().removeCallbacks(mPersistTabsRunnable);
if (mContentObserver != null) {
BrowserDB.unregisterContentObserver(getContentResolver(), mContentObserver);
}
@ -545,44 +556,40 @@ public class Tabs implements GeckoEventListener {
private void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
switch (msg) {
case LOCATION_CHANGE:
mScore += SCORE_INCREMENT_TAB_LOCATION_CHANGE;
queuePersistAllTabs();
break;
case RESTORED:
mInitialTabsAdded = true;
break;
// When one tab is deselected, another one is always selected, so only
// increment the score once. When tabs are added/closed, they are also
// selected/unselected, so it would be redundant to also listen
// queue a single persist operation. When tabs are added/closed, they
// are also selected/unselected, so it would be redundant to also listen
// for ADDED/CLOSED events.
case SELECTED:
mScore += SCORE_INCREMENT_TAB_SELECTED;
queuePersistAllTabs();
case UNSELECTED:
tab.onChange();
break;
default:
break;
}
if (mScore > SCORE_THRESHOLD) {
persistAllTabs();
mScore = 0;
}
}
// This method persists the current ordered list of tabs in our tabs content provider.
public void persistAllTabs() {
final GeckoApp activity = getActivity();
final Iterable<Tab> tabs = getTabsInOrder();
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
boolean syncIsSetup = SyncAccounts.syncAccountsExist(activity);
if (syncIsSetup) {
TabsAccessor.persistLocalTabs(getContentResolver(), tabs);
}
}
});
ThreadUtils.postToBackgroundThread(mPersistTabsRunnable);
}
/**
* Queues a request to persist tabs after PERSIST_TABS_AFTER_MILLISECONDS
* milliseconds have elapsed. If any existing requests are already queued then
* those requests are removed.
*/
private void queuePersistAllTabs() {
Handler backgroundHandler = ThreadUtils.getBackgroundHandler();
backgroundHandler.removeCallbacks(mPersistTabsRunnable);
backgroundHandler.postDelayed(mPersistTabsRunnable, PERSIST_TABS_AFTER_MILLISECONDS);
}
private void registerEventListener(String event) {