Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7582a00 authored by Massimo Carli's avatar Massimo Carli Committed by Android (Google) Code Review
Browse files

Merge "[20/n] Encapsulate Fake Focus policy" into main

parents e1dd0c8d cefabe1b
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -10890,12 +10890,8 @@ 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 mLetterboxUiController.shouldSendFakeFocus() && inMultiWindowMode()
                && !inPinnedWindowingMode() && !inFreeformWindowingMode();
        return mAppCompatController.getAppCompatFocusOverrides().shouldSendFakeFocus();
    }

    boolean canCaptureSnapshot() {
+5 −0
Original line number Diff line number Diff line
@@ -94,4 +94,9 @@ class AppCompatController {
        }
        return null;
    }

    @NonNull
    AppCompatFocusOverrides getAppCompatFocusOverrides() {
        return mAppCompatOverrides.getAppCompatFocusOverrides();
    }
}
+68 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wm;

import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;

import static com.android.server.wm.AppCompatUtils.isChangeEnabled;

import android.annotation.NonNull;

import com.android.server.wm.utils.OptPropFactory;

/**
 * Encapsulates app compat focus policy.
 */
class AppCompatFocusOverrides {

    @NonNull
    final ActivityRecord mActivityRecord;
    @NonNull
    private final OptPropFactory.OptProp mFakeFocusOptProp;

    AppCompatFocusOverrides(@NonNull ActivityRecord activityRecord,
            @NonNull AppCompatConfiguration appCompatConfiguration,
            @NonNull OptPropFactory optPropBuilder) {
        mActivityRecord = activityRecord;
        mFakeFocusOptProp = optPropBuilder.create(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS,
                appCompatConfiguration::isCompatFakeFocusEnabled);
    }

    /**
     * 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.
     *
     * <p>This treatment is enabled when the following conditions are met:
     * <ul>
     *     <li>Flag gating the treatment is enabled
     *     <li>Component property is NOT set to false
     *     <li>Component property is set to true or per-app override is enabled
     * </ul>
     */
    boolean shouldSendFakeFocus() {
        // 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.
        return mFakeFocusOptProp.shouldEnableWithOverrideAndProperty(
                isChangeEnabled(mActivityRecord, OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS))
                && mActivityRecord.inMultiWindowMode() && !mActivityRecord.inPinnedWindowingMode()
                && !mActivityRecord.inFreeformWindowingMode();
    }

}
+10 −35
Original line number Diff line number Diff line
@@ -18,17 +18,12 @@ package com.android.server.wm;

import static android.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
import static android.content.pm.ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION;
import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;

import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;

import android.annotation.NonNull;

@@ -39,16 +34,9 @@ import com.android.server.wm.utils.OptPropFactory;
 */
public class AppCompatOverrides {

    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppCompatOverrides" : TAG_ATM;

    @NonNull
    private final AppCompatConfiguration mAppCompatConfiguration;

    @NonNull
    private final ActivityRecord mActivityRecord;

    @NonNull
    private final OptPropFactory.OptProp mFakeFocusOptProp;
    @NonNull
    private final OptPropFactory.OptProp mAllowOrientationOverrideOptProp;
    @NonNull
@@ -61,26 +49,25 @@ public class AppCompatOverrides {
    private final AppCompatCameraOverrides mAppCompatCameraOverrides;
    @NonNull
    private final AppCompatAspectRatioOverrides mAppCompatAspectRatioOverrides;
    @NonNull
    private final AppCompatFocusOverrides mAppCompatFocusOverrides;

    AppCompatOverrides(@NonNull ActivityRecord activityRecord,
            @NonNull AppCompatConfiguration appCompatConfiguration,
            @NonNull OptPropFactory optPropBuilder) {
        mAppCompatConfiguration = appCompatConfiguration;
        mActivityRecord = activityRecord;

        mAppCompatCameraOverrides = new AppCompatCameraOverrides(mActivityRecord,
                mAppCompatConfiguration, optPropBuilder);
                appCompatConfiguration, optPropBuilder);
        mAppCompatOrientationOverrides = new AppCompatOrientationOverrides(mActivityRecord,
                mAppCompatConfiguration, optPropBuilder, mAppCompatCameraOverrides);
                appCompatConfiguration, optPropBuilder, mAppCompatCameraOverrides);
        // TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with reachability.
        mAppCompatAspectRatioOverrides = new AppCompatAspectRatioOverrides(activityRecord,
                mAppCompatConfiguration, optPropBuilder,
                appCompatConfiguration, optPropBuilder,
                activityRecord.mLetterboxUiController::isDisplayFullScreenAndInPosture,
                activityRecord.mLetterboxUiController::getHorizontalPositionMultiplier);

        mFakeFocusOptProp = optPropBuilder.create(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS,
                mAppCompatConfiguration::isCompatFakeFocusEnabled);

        mAppCompatFocusOverrides = new AppCompatFocusOverrides(mActivityRecord,
                appCompatConfiguration, optPropBuilder);

        mAllowOrientationOverrideOptProp = optPropBuilder.create(
                PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
@@ -114,21 +101,9 @@ public class AppCompatOverrides {
        return mAppCompatAspectRatioOverrides;
    }

    /**
     * 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.
     *
     * <p>This treatment is enabled when the following conditions are met:
     * <ul>
     *     <li>Flag gating the treatment is enabled
     *     <li>Component property is NOT set to false
     *     <li>Component property is set to true or per-app override is enabled
     * </ul>
     */
    boolean shouldSendFakeFocus() {
        return mFakeFocusOptProp.shouldEnableWithOverrideAndProperty(
                isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS));
    @NonNull
    AppCompatFocusOverrides getAppCompatFocusOverrides() {
        return mAppCompatFocusOverrides;
    }

    boolean isAllowOrientationOverrideOptOut() {
+9 −0
Original line number Diff line number Diff line
@@ -73,4 +73,13 @@ class AppCompatUtils {
    static boolean isInVrUiMode(Configuration config) {
        return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
    }

    /**
     * @param activityRecord The {@link ActivityRecord} for the app package.
     * @param overrideChangeId The per-app override identifier.
     * @return {@code true} if the per-app override is enable for the given activity.
     */
    static boolean isChangeEnabled(@NonNull ActivityRecord activityRecord, long overrideChangeId) {
        return activityRecord.info.isChangeEnabled(overrideChangeId);
    }
}
Loading