New internal API to eliminate poke locks.

Added a new WindowManager.LayoutParams inputFeatures flag
to disable automatic user activity behavior when an input
event is sent to a window.

Added a new WindowManager.LayoutParams field userActivityTimeout.

Bug: 7165399
Change-Id: I204eafa37ef26aacc2c52a1ba1ecce1eebb0e0d9
This commit is contained in:
Jeff Brown
2012-09-30 18:58:59 -07:00
parent 1f7a09b5df
commit 1e3b98d47d
9 changed files with 102 additions and 106 deletions

View File

@@ -40,7 +40,6 @@ interface IPowerManager
void reboot(String reason);
void crash(String message);
void setPokeLock(int pokey, IBinder lock, String tag);
void setStayOnSetting(int val);
void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs);

View File

@@ -1,28 +0,0 @@
/*
* Copyright (C) 2007 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 android.os;
/** @hide */
public interface LocalPowerManager {
// FIXME: Replace poke locks with something else.
public static final int POKE_LOCK_IGNORE_TOUCH_EVENTS = 0x1;
public static final int POKE_LOCK_SHORT_TIMEOUT = 0x2;
public static final int POKE_LOCK_MEDIUM_TIMEOUT = 0x4;
public static final int POKE_LOCK_TIMEOUT_MASK = 0x6;
}

View File

