diff options
| author | Jeff Brown <jeffbrown@google.com> | 2014-02-20 21:49:15 +0000 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2014-02-20 21:49:15 +0000 |
| commit | baaa080b625f2448758d87dadc2706d0e2335a86 (patch) | |
| tree | a92189054f00b7f6d8a11b67f3b1924c39d783e1 /core/java/android | |
| parent | 17b7705afb3e36a6239fdcc3fadfa6601f32fe98 (diff) | |
| parent | 90506a41c6b85cf7e65b663480e4fe003a99c8c2 (diff) | |
am 90506a41: am 07e6d1b9: Merge "Add a new "doze mode" based on Dream components." into klp-modular-dev
* commit '90506a41c6b85cf7e65b663480e4fe003a99c8c2':
Add a new "doze mode" based on Dream components.
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/os/PowerManager.java | 13 | ||||
| -rw-r--r-- | core/java/android/service/dreams/DozeHardware.java | 77 | ||||
| -rw-r--r-- | core/java/android/service/dreams/DreamManagerInternal.java | 2 | ||||
| -rw-r--r-- | core/java/android/service/dreams/DreamService.java | 294 | ||||
| -rw-r--r-- | core/java/android/service/dreams/IDozeHardware.aidl | 24 | ||||
| -rw-r--r-- | core/java/android/service/dreams/IDreamManager.aidl | 6 | ||||
| -rw-r--r-- | core/java/android/service/dreams/IDreamService.aidl | 2 | ||||
| -rw-r--r-- | core/java/android/view/WindowManagerPolicy.java | 22 |
8 files changed, 333 insertions, 107 deletions
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 5e0d48949c22..86ef4796d75e 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -191,6 +191,18 @@ public final class PowerManager { public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 0x00000020; /** + * Wake lock level: Put the screen in a low power state and allow the CPU to suspend + * if no other wake locks are held. + * <p> + * This is used by the dream manager to implement doze mode. It currently + * has no effect unless the power manager is in the dozing state. + * </p> + * + * {@hide} + */ + public static final int DOZE_WAKE_LOCK = 0x00000040; + + /** * Mask for the wake lock level component of a combined wake lock level and flags integer. * * @hide @@ -418,6 +430,7 @@ public final class PowerManager { case SCREEN_BRIGHT_WAKE_LOCK: case FULL_WAKE_LOCK: case PROXIMITY_SCREEN_OFF_WAKE_LOCK: + case DOZE_WAKE_LOCK: break; default: throw new IllegalArgumentException("Must specify a valid wake lock level."); diff --git a/core/java/android/service/dreams/DozeHardware.java b/core/java/android/service/dreams/DozeHardware.java new file mode 100644 index 000000000000..b5e7f436cd25 --- /dev/null +++ b/core/java/android/service/dreams/DozeHardware.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2014 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.service.dreams; + +import android.os.RemoteException; +import android.util.Log; + +/** + * Provides access to low-level hardware features that a dream may use to provide + * a richer user experience while dozing. + * <p> + * This class contains functions that should be called by the dream to configure + * hardware before starting to doze and allowing the application processor to suspend. + * For example, the dream may provide the hardware with enough information to render + * some content on its own without any further assistance from the application processor. + * </p><p> + * This object is obtained by calling {@link DreamService#getDozeHardware()}. + * </p> + * + * @hide experimental + */ +public final class DozeHardware { + private static final String TAG = "DozeHardware"; + + public static final String MSG_ENABLE_MCU = "enable_mcu"; + + public static final byte[] VALUE_ON = "on".getBytes(); + public static final byte[] VALUE_OFF = "off".getBytes(); + + private final IDozeHardware mHardware; + + DozeHardware(IDozeHardware hardware) { + mHardware = hardware; + } + + /** + * Sets whether to enable the microcontroller. + * + * @param enable If true, enables the MCU otherwise disables it. + */ + public void setEnableMcu(boolean enable) { + sendMessage(MSG_ENABLE_MCU, enable ? VALUE_ON : VALUE_OFF); + } + + /** + * Sends a message to the doze hardware module. + * + * @param msg The name of the message to send. + * @param arg An optional argument data blob, may be null. + * @return A result data blob, may be null. + */ + public byte[] sendMessage(String msg, byte[] arg) { + if (msg == null) { + throw new IllegalArgumentException("msg must not be null"); + } + + try { + return mHardware.sendMessage(msg, arg); + } catch (RemoteException ex) { + Log.e(TAG, "Failed to send message to doze hardware module.", ex); + return null; + } + } +} diff --git a/core/java/android/service/dreams/DreamManagerInternal.java b/core/java/android/service/dreams/DreamManagerInternal.java index 17ea996b38c9..9f7ddbac571b 100644 --- a/core/java/android/service/dreams/DreamManagerInternal.java +++ b/core/java/android/service/dreams/DreamManagerInternal.java @@ -25,7 +25,7 @@ public abstract class DreamManagerInternal { /** * Called by the power manager to start a dream. */ - public abstract void startDream(); + public abstract void startDream(boolean doze); /** * Called by the power manager to stop a dream. diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index f6b6c89cbd48..1abb1d72a98b 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -20,12 +20,14 @@ import java.io.PrintWriter; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.app.AlarmManager; import android.app.Service; import android.content.Intent; import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; import android.os.Handler; import android.os.IBinder; +import android.os.RemoteException; import android.os.ServiceManager; import android.util.Slog; import android.view.ActionMode; @@ -42,6 +44,8 @@ import android.view.WindowManager.LayoutParams; import android.view.accessibility.AccessibilityEvent; import com.android.internal.policy.PolicyManager; +import com.android.internal.util.DumpUtils; +import com.android.internal.util.DumpUtils.Dump; /** * Extend this class to implement a custom dream (available to the user as a "Daydream"). @@ -145,19 +149,26 @@ public class DreamService extends Service implements Window.Callback { */ public static final String DREAM_META_DATA = "android.service.dream"; + private final IDreamManager mSandman; private final Handler mHandler = new Handler(); private IBinder mWindowToken; private Window mWindow; private WindowManager mWindowManager; - private IDreamManager mSandman; private boolean mInteractive = false; private boolean mLowProfile = true; private boolean mFullscreen = false; private boolean mScreenBright = true; private boolean mFinished; + private boolean mCanDoze; + private boolean mDozing; + private DozeHardware mDozeHardware; private boolean mDebug = false; + public DreamService() { + mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE)); + } + /** * @hide */ @@ -444,9 +455,11 @@ public class DreamService extends Service implements Window.Callback { * correct interactions with it (seeing when it is cleared etc). */ public void setLowProfile(boolean lowProfile) { - mLowProfile = lowProfile; - int flag = View.SYSTEM_UI_FLAG_LOW_PROFILE; - applySystemUiVisibilityFlags(mLowProfile ? flag : 0, flag); + if (mLowProfile != lowProfile) { + mLowProfile = lowProfile; + int flag = View.SYSTEM_UI_FLAG_LOW_PROFILE; + applySystemUiVisibilityFlags(mLowProfile ? flag : 0, flag); + } } /** @@ -467,9 +480,11 @@ public class DreamService extends Service implements Window.Callback { * will be cleared. */ public void setFullscreen(boolean fullscreen) { - mFullscreen = fullscreen; - int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN; - applyWindowFlags(mFullscreen ? flag : 0, flag); + if (mFullscreen != fullscreen) { + mFullscreen = fullscreen; + int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN; + applyWindowFlags(mFullscreen ? flag : 0, flag); + } } /** @@ -487,14 +502,16 @@ public class DreamService extends Service implements Window.Callback { * @param screenBright True to keep the screen bright while dreaming. */ public void setScreenBright(boolean screenBright) { - mScreenBright = screenBright; - int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; - applyWindowFlags(mScreenBright ? flag : 0, flag); + if (mScreenBright != screenBright) { + mScreenBright = screenBright; + int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; + applyWindowFlags(mScreenBright ? flag : 0, flag); + } } /** - * Returns whether or not this dream keeps the screen bright while dreaming. Defaults to false, - * allowing the screen to dim if necessary. + * Returns whether or not this dream keeps the screen bright while dreaming. + * Defaults to false, allowing the screen to dim if necessary. * * @see #setScreenBright(boolean) */ @@ -503,6 +520,119 @@ public class DreamService extends Service implements Window.Callback { } /** + * Returns true if this dream is allowed to doze. + * <p> + * The value returned by this method is only meaningful when the dream has started. + * </p> + * + * @return True if this dream can doze. + * @see #startDozing + * @hide experimental + */ + public boolean canDoze() { + return mCanDoze; + } + + /** + * Starts dozing, entering a deep dreamy sleep. + * <p> + * Dozing enables the system to conserve power while the user is not actively interacting + * with the device. While dozing, the display will remain on in a low-power state + * and will continue to show its previous contents but the application processor and + * other system components will be allowed to suspend when possible. + * </p><p> + * While the application processor is suspended, the dream may stop executing code + * for long periods of time. Prior to being suspended, the dream may schedule periodic + * wake-ups to render new content by scheduling an alarm with the {@link AlarmManager}. + * The dream may also keep the CPU awake by acquiring a + * {@link android.os.PowerManager#PARTIAL_WAKE_LOCK partial wake lock} when necessary. + * Note that since the purpose of doze mode is to conserve power (especially when + * running on battery), the dream should not wake the CPU very often or keep it + * awake for very long. + * </p><p> + * It is a good idea to call this method some time after the dream's entry animation + * has completed and the dream is ready to doze. It is important to completely + * finish all of the work needed before dozing since the application processor may + * be suspended at any moment once this method is called unless other wake locks + * are being held. + * </p><p> + * Call {@link #stopDozing} or {@link #finish} to stop dozing. + * </p> + * + * @see #stopDozing + * @hide experimental + */ + public void startDozing() { + if (mCanDoze && !mDozing) { + mDozing = true; + try { + mSandman.startDozing(mWindowToken); + } catch (RemoteException ex) { + // system server died + } + } + } + + /** + * Stops dozing, returns to active dreaming. + * <p> + * This method reverses the effect of {@link #startDozing}. From this moment onward, + * the application processor will be kept awake as long as the dream is running + * or until the dream starts dozing again. + * </p> + * + * @see #startDozing + * @hide experimental + */ + public void stopDozing() { + if (mDozing) { + mDozing = false; + try { + mSandman.stopDozing(mWindowToken); + } catch (RemoteException ex) { + // system server died + } + } + } + + /** + * Returns true if the dream will allow the system to enter a low-power state while + * it is running without actually turning off the screen. Defaults to false, + * keeping the application processor awake while the dream is running. + * + * @return True if the dream is dozing. + * + * @see #setDozing(boolean) + * @hide experimental + */ + public boolean isDozing() { + return mDozing; + } + + /** + * Gets an object that may be used to access low-level hardware features that a + * dream may use to provide a richer user experience while dozing. + * + * @return An instance of {@link DozeHardware} or null if this device does not offer + * hardware support for dozing. + * + * @hide experimental + */ + public DozeHardware getDozeHardware() { + if (mCanDoze && mDozeHardware == null) { + try { + IDozeHardware hardware = mSandman.getDozeHardware(mWindowToken); + if (hardware != null) { + mDozeHardware = new DozeHardware(hardware); + } + } catch (RemoteException ex) { + // system server died + } + } + return mDozeHardware; + } + + /** * Called when this Dream is constructed. */ @Override @@ -536,7 +666,11 @@ public class DreamService extends Service implements Window.Callback { } /** - * Stops the dream, detaches from the window, and wakes up. + * Stops the dream and detaches from the window. + * <p> + * When the dream ends, the system will be allowed to go to sleep fully unless there + * is a reason for it to be awake such as recent user activity or wake locks being held. + * </p> */ public final void finish() { if (mDebug) Slog.v(TAG, "finish()"); @@ -557,10 +691,6 @@ public class DreamService extends Service implements Window.Callback { // end public api - private void loadSandman() { - mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE)); - } - /** * Called by DreamController.stopDream() when the Dream is about to be unbound and destroyed. * @@ -572,23 +702,16 @@ public class DreamService extends Service implements Window.Callback { return; } - try { - onDreamingStopped(); - } catch (Throwable t) { - Slog.w(TAG, "Crashed in onDreamingStopped()", t); - // we were going to stop anyway - } + if (mDebug) Slog.v(TAG, "detach(): Calling onDreamingStopped()"); + onDreamingStopped(); if (mDebug) Slog.v(TAG, "detach(): Removing window from window manager"); - try { - // force our window to be removed synchronously - mWindowManager.removeViewImmediate(mWindow.getDecorView()); - // the following will print a log message if it finds any other leaked windows - WindowManagerGlobal.getInstance().closeAll(mWindowToken, - this.getClass().getName(), "Dream"); - } catch (Throwable t) { - Slog.w(TAG, "Crashed removing window view", t); - } + + // force our window to be removed synchronously + mWindowManager.removeViewImmediate(mWindow.getDecorView()); + // the following will print a log message if it finds any other leaked windows + WindowManagerGlobal.getInstance().closeAll(mWindowToken, + this.getClass().getName(), "Dream"); mWindow = null; mWindowToken = null; @@ -601,23 +724,30 @@ public class DreamService extends Service implements Window.Callback { * * @param windowToken A window token that will allow a window to be created in the correct layer. */ - private final void attach(IBinder windowToken) { + private final void attach(IBinder windowToken, boolean canDoze) { if (mWindowToken != null) { Slog.e(TAG, "attach() called when already attached with token=" + mWindowToken); return; } + if (mFinished) { + Slog.w(TAG, "attach() called after dream already finished"); + try { + mSandman.finishSelf(windowToken); + } catch (RemoteException ex) { + // system server died + } + return; + } if (mDebug) Slog.v(TAG, "Attached on thread " + Thread.currentThread().getId()); - if (mSandman == null) { - loadSandman(); - } mWindowToken = windowToken; mWindow = PolicyManager.makeNewWindow(this); mWindow.setCallback(this); mWindow.requestFeature(Window.FEATURE_NO_TITLE); mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000)); mWindow.setFormat(PixelFormat.OPAQUE); + mCanDoze = canDoze; if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s", windowToken, WindowManager.LayoutParams.TYPE_DREAM)); @@ -642,40 +772,25 @@ public class DreamService extends Service implements Window.Callback { mWindowManager = mWindow.getWindowManager(); if (mDebug) Slog.v(TAG, "Window added on thread " + Thread.currentThread().getId()); - try { - applySystemUiVisibilityFlags( - (mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0), - View.SYSTEM_UI_FLAG_LOW_PROFILE); - getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes()); - } catch (Throwable t) { - Slog.w(TAG, "Crashed adding window view", t); - safelyFinish(); - return; - } + applySystemUiVisibilityFlags( + (mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0), + View.SYSTEM_UI_FLAG_LOW_PROFILE); + getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes()); // start it up mHandler.post(new Runnable() { @Override public void run() { - try { - onDreamingStarted(); - } catch (Throwable t) { - Slog.w(TAG, "Crashed in onDreamingStarted()", t); - safelyFinish(); - } + if (mDebug) Slog.v(TAG, "Calling onDreamingStarted()"); + onDreamingStarted(); } }); } private void safelyFinish() { if (mDebug) Slog.v(TAG, "safelyFinish()"); - try { - finish(); - } catch (Throwable t) { - Slog.w(TAG, "Crashed in safelyFinish()", t); - finishInternal(); - return; - } + + finish(); if (!mFinished) { Slog.w(TAG, "Bad dream, did not call super.finish()"); @@ -685,19 +800,21 @@ public class DreamService extends Service implements Window.Callback { private void finishInternal() { if (mDebug) Slog.v(TAG, "finishInternal() mFinished = " + mFinished); - if (mFinished) return; - try { + + if (!mFinished) { mFinished = true; - if (mSandman != null) { - mSandman.finishSelf(mWindowToken); + if (mWindowToken == null) { + Slog.w(TAG, "Finish was called before the dream was attached."); } else { - Slog.w(TAG, "No dream manager found"); + try { + mSandman.finishSelf(mWindowToken); + } catch (RemoteException ex) { + // system server died + } } - stopSelf(); // if launched via any other means - } catch (Throwable t) { - Slog.w(TAG, "Crashed in finishInternal()", t); + stopSelf(); // if launched via any other means } } @@ -732,32 +849,39 @@ public class DreamService extends Service implements Window.Callback { @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - super.dump(fd, pw, args); - - pw.print(TAG + ": "); - if (mWindowToken == null) { - pw.println("stopped"); - } else { - pw.println("running (token=" + mWindowToken + ")"); - } - pw.println(" window: " + mWindow); - pw.print(" flags:"); - if (isInteractive()) pw.print(" interactive"); - if (isLowProfile()) pw.print(" lowprofile"); - if (isFullscreen()) pw.print(" fullscreen"); - if (isScreenBright()) pw.print(" bright"); - pw.println(); + DumpUtils.dumpAsync(mHandler, new Dump() { + @Override + public void dump(PrintWriter pw) { + pw.print(TAG + ": "); + if (mWindowToken == null) { + pw.println("stopped"); + } else { + pw.println("running (token=" + mWindowToken + ")"); + } + pw.println(" window: " + mWindow); + pw.print(" flags:"); + if (isInteractive()) pw.print(" interactive"); + if (isLowProfile()) pw.print(" lowprofile"); + if (isFullscreen()) pw.print(" fullscreen"); + if (isScreenBright()) pw.print(" bright"); + if (isDozing()) pw.print(" dozing"); + pw.println(); + } + }, pw, 1000); } - private class DreamServiceWrapper extends IDreamService.Stub { - public void attach(final IBinder windowToken) { + private final class DreamServiceWrapper extends IDreamService.Stub { + @Override + public void attach(final IBinder windowToken, final boolean canDoze) { mHandler.post(new Runnable() { @Override public void run() { - DreamService.this.attach(windowToken); + DreamService.this.attach(windowToken, canDoze); } }); } + + @Override public void detach() { mHandler.post(new Runnable() { @Override diff --git a/core/java/android/service/dreams/IDozeHardware.aidl b/core/java/android/service/dreams/IDozeHardware.aidl new file mode 100644 index 000000000000..f5a657b098c4 --- /dev/null +++ b/core/java/android/service/dreams/IDozeHardware.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 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.service.dreams; + +/** + * @hide + */ +interface IDozeHardware { + byte[] sendMessage(String msg, in byte[] arg); +} diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl index 1c1b39094776..2718e3166f18 100644 --- a/core/java/android/service/dreams/IDreamManager.aidl +++ b/core/java/android/service/dreams/IDreamManager.aidl @@ -16,10 +16,11 @@ package android.service.dreams; +import android.content.ComponentName; import android.os.Bundle; import android.os.ParcelFileDescriptor; -import android.content.ComponentName; import android.os.IBinder; +import android.service.dreams.IDozeHardware; /** @hide */ interface IDreamManager { @@ -31,4 +32,7 @@ interface IDreamManager { void testDream(in ComponentName componentName); boolean isDreaming(); void finishSelf(in IBinder token); + void startDozing(in IBinder token); + void stopDozing(in IBinder token); + IDozeHardware getDozeHardware(in IBinder token); }
\ No newline at end of file diff --git a/core/java/android/service/dreams/IDreamService.aidl b/core/java/android/service/dreams/IDreamService.aidl index 99dc0b77d208..bd58f1d905da 100644 --- a/core/java/android/service/dreams/IDreamService.aidl +++ b/core/java/android/service/dreams/IDreamService.aidl @@ -20,6 +20,6 @@ package android.service.dreams; * @hide */ oneway interface IDreamService { - void attach(IBinder windowToken); + void attach(IBinder windowToken, boolean canDoze); void detach(); } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index c5a1b86c0635..74dda7767095 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -115,20 +115,6 @@ public interface WindowManagerPolicy { public final static int ACTION_PASS_TO_USER = 0x00000001; /** - * This key event should wake the device. - * To be returned from {@link #interceptKeyBeforeQueueing}. - * Do not return this and {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}. - */ - public final static int ACTION_WAKE_UP = 0x00000002; - - /** - * This key event should put the device to sleep (and engage keyguard if necessary) - * To be returned from {@link #interceptKeyBeforeQueueing}. - * Do not return this and {@link #ACTION_WAKE_UP} or {@link #ACTION_PASS_TO_USER}. - */ - public final static int ACTION_GO_TO_SLEEP = 0x00000004; - - /** * Interface to the Window Manager state associated with a particular * window. You can hold on to an instance of this interface from the call * to prepareAddWindow() until removeWindow(). @@ -751,8 +737,7 @@ public interface WindowManagerPolicy { * @param policyFlags The policy flags associated with the key. * @param isScreenOn True if the screen is already on * - * @return The bitwise or of the {@link #ACTION_PASS_TO_USER}, - * {@link #ACTION_WAKE_UP} and {@link #ACTION_GO_TO_SLEEP} flags. + * @return Actions flags: may be {@link #ACTION_PASS_TO_USER}. */ public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn); @@ -765,10 +750,9 @@ public interface WindowManagerPolicy { * because it's the most fragile. * @param policyFlags The policy flags associated with the motion. * - * @return The bitwise or of the {@link #ACTION_PASS_TO_USER}, - * {@link #ACTION_WAKE_UP} and {@link #ACTION_GO_TO_SLEEP} flags. + * @return Actions flags: may be {@link #ACTION_PASS_TO_USER}. */ - public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags); + public int interceptMotionBeforeQueueingWhenScreenOff(long whenNanos, int policyFlags); /** * Called from the input dispatcher thread before a key is dispatched to a window. |
