Commit d02c46df authored by yusufo's avatar yusufo Committed by Commit bot

Dont cache activity for external navigation handling

This removes the cached activity copies from InterceptNavigationHandler
and ExternalNavigationHandler.

- Uses application context when it doesn't make any difference(For
  package manager related calls.)
- Tries to get the activity through the tab and if not fail gracefully
  either by early return or using application context for launching new
  activity.

BUG=546736

Review URL: https://codereview.chromium.org/1636573004

Cr-Commit-Position: refs/heads/master@{#371853}
parent 51302060
......@@ -115,7 +115,7 @@ public class OverlayPanelContent {
// which would also handle functionality like long-press-to-paste.
private class InterceptNavigationDelegateImpl implements InterceptNavigationDelegate {
final ExternalNavigationHandler mExternalNavHandler = new ExternalNavigationHandler(
mActivity);
mActivity.getActivityTab());
@Override
public boolean shouldIgnoreNavigation(NavigationParams navigationParams) {
// TODO(mdjones): Rather than passing the two navigation params, instead consider
......
......@@ -4,13 +4,14 @@
package org.chromium.chrome.browser.customtabs;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.TransactionTooLargeException;
import org.chromium.base.Log;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.banners.AppBannerManager;
import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator;
import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator;
......@@ -39,8 +40,8 @@ public class CustomTabDelegateFactory extends TabDelegateFactory {
/**
* Constructs a new instance of {@link CustomTabNavigationDelegate}.
*/
public CustomTabNavigationDelegate(ChromeActivity activity, String clientPackageName) {
super(activity);
public CustomTabNavigationDelegate(Tab tab, String clientPackageName) {
super(tab);
mClientPackageName = clientPackageName;
}
......@@ -57,17 +58,21 @@ public class CustomTabDelegateFactory extends TabDelegateFactory {
try {
// For a URL chrome can handle and there is no default set, handle it ourselves.
if (!hasDefaultHandler) {
if (isPackageSpecializedHandler(getActivity(), mClientPackageName, intent)) {
if (isPackageSpecializedHandler(
mApplicationContext, mClientPackageName, intent)) {
intent.setPackage(mClientPackageName);
} else if (!isExternalProtocol) {
return false;
}
}
// If android fails to find a handler, handle it ourselves.
if (!getActivity().startActivityIfNeeded(intent, -1)) return false;
mHasActivityStarted = true;
return true;
Context context = getAvailableContext();
if (context instanceof Activity
&& ((Activity) context).startActivityIfNeeded(intent, -1)) {
mHasActivityStarted = true;
return true;
}
return false;
} catch (RuntimeException e) {
logTransactionTooLargeOrRethrow(e, intent);
return false;
......@@ -81,9 +86,10 @@ public class CustomTabDelegateFactory extends TabDelegateFactory {
*/
private boolean hasDefaultHandler(Intent intent) {
try {
ResolveInfo info = getActivity().getPackageManager().resolveActivity(intent, 0);
ResolveInfo info =
mApplicationContext.getPackageManager().resolveActivity(intent, 0);
if (info != null) {
final String chromePackage = getActivity().getPackageName();
final String chromePackage = mApplicationContext.getPackageName();
// If a default handler is found and it is not chrome itself, fire the intent.
if (info.match != 0 && !chromePackage.equals(info.activityInfo.packageName)) {
return true;
......@@ -141,11 +147,10 @@ public class CustomTabDelegateFactory extends TabDelegateFactory {
}
@Override
public InterceptNavigationDelegateImpl createInterceptNavigationDelegate(Tab tab,
ChromeActivity activity) {
mNavigationDelegate = new CustomTabNavigationDelegate(activity, tab.getAppAssociatedWith());
public InterceptNavigationDelegateImpl createInterceptNavigationDelegate(Tab tab) {
mNavigationDelegate = new CustomTabNavigationDelegate(tab, tab.getAppAssociatedWith());
mNavigationHandler = new ExternalNavigationHandler(mNavigationDelegate);
return new InterceptNavigationDelegateImpl(mNavigationHandler, activity, tab);
return new InterceptNavigationDelegateImpl(mNavigationHandler, tab);
}
@Override
......
......@@ -41,6 +41,7 @@ import org.chromium.chrome.browser.util.UrlUtilities;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.common.Referrer;
import org.chromium.ui.base.PageTransition;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.base.WindowAndroid.PermissionCallback;
import java.util.List;
......@@ -53,17 +54,28 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
private static final String PDF_VIEWER = "com.google.android.apps.docs";
private static final String PDF_MIME = "application/pdf";
private static final String PDF_SUFFIX = ".pdf";
private final ChromeActivity mActivity;
public ExternalNavigationDelegateImpl(ChromeActivity activity) {
mActivity = activity;
protected final Context mApplicationContext;
private final Tab mTab;
public ExternalNavigationDelegateImpl(Tab tab) {
mTab = tab;
mApplicationContext = tab.getContentViewCore().getContext().getApplicationContext();
}
/**
* @return The activity that this delegate is associated with.
* Get a {@link Context} linked to this delegate with preference to {@link Activity}.
* The tab this delegate associates with can swap the {@link Activity} it is hosted in and
* during the swap, there might not be an available {@link Activity}.
* @return The activity {@link Context} if it can be reached.
* Application {@link Context} if not.
*/
protected final Activity getActivity() {
return mActivity;
protected final Context getAvailableContext() {
if (mTab.getWindowAndroid() == null) return mApplicationContext;
Context activityContext = WindowAndroid.activityFromContext(
mTab.getWindowAndroid().getContext().get());
if (activityContext == null) return mApplicationContext;
return activityContext;
}
/**
......@@ -189,17 +201,17 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
@Override
public List<ComponentName> queryIntentActivities(Intent intent) {
return IntentUtils.getIntentHandlers(mActivity, intent);
return IntentUtils.getIntentHandlers(mApplicationContext, intent);
}
@Override
public boolean willChromeHandleIntent(Intent intent) {
return willChromeHandleIntent(mActivity, intent, false);
return willChromeHandleIntent(mApplicationContext, intent, false);
}
@Override
public boolean isSpecializedHandlerAvailable(Intent intent) {
return isPackageSpecializedHandler(mActivity, null, intent);
return isPackageSpecializedHandler(mApplicationContext, null, intent);
}
/**
......@@ -242,14 +254,16 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
@Override
public String getPackageName() {
return mActivity.getPackageName();
return mApplicationContext.getPackageName();
}
@Override
public void startActivity(Intent intent) {
try {
forcePdfViewerAsIntentHandlerIfNeeded(mActivity, intent);
mActivity.startActivity(intent);
forcePdfViewerAsIntentHandlerIfNeeded(mApplicationContext, intent);
Context context = getAvailableContext();
if (!(context instanceof Activity)) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (RuntimeException e) {
logTransactionTooLargeOrRethrow(e, intent);
}
......@@ -258,8 +272,13 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
@Override
public boolean startActivityIfNeeded(Intent intent) {
try {
forcePdfViewerAsIntentHandlerIfNeeded(mActivity, intent);
return mActivity.startActivityIfNeeded(intent, -1);
forcePdfViewerAsIntentHandlerIfNeeded(mApplicationContext, intent);
Context context = getAvailableContext();
if (context instanceof Activity) {
return ((Activity) context).startActivityIfNeeded(intent, -1);
} else {
return false;
}
} catch (RuntimeException e) {
logTransactionTooLargeOrRethrow(e, intent);
return false;
......@@ -269,7 +288,11 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
@Override
public void startIncognitoIntent(final Intent intent, final String referrerUrl,
final String fallbackUrl, final Tab tab, final boolean needsToCloseTab) {
new AlertDialog.Builder(mActivity, R.style.AlertDialogTheme)
Context context = tab.getWindowAndroid().getContext().get();
if (!(context instanceof Activity)) return;
Activity activity = (Activity) context;
new AlertDialog.Builder(activity, R.style.AlertDialogTheme)
.setTitle(R.string.external_app_leave_incognito_warning_title)
.setMessage(R.string.external_app_leave_incognito_warning)
.setPositiveButton(R.string.ok, new OnClickListener() {
......@@ -304,8 +327,7 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
// If the url points inside of Chromium's data directory, no permissions are necessary.
// This is required to prevent permission prompt when uses wants to access offline pages.
if (url.startsWith("file://" + PathUtils.getDataDirectory(
mActivity.getApplicationContext()))) {
if (url.startsWith("file://" + PathUtils.getDataDirectory(mApplicationContext))) {
return false;
}
......@@ -359,7 +381,7 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setClassName(getPackageName(), ChromeLauncherActivity.class.getName());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
IntentHandler.addTrustedIntentExtras(intent, mActivity);
IntentHandler.addTrustedIntentExtras(intent, mApplicationContext);
startActivity(intent);
if (needsToCloseTab) closeTab(tab);
......@@ -406,13 +428,13 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
@Override
public boolean isDocumentMode() {
return FeatureUtilities.isDocumentMode(mActivity);
return FeatureUtilities.isDocumentMode(mApplicationContext);
}
@Override
public String getDefaultSmsPackageName() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return null;
return Telephony.Sms.getDefaultSmsPackage(mActivity);
return Telephony.Sms.getDefaultSmsPackage(mApplicationContext);
}
private static void logTransactionTooLargeOrRethrow(RuntimeException e, Intent intent) {
......@@ -425,6 +447,9 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
}
private void closeTab(Tab tab) {
mActivity.getTabModelSelector().closeTab(tab);
Context context = tab.getWindowAndroid().getContext().get();
if (context instanceof ChromeActivity) {
((ChromeActivity) context).getTabModelSelector().closeTab(tab);
}
}
}
......@@ -17,10 +17,10 @@ import org.chromium.base.CommandLine;
import org.chromium.base.Log;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.UrlConstants;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.chrome.browser.util.UrlUtilities;
import org.chromium.ui.base.PageTransition;
......@@ -65,10 +65,10 @@ public class ExternalNavigationHandler {
/**
* A constructor for UrlHandler.
*
* @param activity The activity to launch an external intent from.
* @param tab The tab that initiated the external intent.
*/
public ExternalNavigationHandler(ChromeActivity activity) {
this(new ExternalNavigationDelegateImpl(activity));
public ExternalNavigationHandler(Tab tab) {
this(new ExternalNavigationDelegateImpl(tab));
}
/**
......
......@@ -6,7 +6,6 @@ package org.chromium.chrome.browser.tab;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.datausage.DataUseTabUIManager;
import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler;
......@@ -25,7 +24,6 @@ import org.chromium.content_public.common.ConsoleMessageLevel;
* tracking has ended.
*/
public class InterceptNavigationDelegateImpl implements InterceptNavigationDelegate {
private final ChromeActivity mActivity;
private final Tab mTab;
private final ExternalNavigationHandler mExternalNavHandler;
private final AuthenticatorNavigationInterceptor mAuthenticatorHelper;
......@@ -41,17 +39,15 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
/**
* Default constructor of {@link InterceptNavigationDelegateImpl}.
*/
public InterceptNavigationDelegateImpl(ChromeActivity activity, Tab tab) {
this(new ExternalNavigationHandler(activity), activity, tab);
public InterceptNavigationDelegateImpl(Tab tab) {
this(new ExternalNavigationHandler(tab), tab);
}
/**
* Constructs a new instance of {@link InterceptNavigationDelegateImpl} with the given
* {@link ExternalNavigationHandler}.
*/
public InterceptNavigationDelegateImpl(ExternalNavigationHandler externalNavHandler,
ChromeActivity activity, Tab tab) {
mActivity = activity;
public InterceptNavigationDelegateImpl(ExternalNavigationHandler externalNavHandler, Tab tab) {
mTab = tab;
mExternalNavHandler = externalNavHandler;
mAuthenticatorHelper = ((ChromeApplication) mTab.getApplicationContext())
......@@ -88,7 +84,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
tabRedirectHandler.updateNewUrlLoading(navigationParams.pageTransitionType,
navigationParams.isRedirect,
navigationParams.hasUserGesture || navigationParams.hasUserGestureCarryover,
mActivity.getLastUserInteractionTime(), getLastCommittedEntryIndex());
mTab.getActivity().getLastUserInteractionTime(), getLastCommittedEntryIndex());
boolean shouldCloseTab = shouldCloseContentsOnOverrideUrlLoadingAndLaunchIntent();
boolean isInitialTabLaunchInBackground =
mTab.getLaunchType() == TabLaunchType.FROM_LONGPRESS_BACKGROUND && shouldCloseTab;
......@@ -131,7 +127,7 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
logBlockedNavigationToDevToolsConsole(url);
return true;
}
return DataUseTabUIManager.shouldOverrideUrlLoading(mActivity, mTab, url,
return DataUseTabUIManager.shouldOverrideUrlLoading(mTab.getActivity(), mTab, url,
navigationParams.pageTransitionType, navigationParams.referrer);
}
}
......@@ -209,9 +205,9 @@ public class InterceptNavigationDelegateImpl implements InterceptNavigationDeleg
// Moving task back before closing the tab allows back button to function better
// when Chrome was an intermediate link redirector between two apps.
// crbug.com/487938.
mActivity.moveTaskToBack(true);
mTab.getActivity().moveTaskToBack(true);
}
mActivity.getTabModelSelector().closeTab(mTab);
mTab.getTabModelSelector().closeTab(mTab);
} else if (mTab.getTabRedirectHandler().isOnNavigation()) {
int lastCommittedEntryIndexBeforeNavigation = mTab.getTabRedirectHandler()
.getLastCommittedEntryIndexBeforeStartingNavigation();
......
......@@ -1609,7 +1609,7 @@ public final class Tab implements ViewGroup.OnHierarchyChangeListener,
cvc.setDownloadDelegate(mDownloadDelegate);
setInterceptNavigationDelegate(mDelegateFactory.createInterceptNavigationDelegate(
this, getActivity()));
this));
if (mGestureStateListener == null) {
mGestureStateListener = createGestureStateListener();
......
......@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.tab;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.banners.AppBannerManager;
import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator;
import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator;
......@@ -27,12 +26,10 @@ public class TabDelegateFactory {
/**
* Creates the {@link InterceptNavigationDelegate} the tab will be initialized with.
* @param tab The associated {@link Tab}.
* @param activity The {@link ChromeActivity} that the tab belongs to.
* @return The {@link InterceptNavigationDelegate} to be used for this tab.
*/
public InterceptNavigationDelegateImpl createInterceptNavigationDelegate(
Tab tab, ChromeActivity activity) {
return new InterceptNavigationDelegateImpl(activity, tab);
public InterceptNavigationDelegateImpl createInterceptNavigationDelegate(Tab tab) {
return new InterceptNavigationDelegateImpl(tab);
}
/**
......
......@@ -2000,7 +2000,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
@Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
public void testExternalNavigationWithUserGesture() {
final ExternalNavigationHandler externalNavHandler =
new ExternalNavigationHandler(getActivity());
new ExternalNavigationHandler(getActivity().getActivityTab());
final NavigationParams navigationParams = new NavigationParams(
"intent://test/#Intent;scheme=test;package=com.chrome.test;end", "",
false /* isPost */, true /* hasUserGesture */, PageTransition.LINK,
......@@ -2026,7 +2026,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
@Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
public void testRedirectedExternalNavigationWithUserGesture() {
final ExternalNavigationHandler externalNavHandler =
new ExternalNavigationHandler(getActivity());
new ExternalNavigationHandler(getActivity().getActivityTab());
final NavigationParams initialNavigationParams = new NavigationParams("http://test.com", "",
false /* isPost */, true /* hasUserGesture */, PageTransition.LINK,
......@@ -2060,7 +2060,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
@Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
public void testExternalNavigationWithoutUserGesture() {
final ExternalNavigationHandler externalNavHandler =
new ExternalNavigationHandler(getActivity());
new ExternalNavigationHandler(getActivity().getActivityTab());
final NavigationParams navigationParams = new NavigationParams(
"intent://test/#Intent;scheme=test;package=com.chrome.test;end", "",
false /* isPost */, false /* hasUserGesture */, PageTransition.LINK,
......
......@@ -46,7 +46,7 @@ public class InterceptNavigationDelegateTest extends ChromeActivityTestCaseBase<
class TestInterceptNavigationDelegate extends InterceptNavigationDelegateImpl {
TestInterceptNavigationDelegate() {
super(mActivity, mActivity.getActivityTab());
super(mActivity.getActivityTab());
}
@Override
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment