blob: 116137f7beb6fe6aa10e12e29eb61d91bde25644 [file] [log] [blame]
// Copyright 2017 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.webapk.shell_apk;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import org.chromium.webapk.lib.common.WebApkConstants;
import java.util.ArrayList;
/** Contains methods for launching host browser. */
public class HostBrowserLauncher {
private static final String TAG = "cr_HostBrowserLauncher";
// Action for launching {@link WebappLauncherActivity}.
// TODO(hanxi): crbug.com/737556. Replaces this string with the new WebAPK launch action after
// it is propagated to all the Chrome's channels.
public static final String ACTION_START_WEBAPK =
"com.google.android.apps.chrome.webapps.WebappManager.ACTION_START_WEBAPP";
// Must stay in sync with
// {@link org.chromium.chrome.browser.ShortcutHelper#REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB}.
private static final String REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB =
"REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB";
private static void grantUriPermissionToHostBrowser(
Context context, Intent launchIntent, String hostBrowserPackageName) {
ArrayList<Uri> uris = launchIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (uris == null) {
uris = new ArrayList<>();
Uri uri = launchIntent.getParcelableExtra(Intent.EXTRA_STREAM);
if (uri != null) {
uris.add(uri);
}
}
for (Uri uri : uris) {
context.grantUriPermission(
hostBrowserPackageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
/**
* Launches host browser in WebAPK mode if the browser is WebAPK-compatible.
* Otherwise, launches the host browser in tabbed mode.
*/
public static void launch(Context context, HostBrowserLauncherParams params) {
Log.v(TAG, "WebAPK Launch URL: " + params.getStartUrl());
if (HostBrowserUtils.shouldLaunchInTab(params.getHostBrowserPackageName(),
params.getHostBrowserMajorChromiumVersion())) {
launchInTab(context, params);
return;
}
Intent launchIntent = createLaunchInWebApkModeIntent(context, params);
if (params.getSelectedShareTargetActivityClassName() != null) {
grantUriPermissionToHostBrowser(
context, launchIntent, params.getHostBrowserPackageName());
}
try {
context.startActivity(launchIntent);
} catch (ActivityNotFoundException e) {
Log.w(TAG, "Unable to launch browser in WebAPK mode.");
e.printStackTrace();
}
}
/** Creates intent to launch host browser in WebAPK mode. */
public static Intent createLaunchInWebApkModeIntent(
Context context, HostBrowserLauncherParams params) {
Intent intent = new Intent();
intent.setAction(ACTION_START_WEBAPK);
intent.setPackage(params.getHostBrowserPackageName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle copiedExtras = params.getOriginalIntent().getExtras();
if (copiedExtras != null) {
intent.putExtras(copiedExtras);
}
intent.putExtra(WebApkConstants.EXTRA_URL, params.getStartUrl())
.putExtra(WebApkConstants.EXTRA_SOURCE, params.getSource())
.putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, context.getPackageName())
.putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME,
params.getSelectedShareTargetActivityClassName())
.putExtra(WebApkConstants.EXTRA_FORCE_NAVIGATION, params.getForceNavigation());
// Only pass on the start time if no user action was required between launching the webapk
// and chrome starting up. See https://crbug.com/842023
if (!params.wasDialogShown()) {
intent.putExtra(WebApkConstants.EXTRA_WEBAPK_LAUNCH_TIME, params.getLaunchTimeMs());
}
return intent;
}
/** Launches a WebAPK in its runtime host browser as a tab. */
private static void launchInTab(Context context, HostBrowserLauncherParams params) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(params.getStartUrl()));
intent.setPackage(params.getHostBrowserPackageName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true)
.putExtra(WebApkConstants.EXTRA_SOURCE, params.getSource());
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
}
}
}