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

Commit a9667ff3 authored by Dave Mankoff's avatar Dave Mankoff Committed by Android (Google) Code Review
Browse files

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

Merge "Add new ProximitySensor wrapper that automatically uses appropriate sensor." into qt-qpr1-dev
parents a295feab 46b9d68f
Loading
Loading
Loading
Loading
+11 −6
Original line number Original line Diff line number Diff line
@@ -34,7 +34,7 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingPlugin;
import com.android.systemui.plugins.FalsingPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.util.AsyncSensorManager;
import com.android.systemui.util.ProximitySensor;


import java.io.PrintWriter;
import java.io.PrintWriter;


@@ -50,18 +50,23 @@ import javax.inject.Singleton;
@Singleton
@Singleton
public class FalsingManagerProxy implements FalsingManager {
public class FalsingManagerProxy implements FalsingManager {


    private static final String PROXIMITY_SENSOR_TAG = "FalsingManager";

    private final ProximitySensor mProximitySensor;
    private FalsingManager mInternalFalsingManager;
    private FalsingManager mInternalFalsingManager;
    private final Handler mMainHandler;
    private final Handler mMainHandler;


    @Inject
    @Inject
    FalsingManagerProxy(Context context, PluginManager pluginManager,
    FalsingManagerProxy(Context context, PluginManager pluginManager,
            @Named(MAIN_HANDLER_NAME) Handler handler) {
            @Named(MAIN_HANDLER_NAME) Handler handler,
            ProximitySensor proximitySensor) {
        mMainHandler = handler;
        mMainHandler = handler;
        mProximitySensor = proximitySensor;
        mProximitySensor.setTag(PROXIMITY_SENSOR_TAG);
        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
                command -> mMainHandler.post(command),
                command -> mMainHandler.post(command),
                properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace())
                properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace())
        );
        );        setupFalsingManager(context);
        setupFalsingManager(context);
        final PluginListener<FalsingPlugin> mPluginListener = new PluginListener<FalsingPlugin>() {
        final PluginListener<FalsingPlugin> mPluginListener = new PluginListener<FalsingPlugin>() {
            public void onPluginConnected(FalsingPlugin plugin, Context context) {
            public void onPluginConnected(FalsingPlugin plugin, Context context) {
                FalsingManager pluginFalsingManager = plugin.getFalsingManager(context);
                FalsingManager pluginFalsingManager = plugin.getFalsingManager(context);
@@ -103,8 +108,8 @@ public class FalsingManagerProxy implements FalsingManager {
        } else {
        } else {
            mInternalFalsingManager = new BrightLineFalsingManager(
            mInternalFalsingManager = new BrightLineFalsingManager(
                    new FalsingDataProvider(context.getResources().getDisplayMetrics()),
                    new FalsingDataProvider(context.getResources().getDisplayMetrics()),
                    Dependency.get(AsyncSensorManager.class),
                    Dependency.get(KeyguardUpdateMonitor.class),
                    KeyguardUpdateMonitor.getInstance(context)
                    mProximitySensor
            );
            );
        }
        }


+10 −38
Original line number Original line 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_REMAIN_LOCKED;
import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_SUCCESS;
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.hardware.biometrics.BiometricSourceType;
import android.net.Uri;
import android.net.Uri;
import android.util.Log;
import android.util.Log;
@@ -33,12 +29,11 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.util.ProximitySensor;


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


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


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


    private final ExecutorService mBackgroundExecutor = Executors.newSingleThreadExecutor();

    private final List<FalsingClassifier> mClassifiers;
    private final List<FalsingClassifier> mClassifiers;


    private SensorEventListener mSensorEventListener = new SensorEventListener() {
    private ProximitySensor.ProximitySensorListener mSensorEventListener = this::onProximityEvent;
        @Override
        public synchronized void onSensorChanged(SensorEvent event) {
            onSensorEvent(event);
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };


    private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
    private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
            new KeyguardUpdateMonitorCallback() {
            new KeyguardUpdateMonitorCallback() {
@@ -87,11 +71,11 @@ public class BrightLineFalsingManager implements FalsingManager {


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


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


    private void registerSensors() {
    private void registerSensors() {
        Sensor s = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        mProximitySensor.register(mSensorEventListener);
        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);
            });
        }
    }
    }




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


    private void sessionStart() {
    private void sessionStart() {
@@ -187,10 +159,10 @@ public class BrightLineFalsingManager implements FalsingManager {
        mClassifiers.forEach((classifier) -> classifier.onTouchEvent(motionEvent));
        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
        // TODO: some of these classifiers might allow us to abort early, meaning we don't have to
        // make these calls.
        // make these calls.
        mClassifiers.forEach((classifier) -> classifier.onSensorEvent(sensorEvent));
        mClassifiers.forEach((classifier) -> classifier.onProximityEvent(proximityEvent));
    }
    }


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


package com.android.systemui.classifier.brightline;
package com.android.systemui.classifier.brightline;


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


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


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


@@ -98,9 +98,9 @@ abstract class FalsingClassifier {
    void onTouchEvent(MotionEvent motionEvent) {};
    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.
     * The phone screen has turned on and we need to begin falsing detection.
+8 −10
Original line number Original line Diff line number Diff line
@@ -19,11 +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.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;


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


import com.android.systemui.util.ProximitySensor;



/**
/**
 * False touch if proximity sensor is covered for more than a certain percentage of the gesture.
 * False touch if proximity sensor is covered for more than a certain percentage of the gesture.
@@ -97,14 +97,12 @@ class ProximityClassifier extends FalsingClassifier {
    }
    }


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


    @Override
    @Override
+186 −0
Original line number Original line 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