Commit 52f1906f authored by Brandon Wylie's avatar Brandon Wylie Committed by Commit Bot

Revert "Reland "[Multi-Instance] Add method to detect Multi-Instance""

This reverts commit fe2b5e8c.

Reason for revert: Deterministic failure: org.chromium.chrome.browser.multiwindow.MultiWindowUtilsTest#testAreMultipleChromeInstancesRunningFirstInstanceKilledFirst (status FAILURE)

Original change's description:
> Reland "[Multi-Instance] Add method to detect Multi-Instance"
> 
> This is a reland of 621c283e
> 
> Looks like activities were being preemptively killed on test-n-tablet.
> This caused a failure with the way CallbackHelper was used.
> 
> Reverted due to failing on test-n-tablet.
> > Reason for revert:
> > testAreMultipleChromeInstancesRunningFirstInstanceKilledFirst
> > failing on test-n-tablet
> > https://ci.chromium.org/p/chrome/builders/ci/test-n-tablet
> 
> Original change's description:
> > [Multi-Instance] Add method to detect Multi-Instance
> >
> > This change provides a simple method to detect if Chrome is in
> > multi-instance mode.
> >
> > Bug: 1071925
> > Change-Id: I3b82e5fe7a97e923f67f0ca49735c724f9ed4f17
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2155017
> > Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
> > Reviewed-by: Theresa  <twellington@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#762344}
> 
> Bug: 1071925
> Change-Id: Ifcfc192011b0ddf4fdb7b9cc5ecae90b63ae4fb5
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2167992
> Reviewed-by: Theresa  <twellington@chromium.org>
> Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#763387}

TBR=twellington@chromium.org,ckitagawa@chromium.org

