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

Commit 7a45a2ec authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 8681

* changes:
  PowerManager: Add proximity sensor support.
parents 22339177 bc706a03
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ interface IPowerManager
    void userActivity(long when, boolean noChangeLights);
    void userActivityWithForce(long when, boolean noChangeLights, boolean force);
    void setPokeLock(int pokey, IBinder lock, String tag);
    int getSupportedWakeLockFlags();
    void setStayOnSetting(int val);
    long getScreenOnTime();
    void preventScreenOn(boolean prevent);
+41 −2
Original line number Diff line number Diff line
@@ -114,12 +114,14 @@ public class PowerManager
    private static final int WAKE_BIT_SCREEN_DIM = 4;
    private static final int WAKE_BIT_SCREEN_BRIGHT = 8;
    private static final int WAKE_BIT_KEYBOARD_BRIGHT = 16;
    private static final int WAKE_BIT_PROXIMITY_SCREEN_OFF = 32;
    
    private static final int LOCK_MASK = WAKE_BIT_CPU_STRONG
                                        | WAKE_BIT_CPU_WEAK
                                        | WAKE_BIT_SCREEN_DIM
                                        | WAKE_BIT_SCREEN_BRIGHT
                                        | WAKE_BIT_KEYBOARD_BRIGHT;
                                        | WAKE_BIT_KEYBOARD_BRIGHT
                                        | WAKE_BIT_PROXIMITY_SCREEN_OFF;

    /**
     * Wake lock that ensures that the CPU is running.  The screen might
@@ -146,6 +148,16 @@ public class PowerManager
     */
    public static final int SCREEN_DIM_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_DIM;

    /**
     * Wake lock that turns the screen off when the proximity sensor activates.
     * Since not all devices have proximity sensors, use
     * {@link #getSupportedWakeLockFlags() getSupportedWakeLockFlags()} to determine if
     * this wake lock mode is supported.
     *
     * {@hide}
     */
    public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = WAKE_BIT_PROXIMITY_SCREEN_OFF;

    /**
     * Normally wake locks don't actually wake the device, they just cause
     * it to remain on once it's already on.  Think of the video player
@@ -196,6 +208,7 @@ public class PowerManager
            case SCREEN_DIM_WAKE_LOCK:
            case SCREEN_BRIGHT_WAKE_LOCK:
            case FULL_WAKE_LOCK:
            case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                break;
            default:
                throw new IllegalArgumentException();
@@ -366,6 +379,32 @@ public class PowerManager
        }
    }

   /**
     * Returns the set of flags for {@link #newWakeLock(int, String) newWakeLock()}
     * that are supported on the device.
     * For example, to test to see if the {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK}
     * is supported:
     *
     * {@samplecode
     * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
     * int supportedFlags = pm.getSupportedWakeLockFlags();
     *  boolean proximitySupported = ((supportedFlags & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)
     *                                  == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK);
     * }
     *
     * @return the set of supported WakeLock flags.
     *
     * {@hide}
     */
    public int getSupportedWakeLockFlags()
    {
        try {
            return mService.getSupportedWakeLockFlags();
        } catch (RemoteException e) {
            return 0;
        }
    }

    private PowerManager()
    {
    }
+65 −2
Original line number Diff line number Diff line
@@ -29,6 +29,10 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Handler;
@@ -58,7 +62,8 @@ import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;

class PowerManagerService extends IPowerManager.Stub implements LocalPowerManager, Watchdog.Monitor {
class PowerManagerService extends IPowerManager.Stub
        implements LocalPowerManager,Watchdog.Monitor, SensorEventListener {

    private static final String TAG = "PowerManagerService";
    static final String PARTIAL_NAME = "PowerManagerService";
@@ -72,7 +77,8 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
    private static final int LOCK_MASK = PowerManager.PARTIAL_WAKE_LOCK
                                        | PowerManager.SCREEN_DIM_WAKE_LOCK
                                        | PowerManager.SCREEN_BRIGHT_WAKE_LOCK
                                        | PowerManager.FULL_WAKE_LOCK;
                                        | PowerManager.FULL_WAKE_LOCK
                                        | PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;

    //                       time since last state:               time since last event:
    // The short keylight delay comes from Gservices; this is the default.
@@ -138,6 +144,7 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
    private int[] mBroadcastQueue = new int[] { -1, -1, -1 };
    private int[] mBroadcastWhy = new int[3];
    private int mPartialCount = 0;
    private int mProximityCount = 0;
    private int mPowerState;
    private boolean mOffBecauseOfUser;
    private int mUserState;
@@ -175,6 +182,8 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
    private IActivityManager mActivityService;
    private IBatteryStats mBatteryStats;
    private BatteryService mBatteryService;
    private SensorManager mSensorManager;
    private Sensor mProximitySensor;
    private boolean mDimScreen = true;
    private long mNextTimeout;
    private volatile int mPokey = 0;
@@ -536,6 +545,7 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
                    wl.minState = SCREEN_DIM;
                    break;
                case PowerManager.PARTIAL_WAKE_LOCK:
                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                    break;
                default:
                    // just log and bail.  we're in the server, so don't
@@ -583,6 +593,11 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
                }
            }
            Power.acquireWakeLock(Power.PARTIAL_WAKE_LOCK,PARTIAL_NAME);
        } else if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
            mProximityCount++;
            if (mProximityCount == 1) {
                enableProximityLockLocked();
            }
        }
        if (newlock) {
            acquireUid = wl.uid;
@@ -639,6 +654,11 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
                if (LOG_PARTIAL_WL) EventLog.writeEvent(LOG_POWER_PARTIAL_WAKE_STATE, 0, wl.tag);
                Power.releaseWakeLock(PARTIAL_NAME);
            }
        } else if ((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
            mProximityCount--;
            if (mProximityCount == 0) {
                disableProximityLockLocked();
            }
        }
        // Unlink the lock from the binder.
        wl.binder.unlinkToDeath(wl, 0);
@@ -1996,4 +2016,47 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
    public void monitor() {
        synchronized (mLocks) { }
    }

    public int getSupportedWakeLockFlags() {
        int result = PowerManager.PARTIAL_WAKE_LOCK
                   | PowerManager.FULL_WAKE_LOCK
                   | PowerManager.SCREEN_DIM_WAKE_LOCK;

        // call getSensorManager() to make sure mProximitySensor is initialized
        getSensorManager();
        if (mProximitySensor != null) {
            result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
        }

        return result;
    }

    private SensorManager getSensorManager() {
        if (mSensorManager == null) {
            mSensorManager = new SensorManager(mHandlerThread.getLooper());
            mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        }
        return mSensorManager;
    }

    private void enableProximityLockLocked() {
        mSensorManager.registerListener(this, mProximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
    }

    private void disableProximityLockLocked() {
        mSensorManager.unregisterListener(this);
    }

    public void onSensorChanged(SensorEvent event) {
        long milliseconds = event.timestamp / 1000000;
        if (event.values[0] == 0.0) {
            goToSleep(milliseconds);
        } else {
            userActivity(milliseconds, false);
        }
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // ignore
    }
}