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

Commit deec31dd authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge "Merge changes If44268b0,Ie808507f into qt-dev am: c5533578 am:...

Merge "Merge changes If44268b0,Ie808507f into qt-dev am: c5533578 am: f17baa09" into qt-r1-dev-plus-aosp
parents ebb3c8ed 45c6b4fc
Loading
Loading
Loading
Loading
+44 −5
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.wm.WindowManagerInternal;

import java.util.ArrayList;
import java.util.Collection;
@@ -90,8 +91,10 @@ public class CameraServiceProxy extends SystemService

    private ICameraService mCameraServiceRaw;

    // Map of currently active camera IDs
    private final ArrayMap<String, CameraUsageEvent> mActiveCameraUsage = new ArrayMap<>();
    private final List<CameraUsageEvent> mCameraUsageHistory = new ArrayList<>();

    private final MetricsLogger mLogger = new MetricsLogger();
    private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc";
    private static final String NFC_SERVICE_BINDER_NAME = "nfc";
@@ -415,6 +418,24 @@ public class CameraServiceProxy extends SystemService
                    }
                    break;
                case ICameraServiceProxy.CAMERA_STATE_ACTIVE:
                    // Check current active camera IDs to see if this package is already talking to
                    // some camera
                    boolean alreadyActivePackage = false;
                    for (int i = 0; i < mActiveCameraUsage.size(); i++) {
                        if (mActiveCameraUsage.valueAt(i).mClientName.equals(clientName)) {
                            alreadyActivePackage = true;
                            break;
                        }
                    }
                    // If not already active, notify window manager about this new package using a
                    // camera
                    if (!alreadyActivePackage) {
                        WindowManagerInternal wmi =
                                LocalServices.getService(WindowManagerInternal.class);
                        wmi.addNonHighRefreshRatePackage(clientName);
                    }

                    // Update activity events
                    CameraUsageEvent newEvent = new CameraUsageEvent(facing, clientName, apiLevel);
                    CameraUsageEvent oldEvent = mActiveCameraUsage.put(cameraId, newEvent);
                    if (oldEvent != null) {
@@ -426,13 +447,31 @@ public class CameraServiceProxy extends SystemService
                case ICameraServiceProxy.CAMERA_STATE_IDLE:
                case ICameraServiceProxy.CAMERA_STATE_CLOSED:
                    CameraUsageEvent doneEvent = mActiveCameraUsage.remove(cameraId);
                    if (doneEvent != null) {
                    if (doneEvent == null) break;

                    doneEvent.markCompleted();
                    mCameraUsageHistory.add(doneEvent);
                    if (mCameraUsageHistory.size() > MAX_USAGE_HISTORY) {
                        dumpUsageEvents();
                    }

                    // Check current active camera IDs to see if this package is still talking to
                    // some camera
                    boolean stillActivePackage = false;
                    for (int i = 0; i < mActiveCameraUsage.size(); i++) {
                        if (mActiveCameraUsage.valueAt(i).mClientName.equals(clientName)) {
                            stillActivePackage = true;
                            break;
                        }
                    }
                    // If not longer active, notify window manager about this package being done
                    // with camera
                    if (!stillActivePackage) {
                        WindowManagerInternal wmi =
                                LocalServices.getService(WindowManagerInternal.class);
                        wmi.removeNonHighRefreshRatePackage(clientName);
                    }

                    break;
            }
            boolean isEmpty = mActiveCameraUsage.isEmpty();
+4 −3
Original line number Diff line number Diff line
@@ -804,10 +804,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                    mTmpApplySurfaceChangesTransactionState.preferredRefreshRate
                            = w.mAttrs.preferredRefreshRate;
                }
                final int preferredModeId = getDisplayPolicy().getRefreshRatePolicy()
                        .getPreferredModeId(w);
                if (mTmpApplySurfaceChangesTransactionState.preferredModeId == 0
                        && w.mAttrs.preferredDisplayModeId != 0) {
                    mTmpApplySurfaceChangesTransactionState.preferredModeId
                            = w.mAttrs.preferredDisplayModeId;
                        && preferredModeId != 0) {
                    mTmpApplySurfaceChangesTransactionState.preferredModeId = preferredModeId;
                }
            }
        }
