下面列出了android.app.ActivityManager.RecentTaskInfo#org.chromium.chrome.browser.ChromeTabbedActivity 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void focusChromeIfNecessary() {
Set<Integer> visibleTaskIds = getTaskIdsForVisibleActivities();
int tabbedTaskId = -1;
List<WeakReference<Activity>> runningActivities =
ApplicationStatus.getRunningActivities();
for (int i = 0; i < runningActivities.size(); i++) {
Activity activity = runningActivities.get(i).get();
if (activity == null) continue;
if (activity instanceof ChromeTabbedActivity) {
tabbedTaskId = activity.getTaskId();
break;
}
}
// If the task containing the tabbed activity is visible, then do nothing as there is no
// snapshot that would need to be regenerated.
if (visibleTaskIds.contains(tabbedTaskId)) return;
Context context = ContextUtils.getApplicationContext();
Intent startIntent = new Intent(Intent.ACTION_MAIN);
startIntent.setPackage(context.getPackageName());
startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startIntent);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void removeNonVisibleChromeTabbedRecentEntries() {
Set<Integer> visibleTaskIds = getTaskIdsForVisibleActivities();
Context context = ContextUtils.getApplicationContext();
ActivityManager manager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
PackageManager pm = getPackageManager();
for (AppTask task : manager.getAppTasks()) {
RecentTaskInfo info = DocumentUtils.getTaskInfoFromTask(task);
if (info == null) continue;
String className = DocumentUtils.getTaskClassName(task, pm);
// It is not easily possible to distinguish between tasks sitting on top of
// ChromeLauncherActivity, so we treat them all as likely ChromeTabbedActivities and
// close them to be on the cautious side of things.
if ((TextUtils.equals(className, ChromeTabbedActivity.class.getName())
|| TextUtils.equals(className, ChromeLauncherActivity.class.getName()))
&& !visibleTaskIds.contains(info.id)) {
task.finishAndRemoveTask();
}
}
}
/**
* Iterate across the running activities and for any running tabbed mode activities close their
* incognito tabs.
*
* @see TabWindowManager#getIndexForWindow(Activity)
*/
private void closeIncognitoTabsInRunningTabbedActivities() {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
List<WeakReference<Activity>> runningActivities =
ApplicationStatus.getRunningActivities();
for (int i = 0; i < runningActivities.size(); i++) {
Activity activity = runningActivities.get(i).get();
if (activity == null) continue;
if (!(activity instanceof ChromeTabbedActivity)) continue;
ChromeTabbedActivity tabbedActivity = (ChromeTabbedActivity) activity;
if (tabbedActivity.isActivityDestroyed()) continue;
tabbedActivity.getTabModelSelector().getModel(true).closeAllTabs(
false, false);
}
}
});
}
/**
* Returns the activity to use when handling "open in other window" or "move to other window".
* Returns null if the current activity doesn't support opening/moving tabs to another activity.
*/
public Class<? extends Activity> getOpenInOtherWindowActivity(Activity current) {
if (current instanceof ChromeTabbedActivity2) {
// If a second ChromeTabbedActivity is created, MultiWindowUtils needs to listen for
// activity state changes to facilitate determining which ChromeTabbedActivity should
// be used for intents.
ApplicationStatus.registerStateListenerForAllActivities(sInstance.get());
return ChromeTabbedActivity.class;
} else if (current instanceof ChromeTabbedActivity) {
mTabbedActivity2TaskRunning = true;
ApplicationStatus.registerStateListenerForAllActivities(sInstance.get());
return ChromeTabbedActivity2.class;
} else {
return null;
}
}
private void focusChromeIfNecessary() {
Set<Integer> visibleTaskIds = getTaskIdsForVisibleActivities();
int tabbedTaskId = -1;
List<WeakReference<Activity>> runningActivities =
ApplicationStatus.getRunningActivities();
for (int i = 0; i < runningActivities.size(); i++) {
Activity activity = runningActivities.get(i).get();
if (activity == null) continue;
if (activity instanceof ChromeTabbedActivity) {
tabbedTaskId = activity.getTaskId();
break;
}
}
// If the task containing the tabbed activity is visible, then do nothing as there is no
// snapshot that would need to be regenerated.
if (visibleTaskIds.contains(tabbedTaskId)) return;
Context context = ContextUtils.getApplicationContext();
Intent startIntent = new Intent(Intent.ACTION_MAIN);
startIntent.setPackage(context.getPackageName());
startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startIntent);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void removeNonVisibleChromeTabbedRecentEntries() {
Set<Integer> visibleTaskIds = getTaskIdsForVisibleActivities();
Context context = ContextUtils.getApplicationContext();
ActivityManager manager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
PackageManager pm = getPackageManager();
for (AppTask task : manager.getAppTasks()) {
RecentTaskInfo info = DocumentUtils.getTaskInfoFromTask(task);
if (info == null) continue;
String className = DocumentUtils.getTaskClassName(task, pm);
// It is not easily possible to distinguish between tasks sitting on top of
// ChromeLauncherActivity, so we treat them all as likely ChromeTabbedActivities and
// close them to be on the cautious side of things.
if ((TextUtils.equals(className, ChromeTabbedActivity.class.getName())
|| TextUtils.equals(className, ChromeLauncherActivity.class.getName()))
&& !visibleTaskIds.contains(info.id)) {
task.finishAndRemoveTask();
}
}
}
/**
* Iterate across the running activities and for any running tabbed mode activities close their
* incognito tabs.
*
* @see TabWindowManager#getIndexForWindow(Activity)
*/
private void closeIncognitoTabsInRunningTabbedActivities() {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
List<WeakReference<Activity>> runningActivities =
ApplicationStatus.getRunningActivities();
for (int i = 0; i < runningActivities.size(); i++) {
Activity activity = runningActivities.get(i).get();
if (activity == null) continue;
if (!(activity instanceof ChromeTabbedActivity)) continue;
ChromeTabbedActivity tabbedActivity = (ChromeTabbedActivity) activity;
if (tabbedActivity.isActivityDestroyed()) continue;
tabbedActivity.getTabModelSelector().getModel(true).closeAllTabs(
false, false);
}
}
});
}
/**
* Returns the activity to use when handling "open in other window" or "move to other window".
* Returns null if the current activity doesn't support opening/moving tabs to another activity.
*/
public Class<? extends Activity> getOpenInOtherWindowActivity(Activity current) {
if (current instanceof ChromeTabbedActivity2) {
// If a second ChromeTabbedActivity is created, MultiWindowUtils needs to listen for
// activity state changes to facilitate determining which ChromeTabbedActivity should
// be used for intents.
ApplicationStatus.registerStateListenerForAllActivities(sInstance.get());
return ChromeTabbedActivity.class;
} else if (current instanceof ChromeTabbedActivity) {
mTabbedActivity2TaskRunning = true;
ApplicationStatus.registerStateListenerForAllActivities(sInstance.get());
return ChromeTabbedActivity2.class;
} else {
return null;
}
}
private void focusChromeIfNecessary() {
Set<Integer> visibleTaskIds = getTaskIdsForVisibleActivities();
int tabbedTaskId = -1;
List<WeakReference<Activity>> runningActivities =
ApplicationStatus.getRunningActivities();
for (int i = 0; i < runningActivities.size(); i++) {
Activity activity = runningActivities.get(i).get();
if (activity == null) continue;
if (activity instanceof ChromeTabbedActivity) {
tabbedTaskId = activity.getTaskId();
break;
}
}
// If the task containing the tabbed activity is visible, then do nothing as there is no
// snapshot that would need to be regenerated.
if (visibleTaskIds.contains(tabbedTaskId)) return;
Context context = ContextUtils.getApplicationContext();
Intent startIntent = new Intent(Intent.ACTION_MAIN);
startIntent.setPackage(context.getPackageName());
startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startIntent);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void removeNonVisibleChromeTabbedRecentEntries() {
Set<Integer> visibleTaskIds = getTaskIdsForVisibleActivities();
Context context = ContextUtils.getApplicationContext();
ActivityManager manager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
PackageManager pm = getPackageManager();
for (AppTask task : manager.getAppTasks()) {
RecentTaskInfo info = DocumentUtils.getTaskInfoFromTask(task);
if (info == null) continue;
String className = DocumentUtils.getTaskClassName(task, pm);
// It is not easily possible to distinguish between tasks sitting on top of
// ChromeLauncherActivity, so we treat them all as likely ChromeTabbedActivities and
// close them to be on the cautious side of things.
if ((ChromeTabbedActivity.isTabbedModeClassName(className)
|| TextUtils.equals(className, ChromeLauncherActivity.class.getName()))
&& !visibleTaskIds.contains(info.id)) {
task.finishAndRemoveTask();
}
}
}
@Override
public void openNewTab(String url, String extraHeaders, ResourceRequestBody postData,
int disposition, boolean isRendererInitiated) {
// If attempting to open an incognito tab, always send the user to tabbed mode.
if (disposition == WindowOpenDisposition.OFF_THE_RECORD) {
if (isRendererInitiated) {
throw new IllegalStateException(
"Invalid attempt to open an incognito tab from the renderer");
}
LoadUrlParams loadUrlParams = new LoadUrlParams(url);
loadUrlParams.setVerbatimHeaders(extraHeaders);
loadUrlParams.setPostData(postData);
loadUrlParams.setIsRendererInitiated(isRendererInitiated);
Class<? extends ChromeTabbedActivity> tabbedClass =
MultiWindowUtils.getInstance().getTabbedActivityForIntent(
null, ContextUtils.getApplicationContext());
AsyncTabCreationParams tabParams = new AsyncTabCreationParams(loadUrlParams,
new ComponentName(ContextUtils.getApplicationContext(), tabbedClass));
new TabDelegate(true).createNewTab(tabParams,
TabLaunchType.FROM_LONGPRESS_FOREGROUND, TabModel.INVALID_TAB_INDEX);
return;
}
super.openNewTab(url, extraHeaders, postData, disposition, isRendererInitiated);
}
/**
* Returns the activity to use when handling "open in other window" or "move to other window".
* Returns null if the current activity doesn't support opening/moving tabs to another activity.
*/
public Class<? extends Activity> getOpenInOtherWindowActivity(Activity current) {
if (current instanceof ChromeTabbedActivity2) {
// If a second ChromeTabbedActivity is created, MultiWindowUtils needs to listen for
// activity state changes to facilitate determining which ChromeTabbedActivity should
// be used for intents.
ApplicationStatus.registerStateListenerForAllActivities(sInstance.get());
return ChromeTabbedActivity.class;
} else if (current instanceof ChromeTabbedActivity) {
mTabbedActivity2TaskRunning = true;
ApplicationStatus.registerStateListenerForAllActivities(sInstance.get());
return ChromeTabbedActivity2.class;
} else {
return null;
}
}
protected NativePage buildNewTabPage(ChromeActivity activity, Tab tab,
TabModelSelector tabModelSelector) {
if (FeatureUtilities.isChromeHomeEnabled()) {
if (tab.isIncognito()) {
return new ChromeHomeIncognitoNewTabPage(activity, tab, tabModelSelector,
((ChromeTabbedActivity) activity).getLayoutManager());
} else {
return new ChromeHomeNewTabPage(activity, tab, tabModelSelector,
((ChromeTabbedActivity) activity).getLayoutManager());
}
} else if (tab.isIncognito()) {
return new IncognitoNewTabPage(activity);
} else {
return new NewTabPage(activity, new TabShim(tab), tabModelSelector);
}
}
private String getCurrentTabOrigin() {
Activity activity = ApplicationStatus.getLastTrackedFocusedActivity();
if (!(activity instanceof ChromeTabbedActivity)) return null;
Tab tab = ((ChromeTabbedActivity) activity).getActivityTab();
if (tab == null || !tab.isInitialized()) return null;
String url = tab.getUrl();
try {
return UrlFormatter.formatUrlForSecurityDisplay(new URI(url), true);
} catch (URISyntaxException | UnsatisfiedLinkError e) {
// UnstatisfiedLinkError can only happen in tests as the natives are not initialized
// yet.
Log.e(TAG, "Unable to parse the origin from the URL. Using the full URL instead.");
return url;
}
}
/**
* @return Whether {@link ChromeTabbedActivity} is waiting for a result from this Activity.
*/
private boolean isHerbResultNeeded() {
if (!TextUtils.equals(FeatureUtilities.getHerbFlavor(), ChromeSwitches.HERB_FLAVOR_DILL)) {
return false;
}
String callingActivity =
getCallingActivity() == null ? null : getCallingActivity().getClassName();
return TextUtils.equals(callingActivity, ChromeTabbedActivity.class.getName());
}
@Override
public void onActivityStateChange(Activity activity, int newState) {
if (newState == ActivityState.RESUMED && activity instanceof ChromeTabbedActivity) {
mLastResumedTabbedActivity =
new WeakReference<ChromeTabbedActivity>((ChromeTabbedActivity) activity);
}
}
/**
* Makes |intent| able to support multi-instance in pre-N Samsung multi-window mode.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void makeLegacyMultiInstanceIntent(ChromeLauncherActivity activity, Intent intent) {
if (isLegacyMultiWindow(activity)) {
if (TextUtils.equals(ChromeTabbedActivity.class.getName(),
intent.getComponent().getClassName())) {
intent.setClassName(activity, MultiInstanceChromeTabbedActivity.class.getName());
}
intent.setFlags(intent.getFlags()
& ~(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT));
}
}
/**
* @return Whether there is already an browser instance of Chrome already running.
*/
public boolean isChromeBrowserActivityRunning() {
for (WeakReference<Activity> reference : ApplicationStatus.getRunningActivities()) {
Activity activity = reference.get();
if (activity == null) continue;
String className = activity.getClass().getName();
if (TextUtils.equals(className, ChromeTabbedActivity.class.getName())) {
return true;
}
}
return false;
}
@Override
public TabModelSelector buildSelector(Activity activity,
TabCreatorManager tabCreatorManager, int selectorIndex) {
// Merge tabs if this is the TabModelSelector for ChromeTabbedActivity and there are no
// other instances running. This indicates that it is a complete cold start of
// ChromeTabbedActivity. Tabs should only be merged during a cold start of
// ChromeTabbedActivity and not other instances (e.g. ChromeTabbedActivity2).
boolean mergeTabs = FeatureUtilities.isTabModelMergingEnabled()
&& activity.getClass().equals(ChromeTabbedActivity.class)
&& getInstance().getNumberOfAssignedTabModelSelectors() == 0;
TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePolicy(
selectorIndex, mergeTabs);
return new TabModelSelectorImpl(
activity, tabCreatorManager, persistencePolicy, true, true);
}
@Override
public void onActivityStateChange(Activity activity, int newState) {
if (newState == ActivityState.RESUMED && activity instanceof ChromeTabbedActivity) {
mLastResumedTabbedActivity =
new WeakReference<ChromeTabbedActivity>((ChromeTabbedActivity) activity);
}
}
/**
* Makes |intent| able to support multi-instance in pre-N Samsung multi-window mode.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void makeLegacyMultiInstanceIntent(ChromeLauncherActivity activity, Intent intent) {
if (isLegacyMultiWindow(activity)) {
if (TextUtils.equals(ChromeTabbedActivity.class.getName(),
intent.getComponent().getClassName())) {
intent.setClassName(activity, MultiInstanceChromeTabbedActivity.class.getName());
}
intent.setFlags(intent.getFlags()
& ~(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT));
}
}
/**
* @return Whether there is already an browser instance of Chrome already running.
*/
public boolean isChromeBrowserActivityRunning() {
for (WeakReference<Activity> reference : ApplicationStatus.getRunningActivities()) {
Activity activity = reference.get();
if (activity == null) continue;
String className = activity.getClass().getName();
if (TextUtils.equals(className, ChromeTabbedActivity.class.getName())) {
return true;
}
}
return false;
}
private static ComponentName getComponentName() {
if (!ApplicationStatus.hasVisibleActivities()) return null;
Activity activity = ApplicationStatus.getLastTrackedFocusedActivity();
if (activity instanceof ChromeTabbedActivity) {
return activity.getComponentName();
}
return null;
}
@Override
public TabModelSelector buildSelector(Activity activity,
TabCreatorManager tabCreatorManager, int selectorIndex) {
// Merge tabs if this is the TabModelSelector for ChromeTabbedActivity and there are no
// other instances running. This indicates that it is a complete cold start of
// ChromeTabbedActivity. Tabs should only be merged during a cold start of
// ChromeTabbedActivity and not other instances (e.g. ChromeTabbedActivity2).
boolean mergeTabs = FeatureUtilities.isTabModelMergingEnabled()
&& activity.getClass().equals(ChromeTabbedActivity.class)
&& getInstance().getNumberOfAssignedTabModelSelectors() == 0;
TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePolicy(
selectorIndex, mergeTabs);
return new TabModelSelectorImpl(
activity, tabCreatorManager, persistencePolicy, true, true);
}
@CalledByNative
public void navigateBack() {
if (mActivity instanceof ChromeTabbedActivity) {
// TODO(mthiesse): We should do this for custom tabs as well, as back for custom tabs
// is also expected to close tabs.
((ChromeTabbedActivity) mActivity).handleBackPressed();
} else {
mActivity.getToolbarManager().back();
}
updateHistoryButtonsVisibility();
}
private void updateHistoryButtonsVisibility() {
if (mTab == null) {
nativeSetHistoryButtonsEnabled(mNativeVrShell, false, false);
return;
}
// Hitting back when on the NTP usually closes Chrome, which we don't allow in VR, so we
// just disable the back button.
boolean shouldAlwaysGoBack = mActivity instanceof ChromeTabbedActivity
&& (mNativePage == null || !(mNativePage instanceof NewTabPage));
boolean canGoBack = mTab.canGoBack() || shouldAlwaysGoBack;
nativeSetHistoryButtonsEnabled(mNativeVrShell, canGoBack, mTab.canGoForward());
}
private static boolean activitySupportsVrBrowsing(Activity activity) {
if (activity instanceof ChromeTabbedActivity) return true;
if (activity instanceof CustomTabActivity) {
return ChromeFeatureList.isEnabled(ChromeFeatureList.VR_CUSTOM_TAB_BROWSING);
}
return false;
}
/**
* Iterate across the running activities and for any running tabbed mode activities close their
* incognito tabs.
*
* @see TabWindowManager#getIndexForWindow(Activity)
*/
private void closeIncognitoTabsInRunningTabbedActivities() {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
List<WeakReference<Activity>> runningActivities =
ApplicationStatus.getRunningActivities();
for (int i = 0; i < runningActivities.size(); i++) {
Activity activity = runningActivities.get(i).get();
if (activity == null) continue;
if (!(activity instanceof ChromeTabbedActivity)) continue;
ChromeTabbedActivity tabbedActivity = (ChromeTabbedActivity) activity;
if (tabbedActivity.isActivityDestroyed()) continue;
// Close the Chrome Home bottom sheet if it is open over an incognito tab.
if (tabbedActivity.getBottomSheet() != null
&& tabbedActivity.getBottomSheet().isSheetOpen()
&& tabbedActivity.getTabModelSelector().isIncognitoSelected()) {
// Skip animating to ensure to sheet is closed immediately. If the animation
// is run, the incognito profile will be in use until the end of the
// animation.
tabbedActivity.getBottomSheet().setSheetState(
BottomSheet.SHEET_STATE_PEEK, false);
}
tabbedActivity.getTabModelSelector().getModel(true).closeAllTabs(
false, false);
}
}
});
}
@Override
public void onActivityStateChange(Activity activity, int newState) {
if (newState == ActivityState.RESUMED && activity instanceof ChromeTabbedActivity) {
mLastResumedTabbedActivity =
new WeakReference<ChromeTabbedActivity>((ChromeTabbedActivity) activity);
}
}
/**
* Makes |intent| able to support multi-instance in pre-N Samsung multi-window mode.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void makeLegacyMultiInstanceIntent(ChromeLauncherActivity activity, Intent intent) {
if (isLegacyMultiWindow(activity)) {
if (TextUtils.equals(ChromeTabbedActivity.class.getName(),
intent.getComponent().getClassName())) {
intent.setClassName(activity, MultiInstanceChromeTabbedActivity.class.getName());
}
intent.setFlags(intent.getFlags()
& ~(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT));
}
}