@@ -1175,15 +1175,43 @@ public interface WindowManager extends ViewManager {
*/
public static final int INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002;
/**
* When this window has focus, does not call user activity for all input events so
* the application will have to do it itself. Should only be used by
* the keyguard and phone app.
* <p>
* Should only be used by the keyguard and phone app.
* </p>
*
* @hide
*/
public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004;
/**
* Control special features of the input subsystem.
*
* @see #INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES
* @see #INPUT_FEATURE_NO_INPUT_CHANNEL
* @see #INPUT_FEATURE_DISABLE_USER_ACTIVITY
* @hide
*/
public int inputFeatures;
/**
* Sets the number of milliseconds before the user activity timeout occurs
* when this window has focus. A value of -1 uses the standard timeout.
* A value of 0 uses the minimum support display timeout.
* <p>
* This property can only be used to reduce the user specified display timeout;
* it can never make the timeout longer than it normally would be.
* </p><p>
* Should only be used by the keyguard and phone app.
* </p>
*
* @hide
*/
public long userActivityTimeout = -1;
public LayoutParams() {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = TYPE_APPLICATION;
@@ -1268,6 +1296,7 @@ public interface WindowManager extends ViewManager {
out.writeInt(subtreeSystemUiVisibility);
out.writeInt(hasSystemUiListeners ? 1 : 0);
out.writeInt(inputFeatures);
out.writeLong(userActivityTimeout);
}
public static final Parcelable.Creator<LayoutParams> CREATOR
@@ -1308,6 +1337,7 @@ public interface WindowManager extends ViewManager {
subtreeSystemUiVisibility = in.readInt();
hasSystemUiListeners = in.readInt() != 0;
inputFeatures = in.readInt();
userActivityTimeout = in.readLong();
}
@SuppressWarnings({"PointlessBitwiseExpression"})
@@ -1334,6 +1364,8 @@ public interface WindowManager extends ViewManager {
/** {@hide} */
public static final int PRIVATE_FLAGS_CHANGED = 1<<16;
/** {@hide} */
public static final int USER_ACTIVITY_TIMEOUT_CHANGED = 1<<17;
/** {@hide} */
public static final int EVERYTHING_CHANGED = 0xffffffff;
// internal buffer to backup/restore parameters under compatibility mode.
@@ -1455,6 +1487,11 @@ public interface WindowManager extends ViewManager {
changes |= INPUT_FEATURES_CHANGED;
}
if (userActivityTimeout != o.userActivityTimeout) {
userActivityTimeout = o.userActivityTimeout;
changes |= USER_ACTIVITY_TIMEOUT_CHANGED;
}
return changes;
}
@@ -1547,6 +1584,9 @@ public interface WindowManager extends ViewManager {
if (inputFeatures != 0) {
sb.append(" if=0x").append(Integer.toHexString(inputFeatures));
}
if (userActivityTimeout >= 0) {
sb.append(" userActivityTimeout=").append(userActivityTimeout);
}
sb.append('}');
return sb.toString();
}

View File

@@ -1716,6 +1716,16 @@ String8 InputDispatcher::getApplicationWindowLabelLocked(
}
void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
if (mFocusedWindowHandle != NULL) {
const InputWindowInfo* info = mFocusedWindowHandle->getInfo();
if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
#if DEBUG_DISPATCH_CYCLE
ALOGD("Not poking user activity: disabled by window '%s'.", info->name.string());
#endif
return;
}
}
int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
switch (eventEntry->type) {
case EventEntry::TYPE_MOTION: {

View File

@@ -110,6 +110,8 @@ struct InputWindowInfo {
enum {
INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002,
INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
};
sp<InputChannel> inputChannel;

View File

@@ -266,6 +266,11 @@ public final class PowerManagerService extends IPowerManager.Stub
// Use -1 to disable.
private int mScreenBrightnessOverrideFromWindowManager = -1;
// The user activity timeout override from the window manager
// to allow the current foreground activity to override the user activity timeout.
// Use -1 to disable.
private long mUserActivityTimeoutOverrideFromWindowManager = -1;
// The screen brightness setting override from the settings application
// to temporarily adjust the brightness until next updated,
// Use -1 to disable.
@@ -1156,6 +1161,9 @@ public final class PowerManagerService extends IPowerManager.Stub
if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
}
if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
}
return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
}
@@ -1573,12 +1581,6 @@ public final class PowerManagerService extends IPowerManager.Stub
}
}
@Override // Binder call
public void setPokeLock(int pokey, IBinder lock, String tag) {
// TODO Auto-generated method stub
// Only used by phone app, delete this
}
/**
* Set the setting that determines whether the device stays on when plugged in.
* The argument is a bit string, with each bit specifying a power source that,
@@ -1720,6 +1722,36 @@ public final class PowerManagerService extends IPowerManager.Stub
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
}
/**
* Used by the window manager to override the user activity timeout based on the
* current foreground activity. It can only be used to make the timeout shorter
* than usual, not longer.
*
* This method must only be called by the window manager.
*
* @param timeoutMillis The overridden timeout, or -1 to disable the override.
*/
public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
final long ident = Binder.clearCallingIdentity();
try {
setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
synchronized (mLock) {
if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
mDirty |= DIRTY_SETTINGS;
updatePowerStateLocked();
}
}
}
/**
* Used by the settings application and brightness control widgets to
* temporarily override the current screen brightness setting so that the
@@ -1869,6 +1901,8 @@ public final class PowerManagerService extends IPowerManager.Stub
pw.println(" mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
pw.println(" mScreenBrightnessOverrideFromWindowManager="
+ mScreenBrightnessOverrideFromWindowManager);
pw.println(" mUserActivityTimeoutOverrideFromWindowManager="
+ mUserActivityTimeoutOverrideFromWindowManager);
pw.println(" mTemporaryScreenBrightnessSettingOverride="
+ mTemporaryScreenBrightnessSettingOverride);
pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="

View File

@@ -598,6 +598,7 @@ public class WindowManagerService extends IWindowManager.Stub
private boolean mSyswin = false;
private float mScreenBrightness = -1;
private float mButtonBrightness = -1;
private long mUserActivityTimeout = -1;
private boolean mUpdateRotation = false;
private static final int DISPLAY_CONTENT_UNKNOWN = 0;
@@ -8775,6 +8776,11 @@ public class WindowManagerService extends IWindowManager.Stub
&& mInnerFields.mButtonBrightness < 0) {
mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
}
if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
&& mInnerFields.mUserActivityTimeout < 0) {
mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
}
final int type = attrs.type;
if (canBeSeen
&& (type == TYPE_SYSTEM_DIALOG
@@ -8874,7 +8880,9 @@ public class WindowManagerService extends IWindowManager.Stub
mInnerFields.mHoldScreen = null;
mInnerFields.mScreenBrightness = -1;
mInnerFields.mButtonBrightness = -1;
mInnerFields.mUserActivityTimeout = -1;
mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
mTransactionSequence++;
final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
@@ -9349,6 +9357,8 @@ public class WindowManagerService extends IWindowManager.Stub
mPowerManager.setButtonBrightnessOverrideFromWindowManager(
toBrightnessOverride(mInnerFields.mButtonBrightness));
}
mPowerManager.setUserActivityTimeoutOverrideFromWindowManager(
mInnerFields.mUserActivityTimeout);
}
if (mTurnOnScreen) {

View File

@@ -21,9 +21,7 @@ import android.os.IBinder;
import android.os.IPowerManager;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.Handler;
import android.os.LocalPowerManager;
import android.os.ServiceManager;
import android.os.PowerManager;
@@ -106,69 +104,5 @@ public class PowerTest extends TestActivity
}, 5000);
}
},
new Test("Touch events don't poke") {
public void run() {
mPokeState |= LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_EVENTS;
try {
mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
},
new Test("Touch events poke") {
public void run() {
mPokeState &= ~LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_EVENTS;
try {
mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
},
new Test("Short timeout") {
public void run() {
mPokeState &= ~LocalPowerManager.POKE_LOCK_TIMEOUT_MASK;
mPokeState |= LocalPowerManager.POKE_LOCK_SHORT_TIMEOUT;
try {
mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
},
new Test("Medium timeout") {
public void run() {
mPokeState &= ~LocalPowerManager.POKE_LOCK_TIMEOUT_MASK;
mPokeState |= LocalPowerManager.POKE_LOCK_MEDIUM_TIMEOUT;
try {
mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
},
new Test("Normal timeout") {
public void run() {
mPokeState &= ~LocalPowerManager.POKE_LOCK_TIMEOUT_MASK;
try {
mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
},
new Test("Illegal timeout") {
public void run() {
mPokeState |= LocalPowerManager.POKE_LOCK_SHORT_TIMEOUT
| LocalPowerManager.POKE_LOCK_MEDIUM_TIMEOUT;
try {
mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
},
};
}

View File

@@ -89,11 +89,6 @@ public class BridgePowerManager implements IPowerManager {
// pass for now.
}
@Override
public void setPokeLock(int arg0, IBinder arg1, String arg2) throws RemoteException {
// pass for now.
}
@Override
public void setStayOnSetting(int arg0) throws RemoteException {
// pass for now.