Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / android / java / src / org / chromium / chrome / browser / tabmodel / TabModelBase.java
index 91e1423..58ae327 100644 (file)
@@ -4,13 +4,9 @@
 
 package org.chromium.chrome.browser.tabmodel;
 
-import android.os.SystemClock;
-
-import org.chromium.base.CalledByNative;
 import org.chromium.base.ObserverList;
 import org.chromium.base.TraceEvent;
 import org.chromium.chrome.browser.Tab;
-import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.util.MathUtils;
 import org.chromium.content_public.browser.WebContents;
 
@@ -20,16 +16,9 @@ import java.util.List;
 /**
  * This is the default implementation of the {@link TabModel} interface.
  */
-public abstract class TabModelBase implements TabModel {
+public abstract class TabModelBase extends TabModelJniBridge {
     private static final String TAG = "TabModelBase";
 
-    // TODO(dtrainor, simonb): Make these non-static so we don't break if we have multiple instances
-    // of chrome running.  Also investigate how this affects document mode.
-    private static long sTabSwitchStartTime;
-    private static TabSelectionType sTabSelectionType;
-    private static boolean sTabSwitchLatencyMetricRequired;
-    private static boolean sPerceivedTabSwitchLatencyMetricLogged;
-
     /**
      * The main list of tabs.  Note that when this changes, all pending closures must be committed
      * via {@link #commitAllTabClosures()} as the indices are no longer valid. Also
@@ -38,8 +27,6 @@ public abstract class TabModelBase implements TabModel {
      */
     private final List<Tab> mTabs = new ArrayList<Tab>();
 
-    private final boolean mIsIncognito;
-
     private final TabModelOrderController mOrderController;
 
     protected final TabModelDelegate mModelDelegate;
@@ -61,43 +48,26 @@ public abstract class TabModelBase implements TabModel {
      */
     private int mIndex = INVALID_TAB_INDEX;
 
-    /** Native Tab pointer which will be set by nativeInit(). */
-    private long mNativeTabModelImpl = 0;
-
     public TabModelBase(boolean incognito, TabModelOrderController orderController,
             TabModelDelegate modelDelegate) {
-        mIsIncognito = incognito;
-        mNativeTabModelImpl = nativeInit(incognito);
+        super(incognito);
+        initializeNative();
         mOrderController = orderController;
         mModelDelegate = modelDelegate;
         mObservers = new ObserverList<TabModelObserver>();
     }
 
     @Override
-    public Profile getProfile() {
-        return nativeGetProfileAndroid(mNativeTabModelImpl);
-    }
-
-    @Override
-    public boolean isIncognito() {
-        return mIsIncognito;
-    }
-
-    @Override
     public void destroy() {
         for (Tab tab : mTabs) {
             if (tab.isInitialized()) tab.destroy();
         }
 
         mRewoundList.destroy();
-
-        if (mNativeTabModelImpl != 0) {
-            nativeDestroy(mNativeTabModelImpl);
-            mNativeTabModelImpl = 0;
-        }
-
         mTabs.clear();
         mObservers.clear();
+
+        super.destroy();
     }
 
     @Override
@@ -120,12 +90,12 @@ public abstract class TabModelBase implements TabModel {
 
         for (TabModelObserver obs : mObservers) obs.willAddTab(tab, type);
 
-        boolean selectTab = mOrderController.willOpenInForeground(type, mIsIncognito);
+        boolean selectTab = mOrderController.willOpenInForeground(type, isIncognito());
 
         index = mOrderController.determineInsertionIndex(type, index, tab);
         assert index <= mTabs.size();
 
-        assert tab.isIncognito() == mIsIncognito;
+        assert tab.isIncognito() == isIncognito();
 
         // TODO(dtrainor): Update the list of undoable tabs instead of committing it.
         commitAllTabClosures();
@@ -152,12 +122,12 @@ public abstract class TabModelBase implements TabModel {
         mModelDelegate.didChange();
         mModelDelegate.didCreateNewTab(tab);
 
-        if (mNativeTabModelImpl != 0) nativeTabAddedToModel(mNativeTabModelImpl, tab);
+        tabAddedToModel(tab);
 
         for (TabModelObserver obs : mObservers) obs.didAddTab(tab, type);
 
         if (selectTab) {
-            mModelDelegate.selectModel(mIsIncognito);
+            mModelDelegate.selectModel(isIncognito());
             setIndex(newIndex, TabModel.TabSelectionType.FROM_NEW);
         }
 
@@ -197,15 +167,14 @@ public abstract class TabModelBase implements TabModel {
     }
 
     @Override
-    @CalledByNative
     public boolean closeTab(Tab tab) {
         return closeTab(tab, true, false, false);
     }
 
     private Tab findTabInAllTabModels(int tabId) {
-        Tab tab = TabModelUtils.getTabById(mModelDelegate.getModel(mIsIncognito), tabId);
+        Tab tab = TabModelUtils.getTabById(mModelDelegate.getModel(isIncognito()), tabId);
         if (tab != null) return tab;
-        return TabModelUtils.getTabById(mModelDelegate.getModel(!mIsIncognito), tabId);
+        return TabModelUtils.getTabById(mModelDelegate.getModel(!isIncognito()), tabId);
     }
 
     @Override
@@ -231,7 +200,7 @@ public abstract class TabModelBase implements TabModel {
             nextTab = parentTab;
         } else if (adjacentTab != null) {
             nextTab = adjacentTab;
-        } else if (mIsIncognito) {
+        } else if (isIncognito()) {
             nextTab = TabModelUtils.getCurrentTab(mModelDelegate.getModel(false));
         }
 
@@ -245,7 +214,7 @@ public abstract class TabModelBase implements TabModel {
 
     @Override
     public boolean supportsPendingClosures() {
-        return !mIsIncognito;
+        return !isIncognito();
     }
 
     @Override
@@ -287,7 +256,7 @@ public abstract class TabModelBase implements TabModel {
         // If we're the active model call setIndex to actually select this tab, otherwise just set
         // mIndex but don't kick off everything that happens when calling setIndex().
         if (activeModel) {
-            setIndex(insertIndex);
+            TabModelUtils.setIndex(this, insertIndex);
         } else {
             mIndex = insertIndex;
         }
@@ -318,6 +287,19 @@ public abstract class TabModelBase implements TabModel {
 
     @Override
     public boolean closeTab(Tab tabToClose, boolean animate, boolean uponExit, boolean canUndo) {
+        return closeTab(tabToClose, animate, uponExit, canUndo, canUndo);
+    }
+
+    /**
+     * See TabModel.java documentation for description of other parameters.
+     * @param notify Whether or not to notify observers about the pending closure. If this is
+     *               {@code true}, {@link #supportsPendingClosures()} is {@code true},
+     *               and canUndo is {@code true}, observers will be notified of the pending
+     *               closure. Observers will still be notified of a committed/cancelled closure
+     *               even if they are not notified of a pending closure to start with.
+     */
+    private boolean closeTab(Tab tabToClose, boolean animate, boolean uponExit,
+            boolean canUndo, boolean notify) {
         if (tabToClose == null) {
             assert false : "Tab is null!";
             return false;
@@ -330,7 +312,7 @@ public abstract class TabModelBase implements TabModel {
 
         canUndo &= supportsPendingClosures();
 
-        if (canUndo) {
+        if (notify && canUndo) {
             for (TabModelObserver obs : mObservers) obs.tabPendingClosure(tabToClose);
         }
         startTabClosure(tabToClose, animate, uponExit, canUndo);
@@ -341,6 +323,11 @@ public abstract class TabModelBase implements TabModel {
 
     @Override
     public void closeAllTabs() {
+        closeAllTabs(true, false);
+    }
+
+    @Override
+    public void closeAllTabs(boolean allowDelegation, boolean uponExit) {
         commitAllTabClosures();
 
         while (getCount() > 0) {
@@ -348,8 +335,30 @@ public abstract class TabModelBase implements TabModel {
         }
     }
 
+    /**
+     * Close all tabs on this model without notifying observers about pending tab closures.
+     *
+     * @param animate true iff the closing animation should be displayed
+     * @param uponExit true iff the tabs are being closed upon application exit (after user presses
+     *                 the system back button)
+     * @param canUndo Whether or not this action can be undone. If this is {@code true} and
+     *                {@link #supportsPendingClosures()} is {@code true}, these {@link Tab}s
+     *                will not actually be closed until {@link #commitTabClosure(int)} or
+     *                {@link #commitAllTabClosures()} is called, but they will be effectively
+     *                removed from this list.
+     * @return a list containing the ids of tabs that have been closed
+     */
+    public ArrayList<Integer> closeAllTabs(boolean animate, boolean uponExit, boolean canUndo) {
+        ArrayList<Integer> closedTabs = new ArrayList<Integer>();
+        while (getCount() > 0) {
+            Tab tab = getTabAt(0);
+            closedTabs.add(tab.getId());
+            closeTab(tab, animate, uponExit, canUndo, false);
+        }
+        return closedTabs;
+    }
+
     @Override
-    @CalledByNative
     public Tab getTabAt(int index) {
         // This will catch INVALID_TAB_INDEX and return null
         if (index < 0 || index >= mTabs.size()) return null;
@@ -410,16 +419,6 @@ public abstract class TabModelBase implements TabModel {
     }
 
     /**
-     * @param incognito
-     * @param nativeWebContents
-     * @param parentId
-     * @return
-     */
-    @CalledByNative
-    protected abstract Tab createTabWithNativeContents(boolean incognito, long nativeWebContents,
-            int parentId);
-
-    /**
      * Performs the necessary actions to remove this {@link Tab} from this {@link TabModel}.
      * This does not actually destroy the {@link Tab} (see
      * {@link #finalizeTabClosure(Tab)}.
@@ -488,7 +487,7 @@ public abstract class TabModelBase implements TabModel {
          * rewindable closes were undone). If there are no possible rewindable closes this list
          * should match {@link #mTabs}.
          */
-        private List<Tab> mRewoundTabs = new ArrayList<Tab>();
+        private final List<Tab> mRewoundTabs = new ArrayList<Tab>();
 
         @Override
         public boolean isIncognito() {
@@ -603,119 +602,23 @@ public abstract class TabModelBase implements TabModel {
         }
     }
 
-    /**
-     * Broadcast a notification (in native code) that all tabs are now loaded from storage.
-     */
-    public void broadcastSessionRestoreComplete() {
-        nativeBroadcastSessionRestoreComplete(mNativeTabModelImpl);
+    @Override
+    protected boolean closeTabAt(int index) {
+        return closeTab(getTabAt(index));
     }
 
-    // JNI related methods -------------------------------------------------------------------------
-
     @Override
-    @CalledByNative
     public int getCount() {
         return mTabs.size();
     }
 
     @Override
-    @CalledByNative
     public int index() {
         return mIndex;
     }
 
-    @SuppressWarnings("unused")
-    @CalledByNative
-    private void setIndex(int index) {
-        TabModelUtils.setIndex(this, index);
-    }
-
-    /**
-     * Used by Developer Tools to create a new tab with a given URL.
-     *
-     * @param url The URL to open.
-     * @return The new tab.
-     */
-    @CalledByNative
-    protected abstract Tab createNewTabForDevTools(String url);
-
-    @CalledByNative
-    private boolean isSessionRestoreInProgress() {
+    @Override
+    protected boolean isSessionRestoreInProgress() {
         return mModelDelegate.isSessionRestoreInProgress();
     }
-
-    /**
-     * Register the start of tab switch latency timing. Called when setIndex() indicates a tab
-     * switch event.
-     * @param type The type of action that triggered the tab selection.
-     */
-    public static void startTabSwitchLatencyTiming(final TabSelectionType type) {
-        sTabSwitchStartTime = SystemClock.uptimeMillis();
-        sTabSelectionType = type;
-        sTabSwitchLatencyMetricRequired = false;
-        sPerceivedTabSwitchLatencyMetricLogged = false;
-    }
-
-    /**
-     * Should be called a visible {@link ChromeTab} gets a frame to render in the browser process.
-     * If we don't get this call, we ignore requests to
-     * {@link #flushActualTabSwitchLatencyMetric()}.
-     */
-    public static void setActualTabSwitchLatencyMetricRequired() {
-        if (sTabSwitchStartTime <= 0) return;
-        sTabSwitchLatencyMetricRequired = true;
-    }
-
-    /**
-     * Logs the perceived tab switching latency metric.  This will automatically be logged if
-     * the actual metric is set and flushed.
-     */
-    public static void logPerceivedTabSwitchLatencyMetric() {
-        if (sTabSwitchStartTime <= 0 || sPerceivedTabSwitchLatencyMetricLogged) return;
-
-        flushTabSwitchLatencyMetric(true);
-        sPerceivedTabSwitchLatencyMetricLogged = true;
-    }
-
-    /**
-     * Flush the latency metric if called after the indication that a frame is ready.
-     */
-    public static void flushActualTabSwitchLatencyMetric() {
-        if (sTabSwitchStartTime <= 0 || !sTabSwitchLatencyMetricRequired) return;
-        logPerceivedTabSwitchLatencyMetric();
-        flushTabSwitchLatencyMetric(false);
-
-        sTabSwitchStartTime = 0;
-        sTabSwitchLatencyMetricRequired = false;
-    }
-
-    private static void flushTabSwitchLatencyMetric(boolean perceived) {
-        if (sTabSwitchStartTime <= 0) return;
-        final long ms = SystemClock.uptimeMillis() - sTabSwitchStartTime;
-        switch (sTabSelectionType) {
-            case FROM_CLOSE:
-                nativeLogFromCloseMetric(ms, perceived);
-                break;
-            case FROM_EXIT:
-                nativeLogFromExitMetric(ms, perceived);
-                break;
-            case FROM_NEW:
-                nativeLogFromNewMetric(ms, perceived);
-                break;
-            case FROM_USER:
-                nativeLogFromUserMetric(ms, perceived);
-                break;
-        }
-    }
-
-    private native long nativeInit(boolean isIncognito);
-    private native void nativeDestroy(long nativeTabModelBase);
-    private native void nativeBroadcastSessionRestoreComplete(long nativeTabModelBase);
-    private native Profile nativeGetProfileAndroid(long nativeTabModelBase);
-    private native void nativeTabAddedToModel(long nativeTabModelBase, Tab tab);
-    // Native methods for tab switch latency metrics.
-    private static native void nativeLogFromCloseMetric(long ms, boolean perceived);
-    private static native void nativeLogFromExitMetric(long ms, boolean perceived);
-    private static native void nativeLogFromNewMetric(long ms, boolean perceived);
-    private static native void nativeLogFromUserMetric(long ms, boolean perceived);
 }