diff options
| author | 2016-01-04 22:22:16 +0000 | |
|---|---|---|
| committer | 2016-01-04 22:22:16 +0000 | |
| commit | 46ca282851ef12755a64810658a6043e70d6db5d (patch) | |
| tree | 56de700583b6cad489f9f2e164bd7fdd55945f21 | |
| parent | 4bd4f40fb21dbf24d0b1d7c73fc1e2c6bd242f06 (diff) | |
| parent | 4cea0f5bfc7d34299f5f645d37f94b14ac3dc22a (diff) | |
Merge "Don't allow unfocusable activity/stack to gain focus"
4 files changed, 42 insertions, 22 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1c25067f8a22..295fea053d0c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2748,6 +2748,12 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } + if (!r.isFocusable()) { + if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, + "setFocusedActivityLocked: unfocusable r=" + r); + return false; + } + if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r); final ActivityRecord last = mFocusedActivity; mFocusedActivity = r; diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 4d9120b09478..f0df0c43763a 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -16,6 +16,7 @@ package com.android.server.am; +import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE; @@ -739,6 +740,10 @@ final class ActivityRecord { (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0); } + boolean isFocusable() { + return StackId.canReceiveKeys(task.stack.mStackId); + } + void makeFinishingLocked() { if (!finishing) { if (task != null && task.stack != null diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index b9ff32c5cf46..9a6a7f72d751 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -560,7 +560,7 @@ final class ActivityStack { // TODO(multi-display): Needs to also work if focus is moving to the non-home display. if (isOnHomeDisplay()) { - mStackSupervisor.setFocusStack(reason, this); + mStackSupervisor.setFocusStackUnchecked(reason, this); } if (task != null) { insertTaskAtTop(task, null); @@ -573,7 +573,13 @@ final class ActivityStack { } boolean isFocusable() { - return StackId.canReceiveKeys(mStackId); + if (StackId.canReceiveKeys(mStackId)) { + return true; + } + // The stack isn't focusable. See if its top activity is focusable to force focus on the + // stack. + final ActivityRecord r = topRunningActivityLocked(); + return r != null && r.isFocusable(); } final boolean isAttached() { @@ -1299,7 +1305,7 @@ final class ActivityStack { return null; } - private ActivityStack getNextVisibleStackLocked() { + ActivityStack getNextFocusableStackLocked() { ArrayList<ActivityStack> stacks = mStacks; final ActivityRecord parent = mActivityContainer.mParentActivity; if (parent != null) { @@ -1308,7 +1314,7 @@ final class ActivityStack { if (stacks != null) { for (int i = stacks.size() - 1; i >= 0; --i) { ActivityStack stack = stacks.get(i); - if (stack != this && stack.isStackVisibleLocked()) { + if (stack != this && stack.isFocusable() && stack.isStackVisibleLocked()) { return stack; } } @@ -1836,14 +1842,13 @@ final class ActivityStack { if (next == null) { // There are no more activities! final String reason = "noMoreActivities"; - if (!mFullscreen) { + if (!mFullscreen && adjustFocusToNextFocusableStackLocked(reason)) { // Try to move focus to the next visible stack with a running activity if this // stack is not covering the entire screen. - final ActivityStack stack = getNextVisibleStackLocked(); - if (adjustFocusToNextVisibleStackLocked(stack, reason)) { - return mStackSupervisor.resumeFocusedStackTopActivityLocked(stack, prev, null); - } + return mStackSupervisor.resumeFocusedStackTopActivityLocked( + mStackSupervisor.getFocusedStack(), prev, null); } + // Let's just start up the Launcher... ActivityOptions.abort(options); if (DEBUG_STATES) Slog.d(TAG_STATES, @@ -2875,7 +2880,7 @@ final class ActivityStack { final ActivityRecord next = topRunningActivityLocked(); final String myReason = reason + " adjustFocus"; if (next != r) { - if (next != null && StackId.keepFocusInStackIfPossible(mStackId)) { + if (next != null && StackId.keepFocusInStackIfPossible(mStackId) && isFocusable()) { // For freeform, docked, and pinned stacks we always keep the focus within the // stack as long as there is a running activity in the stack that we can adjust // focus to. @@ -2887,8 +2892,7 @@ final class ActivityStack { // For non-fullscreen stack, we want to move the focus to the next visible // stack to prevent the home screen from moving to the top and obscuring // other visible stacks. - if (!mFullscreen - && adjustFocusToNextVisibleStackLocked(null, myReason)) { + if (!mFullscreen && adjustFocusToNextFocusableStackLocked(myReason)) { return; } // Move the home stack to the top if this stack is fullscreen or there is no @@ -2905,9 +2909,9 @@ final class ActivityStack { mService.setFocusedActivityLocked(mStackSupervisor.topRunningActivityLocked(), myReason); } - private boolean adjustFocusToNextVisibleStackLocked(ActivityStack inStack, String reason) { - final ActivityStack stack = (inStack != null) ? inStack : getNextVisibleStackLocked(); - final String myReason = reason + " adjustFocusToNextVisibleStack"; + private boolean adjustFocusToNextFocusableStackLocked(String reason) { + final ActivityStack stack = getNextFocusableStackLocked(); + final String myReason = reason + " adjustFocusToNextFocusableStack"; if (stack == null) { return false; } @@ -4658,7 +4662,7 @@ final class ActivityStack { // We only need to adjust focused stack if this stack is in focus. if (isOnHomeDisplay() && mStackSupervisor.isFocusedStack(this)) { String myReason = reason + " leftTaskHistoryEmpty"; - if (mFullscreen || !adjustFocusToNextVisibleStackLocked(null, myReason)) { + if (mFullscreen || !adjustFocusToNextFocusableStackLocked(myReason)) { mStackSupervisor.moveHomeStackToFront(myReason); } } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index df1aa52ee68f..688243d48fa1 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -492,8 +492,8 @@ public final class ActivityStackSupervisor implements DisplayListener { calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); } - createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY, true); - mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID); + mHomeStack = mFocusedStack = mLastFocusedStack = + getStack(HOME_STACK_ID, CREATE_IF_NEEDED, ON_TOP); mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); } @@ -538,10 +538,15 @@ public final class ActivityStackSupervisor implements DisplayListener { } /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */ - void setFocusStack(String reason, ActivityStack focusedStack) { - if (focusedStack != mFocusedStack) { + void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) { + if (!focusCandidate.isFocusable()) { + // The focus candidate isn't focusable. Move focus to the top stack that is focusable. + focusCandidate = focusCandidate.getNextFocusableStackLocked(); + } + + if (focusCandidate != mFocusedStack) { mLastFocusedStack = mFocusedStack; - mFocusedStack = focusedStack; + mFocusedStack = focusCandidate; EventLogTags.writeAmFocusedStack( mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(), @@ -904,7 +909,7 @@ public final class ActivityStackSupervisor implements DisplayListener { final ArrayList<ActivityStack> stacks = mHomeStack.mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); - if (stack != focusedStack && isFrontStack(stack)) { + if (stack != focusedStack && isFrontStack(stack) && stack.isFocusable()) { r = stack.topRunningActivityLocked(); if (r != null) { return r; |