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

Commit 22f7cd13 authored by Michael Wright's avatar Michael Wright Committed by Android (Google) Code Review
Browse files

Merge "Add DisplayModeDirector support for UDFPS" into sc-dev

parents 5b4e1622 e651abc2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -24,6 +24,13 @@ package android.hardware.fingerprint;
 * @hide
 */
oneway interface IUdfpsHbmListener {

    /** HBM that applies to the whole screen. */
    const int GLOBAL_HBM = 0;

    /** HBM that only applies to a portion of the screen. */
    const int LOCAL_HBM = 1;

    /**
     * UdfpsController will call this method when the HBM is enabled.
     *
+3 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics;

import android.annotation.IntDef;
import android.hardware.fingerprint.IUdfpsHbmListener;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -26,10 +27,10 @@ import java.lang.annotation.RetentionPolicy;
 */
public final class HbmTypes {
    /** HBM that applies to the whole screen. */
    public static final int GLOBAL_HBM = 0;
    public static final int GLOBAL_HBM = IUdfpsHbmListener.GLOBAL_HBM;

    /** HBM that only applies to a portion of the screen. */
    public static final int LOCAL_HBM = 1;
    public static final int LOCAL_HBM = IUdfpsHbmListener.LOCAL_HBM;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({GLOBAL_HBM, LOCAL_HBM})
+103 −8
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
@@ -40,14 +41,17 @@ import android.util.IndentingPrintWriter;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.Display;
import android.view.DisplayInfo;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.display.utils.AmbientFilter;
import com.android.server.display.utils.AmbientFilterFactory;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.utils.DeviceConfigInterface;

import java.io.PrintWriter;
@@ -93,6 +97,7 @@ public class DisplayModeDirector {
    private final AppRequestObserver mAppRequestObserver;
    private final SettingsObserver mSettingsObserver;
    private final DisplayObserver mDisplayObserver;
    private final UdfpsObserver mUdfpsObserver;
    private final DeviceConfigInterface mDeviceConfig;
    private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;

@@ -133,6 +138,7 @@ public class DisplayModeDirector {
        mSettingsObserver = new SettingsObserver(context, handler);
        mDisplayObserver = new DisplayObserver(context, handler);
        mBrightnessObserver = new BrightnessObserver(context, handler);
        mUdfpsObserver = new UdfpsObserver();
        mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
        mDeviceConfig = injector.getDeviceConfig();
        mAlwaysRespectAppRequest = false;
@@ -149,6 +155,7 @@ public class DisplayModeDirector {
        mSettingsObserver.observe();
        mDisplayObserver.observe();
        mBrightnessObserver.observe(sensorManager);
        mUdfpsObserver.observe();
        synchronized (mLock) {
            // We may have a listener already registered before the call to start, so go ahead and
            // notify them to pick up our newly initialized state.
@@ -545,6 +552,7 @@ public class DisplayModeDirector {
            mSettingsObserver.dumpLocked(pw);
            mAppRequestObserver.dumpLocked(pw);
            mBrightnessObserver.dumpLocked(pw);
            mUdfpsObserver.dumpLocked(pw);
        }
    }

@@ -566,7 +574,6 @@ public class DisplayModeDirector {
        }
        final SparseArray<Vote> votes = getOrCreateVotesByDisplay(displayId);

        Vote currentVote = votes.get(priority);
        if (vote != null) {
            votes.put(priority, vote);
        } else {
@@ -649,6 +656,11 @@ public class DisplayModeDirector {
        return mSettingsObserver;
    }

    @VisibleForTesting
    UdfpsObserver getUdpfsObserver() {
        return mUdfpsObserver;
    }


    @VisibleForTesting
    DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings(
@@ -928,11 +940,15 @@ public class DisplayModeDirector {
        // LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on.
        public static final int PRIORITY_LOW_POWER_MODE = 6;

        // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
        // to function, so this needs to be the highest priority of all votes.
        public static final int PRIORITY_UDFPS = 7;

        // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
        // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.

        public static final int MIN_PRIORITY = PRIORITY_DEFAULT_REFRESH_RATE;
        public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
        public static final int MAX_PRIORITY = PRIORITY_UDFPS;

        // The cutoff for the app request refresh rate range. Votes with priorities lower than this
        // value will not be considered when constructing the app request refresh rate range.
@@ -989,6 +1005,9 @@ public class DisplayModeDirector {
                    return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
                case PRIORITY_LOW_POWER_MODE:
                    return "PRIORITY_LOW_POWER_MODE";
                case PRIORITY_UDFPS:
                    return "PRIORITY_UDFPS";

                default:
                    return Integer.toString(priority);
            }
@@ -1162,7 +1181,7 @@ public class DisplayModeDirector {
    }

    final class AppRequestObserver {
        private SparseArray<Display.Mode> mAppRequestedModeByDisplay;
        private final SparseArray<Display.Mode> mAppRequestedModeByDisplay;

        AppRequestObserver() {
            mAppRequestedModeByDisplay = new SparseArray<>();
@@ -1196,7 +1215,6 @@ public class DisplayModeDirector {

            updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, refreshRateVote);
            updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
            return;
        }

        private Display.Mode findModeByIdLocked(int displayId, int modeId) {
@@ -1328,7 +1346,8 @@ public class DisplayModeDirector {

        private SensorManager mSensorManager;
        private Sensor mLightSensor;
        private LightSensorEventListener mLightSensorListener = new LightSensorEventListener();
        private final LightSensorEventListener mLightSensorListener =
                new LightSensorEventListener();
        // Take it as low brightness before valid sensor data comes
        private float mAmbientLux = -1.0f;
        private AmbientFilter mAmbientFilter;
@@ -1559,8 +1578,7 @@ public class DisplayModeDirector {
            mLightSensorListener.dumpLocked(pw);

            if (mAmbientFilter != null) {
                IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
                ipw.setIndent("    ");
                IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
                mAmbientFilter.dump(ipw);
            }
        }
@@ -1907,7 +1925,7 @@ public class DisplayModeDirector {
                return false;
            }

            private Runnable mInjectSensorEventRunnable = new Runnable() {
            private final Runnable mInjectSensorEventRunnable = new Runnable() {
                @Override
                public void run() {
                    long now = SystemClock.uptimeMillis();
@@ -1926,6 +1944,83 @@ public class DisplayModeDirector {
        }
    }

    private class UdfpsObserver extends IUdfpsHbmListener.Stub {
        private final SparseBooleanArray mLocalHbmEnabled = new SparseBooleanArray();
        private final SparseBooleanArray mGlobalHbmEnabled = new SparseBooleanArray();

        public void observe() {
            StatusBarManagerInternal statusBar =
                    LocalServices.getService(StatusBarManagerInternal.class);
            statusBar.setUdfpsHbmListener(this);
        }

        @Override
        public void onHbmEnabled(int hbmType, int displayId) {
            synchronized (mLock) {
                updateHbmStateLocked(hbmType, displayId, true /*enabled*/);
            }
        }

        @Override
        public void onHbmDisabled(int hbmType, int displayId) {
            synchronized (mLock) {
                updateHbmStateLocked(hbmType, displayId, false /*enabled*/);
            }
        }

        private void updateHbmStateLocked(int hbmType, int displayId, boolean enabled) {
            switch (hbmType) {
                case UdfpsObserver.LOCAL_HBM:
                    mLocalHbmEnabled.put(displayId, enabled);
                    break;
                case UdfpsObserver.GLOBAL_HBM:
                    mGlobalHbmEnabled.put(displayId, enabled);
                    break;
                default:
                    Slog.w(TAG, "Unknown HBM type reported. Ignoring.");
                    return;
            }
            updateVoteLocked(displayId);
        }

        private void updateVoteLocked(int displayId) {
            final Vote vote;
            if (mGlobalHbmEnabled.get(displayId)) {
                vote = Vote.forRefreshRates(60f, 60f);
            } else if (mLocalHbmEnabled.get(displayId)) {
                Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
                float maxRefreshRate = 0f;
                for (Display.Mode mode : modes) {
                    if (mode.getRefreshRate() > maxRefreshRate) {
                        maxRefreshRate = mode.getRefreshRate();
                    }
                }
                vote = Vote.forRefreshRates(maxRefreshRate, maxRefreshRate);
            } else {
                vote = null;
            }

            DisplayModeDirector.this.updateVoteLocked(displayId, Vote.PRIORITY_UDFPS, vote);
        }

        void dumpLocked(PrintWriter pw) {
            pw.println("  UdfpsObserver");
            pw.println("    mLocalHbmEnabled: ");
            for (int i = 0; i < mLocalHbmEnabled.size(); i++) {
                final int displayId = mLocalHbmEnabled.keyAt(i);
                final String enabled = mLocalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
                pw.println("      Display " + displayId + ": " + enabled);
            }
            pw.println("    mGlobalHbmEnabled: ");
            for (int i = 0; i < mGlobalHbmEnabled.size(); i++) {
                final int displayId = mGlobalHbmEnabled.keyAt(i);
                final String enabled = mGlobalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
                pw.println("      Display " + displayId + ": " + enabled);
            }

        }
    }

    private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
        public DeviceConfigDisplaySettings() {
        }
+8 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.statusbar;

import android.annotation.Nullable;
import android.app.ITransientNotificationCallback;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -166,4 +167,11 @@ public interface StatusBarManagerInternal {
     * boolean)
     */
    void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable);

    /**
     * Sets the system-wide listener for UDFPS HBM status changes.
     *
     * @see com.android.internal.statusbar.IStatusBar#setUdfpsHbmListener(IUdfpsHbmListener)
     */
    void setUdfpsHbmListener(IUdfpsHbmListener listener);
}
+26 −4
Original line number Diff line number Diff line
@@ -107,15 +107,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D

    private final Context mContext;

    private Handler mHandler = new Handler();
    private final Handler mHandler = new Handler();
    private NotificationDelegate mNotificationDelegate;
    private volatile IStatusBar mBar;
    private ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();
    private final ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();

    // for disabling the status bar
    private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
    private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
    private IBinder mSysUiVisToken = new Binder();
    private final IBinder mSysUiVisToken = new Binder();

    private final Object mLock = new Object();
    private final DeathRecipient mDeathRecipient = new DeathRecipient();
@@ -123,7 +123,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
    private int mCurrentUserId;
    private boolean mTracingEnabled;

    private SparseArray<UiState> mDisplayUiState = new SparseArray<>();
    private final SparseArray<UiState> mDisplayUiState = new SparseArray<>();
    @GuardedBy("mLock")
    private IUdfpsHbmListener mUdfpsHbmListener;

    private class DeathRecipient implements IBinder.DeathRecipient {
        public void binderDied() {
@@ -598,6 +600,18 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
                } catch (RemoteException ex) { }
            }
        }

        @Override
        public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
            synchronized (mLock) {
                mUdfpsHbmListener = listener;
            }
            if (mBar != null) {
                try {
                    mBar.setUdfpsHbmListener(listener);
                } catch (RemoteException ex) { }
            }
        }
    };

    private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
@@ -1204,6 +1218,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
            if (mGlobalActionListener == null) return;
            mGlobalActionListener.onGlobalActionsAvailableChanged(mBar != null);
        });
        // If StatusBarService dies, system_server doesn't get killed with it, so we need to make
        // sure the UDFPS listener is refreshed as well. Deferring to the handler just so to avoid
        // making registerStatusBar re-entrant.
        mHandler.post(() -> {
            synchronized (mLock) {
                setUdfpsHbmListener(mUdfpsHbmListener);
            }
        });
    }

    /**
Loading