Merge "Fixes statsd reports missing strings and SCS." into pi-dev
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index fbf690f..a8ad810 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -25,7 +25,6 @@
import android.content.res.Resources;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
-import android.util.Log;
import android.view.Display;
import android.view.DisplayInfo;
@@ -108,6 +107,12 @@
}
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
+ boolean isHorizontalDivision, Rect insets, int dockSide) {
+ this(res, displayWidth, displayHeight, dividerSize, isHorizontalDivision, insets,
+ dockSide, false);
+ }
+
+ public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
boolean isHorizontalDivision, Rect insets, int dockSide, boolean isMinimizedMode) {
mMinFlingVelocityPxPerSecond =
MIN_FLING_VELOCITY_DP_PER_SECOND * res.getDisplayMetrics().density;
@@ -265,7 +270,11 @@
? mDisplayHeight
: mDisplayWidth;
int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
- mTargets.add(new SnapTarget(-mDividerSize, -mDividerSize, SnapTarget.FLAG_DISMISS_START,
+ int startPos = -mDividerSize;
+ if (dockedSide == DOCKED_RIGHT) {
+ startPos += mInsets.left;
+ }
+ mTargets.add(new SnapTarget(startPos, startPos, SnapTarget.FLAG_DISMISS_START,
0.35f));
switch (mSnapMode) {
case SNAP_MODE_16_9:
diff --git a/core/res/res/layout-television/autofill_save.xml b/core/res/res/layout-television/autofill_save.xml
index ebd2dec..e221008 100644
--- a/core/res/res/layout-television/autofill_save.xml
+++ b/core/res/res/layout-television/autofill_save.xml
@@ -62,8 +62,9 @@
android:textSize="24sp" />
</LinearLayout>
- <com.android.server.autofill.ui.CustomScrollView
+ <LinearLayout
android:id="@+id/autofill_save_custom_subtitle"
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 6d677ab..8d89314 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -126,8 +126,10 @@
private SnapTarget mSnapTargetBeforeMinimized;
private int mDividerInsets;
+ private final Display mDefaultDisplay;
private int mDisplayWidth;
private int mDisplayHeight;
+ private int mDisplayRotation;
private int mDividerWindowWidth;
private int mDividerSize;
private int mTouchElevation;
@@ -140,7 +142,7 @@
private final Rect mDockedInsetRect = new Rect();
private final Rect mOtherInsetRect = new Rect();
private final Rect mLastResizeRect = new Rect();
- private final Rect mDisplayRect = new Rect();
+ private final Rect mTmpRect = new Rect();
private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance();
private DividerWindowManager mWindowManager;
private VelocityTracker mVelocityTracker;
@@ -274,6 +276,9 @@
super(context, attrs, defStyleAttr, defStyleRes);
mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, context.getDisplay(),
Choreographer.getInstance());
+ final DisplayManager displayManager =
+ (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+ mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
}
@Override
@@ -373,7 +378,13 @@
if (mStableInsets.isEmpty()) {
SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
}
- repositionSnapTargetBeforeMinimized();
+
+ if (mState.mRatioPositionBeforeMinimized == 0) {
+ // Set the middle target as the initial state
+ mSnapTargetBeforeMinimized = mSnapAlgorithm.getMiddleTarget();
+ } else {
+ repositionSnapTargetBeforeMinimized();
+ }
}
public WindowManagerProxy getWindowManagerProxy() {
@@ -403,6 +414,11 @@
mHandle.setTouching(true, animate);
}
mDockSide = mWindowManagerProxy.getDockSide();
+
+ // Update snap algorithm if rotation has occurred
+ if (mDisplayRotation != mDefaultDisplay.getRotation()) {
+ updateDisplayInfo();
+ }
initializeSnapAlgorithm();
mWindowManagerProxy.setResizing(true);
if (touching) {
@@ -453,7 +469,7 @@
private void initializeSnapAlgorithm() {
if (mSnapAlgorithm == null) {
mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth,
- mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets);
+ mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets, mDockSide);
}
if (mMinimizedSnapAlgorithm == null) {
mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(),
@@ -620,7 +636,10 @@
} else {
saveTarget = snapTarget;
}
- saveSnapTargetBeforeMinimized(saveTarget);
+ if (saveTarget.position != mSnapAlgorithm.getDismissEndTarget().position
+ && saveTarget.position != mSnapAlgorithm.getDismissStartTarget().position) {
+ saveSnapTargetBeforeMinimized(saveTarget);
+ }
}
};
Runnable notCancelledEndAction = () -> {
@@ -764,6 +783,8 @@
initializeSnapAlgorithm();
if (mIsInMinimizeInteraction != minimized) {
if (minimized) {
+ // Relayout to recalculate the divider shadow when minimizing
+ requestLayout();
mIsInMinimizeInteraction = true;
resizeStack(mMinimizedSnapAlgorithm.getMiddleTarget());
} else {
@@ -913,11 +934,9 @@
}
private void updateDisplayInfo() {
- final DisplayManager displayManager =
- (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+ mDisplayRotation = mDefaultDisplay.getRotation();
final DisplayInfo info = new DisplayInfo();
- display.getDisplayInfo(info);
+ mDefaultDisplay.getDisplayInfo(info);
mDisplayWidth = info.logicalWidth;
mDisplayHeight = info.logicalHeight;
mSnapAlgorithm = null;
@@ -991,44 +1010,47 @@
if (mHomeStackResizable && mIsInMinimizeInteraction) {
calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide,
mDockedTaskRect);
+ calculateBoundsForPosition(mSnapTargetBeforeMinimized.position,
+ DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
// Move a right-docked-app to line up with the divider while dragging it
if (mDockSide == DOCKED_RIGHT) {
mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize)
- mDockedTaskRect.left + mDividerSize, 0);
+ mOtherTaskRect.offset(mStableInsets.left, 0);
}
- calculateBoundsForPosition(mSnapTargetBeforeMinimized.position,
- DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect,
mOtherTaskRect, null);
return;
}
if (mEntranceAnimationRunning && taskPosition != TASK_POSITION_SAME) {
- if (mCurrentAnimator != null) {
- calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
- } else {
- calculateBoundsForPosition(isHorizontalDivision() ? mDisplayHeight : mDisplayWidth,
- mDockSide, mDockedTaskRect);
- }
+ calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
// Move a docked app if from the right in position with the divider up to insets
if (mDockSide == DOCKED_RIGHT) {
- mDockedTaskRect.offset(Math.max(position,
- mStableInsets.left) - mDockedTaskRect.left, 0);
+ mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize)
+ - mDockedTaskRect.left + mDividerSize, 0);
+ mOtherTaskRect.offset(mStableInsets.left, 0);
}
calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide),
mOtherTaskRect);
mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null,
mOtherTaskRect, null);
} else if (mExitAnimationRunning && taskPosition != TASK_POSITION_SAME) {
- calculateBoundsForPosition(taskPosition,
- mDockSide, mDockedTaskRect);
+ calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
+ mDockedInsetRect.set(mDockedTaskRect);
calculateBoundsForPosition(mExitStartPosition,
DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
mOtherInsetRect.set(mOtherTaskRect);
applyExitAnimationParallax(mOtherTaskRect, position);
- mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null,
+
+ // Move a right-docked-app to line up with the divider while dragging it
+ if (mDockSide == DOCKED_RIGHT) {
+ mDockedTaskRect.offset(position - mStableInsets.left + mDividerSize, 0);
+ mOtherTaskRect.offset(mStableInsets.left, 0);
+ }
+ mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedInsetRect,
mOtherTaskRect, mOtherInsetRect);
} else if (taskPosition != TASK_POSITION_SAME) {
calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
@@ -1040,17 +1062,17 @@
restrictDismissingTaskPosition(taskPosition, dockSideInverted, taskSnapTarget);
calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect);
calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect);
- mDisplayRect.set(0, 0, mDisplayWidth, mDisplayHeight);
+ mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight);
alignTopLeft(mDockedRect, mDockedTaskRect);
alignTopLeft(mOtherRect, mOtherTaskRect);
mDockedInsetRect.set(mDockedTaskRect);
mOtherInsetRect.set(mOtherTaskRect);
if (dockSideTopLeft(mDockSide)) {
- alignTopLeft(mDisplayRect, mDockedInsetRect);
- alignBottomRight(mDisplayRect, mOtherInsetRect);
+ alignTopLeft(mTmpRect, mDockedInsetRect);
+ alignBottomRight(mTmpRect, mOtherInsetRect);
} else {
- alignBottomRight(mDisplayRect, mDockedInsetRect);
- alignTopLeft(mDisplayRect, mOtherInsetRect);
+ alignBottomRight(mTmpRect, mDockedInsetRect);
+ alignTopLeft(mTmpRect, mOtherInsetRect);
}
applyDismissingParallax(mDockedTaskRect, mDockSide, taskSnapTarget, position,
taskPositionDocked);
@@ -1269,23 +1291,22 @@
startDragging(false /* animate */, false /* touching */);
}
updateDockSide();
- int position = DockedDividerUtils.calculatePositionForBounds(event.initialRect,
- mDockSide, mDividerSize);
mEntranceAnimationRunning = true;
- resizeStack(position, mSnapAlgorithm.getMiddleTarget().position,
+ resizeStack(calculatePositionForInsetBounds(), mSnapAlgorithm.getMiddleTarget().position,
mSnapAlgorithm.getMiddleTarget());
}
public void onRecentsDrawn() {
+ updateDockSide();
+ final int position = calculatePositionForInsetBounds();
if (mState.animateAfterRecentsDrawn) {
mState.animateAfterRecentsDrawn = false;
- updateDockSide();
mHandler.post(() -> {
// Delay switching resizing mode because this might cause jank in recents animation
// that's longer than this animation.
- stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(),
+ stopDragging(position, getSnapAlgorithm().getMiddleTarget(),
mLongPressEntraceAnimDuration, Interpolators.FAST_OUT_SLOW_IN,
200 /* endDelay */);
});
@@ -1294,7 +1315,7 @@
mState.growAfterRecentsDrawn = false;
updateDockSide();
EventBus.getDefault().send(new RecentsGrowingEvent());
- stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 336,
+ stopDragging(position, getSnapAlgorithm().getMiddleTarget(), 336,
Interpolators.FAST_OUT_SLOW_IN);
}
}
@@ -1315,4 +1336,10 @@
0 /* endDelay */, Interpolators.FAST_OUT_SLOW_IN);
}
}
+
+ private int calculatePositionForInsetBounds() {
+ mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight);
+ mTmpRect.inset(mStableInsets);
+ return DockedDividerUtils.calculatePositionForBounds(mTmpRect, mDockSide, mDividerSize);
+ }
}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 2c0e97e..aa426d3 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -762,26 +762,16 @@
}
/**
- * Action taken when GattService is turned on
+ * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
*/
- private void onBluetoothGattServiceUp() {
+ private void continueFromBleOnState() {
if (DBG) {
- Slog.d(TAG, "BluetoothGatt Service is Up");
+ Slog.d(TAG, "continueFromBleOnState()");
}
try {
mBluetoothLock.readLock().lock();
if (mBluetooth == null) {
- if (DBG) {
- Slog.w(TAG, "onBluetoothServiceUp: mBluetooth is null!");
- }
- return;
- }
- int st = mBluetooth.getState();
- if (st != BluetoothAdapter.STATE_BLE_ON) {
- if (DBG) {
- Slog.v(TAG, "onBluetoothServiceUp: state isn't BLE_ON: "
- + BluetoothAdapter.nameForState(st));
- }
+ Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
return;
}
if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
@@ -1637,7 +1627,7 @@
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
mBluetoothGatt =
IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
- onBluetoothGattServiceUp();
+ continueFromBleOnState();
break;
} // else must be SERVICE_IBLUETOOTH
@@ -2054,21 +2044,16 @@
if (DBG) {
Slog.d(TAG, "Bluetooth is in LE only mode");
}
- if (mBluetoothGatt != null) {
- if (DBG) {
- Slog.d(TAG, "Calling BluetoothGattServiceUp");
- }
- onBluetoothGattServiceUp();
+ if (mBluetoothGatt != null || !mContext.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
+ continueFromBleOnState();
} else {
if (DBG) {
Slog.d(TAG, "Binding Bluetooth GATT service");
}
- if (mContext.getPackageManager()
- .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
- Intent i = new Intent(IBluetoothGatt.class.getName());
- doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
- UserHandle.CURRENT);
- }
+ Intent i = new Intent(IBluetoothGatt.class.getName());
+ doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+ UserHandle.CURRENT);
}
sendBleStateChanged(prevState, newState);
//Don't broadcase this as std intent
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 27eae57..698b6f7 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -800,6 +800,20 @@
}
}
+ /**
+ * See {@link DisplayWindowController#deferUpdateImeTarget()}
+ */
+ public void deferUpdateImeTarget() {
+ mWindowContainerController.deferUpdateImeTarget();
+ }
+
+ /**
+ * See {@link DisplayWindowController#deferUpdateImeTarget()}
+ */
+ public void continueUpdateImeTarget() {
+ mWindowContainerController.continueUpdateImeTarget();
+ }
+
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size());
final String myPrefix = prefix + " ";
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index a85df03..c182502 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -639,6 +639,9 @@
// so that the divider matches and remove this logic.
// TODO: This is currently only called when entering split-screen while in another
// task, and from the tests
+ // TODO (b/78247419): Check if launcher and overview are same then move home stack
+ // instead of recents stack. Then fix the rotation animation from fullscreen to
+ // minimized mode
final ActivityStack recentStack = display.getOrCreateStack(
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS,
true /* onTop */);
@@ -4592,46 +4595,58 @@
}
}
- // Shift all activities with this task up to the top
- // of the stack, keeping them in the same internal order.
- insertTaskAtTop(tr, null);
+ try {
+ // Defer updating the IME target since the new IME target will try to get computed
+ // before updating all closing and opening apps, which can cause the ime target to
+ // get calculated incorrectly.
+ getDisplay().deferUpdateImeTarget();
- // Don't refocus if invisible to current user
- final ActivityRecord top = tr.getTopActivity();
- if (top == null || !top.okToShowLocked()) {
- if (top != null) {
- mStackSupervisor.mRecentTasks.add(top.getTask());
+ // Shift all activities with this task up to the top
+ // of the stack, keeping them in the same internal order.
+ insertTaskAtTop(tr, null);
+
+ // Don't refocus if invisible to current user
+ final ActivityRecord top = tr.getTopActivity();
+ if (top == null || !top.okToShowLocked()) {
+ if (top != null) {
+ mStackSupervisor.mRecentTasks.add(top.getTask());
+ }
+ ActivityOptions.abort(options);
+ return;
}
- ActivityOptions.abort(options);
- return;
- }
- // Set focus to the top running activity of this stack.
- final ActivityRecord r = topRunningActivityLocked();
- mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason);
+ // Set focus to the top running activity of this stack.
+ final ActivityRecord r = topRunningActivityLocked();
+ mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason);
- if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
- if (noAnimation) {
- mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
- if (r != null) {
- mStackSupervisor.mNoAnimActivities.add(r);
+ if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
+ if (noAnimation) {
+ mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
+ if (r != null) {
+ mStackSupervisor.mNoAnimActivities.add(r);
+ }
+ ActivityOptions.abort(options);
+ } else {
+ updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
}
- ActivityOptions.abort(options);
- } else {
- updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
- }
- // If a new task is moved to the front, then mark the existing top activity as supporting
- // picture-in-picture while paused only if the task would not be considered an oerlay on top
- // of the current activity (eg. not fullscreen, or the assistant)
- if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */,
- options)) {
- topActivity.supportsEnterPipOnTaskSwitch = true;
- }
+ // If a new task is moved to the front, then mark the existing top activity as
+ // supporting
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
- EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
+ // picture-in-picture while paused only if the task would not be considered an oerlay
+ // on top
+ // of the current activity (eg. not fullscreen, or the assistant)
+ if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */,
+ options)) {
+ topActivity.supportsEnterPipOnTaskSwitch = true;
+ }
- mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
+ mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
+
+ mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
+ } finally {
+ getDisplay().continueUpdateImeTarget();
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index 5e29d10..bbdc924 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -339,7 +339,8 @@
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0,
- null, userId, realCallingUid);
+ null, userId, ActivityStarter.computeResolveFilterUid(
+ callingUid, realCallingUid));
// TODO: New, check if this is correct
aInfo = mService.getActivityInfoForUser(aInfo, userId);
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 3b18d32..bbf6e6c 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -791,7 +791,8 @@
callingUid = realCallingUid;
callingPid = realCallingPid;
- rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0, realCallingUid);
+ rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
+ computeResolveFilterUid(callingUid, realCallingUid));
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
null /*profilerInfo*/);
@@ -955,6 +956,16 @@
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
+ int callingPid;
+ if (callingUid >= 0) {
+ callingPid = -1;
+ } else if (caller == null) {
+ callingPid = realCallingPid;
+ callingUid = realCallingUid;
+ } else {
+ callingPid = callingUid = -1;
+ }
+
// Save a copy in case ephemeral needs it
final Intent ephemeralIntent = new Intent(intent);
// Don't modify the client's object!
@@ -973,7 +984,7 @@
}
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
- 0 /* matchFlags */, realCallingUid);
+ 0 /* matchFlags */, computeResolveFilterUid(callingUid, realCallingUid));
if (rInfo == null) {
UserInfo userInfo = mSupervisor.getUserInfo(userId);
if (userInfo != null && userInfo.isManagedProfile()) {
@@ -995,7 +1006,7 @@
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- realCallingUid);
+ computeResolveFilterUid(callingUid, realCallingUid));
}
}
}
@@ -1003,16 +1014,6 @@
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
synchronized (mService) {
- int callingPid;
- if (callingUid >= 0) {
- callingPid = -1;
- } else if (caller == null) {
- callingPid = realCallingPid;
- callingUid = realCallingUid;
- } else {
- callingPid = callingUid = -1;
- }
-
final ActivityStack stack = mSupervisor.mFocusedStack;
stack.mConfigWillChange = globalConfig != null
&& mService.getGlobalConfiguration().diff(globalConfig) != 0;
@@ -1077,7 +1078,8 @@
callingPid = Binder.getCallingPid();
componentSpecified = true;
rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
- 0 /* matchFlags */, realCallingUid);
+ 0 /* matchFlags */, computeResolveFilterUid(callingUid,
+ realCallingUid));
aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
aInfo = mService.getActivityInfoForUser(aInfo, userId);
@@ -1164,6 +1166,19 @@
}
}
+ /**
+ * Compute the logical UID based on which the package manager would filter
+ * app components i.e. based on which the instant app policy would be applied
+ * because it is the logical calling UID.
+ *
+ * @param customCallingUid The UID on whose behalf to make the call.
+ * @param actualCallingUid The UID actually making the call.
+ * @return The logical UID making the call.
+ */
+ static int computeResolveFilterUid(int customCallingUid, int actualCallingUid) {
+ return customCallingUid >= 0 ? customCallingUid : actualCallingUid;
+ }
+
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 8ad8256..18c0957 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -64,6 +64,7 @@
import android.os.IProgressListener;
import android.os.IRemoteCallback;
import android.os.IUserManager;
+import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteCallbackList;
@@ -962,6 +963,11 @@
updateStartedUserArrayLU();
needStart = true;
updateUmState = true;
+ } else if (uss.state == UserState.STATE_SHUTDOWN && !isCallingOnHandlerThread()) {
+ Slog.i(TAG, "User #" + userId
+ + " is shutting down - will start after full stop");
+ mHandler.post(() -> startUser(userId, foreground, unlockListener));
+ return true;
}
final Integer userIdInt = userId;
mUserLru.remove(userIdInt);
@@ -1086,6 +1092,10 @@
return true;
}
+ private boolean isCallingOnHandlerThread() {
+ return Looper.myLooper() == mHandler.getLooper();
+ }
+
/**
* Start user, if its not already running, and bring it to foreground.
*/
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c0dc750..f3423c6 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -390,6 +390,11 @@
*/
int mLayoutSeq = 0;
+ /**
+ * Specifies the count to determine whether to defer updating the IME target until ready.
+ */
+ private int mDeferUpdateImeTargetCount;
+
/** Temporary float array to retrieve 3x3 matrix values. */
private final float[] mTmpFloats = new float[9];
@@ -2454,6 +2459,12 @@
return null;
}
+ final WindowState curTarget = mService.mInputMethodTarget;
+ if (!canUpdateImeTarget()) {
+ if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target");
+ return curTarget;
+ }
+
// TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
// same display. Or even when the current IME/target are not on the same screen as the next
// IME/target. For now only look for input windows on the main screen.
@@ -2477,16 +2488,13 @@
if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM,
"Proposed new IME target: " + target);
- // Now, a special case -- if the last target's window is in the process of exiting, and is
- // above the new target, keep on the last target to avoid flicker. Consider for example a
- // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it
- // until it is completely gone so it doesn't drop behind the dialog or its full-screen
- // scrim.
- final WindowState curTarget = mService.mInputMethodTarget;
+ // Now, a special case -- if the last target's window is in the process of exiting, and the
+ // new target is home, keep on the last target to avoid flicker. Home is a special case
+ // since its above other stacks in the ordering list, but layed out below the others.
if (curTarget != null && curTarget.isDisplayedLw() && curTarget.isClosing()
- && (target == null
- || curTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer)) {
- if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
+ && (target == null || target.isActivityTypeHome())) {
+ if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "New target is home while current target is"
+ + "closing, not changing");
return curTarget;
}
@@ -3958,4 +3966,33 @@
void assignStackOrdering() {
mTaskStackContainers.assignStackOrdering(getPendingTransaction());
}
+
+ /**
+ * Increment the deferral count to determine whether to update the IME target.
+ */
+ void deferUpdateImeTarget() {
+ mDeferUpdateImeTargetCount++;
+ }
+
+ /**
+ * Decrement the deferral count to determine whether to update the IME target. If the count
+ * reaches 0, a new ime target will get computed.
+ */
+ void continueUpdateImeTarget() {
+ if (mDeferUpdateImeTargetCount == 0) {
+ return;
+ }
+
+ mDeferUpdateImeTargetCount--;
+ if (mDeferUpdateImeTargetCount == 0) {
+ computeImeTarget(true /* updateImeTarget */);
+ }
+ }
+
+ /**
+ * @return Whether a new IME target should be computed.
+ */
+ private boolean canUpdateImeTarget() {
+ return mDeferUpdateImeTargetCount == 0;
+ }
}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index ba8ec69..a1639c2 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -94,6 +94,31 @@
}
}
+ /**
+ * Starts deferring the ability to update the IME target. This is needed when a call will
+ * attempt to update the IME target before all information about the Windows have been updated.
+ */
+ public void deferUpdateImeTarget() {
+ synchronized (mWindowMap) {
+ final DisplayContent dc = mRoot.getDisplayContent(mDisplayId);
+ if (dc != null) {
+ dc.deferUpdateImeTarget();
+ }
+ }
+ }
+
+ /**
+ * Resumes updating the IME target after deferring. See {@link #deferUpdateImeTarget()}
+ */
+ public void continueUpdateImeTarget() {
+ synchronized (mWindowMap) {
+ final DisplayContent dc = mRoot.getDisplayContent(mDisplayId);
+ if (dc != null) {
+ dc.continueUpdateImeTarget();
+ }
+ }
+ }
+
@Override
public String toString() {
return "{DisplayWindowController displayId=" + mDisplayId + "}";
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c710c97..7883e2e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2726,7 +2726,7 @@
}
boolean isClosing() {
- return mAnimatingExit || (mService.mClosingApps.contains(mAppToken));
+ return mAnimatingExit || (mAppToken.isAnimating() && mAppToken.hiddenRequested);
}
void addWinAnimatorToList(ArrayList<WindowStateAnimator> animators) {