+10 −0
Original line number Diff line number Diff line
@@ -381,6 +381,8 @@ public class DisplayPolicy {
     */
    @NonNull private Insets mForwardedInsets = Insets.NONE;

    private RefreshRatePolicy mRefreshRatePolicy;

    // -------- PolicyHandler --------
    private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 1;
    private static final int MSG_REQUEST_TRANSIENT_BARS = 2;
@@ -591,6 +593,10 @@ public class DisplayPolicy {
            mHasStatusBar = false;
            mHasNavigationBar = mDisplayContent.supportsSystemDecorations();
        }

        mRefreshRatePolicy = new RefreshRatePolicy(mService,
                mDisplayContent.getDisplayInfo(),
                mService.mHighRefreshRateBlacklist);
    }

    void systemReady() {
@@ -3596,6 +3602,10 @@ public class DisplayPolicy {
        }
    }

    RefreshRatePolicy getRefreshRatePolicy() {
        return mRefreshRatePolicy;
    }

    void dump(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("DisplayPolicy");
        prefix += "  ";
+75 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 android.annotation.NonNull;
import android.os.SystemProperties;
import android.util.ArraySet;

import com.android.internal.annotations.VisibleForTesting;

/**
 * A Blacklist for packages that should force the display out of high refresh rate.
 */
class HighRefreshRateBlacklist {

    private static final String SYSPROP_KEY = "ro.window_manager.high_refresh_rate_blacklist";
    private static final String SYSPROP_KEY_LENGTH_SUFFIX = "_length";
    private static final String SYSPROP_KEY_ENTRY_SUFFIX = "_entry";
    private static final int MAX_ENTRIES = 50;

    private ArraySet<String> mBlacklistedPackages = new ArraySet<>();

    static HighRefreshRateBlacklist create() {
        return new HighRefreshRateBlacklist(new SystemPropertyGetter() {
            @Override
            public int getInt(String key, int def) {
                return SystemProperties.getInt(key, def);
            }

            @Override
            public String get(String key) {
                return SystemProperties.get(key);
            }
        });
    }

    @VisibleForTesting
    HighRefreshRateBlacklist(SystemPropertyGetter propertyGetter) {

        // Read and populate the blacklist
        final int length = Math.min(
                propertyGetter.getInt(SYSPROP_KEY + SYSPROP_KEY_LENGTH_SUFFIX, 0),
                MAX_ENTRIES);
        for (int i = 1; i <= length; i++) {
            final String packageName = propertyGetter.get(
                    SYSPROP_KEY + SYSPROP_KEY_ENTRY_SUFFIX + i);
            if (!packageName.isEmpty()) {
                mBlacklistedPackages.add(packageName);
            }
        }
    }

    boolean isBlacklisted(String packageName) {
        return mBlacklistedPackages.contains(packageName);
    }

    interface SystemPropertyGetter {
        int getInt(String key, int def);
        @NonNull String get(String key);
    }
}
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 android.util.ArraySet;
import android.view.Display.Mode;
import android.view.DisplayInfo;

/**
 * Policy to select a lower refresh rate for the display if applicable.
 */
class RefreshRatePolicy {

    private final int mLowRefreshRateId;
    private final ArraySet<String> mNonHighRefreshRatePackages = new ArraySet<>();
    private final HighRefreshRateBlacklist mHighRefreshRateBlacklist;
    private final WindowManagerService mWmService;

    RefreshRatePolicy(WindowManagerService wmService, DisplayInfo displayInfo,
            HighRefreshRateBlacklist blacklist) {
        mLowRefreshRateId = findLowRefreshRateModeId(displayInfo);
        mHighRefreshRateBlacklist = blacklist;
        mWmService = wmService;
    }

    /**
     * Finds the mode id with the lowest refresh rate which is >= 60hz and same resolution as the
     * default mode.
     */
    private int findLowRefreshRateModeId(DisplayInfo displayInfo) {
        Mode mode = displayInfo.getDefaultMode();
        float[] refreshRates = displayInfo.getDefaultRefreshRates();
        float bestRefreshRate = mode.getRefreshRate();
        for (int i = refreshRates.length - 1; i >= 0; i--) {
            if (refreshRates[i] >= 60f && refreshRates[i] < bestRefreshRate) {
                bestRefreshRate = refreshRates[i];
            }
        }
        return displayInfo.findDefaultModeByRefreshRate(bestRefreshRate);
    }

    void addNonHighRefreshRatePackage(String packageName) {
        mNonHighRefreshRatePackages.add(packageName);
        mWmService.requestTraversal();
    }

    void removeNonHighRefreshRatePackage(String packageName) {
        mNonHighRefreshRatePackages.remove(packageName);
        mWmService.requestTraversal();
    }

    int getPreferredModeId(WindowState w) {

        // If app is animating, it's not able to control refresh rate because we want the animation
        // to run in default refresh rate.
        if (w.isAnimating()) {
            return 0;
        }

        // If app requests a certain refresh rate or mode, don't override it.
        if (w.mAttrs.preferredRefreshRate != 0 || w.mAttrs.preferredDisplayModeId != 0) {
            return w.mAttrs.preferredDisplayModeId;
        }

        final String packageName = w.getOwningPackage();

        // If app is using Camera, force it to default (lower) refresh rate.
        if (mNonHighRefreshRatePackages.contains(packageName)) {
            return mLowRefreshRateId;
        }

        // If app is blacklisted using higher refresh rate, return default (lower) refresh rate
        if (mHighRefreshRateBlacklist.isBlacklisted(packageName)) {
            return mLowRefreshRateId;
        }
        return 0;
    }
}
Loading