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

Commit 41bb8842 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add new ProximitySensor wrapper that automatically uses appropriate sensor."

parents 5ef1f829 84fa2705
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -34,8 +34,8 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.util.AsyncSensorManager;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.ProximitySensor;

import java.io.PrintWriter;

@@ -51,6 +51,9 @@ import javax.inject.Singleton;
@Singleton
public class FalsingManagerProxy implements FalsingManager {

    private static final String PROXIMITY_SENSOR_TAG = "FalsingManager";

    private final ProximitySensor mProximitySensor;
    private FalsingManager mInternalFalsingManager;
    private DeviceConfig.OnPropertiesChangedListener mDeviceConfigListener;
    private final DeviceConfigProxy mDeviceConfig;
@@ -58,7 +61,11 @@ public class FalsingManagerProxy implements FalsingManager {

    @Inject
    FalsingManagerProxy(Context context, PluginManager pluginManager,
            @Named(MAIN_HANDLER_NAME) Handler handler, DeviceConfigProxy deviceConfig) {
            @Named(MAIN_HANDLER_NAME) Handler handler,
            ProximitySensor proximitySensor,
            DeviceConfigProxy deviceConfig) {
        mProximitySensor = proximitySensor;
        mProximitySensor.setTag(PROXIMITY_SENSOR_TAG);
        mDeviceConfig = deviceConfig;
        mDeviceConfigListener =
                properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace());
@@ -113,8 +120,8 @@ public class FalsingManagerProxy implements FalsingManager {
        } else {
            mInternalFalsingManager = new BrightLineFalsingManager(
                    new FalsingDataProvider(context.getResources().getDisplayMetrics()),
                    Dependency.get(AsyncSensorManager.class),
                    Dependency.get(KeyguardUpdateMonitor.class),
                    mProximitySensor,
                    mDeviceConfig
            );
        }
+9 −37
Original line number Diff line number Diff line
@@ -19,10 +19,6 @@ package com.android.systemui.classifier.brightline;
import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_REMAIN_LOCKED;
import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_SUCCESS;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.biometrics.BiometricSourceType;
import android.net.Uri;
import android.util.Log;
@@ -34,12 +30,11 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.ProximitySensor;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * FalsingManager designed to make clear why a touch was rejected.
@@ -49,9 +44,9 @@ public class BrightLineFalsingManager implements FalsingManager {
    static final boolean DEBUG = false;
    private static final String TAG = "FalsingManagerPlugin";

    private final SensorManager mSensorManager;
    private final FalsingDataProvider mDataProvider;
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    private final ProximitySensor mProximitySensor;
    private boolean mSessionStarted;
    private MetricsLogger mMetricsLogger;
    private int mIsFalseTouchCalls;
@@ -59,20 +54,9 @@ public class BrightLineFalsingManager implements FalsingManager {
    private boolean mScreenOn;
    private boolean mJustUnlockedWithFace;

    private final ExecutorService mBackgroundExecutor = Executors.newSingleThreadExecutor();

    private final List<FalsingClassifier> mClassifiers;

    private SensorEventListener mSensorEventListener = new SensorEventListener() {
        @Override
        public synchronized void onSensorChanged(SensorEvent event) {
            onSensorEvent(event);
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };
    private ProximitySensor.ProximitySensorListener mSensorEventListener = this::onProximityEvent;

    private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
            new KeyguardUpdateMonitorCallback() {
@@ -88,12 +72,12 @@ public class BrightLineFalsingManager implements FalsingManager {

    public BrightLineFalsingManager(
            FalsingDataProvider falsingDataProvider,
            SensorManager sensorManager,
            KeyguardUpdateMonitor keyguardUpdateMonitor,
            ProximitySensor proximitySensor,
            DeviceConfigProxy deviceConfigProxy) {
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mDataProvider = falsingDataProvider;
        mSensorManager = sensorManager;
        mProximitySensor = proximitySensor;
        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);

        mMetricsLogger = new MetricsLogger();
@@ -111,24 +95,12 @@ public class BrightLineFalsingManager implements FalsingManager {
    }

    private void registerSensors() {
        Sensor s = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        if (s != null) {
            // This can be expensive, and doesn't need to happen on the main thread.
            mBackgroundExecutor.submit(() -> {
                logDebug("registering sensor listener");
                mSensorManager.registerListener(
                        mSensorEventListener, s, SensorManager.SENSOR_DELAY_GAME);
            });
        }
        mProximitySensor.register(mSensorEventListener);
    }


    private void unregisterSensors() {
        // This can be expensive, and doesn't need to happen on the main thread.
        mBackgroundExecutor.submit(() -> {
            logDebug("unregistering sensor listener");
            mSensorManager.unregisterListener(mSensorEventListener);
        });
        mProximitySensor.unregister(mSensorEventListener);
    }

    private void sessionStart() {
@@ -190,10 +162,10 @@ public class BrightLineFalsingManager implements FalsingManager {
        mClassifiers.forEach((classifier) -> classifier.onTouchEvent(motionEvent));
    }

    private void onSensorEvent(SensorEvent sensorEvent) {
    private void onProximityEvent(ProximitySensor.ProximityEvent proximityEvent) {
        // TODO: some of these classifiers might allow us to abort early, meaning we don't have to
        // make these calls.
        mClassifiers.forEach((classifier) -> classifier.onSensorEvent(sensorEvent));
        mClassifiers.forEach((classifier) -> classifier.onProximityEvent(proximityEvent));
    }

    @Override
+3 −3
Original line number Diff line number Diff line
@@ -16,10 +16,10 @@

package com.android.systemui.classifier.brightline;

import android.hardware.SensorEvent;
import android.view.MotionEvent;

import com.android.systemui.classifier.Classifier;
import com.android.systemui.util.ProximitySensor;

import java.util.List;

@@ -98,9 +98,9 @@ abstract class FalsingClassifier {
    void onTouchEvent(MotionEvent motionEvent) {};

    /**
     * Called whenever a SensorEvent occurs, specifically the ProximitySensor.
     * Called when a ProximityEvent occurs (change in near/far).
     */
    void onSensorEvent(SensorEvent sensorEvent) {};
    void onProximityEvent(ProximitySensor.ProximityEvent proximityEvent) {};

    /**
     * The phone screen has turned on and we need to begin falsing detection.
+7 −10
Original line number Diff line number Diff line
@@ -19,12 +19,11 @@ package com.android.systemui.classifier.brightline;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.provider.DeviceConfig;
import android.view.MotionEvent;

import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.ProximitySensor;


/**
@@ -99,14 +98,12 @@ class ProximityClassifier extends FalsingClassifier {
    }

    @Override
    public void onSensorEvent(SensorEvent sensorEvent) {
        if (sensorEvent.sensor.getType() == Sensor.TYPE_PROXIMITY) {
            logDebug("Sensor is: " + (sensorEvent.values[0] < sensorEvent.sensor.getMaximumRange())
                    + " at time " + sensorEvent.timestamp);
            update(
                    sensorEvent.values[0] < sensorEvent.sensor.getMaximumRange(),
                    sensorEvent.timestamp);
        }
    public void onProximityEvent(
            ProximitySensor.ProximityEvent proximityEvent) {
        boolean near = proximityEvent.getNear();
        long timestampNs = proximityEvent.getTimestampNs();
        logDebug("Sensor is: " + near + " at time " + timestampNs);
        update(near, timestampNs);
    }

    @Override
+186 −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.systemui.util;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;

import com.android.systemui.R;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

/**
 * Simple wrapper around SensorManager customized for the Proximity sensor.
 */
public class ProximitySensor {
    private static final String TAG = "ProxSensor";
    private static final boolean DEBUG = false;

    private final Sensor mSensor;
    private final AsyncSensorManager mSensorManager;
    private final boolean mUsingBrightnessSensor;
    private final float mMaxRange;

    private SensorEventListener mSensorEventListener = new SensorEventListener() {
        @Override
        public synchronized void onSensorChanged(SensorEvent event) {
            onSensorEvent(event);
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };
    private boolean mNear;
    private List<ProximitySensorListener> mListeners = new ArrayList<>();
    private String mTag = null;

    @Inject
    public ProximitySensor(Context context, AsyncSensorManager sensorManager) {
        mSensorManager = sensorManager;
        Sensor sensor = findBrightnessSensor(context, sensorManager);

        if (sensor == null) {
            mUsingBrightnessSensor = false;
            sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        } else {
            mUsingBrightnessSensor = true;
        }
        mSensor = sensor;
        if (mSensor != null) {
            mMaxRange = mSensor.getMaximumRange();
        } else {
            mMaxRange = 0;
        }
    }

    public void setTag(String tag) {
        mTag = tag;
    }

    private Sensor findBrightnessSensor(Context context, SensorManager sensorManager) {
        String sensorType = context.getString(R.string.doze_brightness_sensor_type);
        List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
        Sensor sensor = null;
        for (Sensor s : sensorList) {
            if (sensorType.equals(s.getStringType())) {
                sensor = s;
                break;
            }
        }

        return sensor;
    }

    /**
     * Returns {@code false} if a Proximity sensor is not available.
     */
    public boolean getSensorAvailable() {
        return mSensor != null;
    }

    /**
     * Add a listener.
     *
     * Registers itself with the {@link SensorManager} if this is the first listener
     * added.
     */
    public boolean register(ProximitySensorListener listener) {
        if (!getSensorAvailable()) {
            return false;
        }

        logDebug("using brightness sensor? " + mUsingBrightnessSensor);
        mListeners.add(listener);
        if (mListeners.size() == 1) {
            logDebug("registering sensor listener");
            mSensorManager.registerListener(
                    mSensorEventListener, mSensor, SensorManager.SENSOR_DELAY_GAME);
        }

        return true;
    }

    /**
     * Remove a listener.
     *
     * If all listeners are removed from an instance of this class,
     * it will unregister itself with the SensorManager.
     */
    public void unregister(ProximitySensorListener listener) {
        mListeners.remove(listener);
        if (mListeners.size() == 0) {
            logDebug("unregistering sensor listener");
            mSensorManager.unregisterListener(mSensorEventListener);
        }
    }

    public boolean isNear() {
        return getSensorAvailable() && mNear;
    }

    private void onSensorEvent(SensorEvent event) {
        boolean near = event.values[0] < mMaxRange;
        if (mUsingBrightnessSensor) {
            near = event.values[0] == 0;
        }
        mNear = near;
        mListeners.forEach(proximitySensorListener ->
                proximitySensorListener.onProximitySensorEvent(
                        new ProximityEvent(mNear, event.timestamp)));
    }

    /** Implement to be notified of ProximityEvents. */
    public interface ProximitySensorListener {
        /** Called when the ProximitySensor changes. */
        void onProximitySensorEvent(ProximityEvent proximityEvent);
    }

    /**
     * Returned when the near/far state of a {@link ProximitySensor} changes.
     */
    public static class ProximityEvent {
        private final boolean mNear;
        private final long mTimestampNs;

        public ProximityEvent(boolean near, long timestampNs) {
            mNear = near;
            mTimestampNs = timestampNs;
        }

        public boolean getNear() {
            return mNear;
        }

        public long getTimestampNs() {
            return mTimestampNs;
        }
    }

    private void logDebug(String msg) {
        if (DEBUG) {
            Log.d(TAG, (mTag != null ? "[" + mTag + "] " : "") + msg);
        }
    }
}
Loading