Rename hosted to custom tabs
[chromium-blink-merge.git] / chrome / android / java_staging / src / org / chromium / chrome / browser / customtabs / CustomTabActivity.java
blob523f2067d06cbb4e3969c3b2980ca535e511592b
1 // Copyright 2015 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.
5 package org.chromium.chrome.browser.customtabs;
7 import android.content.Intent;
8 import android.net.Uri;
9 import android.text.TextUtils;
10 import android.view.MenuItem;
11 import android.view.View;
12 import android.view.View.OnClickListener;
13 import android.view.ViewGroup;
15 import com.google.android.apps.chrome.R;
17 import org.chromium.base.ApiCompatibilityUtils;
18 import org.chromium.base.VisibleForTesting;
19 import org.chromium.chrome.browser.CompositorChromeActivity;
20 import org.chromium.chrome.browser.IntentHandler;
21 import org.chromium.chrome.browser.Tab;
22 import org.chromium.chrome.browser.appmenu.AppMenuHandler;
23 import org.chromium.chrome.browser.appmenu.AppMenuObserver;
24 import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate;
25 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerDocument;
26 import org.chromium.chrome.browser.document.BrandColorUtils;
27 import org.chromium.chrome.browser.tabmodel.SingleTabModelSelector;
28 import org.chromium.chrome.browser.toolbar.ToolbarControlContainer;
29 import org.chromium.chrome.browser.toolbar.ToolbarHelper;
30 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager;
31 import org.chromium.content_public.browser.LoadUrlParams;
33 /**
34 * The activity for custom tabs. It will be launched on top of a client's task.
36 public class CustomTabActivity extends CompositorChromeActivity {
37 private static CustomTabContentHandler sActiveContentHandler;
39 private CustomTab mTab;
40 private ToolbarHelper mToolbarHelper;
41 private CustomTabAppMenuPropertiesDelegate mAppMenuPropertiesDelegate;
42 private AppMenuHandler mAppMenuHandler;
43 private FindToolbarManager mFindToolbarManager;
44 private CustomTabIntentDataProvider mIntentDataProvider;
45 private long mSessionId;
46 private CustomTabContentHandler mCustomTabContentHandler;
48 // This is to give the right package name while using the client's resources during an
49 // overridePendingTransition call.
50 // TODO(ianwen, yusufo): Figure out a solution to extract external resources without having to
51 // change the package name.
52 private boolean mShouldOverridePackage;
54 /**
55 * Sets the currently active {@link CustomTabContentHandler} in focus.
56 * @param contentHandler {@link CustomTabContentHandler} to set.
58 public static void setActiveContentHandler(CustomTabContentHandler contentHandler) {
59 sActiveContentHandler = contentHandler;
62 /**
63 * Used to check whether an incoming intent can be handled by the
64 * current {@link CustomTabContentHandler}.
65 * @return Whether the active {@link CustomTabContentHandler} has handled the intent.
67 public static boolean handleInActiveContentIfNeeded(Intent intent) {
68 if (sActiveContentHandler == null) return false;
70 long intentSessionId = intent.getLongExtra(
71 CustomTabIntentDataProvider.EXTRA_CUSTOM_TABS_SESSION_ID,
72 CustomTabIntentDataProvider.INVALID_SESSION_ID);
73 if (intentSessionId == CustomTabIntentDataProvider.INVALID_SESSION_ID) return false;
75 if (sActiveContentHandler.getSessionId() != intentSessionId) return false;
76 String url = IntentHandler.getUrlFromIntent(intent);
77 if (TextUtils.isEmpty(url)) return false;
78 sActiveContentHandler.loadUrl(new LoadUrlParams(url));
79 return true;
82 @Override
83 public void onStart() {
84 super.onStart();
85 ChromeBrowserConnection.getInstance(getApplication())
86 .keepAliveForSessionId(mIntentDataProvider.getSessionId(),
87 mIntentDataProvider.getKeepAliveServiceIntent());
90 @Override
91 public void onStop() {
92 super.onStop();
93 ChromeBrowserConnection.getInstance(getApplication())
94 .dontKeepAliveForSessionId(mIntentDataProvider.getSessionId());
97 @Override
98 public void preInflationStartup() {
99 super.preInflationStartup();
100 setTabModelSelector(new SingleTabModelSelector(this, false, true));
101 mIntentDataProvider = new CustomTabIntentDataProvider(getIntent(), this);
104 @Override
105 public void postInflationStartup() {
106 super.postInflationStartup();
107 ToolbarControlContainer controlContainer =
108 ((ToolbarControlContainer) findViewById(R.id.control_container));
109 mAppMenuPropertiesDelegate = new CustomTabAppMenuPropertiesDelegate(this,
110 mIntentDataProvider.getMenuTitles());
111 mAppMenuHandler =
112 new AppMenuHandler(this, mAppMenuPropertiesDelegate, R.menu.custom_tabs_menu);
113 mToolbarHelper = new ToolbarHelper(this, controlContainer,
114 mAppMenuHandler, mAppMenuPropertiesDelegate,
115 getCompositorViewHolder().getInvalidator());
116 mToolbarHelper.setThemeColor(mIntentDataProvider.getToolbarColor());
117 setStatusBarColor(mIntentDataProvider.getToolbarColor());
118 if (mIntentDataProvider.shouldShowActionButton()) {
119 mToolbarHelper.addCustomActionButton(mIntentDataProvider.getActionButtonIcon(),
120 new OnClickListener() {
121 @Override
122 public void onClick(View v) {
123 mIntentDataProvider.sendButtonPendingIntentWithUrl(
124 getApplicationContext(), mTab.getUrl());
128 mAppMenuHandler.addObserver(new AppMenuObserver() {
129 @Override
130 public void onMenuVisibilityChanged(boolean isVisible) {
131 if (!isVisible) {
132 mAppMenuPropertiesDelegate.onMenuDismissed();
138 @Override
139 public void finishNativeInitialization() {
140 String url = IntentHandler.getUrlFromIntent(getIntent());
141 mSessionId = mIntentDataProvider.getSessionId();
142 mTab = new CustomTab(this, getWindowAndroid(), mSessionId, url, Tab.INVALID_TAB_ID);
143 getTabModelSelector().setTab(mTab);
145 ToolbarControlContainer controlContainer = (ToolbarControlContainer) findViewById(
146 R.id.control_container);
147 LayoutManagerDocument layoutDriver = new LayoutManagerDocument(getCompositorViewHolder());
148 initializeCompositorContent(layoutDriver, findViewById(R.id.url_bar),
149 (ViewGroup) findViewById(android.R.id.content), controlContainer);
150 mFindToolbarManager = new FindToolbarManager(this, getTabModelSelector(),
151 mToolbarHelper.getContextualMenuBar().getCustomSelectionActionModeCallback());
152 controlContainer.setFindToolbarManager(mFindToolbarManager);
153 mToolbarHelper.initializeControls(
154 mFindToolbarManager, null, layoutDriver, null, null, null,
155 new OnClickListener() {
156 @Override
157 public void onClick(View v) {
158 CustomTabActivity.this.finish();
162 mTab.setFullscreenManager(getFullscreenManager());
163 mTab.loadUrl(new LoadUrlParams(url));
164 mCustomTabContentHandler = new CustomTabContentHandler() {
165 @Override
166 public void loadUrl(LoadUrlParams params) {
167 mTab.loadUrl(params);
170 @Override
171 public long getSessionId() {
172 return mSessionId;
175 super.finishNativeInitialization();
178 @Override
179 public void onStartWithNative() {
180 super.onStartWithNative();
181 setActiveContentHandler(mCustomTabContentHandler);
184 @Override
185 public void onStopWithNative() {
186 super.onStopWithNative();
187 setActiveContentHandler(null);
190 @Override
191 protected void onDeferredStartup() {
192 super.onDeferredStartup();
193 mToolbarHelper.onDeferredStartup();
196 @Override
197 public boolean hasDoneFirstDraw() {
198 return mToolbarHelper.hasDoneFirstDraw();
202 * Calculate the proper color for status bar and update it. Only works on L and future versions.
204 private void setStatusBarColor(int color) {
205 // If the client did not specify the toolbar color, we do not change the status bar color.
206 if (color == getResources().getColor(R.color.default_primary_color)) return;
208 ApiCompatibilityUtils.setStatusBarColor(getWindow(),
209 BrandColorUtils.computeStatusBarColor(color));
212 @Override
213 public SingleTabModelSelector getTabModelSelector() {
214 return (SingleTabModelSelector) super.getTabModelSelector();
217 @Override
218 protected int getControlContainerLayoutId() {
219 return R.layout.custom_tabs_control_container;
222 @Override
223 protected int getControlContainerHeightResource() {
224 return R.dimen.custom_tabs_control_container_height;
227 @Override
228 public String getPackageName() {
229 if (mShouldOverridePackage) return mIntentDataProvider.getClientPackageName();
230 return super.getPackageName();
233 @Override
234 public void finish() {
235 super.finish();
236 if (mIntentDataProvider.shouldAnimateOnFinish()) {
237 mShouldOverridePackage = true;
238 overridePendingTransition(mIntentDataProvider.getAnimationEnterRes(),
239 mIntentDataProvider.getAnimationExitRes());
240 mShouldOverridePackage = false;
244 @Override
245 protected boolean handleBackPressed() {
246 if (mTab == null) return false;
247 if (mTab.canGoBack()) {
248 mTab.goBack();
249 } else {
250 finish();
252 return true;
255 @Override
256 public boolean shouldShowAppMenu() {
257 return mTab != null && mToolbarHelper.isInitialized();
260 @Override
261 public boolean onOptionsItemSelected(MenuItem item) {
262 int menuIndex = mAppMenuPropertiesDelegate.getIndexOfMenuItem(item);
263 if (menuIndex >= 0) {
264 mIntentDataProvider.clickMenuItemWithUrl(getApplicationContext(), menuIndex,
265 getTabModelSelector().getCurrentTab().getUrl());
266 return true;
268 return super.onOptionsItemSelected(item);
271 @Override
272 public boolean onMenuOrKeyboardAction(int id, boolean fromMenu) {
273 if (id == R.id.show_menu) {
274 if (shouldShowAppMenu()) {
275 mAppMenuHandler.showAppMenu(mToolbarHelper.getMenuAnchor(), true, false);
276 return true;
278 } else if (id == R.id.open_in_chrome_id) {
279 String url = getTabModelSelector().getCurrentTab().getUrl();
280 Intent chromeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
281 chromeIntent.setPackage(getApplicationContext().getPackageName());
282 chromeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
283 startActivity(chromeIntent);
284 return true;
285 } else if (id == R.id.find_in_page_id) {
286 mFindToolbarManager.showToolbar();
287 return true;
289 return super.onMenuOrKeyboardAction(id, fromMenu);
293 * @return The {@link AppMenuPropertiesDelegate} associated with this activity. For test
294 * purposes only.
296 @VisibleForTesting
297 CustomTabAppMenuPropertiesDelegate getAppMenuPropertiesDelegate() {
298 return mAppMenuPropertiesDelegate;
301 @Override
302 @VisibleForTesting
303 public AppMenuHandler getAppMenuHandler() {
304 return mAppMenuHandler;
308 * @return The {@link CustomTabIntentDataProvider} for this {@link CustomTabActivity}. For test
309 * purposes only.
311 @VisibleForTesting
312 CustomTabIntentDataProvider getIntentDataProvider() {
313 return mIntentDataProvider;