OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.customtabs; | 5 package org.chromium.chrome.browser.customtabs; |
6 | 6 |
7 import android.app.PendingIntent; | 7 import android.app.PendingIntent; |
8 import android.app.PendingIntent.CanceledException; | 8 import android.app.PendingIntent.CanceledException; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.graphics.Bitmap; | 10 import android.graphics.Bitmap; |
(...skipping 21 matching lines...) Expand all Loading... | |
32 import org.chromium.chrome.R; | 32 import org.chromium.chrome.R; |
33 import org.chromium.chrome.browser.ChromeActivity; | 33 import org.chromium.chrome.browser.ChromeActivity; |
34 import org.chromium.chrome.browser.IntentHandler; | 34 import org.chromium.chrome.browser.IntentHandler; |
35 import org.chromium.chrome.browser.IntentHandler.ExternalAppId; | 35 import org.chromium.chrome.browser.IntentHandler.ExternalAppId; |
36 import org.chromium.chrome.browser.KeyboardShortcuts; | 36 import org.chromium.chrome.browser.KeyboardShortcuts; |
37 import org.chromium.chrome.browser.WebContentsFactory; | 37 import org.chromium.chrome.browser.WebContentsFactory; |
38 import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate; | 38 import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate; |
39 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChange Reason; | 39 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChange Reason; |
40 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerDocument; | 40 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerDocument; |
41 import org.chromium.chrome.browser.datausage.DataUseTabUIManager; | 41 import org.chromium.chrome.browser.datausage.DataUseTabUIManager; |
42 import org.chromium.chrome.browser.document.ChromeLauncherActivity; | |
43 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; | |
42 import org.chromium.chrome.browser.rappor.RapporServiceBridge; | 44 import org.chromium.chrome.browser.rappor.RapporServiceBridge; |
43 import org.chromium.chrome.browser.tab.Tab; | 45 import org.chromium.chrome.browser.tab.Tab; |
44 import org.chromium.chrome.browser.tab.TabIdManager; | 46 import org.chromium.chrome.browser.tab.TabIdManager; |
45 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; | 47 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; |
46 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; | 48 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
47 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; | 49 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; |
48 import org.chromium.chrome.browser.tabmodel.TabModelObserver; | 50 import org.chromium.chrome.browser.tabmodel.TabModelObserver; |
49 import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; | 51 import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; |
50 import org.chromium.chrome.browser.toolbar.ToolbarControlContainer; | 52 import org.chromium.chrome.browser.toolbar.ToolbarControlContainer; |
51 import org.chromium.chrome.browser.util.ColorUtils; | 53 import org.chromium.chrome.browser.util.ColorUtils; |
52 import org.chromium.chrome.browser.util.IntentUtils; | 54 import org.chromium.chrome.browser.util.IntentUtils; |
53 import org.chromium.chrome.browser.widget.FadingShadow; | 55 import org.chromium.chrome.browser.widget.FadingShadow; |
54 import org.chromium.chrome.browser.widget.FadingShadowView; | 56 import org.chromium.chrome.browser.widget.FadingShadowView; |
55 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; | 57 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; |
56 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; | 58 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; |
57 import org.chromium.content_public.browser.LoadUrlParams; | 59 import org.chromium.content_public.browser.LoadUrlParams; |
58 import org.chromium.content_public.browser.WebContents; | 60 import org.chromium.content_public.browser.WebContents; |
59 import org.chromium.content_public.common.Referrer; | 61 import org.chromium.content_public.common.Referrer; |
60 import org.chromium.ui.base.PageTransition; | 62 import org.chromium.ui.base.PageTransition; |
61 | 63 |
62 import java.util.List; | 64 import java.util.List; |
63 | 65 |
64 /** | 66 /** |
65 * The activity for custom tabs. It will be launched on top of a client's task. | 67 * The activity for custom tabs. It will be launched on top of a client's task. |
66 */ | 68 */ |
67 public class CustomTabActivity extends ChromeActivity { | 69 public class CustomTabActivity extends ChromeActivity { |
68 private static final String TAG = "CustomTabActivity"; | 70 private static final String TAG = "CustomTabActivity"; |
71 | |
72 /** | |
73 * Extra used by Chrome to tell the CustomTabActivity to finish itself and o pen the current URL | |
74 * in Chrome. Guarded explicitly for use only by PendingIntents with the Ch rome package. | |
75 */ | |
76 public static final String EXTRA_ALLOW_OPEN_IN_BROWSER = | |
77 "org.chromium.chrome.browser.customtabs.ALLOW_OPEN_IN_BROWSER"; | |
Ian Wen
2016/02/10 22:08:40
Move this extra to CustomTabsIntentDataProvider, w
gone
2016/02/10 22:28:24
Went with FINISH_AFTER_OPENING_IN_BROWSER. We'll
| |
78 | |
69 private static CustomTabContentHandler sActiveContentHandler; | 79 private static CustomTabContentHandler sActiveContentHandler; |
70 | 80 |
71 private FindToolbarManager mFindToolbarManager; | 81 private FindToolbarManager mFindToolbarManager; |
72 private CustomTabIntentDataProvider mIntentDataProvider; | 82 private CustomTabIntentDataProvider mIntentDataProvider; |
73 private IBinder mSession; | 83 private IBinder mSession; |
74 private CustomTabContentHandler mCustomTabContentHandler; | 84 private CustomTabContentHandler mCustomTabContentHandler; |
75 | 85 |
76 // This is to give the right package name while using the client's resources during an | 86 // This is to give the right package name while using the client's resources during an |
77 // overridePendingTransition call. | 87 // overridePendingTransition call. |
78 // TODO(ianwen, yusufo): Figure out a solution to extract external resources without having to | 88 // TODO(ianwen, yusufo): Figure out a solution to extract external resources without having to |
79 // change the package name. | 89 // change the package name. |
80 private boolean mShouldOverridePackage; | 90 private boolean mShouldOverridePackage; |
81 | 91 |
82 private boolean mRecordedStartupUma; | 92 private boolean mRecordedStartupUma; |
83 private boolean mShouldReplaceCurrentEntry; | 93 private boolean mShouldReplaceCurrentEntry; |
94 private boolean mIsAllowedToOpenInBrowser; | |
84 private CustomTabObserver mTabObserver; | 95 private CustomTabObserver mTabObserver; |
85 | 96 |
86 // Only the normal tab model is observed because there is no icognito tabmod el in Custom Tabs. | 97 // Only the normal tab model is observed because there is no icognito tabmod el in Custom Tabs. |
87 private TabModelObserver mTabModelObserver = new EmptyTabModelObserver() { | 98 private TabModelObserver mTabModelObserver = new EmptyTabModelObserver() { |
88 @Override | 99 @Override |
89 public void didAddTab(Tab tab, TabLaunchType type) { | 100 public void didAddTab(Tab tab, TabLaunchType type) { |
90 if (mTabObserver == null) { | 101 if (mTabObserver == null) { |
91 mTabObserver = new CustomTabObserver(getApplication(), mSession) ; | 102 mTabObserver = new CustomTabObserver(getApplication(), mSession) ; |
92 } | 103 } |
93 tab.addObserver(mTabObserver); | 104 tab.addObserver(mTabObserver); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 super.onStop(); | 178 super.onStop(); |
168 CustomTabsConnection.getInstance(getApplication()) | 179 CustomTabsConnection.getInstance(getApplication()) |
169 .dontKeepAliveForSession(mIntentDataProvider.getSession()); | 180 .dontKeepAliveForSession(mIntentDataProvider.getSession()); |
170 } | 181 } |
171 | 182 |
172 @Override | 183 @Override |
173 public void preInflationStartup() { | 184 public void preInflationStartup() { |
174 super.preInflationStartup(); | 185 super.preInflationStartup(); |
175 | 186 |
176 mIntentDataProvider = new CustomTabIntentDataProvider(getIntent(), this) ; | 187 mIntentDataProvider = new CustomTabIntentDataProvider(getIntent(), this) ; |
188 mIsAllowedToOpenInBrowser = !TextUtils.isEmpty(ChromePreferenceManager.g etHerbFlavor()) | |
Ian Wen
2016/02/10 22:08:40
mIsAllowedToOpenInBrowser() should still be initia
gone
2016/02/10 22:28:24
Done.
| |
189 && IntentUtils.safeGetBooleanExtra( | |
190 getIntent(), EXTRA_ALLOW_OPEN_IN_BROWSER, false); | |
191 | |
177 supportRequestWindowFeature(Window.FEATURE_ACTION_MODE_OVERLAY); | 192 supportRequestWindowFeature(Window.FEATURE_ACTION_MODE_OVERLAY); |
178 } | 193 } |
179 | 194 |
180 @Override | 195 @Override |
181 public void postInflationStartup() { | 196 public void postInflationStartup() { |
182 super.postInflationStartup(); | 197 super.postInflationStartup(); |
183 setTabModelSelector(new TabModelSelectorImpl(this, 0, getWindowAndroid() , false)); | 198 setTabModelSelector(new TabModelSelectorImpl(this, 0, getWindowAndroid() , false)); |
184 getToolbarManager().setCloseButtonDrawable(mIntentDataProvider.getCloseB uttonDrawable()); | 199 getToolbarManager().setCloseButtonDrawable(mIntentDataProvider.getCloseB uttonDrawable()); |
185 getToolbarManager().setShowTitle(mIntentDataProvider.getTitleVisibilityS tate() | 200 getToolbarManager().setShowTitle(mIntentDataProvider.getTitleVisibilityS tate() |
186 == CustomTabsIntent.SHOW_PAGE_TITLE); | 201 == CustomTabsIntent.SHOW_PAGE_TITLE); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
437 finish(); | 452 finish(); |
438 } | 453 } |
439 } | 454 } |
440 return true; | 455 return true; |
441 } | 456 } |
442 | 457 |
443 /** | 458 /** |
444 * Configures the custom button on toolbar. Does nothing if invalid data is provided by clients. | 459 * Configures the custom button on toolbar. Does nothing if invalid data is provided by clients. |
445 */ | 460 */ |
446 private void showCustomButtonOnToolbar() { | 461 private void showCustomButtonOnToolbar() { |
447 CustomButtonParams params = mIntentDataProvider.getCustomButtonOnToolbar (); | 462 final CustomButtonParams params = mIntentDataProvider.getCustomButtonOnT oolbar(); |
448 if (params == null) return; | 463 if (params == null) return; |
449 getToolbarManager().setCustomActionButton( | 464 getToolbarManager().setCustomActionButton( |
450 params.getIcon(getResources()), | 465 params.getIcon(getResources()), |
451 params.getDescription(), | 466 params.getDescription(), |
452 new OnClickListener() { | 467 new OnClickListener() { |
453 @Override | 468 @Override |
454 public void onClick(View v) { | 469 public void onClick(View v) { |
455 mIntentDataProvider.sendButtonPendingIntentWithUrl( | 470 if (mIsAllowedToOpenInBrowser && TextUtils.equals(getPac kageName(), |
456 getApplicationContext(), getActivityTab().getUrl ()); | 471 ApiCompatibilityUtils.getCreatorPackage( |
457 RecordUserAction.record("CustomTabsCustomActionButtonCli ck"); | 472 params.getPendingIntent()))) { |
473 openCurrentUrlInBrowser(); | |
474 finish(); | |
475 } else { | |
476 mIntentDataProvider.sendButtonPendingIntentWithUrl( | |
477 getApplicationContext(), getActivityTab().ge tUrl()); | |
478 RecordUserAction.record("CustomTabsCustomActionButto nClick"); | |
479 } | |
458 } | 480 } |
459 }); | 481 }); |
460 } | 482 } |
461 | 483 |
462 /** | 484 /** |
463 * Updates the button on the bottom bar that corresponds to the given {@link CustomButtonParams} | 485 * Updates the button on the bottom bar that corresponds to the given {@link CustomButtonParams} |
464 */ | 486 */ |
465 private void updateBottomBarButton(CustomButtonParams params) { | 487 private void updateBottomBarButton(CustomButtonParams params) { |
466 ViewGroup bottomBar = (ViewGroup) findViewById(R.id.bottombar); | 488 ViewGroup bottomBar = (ViewGroup) findViewById(R.id.bottombar); |
467 ImageButton button = (ImageButton) bottomBar.findViewById(params.getId() ); | 489 ImageButton button = (ImageButton) bottomBar.findViewById(params.getId() ); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 | 576 |
555 @Override | 577 @Override |
556 public boolean onMenuOrKeyboardAction(int id, boolean fromMenu) { | 578 public boolean onMenuOrKeyboardAction(int id, boolean fromMenu) { |
557 // Disable creating new tabs, bookmark, history, print, help, focus_url, etc. | 579 // Disable creating new tabs, bookmark, history, print, help, focus_url, etc. |
558 if (id == R.id.focus_url_bar || id == R.id.all_bookmarks_menu_id | 580 if (id == R.id.focus_url_bar || id == R.id.all_bookmarks_menu_id |
559 || id == R.id.bookmark_this_page_id || id == R.id.print_id || id == R.id.help_id | 581 || id == R.id.bookmark_this_page_id || id == R.id.print_id || id == R.id.help_id |
560 || id == R.id.recent_tabs_menu_id || id == R.id.new_incognito_ta b_menu_id | 582 || id == R.id.recent_tabs_menu_id || id == R.id.new_incognito_ta b_menu_id |
561 || id == R.id.new_tab_menu_id || id == R.id.open_history_menu_id ) { | 583 || id == R.id.new_tab_menu_id || id == R.id.open_history_menu_id ) { |
562 return true; | 584 return true; |
563 } else if (id == R.id.open_in_browser_id) { | 585 } else if (id == R.id.open_in_browser_id) { |
564 String url = getTabModelSelector().getCurrentTab().getUrl(); | 586 openCurrentUrlInBrowser(); |
565 if (DomDistillerUrlUtils.isDistilledPage(url)) { | |
566 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); | |
567 } | |
568 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |
569 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
570 | |
571 // Temporarily allowing disk access while fixing. TODO: http://crbug .com/581860 | |
572 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads( ); | |
573 StrictMode.allowThreadDiskWrites(); | |
574 try { | |
575 startActivity(intent); | |
576 } finally { | |
577 StrictMode.setThreadPolicy(oldPolicy); | |
578 } | |
579 | |
580 RecordUserAction.record("CustomTabsMenuOpenInChrome"); | 587 RecordUserAction.record("CustomTabsMenuOpenInChrome"); |
581 return true; | 588 return true; |
582 } else if (id == R.id.find_in_page_id) { | 589 } else if (id == R.id.find_in_page_id) { |
583 mFindToolbarManager.showToolbar(); | 590 mFindToolbarManager.showToolbar(); |
584 if (getContextualSearchManager() != null) { | 591 if (getContextualSearchManager() != null) { |
585 getContextualSearchManager().hideContextualSearch(StateChangeRea son.UNKNOWN); | 592 getContextualSearchManager().hideContextualSearch(StateChangeRea son.UNKNOWN); |
586 } | 593 } |
587 if (fromMenu) { | 594 if (fromMenu) { |
588 RecordUserAction.record("MobileMenuFindInPage"); | 595 RecordUserAction.record("MobileMenuFindInPage"); |
589 } else { | 596 } else { |
(...skipping 24 matching lines...) Expand all Loading... | |
614 } | 621 } |
615 | 622 |
616 /** | 623 /** |
617 * @return The {@link CustomTabIntentDataProvider} for this {@link CustomTab Activity}. For test | 624 * @return The {@link CustomTabIntentDataProvider} for this {@link CustomTab Activity}. For test |
618 * purposes only. | 625 * purposes only. |
619 */ | 626 */ |
620 @VisibleForTesting | 627 @VisibleForTesting |
621 CustomTabIntentDataProvider getIntentDataProvider() { | 628 CustomTabIntentDataProvider getIntentDataProvider() { |
622 return mIntentDataProvider; | 629 return mIntentDataProvider; |
623 } | 630 } |
631 | |
632 /** | |
633 * Opens the URL currently being displayed in the Custom Tab in the regular browser. | |
634 */ | |
635 void openCurrentUrlInBrowser() { | |
636 String url = getTabModelSelector().getCurrentTab().getUrl(); | |
637 if (DomDistillerUrlUtils.isDistilledPage(url)) { | |
638 url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url); | |
639 } | |
640 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |
641 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
642 intent.putExtra(ChromeLauncherActivity.EXTRA_IS_ALLOWED_TO_RETURN_TO_PAR ENT, false); | |
643 | |
644 // Temporarily allowing disk access while fixing. TODO: http://crbug.com /581860 | |
645 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); | |
646 StrictMode.allowThreadDiskWrites(); | |
647 try { | |
648 startActivity(intent); | |
649 } finally { | |
650 StrictMode.setThreadPolicy(oldPolicy); | |
651 } | |
652 } | |
624 } | 653 } |
OLD | NEW |