Merge "Revert "Snap for 6793014 from bbbccc3c2b7fc7c5780f6c415c4223e1d0...""
diff --git a/api/test-current.txt b/api/test-current.txt
index 529dcf7..5741fe7 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5579,7 +5579,7 @@
method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @BinderThread public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void registerOrganizer();
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(boolean);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(@NonNull android.window.WindowContainerToken, boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static void setLaunchRoot(int, @NonNull android.window.WindowContainerToken);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void unregisterOrganizer();
}
diff --git a/core/java/android/inputmethodservice/TEST_MAPPING b/core/java/android/inputmethodservice/TEST_MAPPING
new file mode 100644
index 0000000..0ccd75d
--- /dev/null
+++ b/core/java/android/inputmethodservice/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "imports": [
+ {
+ "path": "frameworks/base/core/java/android/view/inputmethod"
+ }
+ ]
+}
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index b807180..cbc304b 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -950,10 +950,6 @@
* This method will be called when an emergency call is placed on any subscription (including
* the no-SIM case), regardless of which subscription this listener was registered on.
*
- * This method is deprecated. Both this method and the new
- * {@link #onOutgoingEmergencyCall(EmergencyNumber, int)} will be called when an outgoing
- * emergency call is placed.
- *
* @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to.
*
* @deprecated Use {@link #onOutgoingEmergencyCall(EmergencyNumber, int)}.
@@ -972,22 +968,24 @@
* This method will be called when an emergency call is placed on any subscription (including
* the no-SIM case), regardless of which subscription this listener was registered on.
*
- * Both this method and the deprecated {@link #onOutgoingEmergencyCall(EmergencyNumber)} will be
- * called when an outgoing emergency call is placed. You should only implement one of these
- * methods.
+ * The default implementation of this method calls
+ * {@link #onOutgoingEmergencyCall(EmergencyNumber)} for backwards compatibility purposes. Do
+ * not call {@code super(...)} from within your implementation unless you want
+ * {@link #onOutgoingEmergencyCall(EmergencyNumber)} to be called as well.
*
* @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to.
* @param subscriptionId The subscription ID used to place the emergency call. If the
* emergency call was placed without a valid subscription (e.g. when there
* are no SIM cards in the device), this will be equal to
* {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
- *
* @hide
*/
@SystemApi
@TestApi
public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
int subscriptionId) {
+ // Default implementation for backwards compatibility
+ onOutgoingEmergencyCall(placedEmergencyNumber);
}
/**
@@ -1375,10 +1373,6 @@
Binder.withCleanCallingIdentity(
() -> mExecutor.execute(
- () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber)));
-
- Binder.withCleanCallingIdentity(
- () -> mExecutor.execute(
() -> psl.onOutgoingEmergencyCall(placedEmergencyNumber,
subscriptionId)));
}
diff --git a/core/java/android/view/inputmethod/TEST_MAPPING b/core/java/android/view/inputmethod/TEST_MAPPING
new file mode 100644
index 0000000..4b2ea1a
--- /dev/null
+++ b/core/java/android/view/inputmethod/TEST_MAPPING
@@ -0,0 +1,18 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsAutoFillServiceTestCases",
+ "options": [
+ {
+ "include-filter": "android.autofillservice.cts.inline"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.AppModeFull"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl
index 92fa80e..12b16ff 100644
--- a/core/java/android/window/ITaskOrganizerController.aidl
+++ b/core/java/android/window/ITaskOrganizerController.aidl
@@ -60,5 +60,6 @@
* Requests that the given task organizer is notified when back is pressed on the root activity
* of one of its controlled tasks.
*/
- void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer, boolean interceptBackPressed);
+ void setInterceptBackPressedOnTaskRoot(in WindowContainerToken task,
+ boolean interceptBackPressed);
}
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index 7ec4f99..38fb023 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -149,9 +149,10 @@
* of one of its controlled tasks.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
- public void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) {
+ public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task,
+ boolean interceptBackPressed) {
try {
- getController().setInterceptBackPressedOnTaskRoot(mInterface, interceptBackPressed);
+ getController().setInterceptBackPressedOnTaskRoot(task, interceptBackPressed);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/window/TaskOrganizerTaskEmbedder.java b/core/java/android/window/TaskOrganizerTaskEmbedder.java
index 46c72f8..eb9dfed 100644
--- a/core/java/android/window/TaskOrganizerTaskEmbedder.java
+++ b/core/java/android/window/TaskOrganizerTaskEmbedder.java
@@ -74,7 +74,7 @@
// windowing mode tasks. Plan is to migrate this to a wm-shell front-end when that
// infrastructure is ready.
// mTaskOrganizer.registerOrganizer();
- mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true);
+ // mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true);
return super.onInitialize();
}
diff --git a/media/packages/BluetoothMidiService/AndroidManifest.xml b/media/packages/BluetoothMidiService/AndroidManifest.xml
index b88bf2a..fc96fd9 100644
--- a/media/packages/BluetoothMidiService/AndroidManifest.xml
+++ b/media/packages/BluetoothMidiService/AndroidManifest.xml
@@ -19,8 +19,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.android.bluetoothmidiservice"
- android:versionCode="1"
- android:versionName="R-initial"
>
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
diff --git a/media/packages/BluetoothMidiService/AndroidManifestBase.xml b/media/packages/BluetoothMidiService/AndroidManifestBase.xml
index ebe62b0..bfb0546 100644
--- a/media/packages/BluetoothMidiService/AndroidManifestBase.xml
+++ b/media/packages/BluetoothMidiService/AndroidManifestBase.xml
@@ -18,8 +18,6 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.bluetoothmidiservice"
- android:versionCode="1"
- android:versionName="R-initial"
>
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
<application
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 51ad30e..78f83d3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -49,6 +49,7 @@
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PixelFormat;
+import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
import android.media.AudioManager;
import android.media.AudioSystem;
@@ -71,6 +72,7 @@
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.ViewStub;
+import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
@@ -109,7 +111,8 @@
* Methods ending in "H" must be called on the (ui) handler.
*/
public class VolumeDialogImpl implements VolumeDialog,
- ConfigurationController.ConfigurationListener {
+ ConfigurationController.ConfigurationListener,
+ ViewTreeObserver.OnComputeInternalInsetsListener {
private static final String TAG = Util.logTag(VolumeDialogImpl.class);
private static final long USER_ATTEMPT_GRACE_PERIOD = 1000;
@@ -126,6 +129,7 @@
private final H mHandler = new H();
private final VolumeDialogController mController;
private final DeviceProvisionedController mDeviceProvisionedController;
+ private final Region mTouchableRegion = new Region();
private Window mWindow;
private CustomDialog mDialog;
@@ -204,6 +208,33 @@
Dependency.get(ConfigurationController.class).removeCallback(this);
}
+ @Override
+ public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo internalInsetsInfo) {
+ // Set touchable region insets on the root dialog view. This tells WindowManager that
+ // touches outside of this region should not be delivered to the volume window, and instead
+ // go to the window below. This is the only way to do this - returning false in
+ // onDispatchTouchEvent results in the event being ignored entirely, rather than passed to
+ // the next window.
+ internalInsetsInfo.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+
+ mTouchableRegion.setEmpty();
+
+ // Set the touchable region to the union of all child view bounds. We don't use touches on
+ // the volume dialog container itself, so this is fine.
+ for (int i = 0; i < mDialogView.getChildCount(); i++) {
+ final View view = mDialogView.getChildAt(i);
+ mTouchableRegion.op(
+ view.getLeft(),
+ view.getTop(),
+ view.getRight(),
+ view.getBottom(),
+ Region.Op.UNION);
+ }
+
+ internalInsetsInfo.touchableRegion.set(mTouchableRegion);
+ }
+
private void initDialog() {
mDialog = new CustomDialog(mContext);
@@ -235,6 +266,7 @@
mDialogView.setAlpha(0);
mDialog.setCanceledOnTouchOutside(true);
mDialog.setOnShowListener(dialog -> {
+ mDialogView.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
if (!isLandscape()) mDialogView.setTranslationX(mDialogView.getWidth() / 2.0f);
mDialogView.setAlpha(0);
mDialogView.animate()
@@ -253,6 +285,11 @@
.start();
});
+ mDialog.setOnDismissListener(dialogInterface ->
+ mDialogView
+ .getViewTreeObserver()
+ .removeOnComputeInternalInsetsListener(VolumeDialogImpl.this));
+
mDialogView.setOnHoverListener((v, event) -> {
int action = event.getActionMasked();
mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
@@ -1369,6 +1406,11 @@
super(context, R.style.volume_dialog_theme);
}
+ /**
+ * NOTE: This will only be called for touches within the touchable region of the volume
+ * dialog, as returned by {@link #onComputeInternalInsets}. Other touches, even if they are
+ * within the bounds of the volume dialog, will fall through to the window below.
+ */
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
rescheduleTimeoutH();
@@ -1387,6 +1429,12 @@
mHandler.sendEmptyMessage(H.RECHECK_ALL);
}
+ /**
+ * NOTE: This will be called with ACTION_OUTSIDE MotionEvents for touches that occur outside
+ * of the touchable region of the volume dialog (as returned by
+ * {@link #onComputeInternalInsets}) even if those touches occurred within the bounds of the
+ * volume dialog.
+ */
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mShowing) {
diff --git a/services/core/java/com/android/server/inputmethod/TEST_MAPPING b/services/core/java/com/android/server/inputmethod/TEST_MAPPING
new file mode 100644
index 0000000..0ccd75d
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "imports": [
+ {
+ "path": "frameworks/base/core/java/android/view/inputmethod"
+ }
+ ]
+}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index be7a6ae..f206259 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1710,8 +1710,9 @@
mRootWindowContainer.startPowerModeLaunchIfNeeded(
false /* forceSend */, mStartActivity);
- mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
- newTask, mKeepCurTransition, mOptions);
+ mTargetStack.startActivityLocked(mStartActivity,
+ topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
+ mKeepCurTransition, mOptions);
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 21e30ce..958adaa 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2289,10 +2289,6 @@
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
final DisplayContent display = getChildAt(displayNdx);
- if (display.shouldSleep()) {
- continue;
- }
-
final boolean curResult = result;
boolean resumedOnDisplay = display.reduceOnAllTaskDisplayAreas(
(taskDisplayArea, resumed) -> {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 19bf451..bfaaf46 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -6348,7 +6348,7 @@
return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea());
}
- void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
+ void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity,
boolean newTask, boolean keepCurTransition, ActivityOptions options) {
Task rTask = r.getTask();
final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
@@ -7585,7 +7585,11 @@
// Do not sleep activities in this stack if we're marked as focused and the keyguard
// is in the process of going away.
if (isFocusedStackOnDisplay()
- && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) {
+ && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()
+ // Avoid resuming activities on secondary displays since we don't want bubble
+ // activities to be resumed while bubble is still collapsed.
+ // TODO(b/113840485): Having keyguard going away state for secondary displays.
+ && display.isDefaultDisplay) {
return false;
}
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 1b779c6..63a595e 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -38,6 +38,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
+import android.util.SparseBooleanArray;
import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.ITaskOrganizerController;
@@ -50,6 +51,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -206,7 +208,6 @@
private final DeathRecipient mDeathRecipient;
private final ArrayList<Task> mOrganizedTasks = new ArrayList<>();
private final int mUid;
- private boolean mInterceptBackPressedOnTaskRoot;
TaskOrganizerState(ITaskOrganizer organizer, int uid) {
final Consumer<Runnable> deferTaskOrgCallbacksConsumer =
@@ -224,10 +225,6 @@
mUid = uid;
}
- void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) {
- mInterceptBackPressedOnTaskRoot = interceptBackPressed;
- }
-
void addTask(Task t) {
if (t.mTaskAppearedSent) return;
@@ -247,6 +244,7 @@
mOrganizer.onTaskVanished(t);
}
mOrganizedTasks.remove(t);
+ mInterceptBackPressedOnRootTasks.remove(t.mTaskId);
}
void dispose() {
@@ -278,6 +276,8 @@
private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
+ // Set of organized tasks (by taskId) that dispatch back pressed to their organizers
+ private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet();
private final ActivityTaskManagerService mService;
@@ -623,7 +623,7 @@
}
@Override
- public void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer,
+ public void setInterceptBackPressedOnTaskRoot(WindowContainerToken token,
boolean interceptBackPressed) {
enforceStackPermission("setInterceptBackPressedOnTaskRoot()");
final long origId = Binder.clearCallingIdentity();
@@ -631,9 +631,15 @@
synchronized (mGlobalLock) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Set intercept back pressed on root=%b",
interceptBackPressed);
- final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
- if (state != null) {
- state.setInterceptBackPressedOnTaskRoot(interceptBackPressed);
+ final Task task = WindowContainer.fromBinder(token.asBinder()).asTask();
+ if (task == null) {
+ Slog.w(TAG, "Could not resolve task from token");
+ return;
+ }
+ if (interceptBackPressed) {
+ mInterceptBackPressedOnRootTasks.add(task.mTaskId);
+ } else {
+ mInterceptBackPressedOnRootTasks.remove(task.mTaskId);
}
}
} finally {
@@ -642,15 +648,12 @@
}
public boolean handleInterceptBackPressedOnTaskRoot(Task task) {
- if (task == null || !task.isOrganized()) {
+ if (task == null || !task.isOrganized()
+ || !mInterceptBackPressedOnRootTasks.contains(task.mTaskId)) {
return false;
}
final TaskOrganizerState state = mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder());
- if (!state.mInterceptBackPressedOnTaskRoot) {
- return false;
- }
-
state.mOrganizer.onBackPressedOnTaskRoot(task);
return true;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index e2948a7..4cad397 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -1202,19 +1202,22 @@
@Test
public void testShouldSleepActivities() {
// When focused activity and keyguard is going away, we should not sleep regardless
- // of the display state
+ // of the display state, but keyguard-going-away should only take effects on default
+ // display since there is no keyguard on secondary displays (yet).
verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
- true /* displaySleeping */, false /* expected*/);
+ true /* displaySleeping */, true /* isDefaultDisplay */, false /* expected */);
+ verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
+ true /* displaySleeping */, false /* isDefaultDisplay */, true /* expected */);
// When not the focused stack, defer to display sleeping state.
verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
- true /* displaySleeping */, true /* expected*/);
+ true /* displaySleeping */, true /* isDefaultDisplay */, true /* expected */);
// If keyguard is going away, defer to the display sleeping state.
verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
- true /* displaySleeping */, true /* expected*/);
+ true /* displaySleeping */, true /* isDefaultDisplay */, true /* expected */);
verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
- false /* displaySleeping */, false /* expected*/);
+ false /* displaySleeping */, true /* isDefaultDisplay */, false /* expected */);
}
@Test
@@ -1423,9 +1426,11 @@
}
private void verifyShouldSleepActivities(boolean focusedStack,
- boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
+ boolean keyguardGoingAway, boolean displaySleeping, boolean isDefaultDisplay,
+ boolean expected) {
final DisplayContent display = mock(DisplayContent.class);
final KeyguardController keyguardController = mSupervisor.getKeyguardController();
+ display.isDefaultDisplay = isDefaultDisplay;
doReturn(display).when(mStack).getDisplay();
doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index b89d168..26b0bfb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -915,24 +915,6 @@
assertEquals(taskDisplayArea.getTopStack(), taskDisplayArea.getRootHomeTask());
}
- @Test
- public void testResumeFocusedStackOnSleepingDisplay() {
- // Create an activity on secondary display.
- final TestDisplayContent secondDisplay = addNewDisplayContentAt(
- DisplayContent.POSITION_TOP);
- final Task stack = secondDisplay.getDefaultTaskDisplayArea()
- .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final ActivityRecord activity = new ActivityBuilder(mAtm).setStack(stack).build();
- spyOn(activity);
- spyOn(stack);
-
- // Cannot resumed activities on secondary display if the display should sleep.
- doReturn(true).when(secondDisplay).shouldSleep();
- mRootWindowContainer.resumeFocusedStacksTopActivities();
- verify(stack, never()).resumeTopActivityUncheckedLocked(any(), any());
- verify(activity, never()).makeActiveIfNeeded(any());
- }
-
/**
* Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity
* info for test cases.
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 289d54e..46a6a82 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -930,23 +930,36 @@
final Task stack = createStack();
final Task task = createTask(stack);
final ActivityRecord activity = createActivityRecordInTask(stack.mDisplayContent, task);
+ final Task stack2 = createStack();
+ final Task task2 = createTask(stack2);
+ final ActivityRecord activity2 = createActivityRecordInTask(stack.mDisplayContent, task2);
final ITaskOrganizer organizer = registerMockOrganizer();
// Setup the task to be controlled by the MW mode organizer
stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
assertTrue(stack.isOrganized());
+ assertTrue(stack2.isOrganized());
// Verify a back pressed does not call the organizer
mWm.mAtmService.onBackPressedOnTaskRoot(activity.token);
verify(organizer, never()).onBackPressedOnTaskRoot(any());
// Enable intercepting back
- mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(organizer,
- true);
+ mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(
+ stack.mRemoteToken.toWindowContainerToken(), true);
// Verify now that the back press does call the organizer
mWm.mAtmService.onBackPressedOnTaskRoot(activity.token);
verify(organizer, times(1)).onBackPressedOnTaskRoot(any());
+
+ // Disable intercepting back
+ mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(
+ stack.mRemoteToken.toWindowContainerToken(), false);
+
+ // Verify now that the back press no longer calls the organizer
+ mWm.mAtmService.onBackPressedOnTaskRoot(activity.token);
+ verify(organizer, times(1)).onBackPressedOnTaskRoot(any());
}
@Test
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 81aad97..f151d9c 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -183,6 +183,7 @@
private static class ActivityData {
private final String mTaskRootPackage;
private final String mTaskRootClass;
+ public int lastEvent = Event.NONE;
private ActivityData(String taskRootPackage, String taskRootClass) {
mTaskRootPackage = taskRootPackage;
mTaskRootClass = taskRootClass;
@@ -785,6 +786,7 @@
switch (event.mEventType) {
case Event.ACTIVITY_RESUMED:
case Event.ACTIVITY_PAUSED:
+ case Event.ACTIVITY_STOPPED:
uid = mPackageManagerInternal.getPackageUid(event.mPackage, 0, userId);
break;
default:
@@ -817,8 +819,10 @@
.APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_FOREGROUND);
// check if this activity has already been resumed
if (mVisibleActivities.get(event.mInstanceId) != null) break;
- mVisibleActivities.put(event.mInstanceId,
- new ActivityData(event.mTaskRootPackage, event.mTaskRootClass));
+ final ActivityData resumedData = new ActivityData(event.mTaskRootPackage,
+ event.mTaskRootClass);
+ resumedData.lastEvent = Event.ACTIVITY_RESUMED;
+ mVisibleActivities.put(event.mInstanceId, resumedData);
try {
switch(mUsageSource) {
case USAGE_SOURCE_CURRENT_ACTIVITY:
@@ -834,16 +838,17 @@
}
break;
case Event.ACTIVITY_PAUSED:
- if (event.mTaskRootPackage == null) {
- // Task Root info is missing. Repair the event based on previous data
- final ActivityData prevData = mVisibleActivities.get(event.mInstanceId);
- if (prevData == null) {
- Slog.w(TAG, "Unexpected activity event reported! (" + event.mPackage
- + "/" + event.mClass + " event : " + event.mEventType
- + " instanceId : " + event.mInstanceId + ")");
- } else {
- event.mTaskRootPackage = prevData.mTaskRootPackage;
- event.mTaskRootClass = prevData.mTaskRootClass;
+ final ActivityData pausedData = mVisibleActivities.get(event.mInstanceId);
+ if (pausedData == null) {
+ Slog.w(TAG, "Unexpected activity event reported! (" + event.mPackage
+ + "/" + event.mClass + " event : " + event.mEventType
+ + " instanceId : " + event.mInstanceId + ")");
+ } else {
+ pausedData.lastEvent = Event.ACTIVITY_PAUSED;
+ if (event.mTaskRootPackage == null) {
+ // Task Root info is missing. Repair the event based on previous data
+ event.mTaskRootPackage = pausedData.mTaskRootPackage;
+ event.mTaskRootClass = pausedData.mTaskRootClass;
}
}
FrameworkStatsLog.write(
@@ -866,6 +871,16 @@
return;
}
+ if (prevData.lastEvent != Event.ACTIVITY_PAUSED) {
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.APP_USAGE_EVENT_OCCURRED,
+ uid,
+ event.mPackage,
+ event.mClass,
+ FrameworkStatsLog
+ .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_BACKGROUND);
+ }
+
ArraySet<String> tokens;
synchronized (mUsageReporters) {
tokens = mUsageReporters.removeReturnOld(event.mInstanceId);
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index aa3a139..9302f78 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -81,6 +81,12 @@
public String capabilities;
/**
+ * The interface name on which the scan result was received.
+ * @hide
+ */
+ public String ifaceName;
+
+ /**
* @hide
* No security protocol.
*/
@@ -939,6 +945,7 @@
flags = source.flags;
radioChainInfos = source.radioChainInfos;
this.mWifiStandard = source.mWifiStandard;
+ this.ifaceName = source.ifaceName;
}
}
@@ -977,6 +984,7 @@
sb.append(", 80211mcResponder: ");
sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported");
sb.append(", Radio Chain Infos: ").append(Arrays.toString(radioChainInfos));
+ sb.append(", interface name: ").append(ifaceName);
return sb.toString();
}
@@ -1056,6 +1064,7 @@
} else {
dest.writeInt(0);
}
+ dest.writeString((ifaceName != null) ? ifaceName.toString() : "");
}
/** Implement the Parcelable interface */
@@ -1134,6 +1143,7 @@
sr.radioChainInfos[i].level = in.readInt();
}
}
+ sr.ifaceName = in.readString();
return sr;
}
diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java
index 5516f43..4a35868 100644
--- a/wifi/tests/src/android/net/wifi/ScanResultTest.java
+++ b/wifi/tests/src/android/net/wifi/ScanResultTest.java
@@ -44,6 +44,7 @@
public static final long TEST_TSF = 04660l;
public static final @WifiAnnotations.WifiStandard int TEST_WIFI_STANDARD =
ScanResult.WIFI_STANDARD_11AC;
+ public static final String TEST_IFACE_NAME = "test_ifname";
/**
* Frequency to channel map. This include some frequencies used outside the US.
@@ -219,7 +220,7 @@
+ "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
+ "standard: 11ac, "
+ "80211mcResponder: is not supported, "
- + "Radio Chain Infos: null", scanResult.toString());
+ + "Radio Chain Infos: null, interface name: test_ifname", scanResult.toString());
}
/**
@@ -242,7 +243,8 @@
+ "standard: 11ac, "
+ "80211mcResponder: is not supported, "
+ "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, "
- + "RadioChainInfo: id=1, level=-54]", scanResult.toString());
+ + "RadioChainInfo: id=1, level=-54], interface name: test_ifname",
+ scanResult.toString());
}
/**
@@ -283,6 +285,8 @@
result.frequency = TEST_FREQUENCY;
result.timestamp = TEST_TSF;
result.setWifiStandard(TEST_WIFI_STANDARD);
+ result.ifaceName = TEST_IFACE_NAME;
+
return result;
}