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

Commit 0a571123 authored by Jeff Brown's avatar Jeff Brown
Browse files

Poke interactive hint from userActivity and add @SystemApi.

Previously we only poked the interactive hint for input events that
were dispatched through the regular input system.  However, when
using a car dock in projection mode input events are directly
delivered to apps by other system components, bypassing user activity.
So now we poke the interactive hint on all user activity.

Added an @SystemApi version of userActivity.

Added a new signature|system permission called USER_ACTIVITY
to allow system apps to poke userActivity.  For now it seems
prudent to keep DEVICE_POWER signature only.

Bug: 17043684
Change-Id: Ia84bd03083065b8938a9853c08901fbf71b2e56b
parent 72671fbb
Loading
Loading
Loading
Loading
+50 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.os;

import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.content.Context;
import android.util.Log;

@@ -274,27 +275,43 @@ public final class PowerManager {
     * User activity event type: Unspecified event type.
     * @hide
     */
    @SystemApi
    public static final int USER_ACTIVITY_EVENT_OTHER = 0;

    /**
     * User activity event type: Button or key pressed or released.
     * @hide
     */
    @SystemApi
    public static final int USER_ACTIVITY_EVENT_BUTTON = 1;

    /**
     * User activity event type: Touch down, move or up.
     * @hide
     */
    @SystemApi
    public static final int USER_ACTIVITY_EVENT_TOUCH = 2;

    /**
     * User activity flag: Do not restart the user activity timeout or brighten
     * the display in response to user activity if it is already dimmed.
     * User activity flag: If already dimmed, extend the dim timeout
     * but do not brighten.  This flag is useful for keeping the screen on
     * a little longer without causing a visible change such as when
     * the power key is pressed.
     * @hide
     */
    @SystemApi
    public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0;

    /**
     * User activity flag: Note the user activity as usual but do not
     * reset the user activity timeout.  This flag is useful for applying
     * user activity power hints when interacting with the device indirectly
     * on a secondary screen while allowing the primary screen to go to sleep.
     * @hide
     */
    @SystemApi
    public static final int USER_ACTIVITY_FLAG_INDIRECT = 1 << 1;

    /**
     * Go to sleep reason code: Going to sleep due by application request.
     * @hide
@@ -506,9 +523,38 @@ public final class PowerManager {
     * @see #goToSleep
     */
    public void userActivity(long when, boolean noChangeLights) {
        try {
            mService.userActivity(when, USER_ACTIVITY_EVENT_OTHER,
        userActivity(when, USER_ACTIVITY_EVENT_OTHER,
                noChangeLights ? USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS : 0);
    }

    /**
     * Notifies the power manager that user activity happened.
     * <p>
     * Resets the auto-off timer and brightens the screen if the device
     * is not asleep.  This is what happens normally when a key or the touch
     * screen is pressed or when some other user activity occurs.
     * This method does not wake up the device if it has been put to sleep.
     * </p><p>
     * Requires the {@link android.Manifest.permission#DEVICE_POWER} or
     * {@link android.Manifest.permission#USER_ACTIVITY} permission.
     * </p>
     *
     * @param when The time of the user activity, in the {@link SystemClock#uptimeMillis()}
     * time base.  This timestamp is used to correctly order the user activity request with
     * other power management functions.  It should be set
     * to the timestamp of the input event that caused the user activity.
     * @param event The user activity event.
     * @param flags Optional user activity flags.
     *
     * @see #wakeUp
     * @see #goToSleep
     *
     * @hide Requires signature or system permission.
     */
    @SystemApi
    public void userActivity(long when, int event, int flags) {
        try {
            mService.userActivity(when, event, flags);
        } catch (RemoteException e) {
        }
    }
+7 −0
Original line number Diff line number Diff line
@@ -2408,6 +2408,13 @@
        android:description="@string/permdesc_devicePower"
        android:protectionLevel="signature" />

   <!-- Allows access to the PowerManager.userActivity function.
   <p>Not for use by third-party applications. @hide @SystemApi -->
    <permission android:name="android.permission.USER_ACTIVITY"
        android:label="@string/permlab_userActivity"
        android:description="@string/permdesc_userActivity"
        android:protectionLevel="signature|system" />

   <!-- @hide Allows low-level access to tun tap driver -->
    <permission android:name="android.permission.NET_TUNNELING"
        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+5 −0
Original line number Diff line number Diff line
@@ -1814,6 +1814,11 @@
    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
    <string name="permdesc_devicePower" product="default">Allows the app to turn the phone on or off.</string>

    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
    <string name="permlab_userActivity">reset display timeout</string>
    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
    <string name="permdesc_userActivity">Allows the app to reset the display timeout.</string>

    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
    <string name="permlab_factoryTest">run in factory test mode</string>
    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+26 −8
Original line number Diff line number Diff line
@@ -160,9 +160,9 @@ public final class PowerManagerService extends com.android.server.SystemService
    // Poll interval in milliseconds for watching boot animation finished.
    private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;

    // Used to send the hint to the PowerHAL indicating transitions
    // from and to the low power mode.
    private static final int POWER_HINT_LOW_POWER_MODE = 5;
    // Power hints defined in hardware/libhardware/include/hardware/power.h.
    private static final int POWER_HINT_INTERACTION = 2;
    private static final int POWER_HINT_LOW_POWER = 5;

    private final Context mContext;
    private final ServiceThread mHandlerThread;
@@ -223,6 +223,9 @@ public final class PowerManagerService extends com.android.server.SystemService
    private long mLastUserActivityTime;
    private long mLastUserActivityTimeNoChangeLights;

    // Timestamp of last interactive power hint.
    private long mLastInteractivePowerHintTime;

    // A bitfield that summarizes the effect of the user activity timer.
    // A zero value indicates that the user activity timer has expired.
    private int mUserActivitySummary;
@@ -707,7 +710,7 @@ public final class PowerManagerService extends com.android.server.SystemService
        final boolean lowPowerModeEnabled = mLowPowerModeSetting;
        if (mLowPowerModeEnabled != lowPowerModeEnabled) {
            mLowPowerModeEnabled = lowPowerModeEnabled;
            powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0);
            powerHintInternal(POWER_HINT_LOW_POWER, lowPowerModeEnabled ? 1 : 0);
            mLowPowerModeEnabled = lowPowerModeEnabled;
            BackgroundThread.getHandler().post(new Runnable() {
                @Override
@@ -969,15 +972,25 @@ public final class PowerManagerService extends com.android.server.SystemService
        }

        if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
                || mWakefulness == WAKEFULNESS_ASLEEP || mWakefulness == WAKEFULNESS_DOZING
                || !mBootCompleted || !mSystemReady) {
            return false;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity");
        try {
            if (eventTime > mLastInteractivePowerHintTime) {
                powerHintInternal(POWER_HINT_INTERACTION, 0);
                mLastInteractivePowerHintTime = eventTime;
            }

            mNotifier.onUserActivity(event, uid);

            if (mWakefulness == WAKEFULNESS_ASLEEP
                    || mWakefulness == WAKEFULNESS_DOZING
                    || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
                return false;
            }

            if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
                if (eventTime > mLastUserActivityTimeNoChangeLights
                        && eventTime > mLastUserActivityTime) {
@@ -2319,6 +2332,8 @@ public final class PowerManagerService extends com.android.server.SystemService
            pw.println("  mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
            pw.println("  mLastUserActivityTimeNoChangeLights="
                    + TimeUtils.formatUptime(mLastUserActivityTimeNoChangeLights));
            pw.println("  mLastInteractivePowerHintTime="
                    + TimeUtils.formatUptime(mLastInteractivePowerHintTime));
            pw.println("  mDisplayReady=" + mDisplayReady);
            pw.println("  mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
            pw.println("  mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker);
@@ -2863,6 +2878,9 @@ public final class PowerManagerService extends com.android.server.SystemService
        public void userActivity(long eventTime, int event, int flags) {
            final long now = SystemClock.uptimeMillis();
            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
                    != PackageManager.PERMISSION_GRANTED
                    && mContext.checkCallingOrSelfPermission(
                            android.Manifest.permission.USER_ACTIVITY)
                            != PackageManager.PERMISSION_GRANTED) {
                // Once upon a time applications could call userActivity().
                // Now we require the DEVICE_POWER permission.  Log a warning and ignore the
@@ -2871,8 +2889,8 @@ public final class PowerManagerService extends com.android.server.SystemService
                    if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
                        mLastWarningAboutUserActivityPermission = now;
                        Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
                                + "caller does not have DEVICE_POWER permission.  "
                                + "Please fix your app!  "
                                + "caller does not have DEVICE_POWER or USER_ACTIVITY "
                                + "permission.  Please fix your app!  "
                                + " pid=" + Binder.getCallingPid()
                                + " uid=" + Binder.getCallingUid());
                    }