Merge "Enable forced focus for resumed split screen activities" into tm-qpr-dev am: f1fc4e774a
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20620288 Change-Id: I321b9cf1c04d4b291b4da1739376fc791e03e422 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -4164,7 +4164,8 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
|
||||
private void scheduleResume(ActivityClientRecord r) {
|
||||
final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
|
||||
transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false));
|
||||
transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false,
|
||||
/* shouldSendCompatFakeFocus */ false));
|
||||
executeTransaction(transaction);
|
||||
}
|
||||
|
||||
@@ -4791,7 +4792,7 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
|
||||
@Override
|
||||
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
|
||||
boolean isForward, String reason) {
|
||||
boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
|
||||
// If we are getting ready to gc after going to the background, well
|
||||
// we are back active so skip it.
|
||||
unscheduleGcIdler();
|
||||
@@ -4898,6 +4899,16 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
if (r.activity.mVisibleFromClient) {
|
||||
r.activity.makeVisible();
|
||||
}
|
||||
|
||||
if (shouldSendCompatFakeFocus) {
|
||||
// Attaching to a window is asynchronous with the activity being resumed,
|
||||
// so it's possible we will need to send a fake focus event after attaching
|
||||
if (impl != null) {
|
||||
impl.dispatchCompatFakeFocus();
|
||||
} else {
|
||||
r.window.getDecorView().fakeFocusAfterAttachingToWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.nextIdle = mNewActivities;
|
||||
|
||||
@@ -109,7 +109,8 @@ public abstract class ClientTransactionHandler {
|
||||
* @param reason Reason for performing this operation.
|
||||
*/
|
||||
public abstract void handleResumeActivity(@NonNull ActivityClientRecord r,
|
||||
boolean finalStateRequest, boolean isForward, String reason);
|
||||
boolean finalStateRequest, boolean isForward, boolean shouldSendCompatFakeFocus,
|
||||
String reason);
|
||||
|
||||
/**
|
||||
* Notify the activity about top resumed state change.
|
||||
|
||||
@@ -39,6 +39,9 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
private int mProcState;
|
||||
private boolean mUpdateProcState;
|
||||
private boolean mIsForward;
|
||||
// Whether we should send compat fake focus when the activity is resumed. This is needed
|
||||
// because some game engines wait to get focus before drawing the content of the app.
|
||||
private boolean mShouldSendCompatFakeFocus;
|
||||
|
||||
@Override
|
||||
public void preExecute(ClientTransactionHandler client, IBinder token) {
|
||||
@@ -52,7 +55,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
|
||||
client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
|
||||
"RESUME_ACTIVITY");
|
||||
mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
|
||||
@@ -74,7 +77,8 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
private ResumeActivityItem() {}
|
||||
|
||||
/** Obtain an instance initialized with provided params. */
|
||||
public static ResumeActivityItem obtain(int procState, boolean isForward) {
|
||||
public static ResumeActivityItem obtain(int procState, boolean isForward,
|
||||
boolean shouldSendCompatFakeFocus) {
|
||||
ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class);
|
||||
if (instance == null) {
|
||||
instance = new ResumeActivityItem();
|
||||
@@ -82,12 +86,13 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
instance.mProcState = procState;
|
||||
instance.mUpdateProcState = true;
|
||||
instance.mIsForward = isForward;
|
||||
instance.mShouldSendCompatFakeFocus = shouldSendCompatFakeFocus;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/** Obtain an instance initialized with provided params. */
|
||||
public static ResumeActivityItem obtain(boolean isForward) {
|
||||
public static ResumeActivityItem obtain(boolean isForward, boolean shouldSendCompatFakeFocus) {
|
||||
ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class);
|
||||
if (instance == null) {
|
||||
instance = new ResumeActivityItem();
|
||||
@@ -95,6 +100,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
instance.mProcState = ActivityManager.PROCESS_STATE_UNKNOWN;
|
||||
instance.mUpdateProcState = false;
|
||||
instance.mIsForward = isForward;
|
||||
instance.mShouldSendCompatFakeFocus = shouldSendCompatFakeFocus;
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -105,6 +111,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
mProcState = ActivityManager.PROCESS_STATE_UNKNOWN;
|
||||
mUpdateProcState = false;
|
||||
mIsForward = false;
|
||||
mShouldSendCompatFakeFocus = false;
|
||||
ObjectPool.recycle(this);
|
||||
}
|
||||
|
||||
@@ -117,6 +124,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
dest.writeInt(mProcState);
|
||||
dest.writeBoolean(mUpdateProcState);
|
||||
dest.writeBoolean(mIsForward);
|
||||
dest.writeBoolean(mShouldSendCompatFakeFocus);
|
||||
}
|
||||
|
||||
/** Read from Parcel. */
|
||||
@@ -124,6 +132,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
mProcState = in.readInt();
|
||||
mUpdateProcState = in.readBoolean();
|
||||
mIsForward = in.readBoolean();
|
||||
mShouldSendCompatFakeFocus = in.readBoolean();
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<ResumeActivityItem> CREATOR =
|
||||
@@ -147,7 +156,8 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
}
|
||||
final ResumeActivityItem other = (ResumeActivityItem) o;
|
||||
return mProcState == other.mProcState && mUpdateProcState == other.mUpdateProcState
|
||||
&& mIsForward == other.mIsForward;
|
||||
&& mIsForward == other.mIsForward
|
||||
&& mShouldSendCompatFakeFocus == other.mShouldSendCompatFakeFocus;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -156,12 +166,14 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
result = 31 * result + mProcState;
|
||||
result = 31 * result + (mUpdateProcState ? 1 : 0);
|
||||
result = 31 * result + (mIsForward ? 1 : 0);
|
||||
result = 31 * result + (mShouldSendCompatFakeFocus ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResumeActivityItem{procState=" + mProcState
|
||||
+ ",updateProcState=" + mUpdateProcState + ",isForward=" + mIsForward + "}";
|
||||
+ ",updateProcState=" + mUpdateProcState + ",isForward=" + mIsForward
|
||||
+ ",shouldSendCompatFakeFocus=" + mShouldSendCompatFakeFocus + "}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,8 @@ public class TransactionExecutor {
|
||||
break;
|
||||
case ON_RESUME:
|
||||
mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
|
||||
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
|
||||
r.isForward, false /* shouldSendCompatFakeFocus */,
|
||||
"LIFECYCLER_RESUME_ACTIVITY");
|
||||
break;
|
||||
case ON_PAUSE:
|
||||
mTransactionHandler.handlePauseActivity(r, false /* finished */,
|
||||
|
||||
@@ -202,7 +202,8 @@ public class TransactionExecutorHelper {
|
||||
lifecycleItem = StopActivityItem.obtain(0 /* configChanges */);
|
||||
break;
|
||||
default:
|
||||
lifecycleItem = ResumeActivityItem.obtain(false /* isForward */);
|
||||
lifecycleItem = ResumeActivityItem.obtain(false /* isForward */,
|
||||
false /* shouldSendCompatFakeFocus */);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -21268,6 +21268,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
return Math.max(vis1, vis2);
|
||||
}
|
||||
|
||||
private boolean mShouldFakeFocus = false;
|
||||
|
||||
/**
|
||||
* Fake send a focus event after attaching to window.
|
||||
* See {@link android.view.ViewRootImpl#dispatchCompatFakeFocus()} for details.
|
||||
* @hide
|
||||
*/
|
||||
public void fakeFocusAfterAttachingToWindow() {
|
||||
mShouldFakeFocus = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param info the {@link android.view.View.AttachInfo} to associated with
|
||||
* this view
|
||||
@@ -21336,6 +21347,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
|
||||
notifyEnterOrExitForAutoFillIfNeeded(true);
|
||||
notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
|
||||
|
||||
if (mShouldFakeFocus) {
|
||||
getViewRootImpl().dispatchCompatFakeFocus();
|
||||
mShouldFakeFocus = false;
|
||||
}
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
|
||||
|
||||
@@ -258,6 +258,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
private static final boolean DEBUG_CONTENT_CAPTURE = false || LOCAL_LOGV;
|
||||
private static final boolean DEBUG_SCROLL_CAPTURE = false || LOCAL_LOGV;
|
||||
private static final boolean DEBUG_BLAST = false || LOCAL_LOGV;
|
||||
private static final int LOGTAG_INPUT_FOCUS = 62001;
|
||||
|
||||
/**
|
||||
* Set to false if we do not want to use the multi threaded renderer even though
|
||||
@@ -3810,8 +3811,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
if (mAdded) {
|
||||
dispatchFocusEvent(hasWindowFocus);
|
||||
|
||||
dispatchFocusEvent(hasWindowFocus, false /* fakeFocus */);
|
||||
// Note: must be done after the focus change callbacks,
|
||||
// so all of the view state is set up correctly.
|
||||
mImeFocusController.onPostWindowFocus(
|
||||
@@ -3846,7 +3846,33 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchFocusEvent(boolean hasWindowFocus) {
|
||||
/**
|
||||
* Send a fake focus event for unfocused apps in split screen as some game engines wait to
|
||||
* get focus before drawing the content of the app. This will be used so that apps do not get
|
||||
* blacked out when they are resumed and do not have focus yet.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
// TODO(b/263094829): Investigate dispatching this for onPause as well
|
||||
public void dispatchCompatFakeFocus() {
|
||||
boolean aboutToHaveFocus = false;
|
||||
synchronized (this) {
|
||||
aboutToHaveFocus = mWindowFocusChanged && mUpcomingWindowFocus;
|
||||
}
|
||||
final boolean alreadyHaveFocus = mAttachInfo.mHasWindowFocus;
|
||||
if (aboutToHaveFocus || alreadyHaveFocus) {
|
||||
// Do not need to toggle focus if app doesn't need it, or has focus.
|
||||
return;
|
||||
}
|
||||
EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
|
||||
"Giving fake focus to " + mBasePackageName, "reason=unity bug workaround");
|
||||
dispatchFocusEvent(true /* hasWindowFocus */, true /* fakeFocus */);
|
||||
EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
|
||||
"Removing fake focus from " + mBasePackageName, "reason=timeout callback");
|
||||
dispatchFocusEvent(false /* hasWindowFocus */, true /* fakeFocus */);
|
||||
}
|
||||
|
||||
private void dispatchFocusEvent(boolean hasWindowFocus, boolean fakeFocus) {
|
||||
profileRendering(hasWindowFocus);
|
||||
if (hasWindowFocus && mAttachInfo.mThreadedRenderer != null && mSurface.isValid()) {
|
||||
mFullRedrawNeeded = true;
|
||||
@@ -3872,8 +3898,10 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
mAttachInfo.mHasWindowFocus = hasWindowFocus;
|
||||
mImeFocusController.updateImeFocusable(mWindowAttributes, true /* force */);
|
||||
mImeFocusController.onPreWindowFocus(hasWindowFocus, mWindowAttributes);
|
||||
if (!fakeFocus) {
|
||||
mImeFocusController.updateImeFocusable(mWindowAttributes, true /* force */);
|
||||
mImeFocusController.onPreWindowFocus(hasWindowFocus, mWindowAttributes);
|
||||
}
|
||||
|
||||
if (mView != null) {
|
||||
mAttachInfo.mKeyDispatchState.reset();
|
||||
|
||||
@@ -5291,6 +5291,11 @@
|
||||
TODO(b/255532890) Enable when ignoreOrientationRequest is set -->
|
||||
<bool name="config_letterboxIsEnabledForTranslucentActivities">false</bool>
|
||||
|
||||
<!-- Whether sending compat fake focus for split screen resumed activities is enabled.
|
||||
Needed because some game engines wait to get focus before drawing the content of
|
||||
the app which isn't guaranteed by default in multi-window modes. -->
|
||||
<bool name="config_isCompatFakeFocusEnabled">false</bool>
|
||||
|
||||
<!-- Whether camera compat treatment is enabled for issues caused by orientation mismatch
|
||||
between camera buffers and an app window. This includes force rotation of fixed
|
||||
orientation activities connected to the camera in fullscreen and showing a tooltip in
|
||||
|
||||
@@ -4484,6 +4484,7 @@
|
||||
<java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
|
||||
<java-symbol type="dimen" name="config_letterboxDefaultMinAspectRatioForUnresizableApps" />
|
||||
<java-symbol type="bool" name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled" />
|
||||
<java-symbol type="bool" name="config_isCompatFakeFocusEnabled" />
|
||||
<java-symbol type="bool" name="config_isWindowManagerCameraCompatTreatmentEnabled" />
|
||||
<java-symbol type="bool" name="config_isCameraCompatControlForStretchedIssuesEnabled" />
|
||||
|
||||
|
||||
@@ -692,7 +692,8 @@ public class ActivityThreadTest {
|
||||
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null,
|
||||
null, 0, new MergedConfiguration(), false /* preserveWindow */);
|
||||
final ResumeActivityItem resumeStateRequest =
|
||||
ResumeActivityItem.obtain(true /* isForward */);
|
||||
ResumeActivityItem.obtain(true /* isForward */,
|
||||
false /* shouldSendCompatFakeFocus*/);
|
||||
|
||||
final ClientTransaction transaction = newTransaction(activity);
|
||||
transaction.addCallback(callbackItem);
|
||||
@@ -703,7 +704,8 @@ public class ActivityThreadTest {
|
||||
|
||||
private static ClientTransaction newResumeTransaction(Activity activity) {
|
||||
final ResumeActivityItem resumeStateRequest =
|
||||
ResumeActivityItem.obtain(true /* isForward */);
|
||||
ResumeActivityItem.obtain(true /* isForward */,
|
||||
false /* shouldSendCompatFakeFocus */);
|
||||
|
||||
final ClientTransaction transaction = newTransaction(activity);
|
||||
transaction.setLifecycleStateRequest(resumeStateRequest);
|
||||
|
||||
@@ -238,15 +238,15 @@ public class ObjectPoolTests {
|
||||
|
||||
@Test
|
||||
public void testRecycleResumeActivityItem() {
|
||||
ResumeActivityItem emptyItem = ResumeActivityItem.obtain(false);
|
||||
ResumeActivityItem item = ResumeActivityItem.obtain(3, true);
|
||||
ResumeActivityItem emptyItem = ResumeActivityItem.obtain(false, false);
|
||||
ResumeActivityItem item = ResumeActivityItem.obtain(3, true, false);
|
||||
assertNotSame(item, emptyItem);
|
||||
assertFalse(item.equals(emptyItem));
|
||||
|
||||
item.recycle();
|
||||
assertEquals(item, emptyItem);
|
||||
|
||||
ResumeActivityItem item2 = ResumeActivityItem.obtain(2, true);
|
||||
ResumeActivityItem item2 = ResumeActivityItem.obtain(2, true, false);
|
||||
assertSame(item, item2);
|
||||
assertFalse(item2.equals(emptyItem));
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ public class TransactionParcelTests {
|
||||
public void testResume() {
|
||||
// Write to parcel
|
||||
ResumeActivityItem item = ResumeActivityItem.obtain(27 /* procState */,
|
||||
true /* isForward */);
|
||||
true /* isForward */, false /* shouldSendCompatFakeFocus */);
|
||||
writeAndPrepareForReading(item);
|
||||
|
||||
// Read from parcel and assert
|
||||
|
||||
@@ -297,6 +297,20 @@ public class ViewRootImplTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDispatchFakeFocus_focusDoesNotPersist() throws Exception {
|
||||
View view = new View(sContext);
|
||||
attachViewToWindow(view);
|
||||
view.clearFocus();
|
||||
|
||||
assertThat(view.hasWindowFocus()).isFalse();
|
||||
|
||||
mViewRootImpl = view.getViewRootImpl();
|
||||
|
||||
mViewRootImpl.dispatchCompatFakeFocus();
|
||||
assertThat(view.hasWindowFocus()).isFalse();
|
||||
}
|
||||
|
||||
/**
|
||||
* When window doesn't have focus, keys should be dropped.
|
||||
*/
|
||||
|
||||
@@ -294,7 +294,7 @@ public class ActivityThreadClientTest {
|
||||
|
||||
private void resumeActivity(ActivityClientRecord r) {
|
||||
mThread.handleResumeActivity(r, true /* finalStateRequest */,
|
||||
true /* isForward */, "test");
|
||||
true /* isForward */, false /* shouldSendCompatFakeFocus */, "test");
|
||||
}
|
||||
|
||||
private void pauseActivity(ActivityClientRecord r) {
|
||||
|
||||
@@ -9351,7 +9351,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
preserveWindow);
|
||||
final ActivityLifecycleItem lifecycleItem;
|
||||
if (andResume) {
|
||||
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward());
|
||||
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward(),
|
||||
shouldSendCompatFakeFocus());
|
||||
} else {
|
||||
lifecycleItem = PauseActivityItem.obtain();
|
||||
}
|
||||
@@ -10118,6 +10119,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we should send fake focus when the activity is resumed. This is done because some
|
||||
* game engines wait to get focus before drawing the content of the app.
|
||||
*/
|
||||
// TODO(b/263593361): Explore enabling compat fake focus for freeform.
|
||||
// TODO(b/263592337): Explore enabling compat fake focus for fullscreen, e.g. for when
|
||||
// covered with bubbles.
|
||||
boolean shouldSendCompatFakeFocus() {
|
||||
return mWmService.mLetterboxConfiguration.isCompatFakeFocusEnabled() && inMultiWindowMode()
|
||||
&& !inPinnedWindowingMode() && !inFreeformWindowingMode();
|
||||
}
|
||||
|
||||
static class Builder {
|
||||
private final ActivityTaskManagerService mAtmService;
|
||||
private WindowProcessController mCallerApp;
|
||||
|
||||
@@ -918,7 +918,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
|
||||
// Set desired final state.
|
||||
final ActivityLifecycleItem lifecycleItem;
|
||||
if (andResume) {
|
||||
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
|
||||
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
|
||||
r.shouldSendCompatFakeFocus());
|
||||
} else {
|
||||
lifecycleItem = PauseActivityItem.obtain();
|
||||
}
|
||||
|
||||
@@ -214,7 +214,8 @@ final class DisplayRotationCompatPolicy {
|
||||
activity.app.getThread(), activity.token);
|
||||
transaction.addCallback(
|
||||
RefreshCallbackItem.obtain(cycleThroughStop ? ON_STOP : ON_PAUSE));
|
||||
transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false));
|
||||
transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(
|
||||
/* isForward */ false, /* shouldSendCompatFakeFocus */ false));
|
||||
activity.mAtmService.getLifecycleManager().scheduleTransaction(transaction);
|
||||
mHandler.postDelayed(
|
||||
() -> onActivityRefreshed(activity),
|
||||
|
||||
@@ -191,6 +191,11 @@ final class LetterboxConfiguration {
|
||||
// Allows to enable letterboxing strategy for translucent activities ignoring flags.
|
||||
private boolean mTranslucentLetterboxingOverrideEnabled;
|
||||
|
||||
// Whether sending compat fake focus is enabled for unfocused apps in splitscreen. Some game
|
||||
// engines wait to get focus before drawing the content of the app so this needs to be used
|
||||
// otherwise the apps get blacked out when they are resumed and do not have focus yet.
|
||||
private boolean mIsCompatFakeFocusEnabled;
|
||||
|
||||
// Whether camera compatibility treatment is enabled.
|
||||
// See DisplayRotationCompatPolicy for context.
|
||||
private final boolean mIsCameraCompatTreatmentEnabled;
|
||||
@@ -259,6 +264,8 @@ final class LetterboxConfiguration {
|
||||
R.bool.config_isWindowManagerCameraCompatTreatmentEnabled);
|
||||
mLetterboxConfigurationPersister = letterboxConfigurationPersister;
|
||||
mLetterboxConfigurationPersister.start();
|
||||
mIsCompatFakeFocusEnabled = mContext.getResources()
|
||||
.getBoolean(R.bool.config_isCompatFakeFocusEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -970,6 +977,13 @@ final class LetterboxConfiguration {
|
||||
"enable_translucent_activity_letterbox", false);
|
||||
}
|
||||
|
||||
// TODO(b/262866240): Add listener to check for device config property
|
||||
/** Whether fake sending focus is enabled for unfocused apps in splitscreen */
|
||||
boolean isCompatFakeFocusEnabled() {
|
||||
return mIsCompatFakeFocusEnabled && DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_WINDOW_MANAGER, "enable_compat_fake_focus", true);
|
||||
}
|
||||
|
||||
/** Whether camera compatibility treatment is enabled. */
|
||||
boolean isCameraCompatTreatmentEnabled(boolean checkDeviceConfig) {
|
||||
return mIsCameraCompatTreatmentEnabled
|
||||
|
||||
@@ -1472,7 +1472,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
next.abortAndClearOptionsAnimation();
|
||||
transaction.setLifecycleStateRequest(
|
||||
ResumeActivityItem.obtain(next.app.getReportedProcState(),
|
||||
dc.isNextTransitionForward()));
|
||||
dc.isNextTransitionForward(), next.shouldSendCompatFakeFocus()));
|
||||
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
|
||||
|
||||
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next);
|
||||
|
||||
@@ -398,7 +398,8 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
|
||||
final ClientTransaction transaction = ClientTransaction.obtain(
|
||||
mActivity.app.getThread(), mActivity.token);
|
||||
transaction.addCallback(RefreshCallbackItem.obtain(cycleThroughStop ? ON_STOP : ON_PAUSE));
|
||||
transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false));
|
||||
transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(
|
||||
/* isForward */ false, /* shouldSendCompatFakeFocus */ false));
|
||||
|
||||
verify(mActivity.mAtmService.getLifecycleManager(), times(refreshRequested ? 1 : 0))
|
||||
.scheduleTransaction(eq(transaction));
|
||||
|
||||
Reference in New Issue
Block a user