blob: fc86d8d5cbd9c8192b60cb609006a18c3bb18517 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.webapps;
import android.content.Intent;
import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.base.annotations.SuppressFBWarnings;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.TabState;
import org.chromium.chrome.browser.compositor.layouts.LayoutManagerDocument;
import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabDelegateFactory;
import org.chromium.chrome.browser.tab.TabUma.TabCreationState;
import org.chromium.chrome.browser.tabmodel.SingleTabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.document.TabDelegate;
import org.chromium.chrome.browser.widget.ControlContainer;
import org.chromium.content.browser.ContentViewCore;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import java.io.File;
/**
* Base class for task-focused activities that need to display web content in a nearly UI-less
* Chrome (InfoBars still appear).
*
* This is vaguely analogous to a WebView, but in Chrome. Example applications that might use this
* Activity would be webapps and streaming media activities - anything where user interaction with
* the regular browser's UI is either unnecessary or undesirable.
* Subclasses can override {@link #createUI()} if they need something more exotic.
*/
@SuppressFBWarnings("URF_UNREAD_FIELD")
public abstract class FullScreenActivity extends ChromeActivity {
protected static final String BUNDLE_TAB_ID = "tabId";
protected static final String BUNDLE_TAB_URL = "tabUrl";
private static final String TAG = "FullScreenActivity";
private Tab mTab;
private WebContents mWebContents;
@SuppressWarnings("unused") // Reference needed to prevent GC.
private WebContentsObserver mWebContentsObserver;
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
protected TabModelSelector createTabModelSelector() {
return new SingleTabModelSelector(this, false, false) {
@Override
public Tab openNewTab(LoadUrlParams loadUrlParams, TabLaunchType type, Tab parent,
boolean incognito) {
getTabCreator(incognito).createNewTab(loadUrlParams, type, parent);
return null;
}
};
}
@Override
protected Pair<TabDelegate, TabDelegate> createTabCreators() {
return Pair.create(createTabDelegate(false), createTabDelegate(true));
}
/** Creates TabDelegates for opening new Tabs. */
protected TabDelegate createTabDelegate(boolean incognito) {
return new TabDelegate(incognito);
}
@Override
public void finishNativeInitialization() {
mTab = createTab();
handleTabContentChanged();
getTabModelSelector().setTab(mTab);
mTab.show(TabSelectionType.FROM_NEW);
ControlContainer controlContainer = (ControlContainer) findViewById(R.id.control_container);
initializeCompositorContent(new LayoutManagerDocument(getCompositorViewHolder()),
(View) controlContainer, (ViewGroup) findViewById(android.R.id.content),
controlContainer);
if (getFullscreenManager() != null) getFullscreenManager().setTab(getActivityTab());
super.finishNativeInitialization();
}
@Override
protected void initializeToolbar() { }
@Override
public SingleTabModelSelector getTabModelSelector() {
return (SingleTabModelSelector) super.getTabModelSelector();
}
@Override
public final Tab getActivityTab() {
return mTab;
}
/**
* Creates the {@link Tab} used by the FullScreenActivity.
* If the {@code savedInstanceState} exists, then the user did not intentionally close the app
* by swiping it away in the recent tasks list. In that case, we try to restore the tab from
* disk.
*/
private Tab createTab() {
Tab tab = null;
boolean unfreeze = false;
int tabId = Tab.INVALID_TAB_ID;
String tabUrl = null;
if (getSavedInstanceState() != null) {
tabId = getSavedInstanceState().getInt(BUNDLE_TAB_ID, Tab.INVALID_TAB_ID);
tabUrl = getSavedInstanceState().getString(BUNDLE_TAB_URL);
}
if (tabId != Tab.INVALID_TAB_ID && tabUrl != null && getActivityDirectory() != null) {
// Restore the tab.
TabState tabState = TabState.restoreTabState(getActivityDirectory(), tabId);
tab = new Tab(tabId, Tab.INVALID_TAB_ID, false, this, getWindowAndroid(),
TabLaunchType.FROM_RESTORE,
TabCreationState.FROZEN_ON_RESTORE, tabState);
unfreeze = true;
}
if (tab == null) {
tab = new Tab(Tab.INVALID_TAB_ID, Tab.INVALID_TAB_ID, false, this, getWindowAndroid(),
TabLaunchType.FROM_CHROME_UI, null, null);
}
tab.initialize(null, getTabContentManager(), createTabDelegateFactory(), false, unfreeze);
tab.addObserver(new EmptyTabObserver() {
@Override
public void onContentChanged(Tab tab) {
assert tab == mTab;
handleTabContentChanged();
}
});
return tab;
}
private void handleTabContentChanged() {
assert mTab != null;
WebContents webContents = mTab.getWebContents();
if (mWebContents == webContents) return;
// Clean up any old references to the previous WebContents.
if (mWebContentsObserver != null) {
mWebContentsObserver.destroy();
mWebContentsObserver = null;
}
mWebContents = webContents;
if (mWebContents == null) return;
ContentViewCore.fromWebContents(webContents).setFullscreenRequiredForOrientationLock(false);
mWebContentsObserver = new WebContentsObserver(webContents) {
@Override
public void didFinishNavigation(String url, boolean isInMainFrame, boolean isErrorPage,
boolean hasCommitted, boolean isSamePage, boolean isFragmentNavigation,
Integer pageTransition, int errorCode, String errorDescription,
int httpStatusCode) {
if (hasCommitted && isInMainFrame) {
// Notify the renderer to permanently hide the top controls since they do
// not apply to fullscreen content views.
mTab.updateBrowserControlsState(
mTab.getBrowserControlsStateConstraints(), true);
}
}
};
}
/**
* @return {@link TabDelegateFactory} to be used while creating the associated {@link Tab}.
*/
protected TabDelegateFactory createTabDelegateFactory() {
return new FullScreenDelegateFactory();
}
/**
* @return {@link File} pointing at a directory specific for this class.
*/
protected File getActivityDirectory() {
return null;
}
@Override
protected boolean handleBackPressed() {
if (mTab == null) return false;
if (mTab.canGoBack()) {
mTab.goBack();
return true;
}
return false;
}
@Override
public void onCheckForUpdate(boolean updateAvailable) {
}
}