blob: aaafb8e5da4bcbfa3f997b940c4b258e7e6e3e56 [file] [log] [blame]
// Copyright 2019 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.incognito;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import org.chromium.base.StrictModeContext;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordUserAction;
import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.ChromeVersionInfo;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.util.IntentUtils;
/**
* An exposed Activity that allows launching an Incognito Tab.
*
* No URL or search term can be entered in, the Incognito tab is started with a blank (but focused)
* omnibox. This component will be disabled if incognito mode is disabled.
* TODO(peconn): Focus the omnibox when the Incognito tab is opened.
*/
public class IncognitoTabLauncher extends Activity {
/** The Intent action used to launch the IncognitoTabLauncher. */
@VisibleForTesting
public static final String ACTION_LAUNCH_NEW_INCOGNITO_TAB =
"org.chromium.chrome.browser.incognito.OPEN_PRIVATE_TAB";
/**
* An Action that will disable this component on local builds only, to help development and
* debugging.
*/
private static final String ACTION_DEBUG =
"org.chromium.chrome.browser.incognito.IncognitoTabLauncher.DISABLE";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (ChromeVersionInfo.isLocalBuild() && ACTION_DEBUG.equals(getIntent().getAction())) {
setComponentEnabled(this, false);
finish();
return;
}
Intent chromeLauncherIntent = IntentHandler.createTrustedOpenNewTabIntent(this, true);
chromeLauncherIntent.putExtra(
IntentHandler.EXTRA_INVOKED_FROM_LAUNCH_NEW_INCOGNITO_TAB, true);
try (StrictModeContext unused = StrictModeContext.allowDiskWrites()) {
startActivity(chromeLauncherIntent);
}
finish();
}
/**
* Returns whether the intent was created by this Activity as part of the Launch New Incognito
* Tab flow.
*/
public static boolean didCreateIntent(Intent intent) {
return IntentHandler.wasIntentSenderChrome(intent) && IntentUtils.safeGetBooleanExtra(
intent, IntentHandler.EXTRA_INVOKED_FROM_LAUNCH_NEW_INCOGNITO_TAB, false);
}
/**
* Records UMA that a new incognito tab has been launched as a result of this Activity.
*/
public static void recordUse() {
RecordUserAction.record("Android.LaunchNewIncognitoTab");
}
/**
* Checks whether Incognito mode is enabled for the user and enables/disables the
* IncognitoLauncherActivity appropriately. This call requires native to be loaded.
*/
public static void updateComponentEnabledState(Context context) {
// TODO(peconn): Update state in a few more places (eg CustomTabsConnection#warmup).
boolean enable = ChromeFeatureList.isEnabled(
ChromeFeatureList.ALLOW_NEW_INCOGNITO_TAB_INTENTS)
&& PrefServiceBridge.getInstance().isIncognitoModeEnabled();
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> setComponentEnabled(context, enable));
}
/**
* Sets whether or not the IncognitoTabLauncher should be enabled. This may trigger a StrictMode
* violation so shouldn't be called on the UI thread.
*/
@VisibleForTesting
static void setComponentEnabled(Context context, boolean enabled) {
PackageManager packageManager = context.getPackageManager();
ComponentName componentName = new ComponentName(context, IncognitoTabLauncher.class);
int newState = enabled
? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
// This indicates that we don't want to kill Chrome when changing component enabled state.
int flags = PackageManager.DONT_KILL_APP;
if (packageManager.getComponentEnabledSetting(componentName) != newState) {
packageManager.setComponentEnabledSetting(componentName, newState, flags);
}
}
}