Change-Id: Ic4d476aef66df41ef0b428efce6718ffc6043520
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1071925
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2171918Reviewed-by: default avatarBrandon Wylie <wylieb@chromium.org>
Commit-Queue: Brandon Wylie <wylieb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#763594}
parent dedee28f
...@@ -247,8 +247,14 @@ public class MultiInstanceManager ...@@ -247,8 +247,14 @@ public class MultiInstanceManager
List<ActivityManager.AppTask> appTasks = activityManager.getAppTasks(); List<ActivityManager.AppTask> appTasks = activityManager.getAppTasks();
ActivityManager.AppTask otherActivityTask = null; ActivityManager.AppTask otherActivityTask = null;
for (ActivityManager.AppTask task : appTasks) { for (ActivityManager.AppTask task : appTasks) {
String baseActivity = MultiWindowUtils.getActivityNameFromTask(task); if (task.getTaskInfo() == null || task.getTaskInfo().baseActivity == null) continue;
String baseActivity = task.getTaskInfo().baseActivity.getClassName();
// Contrary to the documentation task.getTaskInfo().baseActivity for the .LauncherMain
// activity alias is the alias itself, and not the implementation. Filed b/66729258;
// for now translate the alias manually.
if (baseActivity.equals(ChromeTabbedActivity.MAIN_LAUNCHER_ACTIVITY_NAME)) {
baseActivity = ChromeTabbedActivity.class.getName();
}
if (baseActivity.equals(otherWindowActivityClass.getName())) { if (baseActivity.equals(otherWindowActivityClass.getName())) {
otherActivityTask = task; otherActivityTask = task;
} }
......
...@@ -191,61 +191,6 @@ public class MultiWindowUtils implements ActivityStateListener { ...@@ -191,61 +191,6 @@ public class MultiWindowUtils implements ActivityStateListener {
} }
} }
/**
* Determines the name of an activity from its {@link AppTask}.
* @param task The AppTask to get the name of.
*/
public static String getActivityNameFromTask(AppTask task) {
if (task.getTaskInfo() == null || task.getTaskInfo().baseActivity == null) return "";
String baseActivity = task.getTaskInfo().baseActivity.getClassName();
// Contrary to the documentation task.getTaskInfo().baseActivity for the .LauncherMain
// activity alias is the alias itself, and not the implementation. Filed b/66729258;
// for now translate the alias manually.
if (TextUtils.equals(baseActivity, ChromeTabbedActivity.MAIN_LAUNCHER_ACTIVITY_NAME)) {
baseActivity = ChromeTabbedActivity.class.getName();
}
return baseActivity;
}
/**
* Determines if multiple instances of Chrome are running.
* @param context The current Context, used to retrieve the ActivityManager system service.
* @return True if multiple instances of Chrome are running.
*/
public boolean areMultipleChromeInstancesRunning(Context context) {
// Exit early if multi-window isn't supported.
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) return false;
// Check if both tasks are running.
boolean tabbedTaskRunning = false;
boolean tabbed2TaskRunning = false;
for (Activity activity : ApplicationStatus.getRunningActivities()) {
if (activity.getClass().equals(ChromeTabbedActivity.class)) {
tabbedTaskRunning = true;
} else if (activity.getClass().equals(ChromeTabbedActivity2.class)) {
tabbed2TaskRunning = true;
}
}
if (tabbedTaskRunning && tabbed2TaskRunning) return true;
// If a task isn't running check if it is in recents since another instance could be
// recovered from there.
ActivityManager activityManager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<AppTask> appTasks = activityManager.getAppTasks();
for (AppTask task : appTasks) {
String baseActivity = getActivityNameFromTask(task);
if (TextUtils.equals(baseActivity, ChromeTabbedActivity.class.getName())) {
tabbedTaskRunning = true;
} else if (TextUtils.equals(baseActivity, ChromeTabbedActivity2.class.getName())) {
tabbed2TaskRunning = true;
}
}
return tabbedTaskRunning && tabbed2TaskRunning;
}
/** /**
* Determines the correct ChromeTabbedActivity class to use for an incoming intent. * Determines the correct ChromeTabbedActivity class to use for an incoming intent.
* @param intent The incoming intent that is starting ChromeTabbedActivity. * @param intent The incoming intent that is starting ChromeTabbedActivity.
...@@ -339,7 +284,12 @@ public class MultiWindowUtils implements ActivityStateListener { ...@@ -339,7 +284,12 @@ public class MultiWindowUtils implements ActivityStateListener {
context.getSystemService(Context.ACTIVITY_SERVICE); context.getSystemService(Context.ACTIVITY_SERVICE);
List<AppTask> appTasks = activityManager.getAppTasks(); List<AppTask> appTasks = activityManager.getAppTasks();
for (AppTask task : appTasks) { for (AppTask task : appTasks) {
String baseActivity = getActivityNameFromTask(task); if (task.getTaskInfo() == null || task.getTaskInfo().baseActivity == null) continue;
String baseActivity = task.getTaskInfo().baseActivity.getClassName();
if (TextUtils.equals(baseActivity, ChromeTabbedActivity.MAIN_LAUNCHER_ACTIVITY_NAME)) {
baseActivity = ChromeTabbedActivity.class.getName();
}
if (TextUtils.equals(baseActivity, className)) return true; if (TextUtils.equals(baseActivity, className)) return true;
} }
......
...@@ -7,12 +7,10 @@ package org.chromium.chrome.browser.multiwindow; ...@@ -7,12 +7,10 @@ package org.chromium.chrome.browser.multiwindow;
import static org.chromium.chrome.browser.multiwindow.MultiWindowTestHelper.createSecondChromeTabbedActivity; import static org.chromium.chrome.browser.multiwindow.MultiWindowTestHelper.createSecondChromeTabbedActivity;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
...@@ -21,7 +19,6 @@ import org.junit.runner.RunWith; ...@@ -21,7 +19,6 @@ import org.junit.runner.RunWith;
import org.chromium.base.ActivityState; import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.MinAndroidSdkLevel;
...@@ -36,7 +33,6 @@ import org.chromium.content_public.browser.test.util.Criteria; ...@@ -36,7 +33,6 @@ import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.CriteriaHelper;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
/** /**
* Class for testing MultiWindowUtils. * Class for testing MultiWindowUtils.
...@@ -53,11 +49,6 @@ public class MultiWindowUtilsTest { ...@@ -53,11 +49,6 @@ public class MultiWindowUtilsTest {
mActivityTestRule.startMainActivityOnBlankPage(); mActivityTestRule.startMainActivityOnBlankPage();
} }
@After
public void teardown() {
MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(false);
}
/** /**
* Tests that ChromeTabbedActivity2 is used for intents when EXTRA_WINDOW_ID is set to 2. * Tests that ChromeTabbedActivity2 is used for intents when EXTRA_WINDOW_ID is set to 2.
*/ */
...@@ -186,145 +177,4 @@ public class MultiWindowUtilsTest { ...@@ -186,145 +177,4 @@ public class MultiWindowUtilsTest {
mActivityTestRule.getActivity().getIntent(), mActivityTestRule.getActivity()); mActivityTestRule.getActivity().getIntent(), mActivityTestRule.getActivity());
Assert.assertFalse(MultiWindowUtils.getInstance().getTabbedActivity2TaskRunning()); Assert.assertFalse(MultiWindowUtils.getInstance().getTabbedActivity2TaskRunning());
} }
/**
* Tests that {@link MultiWindowUtils#areMultipleChromeInstancesRunning} behaves correctly in
* the case the second instance is killed first.
*/
@Test
@SmallTest
@Feature("MultiWindow")
public void testAreMultipleChromeInstancesRunningSecondInstanceKilledFirst()
throws TimeoutException {
ChromeTabbedActivity activity1 = mActivityTestRule.getActivity();
MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(true);
Assert.assertFalse("Only a single instance should be running at the start.",
MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity1));
CallbackHelper activity1StoppedCallback = new CallbackHelper();
CallbackHelper activity1DestroyedCallback = new CallbackHelper();
CallbackHelper activity1ResumedCallback = new CallbackHelper();
ApplicationStatus.ActivityStateListener activity1StateListener =
new ApplicationStatus.ActivityStateListener() {
@Override
public void onActivityStateChange(Activity activity, int newState) {
switch (newState) {
case ActivityState.STOPPED:
activity1StoppedCallback.notifyCalled();
break;
case ActivityState.DESTROYED:
activity1DestroyedCallback.notifyCalled();
break;
case ActivityState.RESUMED:
activity1ResumedCallback.notifyCalled();
break;
}
}
};
ApplicationStatus.registerStateListenerForActivity(activity1StateListener, activity1);
// Starting activity2 will stop activity1 as this is not truly multi-window mode.
int activity1CallCount = activity1StoppedCallback.getCallCount();
ChromeTabbedActivity activity2 = createSecondChromeTabbedActivity(activity1);
activity1StoppedCallback.waitForCallback(activity1CallCount);
Assert.assertTrue("Both instances should be running now that the second has started.",
MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity1));
CallbackHelper activity2DestroyedCallback = new CallbackHelper();
ApplicationStatus.ActivityStateListener activity2StateListener =
new ApplicationStatus.ActivityStateListener() {
@Override
public void onActivityStateChange(Activity activity, int newState) {
switch (newState) {
case ActivityState.DESTROYED:
activity2DestroyedCallback.notifyCalled();
break;
}
}
};
ApplicationStatus.registerStateListenerForActivity(activity2StateListener, activity2);
// activity1 may have been destroyed in the background. After destroying activity2 it is
// necessary to make sure activity1 gets resumed.
activity1CallCount = activity1ResumedCallback.getCallCount();
activity2.finishAndRemoveTask();
activity2DestroyedCallback.waitForFirst();
activity1ResumedCallback.waitForCallback(activity1CallCount);
Assert.assertFalse("Only a single instance should be running after the second is killed.",
MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity1));
// activity1 may have been destroyed in the background and now it is in the foreground.
// Wait on the next destroyed call rather than the first.
activity1CallCount = activity1DestroyedCallback.getCallCount();
activity1.finishAndRemoveTask();
activity1DestroyedCallback.waitForCallback(activity1CallCount);
Assert.assertFalse("No instances should be running as all instances are killed.",
MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity1));
}
/**
* Tests that {@link MultiWindowUtils#areMultipleChromeInstancesRunning} behaves correctly in
* the case the first instance is killed first.
*/
@Test
@SmallTest
@Feature("MultiWindow")
public void testAreMultipleChromeInstancesRunningFirstInstanceKilledFirst()
throws TimeoutException {
ChromeTabbedActivity activity1 = mActivityTestRule.getActivity();
MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(true);
Assert.assertFalse("Only a single instance should be running at the start.",
MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity1));
CallbackHelper activity1StoppedCallback = new CallbackHelper();
CallbackHelper activity1DestroyedCallback = new CallbackHelper();
ApplicationStatus.ActivityStateListener activity1StateListener =
new ApplicationStatus.ActivityStateListener() {
@Override
public void onActivityStateChange(Activity activity, int newState) {
switch (newState) {
case ActivityState.STOPPED:
activity1StoppedCallback.notifyCalled();
break;
case ActivityState.DESTROYED:
activity1DestroyedCallback.notifyCalled();
break;
}
}
};
ApplicationStatus.registerStateListenerForActivity(activity1StateListener, activity1);
// Starting activity2 will stop activity1 as this is not truly multi-window mode.
// activity1 may be killed in the background, but since it is never foregrounded again
// there should be only one call for both stopped and destroyed in this test.
ChromeTabbedActivity activity2 = createSecondChromeTabbedActivity(activity1);
activity1StoppedCallback.waitForFirst();
Assert.assertTrue("Both instances should be running now that the second has started.",
MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity1));
CallbackHelper activity2DestroyedCallback = new CallbackHelper();
ApplicationStatus.ActivityStateListener activity2StateListener =
new ApplicationStatus.ActivityStateListener() {
@Override
public void onActivityStateChange(Activity activity, int newState) {
switch (newState) {
case ActivityState.DESTROYED:
activity2DestroyedCallback.notifyCalled();
break;
}
}
};
ApplicationStatus.registerStateListenerForActivity(activity2StateListener, activity2);
activity1.finishAndRemoveTask();
activity1DestroyedCallback.waitForFirst();
Assert.assertFalse("Only a single instance should be running after the first is killed.",
MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity1));
// activity2 is always in the foreground so this should be the first time it is destroyed.
activity2.finishAndRemoveTask();
activity2DestroyedCallback.waitForFirst();
Assert.assertFalse("No instances should be running as all instances are killed.",
MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity1));
}
} }
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