diff options
30 files changed, 537 insertions, 372 deletions
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java index 5d8f80e..5ff199a 100644 --- a/core/java/android/database/sqlite/SQLiteGlobal.java +++ b/core/java/android/database/sqlite/SQLiteGlobal.java @@ -18,6 +18,7 @@ package android.database.sqlite; import android.content.res.Resources; import android.os.StatFs; +import android.os.SystemProperties; /** * Provides access to SQLite functions that affect all database connection, @@ -62,7 +63,7 @@ public final class SQLiteGlobal { if (sDefaultPageSize == 0) { sDefaultPageSize = new StatFs("/data").getBlockSize(); } - return sDefaultPageSize; + return SystemProperties.getInt("debug.sqlite.pagesize", sDefaultPageSize); } } @@ -70,47 +71,55 @@ public final class SQLiteGlobal { * Gets the default journal mode when WAL is not in use. */ public static String getDefaultJournalMode() { - return Resources.getSystem().getString( - com.android.internal.R.string.db_default_journal_mode); + return SystemProperties.get("debug.sqlite.journalmode", + Resources.getSystem().getString( + com.android.internal.R.string.db_default_journal_mode)); } /** * Gets the journal size limit in bytes. */ public static int getJournalSizeLimit() { - return Resources.getSystem().getInteger( - com.android.internal.R.integer.db_journal_size_limit); + return SystemProperties.getInt("debug.sqlite.journalsizelimit", + Resources.getSystem().getInteger( + com.android.internal.R.integer.db_journal_size_limit)); } /** * Gets the default database synchronization mode when WAL is not in use. */ public static String getDefaultSyncMode() { - return Resources.getSystem().getString( - com.android.internal.R.string.db_default_sync_mode); + return SystemProperties.get("debug.sqlite.syncmode", + Resources.getSystem().getString( + com.android.internal.R.string.db_default_sync_mode)); } /** * Gets the database synchronization mode when in WAL mode. */ public static String getWALSyncMode() { - return Resources.getSystem().getString( - com.android.internal.R.string.db_wal_sync_mode); + return SystemProperties.get("debug.sqlite.wal.syncmode", + Resources.getSystem().getString( + com.android.internal.R.string.db_wal_sync_mode)); } /** * Gets the WAL auto-checkpoint integer in database pages. */ public static int getWALAutoCheckpoint() { - return Math.max(1, Resources.getSystem().getInteger( + int value = SystemProperties.getInt("debug.sqlite.wal.autocheckpoint", + Resources.getSystem().getInteger( com.android.internal.R.integer.db_wal_autocheckpoint)); + return Math.max(1, value); } /** * Gets the connection pool size when in WAL mode. */ public static int getWALConnectionPoolSize() { - return Math.max(2, Resources.getSystem().getInteger( + int value = SystemProperties.getInt("debug.sqlite.wal.poolsize", + Resources.getSystem().getInteger( com.android.internal.R.integer.db_connection_pool_size)); + return Math.max(2, value); } } diff --git a/core/java/android/os/Power.java b/core/java/android/os/Power.java deleted file mode 100644 index 58df940..0000000 --- a/core/java/android/os/Power.java +++ /dev/null @@ -1,109 +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; - -import java.io.IOException; -import android.os.ServiceManager; - -/** - * Class that provides access to some of the power management functions. - * - * {@hide} - */ -public class Power -{ - // can't instantiate this class - private Power() - { - } - - /** - * Wake lock that ensures that the CPU is running. The screen might - * not be on. - */ - public static final int PARTIAL_WAKE_LOCK = 1; - - /** - * Wake lock that ensures that the screen is on. - */ - public static final int FULL_WAKE_LOCK = 2; - - public static native void acquireWakeLock(int lock, String id); - public static native void releaseWakeLock(String id); - - /** - * Brightness value for fully off - */ - public static final int BRIGHTNESS_OFF = 0; - - /** - * Brightness value for dim backlight - */ - public static final int BRIGHTNESS_DIM = 20; - - /** - * Brightness value for fully on - */ - public static final int BRIGHTNESS_ON = 255; - - /** - * Brightness value to use when battery is low - */ - public static final int BRIGHTNESS_LOW_BATTERY = 10; - - /** - * Threshold for BRIGHTNESS_LOW_BATTERY (percentage) - * Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD - */ - public static final int LOW_BATTERY_THRESHOLD = 10; - - /** - * Turn the screen on or off - * - * @param on Whether you want the screen on or off - */ - public static native int setScreenState(boolean on); - - public static native int setLastUserActivityTimeout(long ms); - - /** - * Low-level function turn the device off immediately, without trying - * to be clean. Most people should use - * {@link android.internal.app.ShutdownThread} for a clean shutdown. - * - * @deprecated - * @hide - */ - @Deprecated - public static native void shutdown(); - - /** - * Reboot the device. - * @param reason code to pass to the kernel (e.g. "recovery"), or null. - * - * @throws IOException if reboot fails for some reason (eg, lack of - * permission) - */ - public static void reboot(String reason) throws IOException - { - rebootNative(reason); - } - - private static native void rebootNative(String reason) throws IOException ; - - public static native int powerInitNative(); -} diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 21373ec..903c8b3 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -197,7 +197,31 @@ public class PowerManager * Does not work with PARTIAL_WAKE_LOCKs. */ public static final int ON_AFTER_RELEASE = 0x20000000; - + + /** + * Brightness value to use when battery is low. + * @hide + */ + public static final int BRIGHTNESS_LOW_BATTERY = 10; + + /** + * Brightness value for fully on. + * @hide + */ + public static final int BRIGHTNESS_ON = 255; + + /** + * Brightness value for dim backlight. + * @hide + */ + public static final int BRIGHTNESS_DIM = 20; + + /** + * Brightness value for fully off. + * @hide + */ + public static final int BRIGHTNESS_OFF = 0; + /** * Class lets you say that you need to have the device on. * <p> diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 388cfb3..bc38368 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -397,6 +397,9 @@ public interface WindowManagerPolicy { * Creates an input channel that will receive all input from the input dispatcher. */ public InputChannel monitorInput(String name); + + public void shutdown(); + public void rebootSafeMode(); } /** diff --git a/core/jni/Android.mk b/core/jni/Android.mk index cd0959b..c24f6c6 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -66,7 +66,6 @@ LOCAL_SRC_FILES:= \ android_os_MessageQueue.cpp \ android_os_ParcelFileDescriptor.cpp \ android_os_Parcel.cpp \ - android_os_Power.cpp \ android_os_StatFs.cpp \ android_os_SystemClock.cpp \ android_os_SystemProperties.cpp \ @@ -217,8 +216,7 @@ LOCAL_SHARED_LIBRARIES := \ libjpeg \ libusbhost \ libharfbuzz \ - libz \ - libsuspend \ + libz ifeq ($(USE_OPENGL_RENDERER),true) LOCAL_SHARED_LIBRARIES += libhwui diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index b877071..241a905 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -133,7 +133,6 @@ extern int register_android_os_Debug(JNIEnv* env); extern int register_android_os_MessageQueue(JNIEnv* env); extern int register_android_os_Parcel(JNIEnv* env); extern int register_android_os_ParcelFileDescriptor(JNIEnv *env); -extern int register_android_os_Power(JNIEnv *env); extern int register_android_os_StatFs(JNIEnv *env); extern int register_android_os_SystemProperties(JNIEnv *env); extern int register_android_os_SystemClock(JNIEnv* env); @@ -1147,7 +1146,6 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_FileUtils), REG_JNI(register_android_os_MessageQueue), REG_JNI(register_android_os_ParcelFileDescriptor), - REG_JNI(register_android_os_Power), REG_JNI(register_android_os_StatFs), REG_JNI(register_android_os_Trace), REG_JNI(register_android_os_UEventObserver), diff --git a/core/jni/android_os_Power.cpp b/core/jni/android_os_Power.cpp deleted file mode 100644 index 373abd4..0000000 --- a/core/jni/android_os_Power.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* //device/libs/android_runtime/android_os_Power.cpp -** -** Copyright 2006, 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. -*/ - -#define LOG_TAG "Power-JNI" - -#include "JNIHelp.h" -#include "jni.h" -#include "android_runtime/AndroidRuntime.h" -#include <utils/misc.h> -#include <hardware/power.h> -#include <hardware_legacy/power.h> -#include <cutils/android_reboot.h> -#include <suspend/autosuspend.h> - -static struct power_module *sPowerModule; - -namespace android -{ - -static void -acquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj) -{ - if (idObj == NULL) { - jniThrowNullPointerException(env, "id is null"); - return ; - } - - const char *id = env->GetStringUTFChars(idObj, NULL); - - acquire_wake_lock(lock, id); - - env->ReleaseStringUTFChars(idObj, id); -} - -static void -releaseWakeLock(JNIEnv *env, jobject clazz, jstring idObj) -{ - if (idObj == NULL) { - jniThrowNullPointerException(env, "id is null"); - return ; - } - - const char *id = env->GetStringUTFChars(idObj, NULL); - - release_wake_lock(id); - - env->ReleaseStringUTFChars(idObj, id); - -} - -static int -setLastUserActivityTimeout(JNIEnv *env, jobject clazz, jlong timeMS) -{ - return set_last_user_activity_timeout(timeMS/1000); -} - -static int -setScreenState(JNIEnv *env, jobject clazz, jboolean on) -{ - if (on) { - autosuspend_disable(); - if (sPowerModule) { - sPowerModule->setInteractive(sPowerModule, true); - } - } else { - if (sPowerModule) { - sPowerModule->setInteractive(sPowerModule, false); - } - autosuspend_enable(); - } - - return 0; -} - -static void android_os_Power_shutdown(JNIEnv *env, jobject clazz) -{ - android_reboot(ANDROID_RB_POWEROFF, 0, 0); -} - -static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason) -{ - if (reason == NULL) { - android_reboot(ANDROID_RB_RESTART, 0, 0); - } else { - const char *chars = env->GetStringUTFChars(reason, NULL); - android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars); - env->ReleaseStringUTFChars(reason, chars); // In case it fails. - } - jniThrowIOException(env, errno); -} - -static int android_os_Power_init(JNIEnv *env, jobject clazz) -{ - status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID, - (hw_module_t const**)&sPowerModule); - ALOGE_IF(err, "couldn't load %s module (%s)", - POWER_HARDWARE_MODULE_ID, strerror(-err)); - - if (!err) - sPowerModule->init(sPowerModule); - - return err; -} - -static JNINativeMethod method_table[] = { - { "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock }, - { "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock }, - { "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout }, - { "setScreenState", "(Z)I", (void*)setScreenState }, - { "shutdown", "()V", (void*)android_os_Power_shutdown }, - { "powerInitNative", "()I", (void*)android_os_Power_init }, - { "rebootNative", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot }, -}; - -int register_android_os_Power(JNIEnv *env) -{ - return AndroidRuntime::registerNativeMethods( - env, "android/os/Power", - method_table, NELEM(method_table)); -} - -}; diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index ec911b0..6c204ab 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -49,9 +49,9 @@ public final class Rect implements Parcelable { * checking is performed, so the caller must ensure that left <= right and * top <= bottom. * - * @param left The X coordinate of the left side of the rectagle + * @param left The X coordinate of the left side of the rectangle * @param top The Y coordinate of the top of the rectangle - * @param right The X coordinate of the right side of the rectagle + * @param right The X coordinate of the right side of the rectangle * @param bottom The Y coordinate of the bottom of the rectangle */ public Rect(int left, int top, int right, int bottom) { @@ -235,9 +235,9 @@ public final class Rect implements Parcelable { * checking is performed, so it is up to the caller to ensure that * left <= right and top <= bottom. * - * @param left The X coordinate of the left side of the rectagle + * @param left The X coordinate of the left side of the rectangle * @param top The Y coordinate of the top of the rectangle - * @param right The X coordinate of the right side of the rectagle + * @param right The X coordinate of the right side of the rectangle * @param bottom The Y coordinate of the bottom of the rectangle */ public void set(int left, int top, int right, int bottom) { diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java index c633d84..108b7f9 100644 --- a/graphics/java/android/graphics/RectF.java +++ b/graphics/java/android/graphics/RectF.java @@ -46,9 +46,9 @@ public class RectF implements Parcelable { * checking is performed, so the caller must ensure that left <= right and * top <= bottom. * - * @param left The X coordinate of the left side of the rectagle + * @param left The X coordinate of the left side of the rectangle * @param top The Y coordinate of the top of the rectangle - * @param right The X coordinate of the right side of the rectagle + * @param right The X coordinate of the right side of the rectangle * @param bottom The Y coordinate of the bottom of the rectangle */ public RectF(float left, float top, float right, float bottom) { @@ -182,9 +182,9 @@ public class RectF implements Parcelable { * checking is performed, so it is up to the caller to ensure that * left <= right and top <= bottom. * - * @param left The X coordinate of the left side of the rectagle + * @param left The X coordinate of the left side of the rectangle * @param top The Y coordinate of the top of the rectangle - * @param right The X coordinate of the right side of the rectagle + * @param right The X coordinate of the right side of the rectangle * @param bottom The Y coordinate of the bottom of the rectangle */ public void set(float left, float top, float right, float bottom) { diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index f412b9b..8015203 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -33,6 +33,7 @@ import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothProfile; +import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -3607,24 +3608,20 @@ public class AudioService extends IAudioService.Stub implements OnFinished { // RemoteControl //========================================================================================== public void dispatchMediaKeyEvent(KeyEvent keyEvent) { - dispatchMediaKeyEvent(keyEvent, false /*needWakeLock*/); + filterMediaKeyEvent(keyEvent, false /*needWakeLock*/); } public void dispatchMediaKeyEventUnderWakelock(KeyEvent keyEvent) { - dispatchMediaKeyEvent(keyEvent, true /*needWakeLock*/); + filterMediaKeyEvent(keyEvent, true /*needWakeLock*/); } - /** - * Handles the dispatching of the media button events to one of the registered listeners, - * or if there was none, broadcast a ACTION_MEDIA_BUTTON intent to the rest of the system. - */ - private void dispatchMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) { + private void filterMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) { // sanity check on the incoming key event if (!isValidMediaKeyEvent(keyEvent)) { Log.e(TAG, "not dispatching invalid media key event " + keyEvent); return; } - // event filtering + // event filtering based on audio mode synchronized(mRingingLock) { if (mIsRinging || (getMode() == AudioSystem.MODE_IN_CALL) || (getMode() == AudioSystem.MODE_IN_COMMUNICATION) || @@ -3632,6 +3629,22 @@ public class AudioService extends IAudioService.Stub implements OnFinished { return; } } + // event filtering based on voice-based interactions + if (isValidVoiceInputKeyCode(keyEvent.getKeyCode())) { + filterVoiceInputKeyEvent(keyEvent, needWakeLock); + } else { + dispatchMediaKeyEvent(keyEvent, needWakeLock); + } + } + + /** + * Handles the dispatching of the media button events to one of the registered listeners, + * or if there was none, broadcast an ACTION_MEDIA_BUTTON intent to the rest of the system. + * @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons + * @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event + * is dispatched. + */ + private void dispatchMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) { if (needWakeLock) { mMediaEventWakeLock.acquire(); } @@ -3660,6 +3673,140 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } } + /** + * The minimum duration during which a user must press to trigger voice-based interactions + */ + private final static int MEDIABUTTON_LONG_PRESS_DURATION_MS = 300; + /** + * The different states of the state machine to handle the launch of voice-based interactions, + * stored in mVoiceButtonState. + */ + private final static int VOICEBUTTON_STATE_IDLE = 0; + private final static int VOICEBUTTON_STATE_DOWN = 1; + private final static int VOICEBUTTON_STATE_DOWN_IGNORE_NEW = 2; + /** + * The different actions after state transitions on mVoiceButtonState. + */ + private final static int VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS = 1; + private final static int VOICEBUTTON_ACTION_START_VOICE_INPUT = 2; + private final static int VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS = 3; + + private final Object mVoiceEventLock = new Object(); + private int mVoiceButtonState = VOICEBUTTON_STATE_IDLE; + private long mVoiceButtonDownTime = 0; + + /** + * Log an error when an unexpected action is encountered in the state machine to filter + * key events. + * @param keyAction the unexpected action of the key event being filtered + * @param stateName the string corresponding to the state in which the error occurred + */ + private static void logErrorForKeyAction(int keyAction, String stateName) { + Log.e(TAG, "unexpected action " + + KeyEvent.actionToString(keyAction) + + " in " + stateName + " state"); + } + + /** + * Filter key events that may be used for voice-based interactions + * @param keyEvent a non-null KeyEvent whose key code is that of one of the supported + * media buttons that can be used to trigger voice-based interactions. + * @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event + * is dispatched. + */ + private void filterVoiceInputKeyEvent(KeyEvent keyEvent, boolean needWakeLock) { + int voiceButtonAction = VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS; + int keyAction = keyEvent.getAction(); + synchronized (mVoiceEventLock) { + // state machine on mVoiceButtonState + switch (mVoiceButtonState) { + + case VOICEBUTTON_STATE_IDLE: + if (keyAction == KeyEvent.ACTION_DOWN) { + mVoiceButtonDownTime = keyEvent.getDownTime(); + // valid state transition + mVoiceButtonState = VOICEBUTTON_STATE_DOWN; + } else if (keyAction == KeyEvent.ACTION_UP) { + // no state transition + // action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS + } else { + logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_IDLE"); + } + break; + + case VOICEBUTTON_STATE_DOWN: + if ((keyEvent.getEventTime() - mVoiceButtonDownTime) + >= MEDIABUTTON_LONG_PRESS_DURATION_MS) { + // press was long enough, start voice-based interactions, regardless of + // whether this was a DOWN or UP key event + voiceButtonAction = VOICEBUTTON_ACTION_START_VOICE_INPUT; + if (keyAction == KeyEvent.ACTION_UP) { + // done tracking the key press, so transition back to idle state + mVoiceButtonState = VOICEBUTTON_STATE_IDLE; + } else if (keyAction == KeyEvent.ACTION_DOWN) { + // no need to observe the upcoming key events + mVoiceButtonState = VOICEBUTTON_STATE_DOWN_IGNORE_NEW; + } else { + logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN"); + } + } else { + if (keyAction == KeyEvent.ACTION_UP) { + // press wasn't long enough, simulate complete key press + voiceButtonAction = VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS; + // not tracking the key press anymore, so transition back to idle state + mVoiceButtonState = VOICEBUTTON_STATE_IDLE; + } else if (keyAction == KeyEvent.ACTION_DOWN) { + // no state transition + // action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS + } else { + logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN"); + } + } + break; + + case VOICEBUTTON_STATE_DOWN_IGNORE_NEW: + if (keyAction == KeyEvent.ACTION_UP) { + // done tracking the key press, so transition back to idle state + mVoiceButtonState = VOICEBUTTON_STATE_IDLE; + // action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS + } else if (keyAction == KeyEvent.ACTION_DOWN) { + // no state transition: we've already launched voice-based interactions + // action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS + } else { + logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN_IGNORE_NEW"); + } + break; + } + }//synchronized (mVoiceEventLock) + + // take action after media button event filtering for voice-based interactions + switch (voiceButtonAction) { + case VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS: + if (DEBUG_RC) Log.v(TAG, " ignore key event"); + break; + case VOICEBUTTON_ACTION_START_VOICE_INPUT: + if (DEBUG_RC) Log.v(TAG, " start voice-based interactions"); + // then start the voice-based interactions + startVoiceBasedInteractions(needWakeLock); + break; + case VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS: + if (DEBUG_RC) Log.v(TAG, " send simulated key event"); + sendSimulatedMediaButtonEvent(keyEvent, needWakeLock); + break; + } + } + + private void sendSimulatedMediaButtonEvent(KeyEvent originalKeyEvent, boolean needWakeLock) { + // send DOWN event + KeyEvent keyEvent = KeyEvent.changeAction(originalKeyEvent, KeyEvent.ACTION_DOWN); + dispatchMediaKeyEvent(keyEvent, needWakeLock); + // send UP event + keyEvent = KeyEvent.changeAction(originalKeyEvent, KeyEvent.ACTION_UP); + dispatchMediaKeyEvent(keyEvent, needWakeLock); + + } + + private static boolean isValidMediaKeyEvent(KeyEvent keyEvent) { if (keyEvent == null) { return false; @@ -3686,6 +3833,63 @@ public class AudioService extends IAudioService.Stub implements OnFinished { return true; } + /** + * Checks whether the given key code is one that can trigger the launch of voice-based + * interactions. + * @param keyCode the key code associated with the key event + * @return true if the key is one of the supported voice-based interaction triggers + */ + private static boolean isValidVoiceInputKeyCode(int keyCode) { + if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK) { + return true; + } else { + return false; + } + } + + /** + * Tell the system to start voice-based interactions / voice commands + */ + private void startVoiceBasedInteractions(boolean needWakeLock) { + Intent voiceIntent = new Intent(android.speech.RecognizerIntent.ACTION_WEB_SEARCH); + if (needWakeLock) { + mMediaEventWakeLock.acquire(); + } + voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + try { + if (mKeyguardManager != null) { + // it's ok to start voice-based interactions when: + // - the device is locked but doesn't require a password to be unlocked + // - the device is not locked + if ((mKeyguardManager.isKeyguardLocked() && !mKeyguardManager.isKeyguardSecure()) + || !mKeyguardManager.isKeyguardLocked()) { + mContext.startActivity(voiceIntent); + } + } + } catch (ActivityNotFoundException e) { + Log.e(TAG, "Error launching activity for ACTION_WEB_SEARCH: " + e); + } finally { + if (needWakeLock) { + mMediaEventWakeLock.release(); + } + } + } + + /** + * Verify whether it is safe to start voice-based interactions given the state of the system + * @return false is the Keyguard is locked and secure, true otherwise + */ + private boolean safeToStartVoiceBasedInteractions() { + KeyguardManager keyguard = + (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); + if (keyguard == null) { + return false; + } + + return true; + } + private PowerManager.WakeLock mMediaEventWakeLock; private static final int WAKELOCK_RELEASE_ON_FINISHED = 1980; //magic number @@ -3703,7 +3907,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished { BroadcastReceiver mKeyEventDone = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { - if (intent.getExtras().containsKey(EXTRA_WAKELOCK_ACQUIRED)) { + if (intent == null) { + return; + } + Bundle extras = intent.getExtras(); + if (extras == null) { + return; + } + if (extras.containsKey(EXTRA_WAKELOCK_ACQUIRED)) { mMediaEventWakeLock.release(); } } diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml index 869b164..8a21117 100644 --- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml @@ -27,12 +27,6 @@ systemui:recentItemLayout="@layout/status_bar_recent_item" > - <ImageView - android:id="@+id/recents_transition_placeholder_icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:visibility="invisible" /> - <FrameLayout android:id="@+id/recents_bg_protect" android:background="@drawable/status_bar_recents_background" @@ -42,6 +36,12 @@ android:clipToPadding="false" android:clipChildren="false"> + <ImageView + android:id="@+id/recents_transition_placeholder_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="invisible" /> + <com.android.systemui.recent.RecentsHorizontalScrollView android:id="@+id/recents_container" android:layout_width="wrap_content" android:layout_height="match_parent" diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml index fc9fcf4..1d29c5a 100644 --- a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml +++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml @@ -27,12 +27,6 @@ systemui:recentItemLayout="@layout/status_bar_recent_item" > - <ImageView - android:id="@+id/recents_transition_placeholder_icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:visibility="invisible" /> - <FrameLayout android:id="@+id/recents_bg_protect" android:background="@drawable/status_bar_recents_background" @@ -40,6 +34,12 @@ android:layout_height="match_parent" android:layout_alignParentBottom="true"> + <ImageView + android:id="@+id/recents_transition_placeholder_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="invisible" /> + <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container" android:layout_width="match_parent" diff --git a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java index a8c2020..ccdf038 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java +++ b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java @@ -102,12 +102,14 @@ import android.view.ViewRootImpl; builder.with(noRecentAppsFadeAnim); } - Drawable background = mScrimView.getBackground(); - if (background != null) { - Animator bgAnim = ObjectAnimator.ofInt(background, - "alpha", appearing ? 0 : 255, appearing ? 255 : 0); - bgAnim.setDuration(appearing ? SCRIM_DURATION : CLOSE_DURATION); - builder.with(bgAnim); + if (appearing) { + Drawable background = mScrimView.getBackground(); + if (background != null) { + Animator bgAnim = ObjectAnimator.ofInt(background, + "alpha", appearing ? 0 : 255, appearing ? 255 : 0); + bgAnim.setDuration(appearing ? SCRIM_DURATION : CLOSE_DURATION); + builder.with(bgAnim); + } } mContentAnim.addListener(this); if (mListener != null) { diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java index feb1ac8..6785c29 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java @@ -469,7 +469,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); if (!ActivityManager.isHighEndGfx(d)) { - mRecentsScrim.setBackgroundDrawable(null); + mRecentsScrim.setBackground(null); } else if (mRecentsScrim.getBackground() instanceof BitmapDrawable) { // In order to save space, we make the background texture repeat in the Y direction ((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index a310b1d..a44279a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -751,6 +751,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected abstract void tick(IBinder key, StatusBarNotification n, boolean firstTime); protected abstract void updateExpandedViewPos(int expandedPosition); protected abstract int getExpandedViewMaxHeight(); + protected abstract boolean isStatusBarExpanded(); protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) { return parent.indexOfChild(entry.row) == 0; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java index e074a80..912a165 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java @@ -53,6 +53,9 @@ public class DelegateViewHelper { } public boolean onInterceptTouchEvent(MotionEvent event) { + if (mBar.isStatusBarExpanded()) { + return false; + } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mDownPoint[0] = event.getX(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index d3fbdab..6122390 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -2109,5 +2109,10 @@ public class PhoneStatusBar extends BaseStatusBar { protected void haltTicker() { mTicker.halt(); } + + @Override + protected boolean isStatusBarExpanded() { + return mExpanded; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java index 72fdfad..3ba36af 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java @@ -31,8 +31,8 @@ import android.widget.CompoundButton; public class BrightnessController implements ToggleSlider.Listener { private static final String TAG = "StatusBar.BrightnessController"; - private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM; - private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON; + private static final int MINIMUM_BACKLIGHT = android.os.PowerManager.BRIGHTNESS_DIM; + private static final int MAXIMUM_BACKLIGHT = android.os.PowerManager.BRIGHTNESS_ON; private Context mContext; private ToggleSlider mControl; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 906d1aa..a2c7637 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -1618,6 +1618,11 @@ public class TabletStatusBar extends BaseStatusBar implements @Override protected void updateExpandedViewPos(int expandedPosition) { } + + @Override + protected boolean isStatusBarExpanded() { + return mNotificationPanel.getVisibility() == View.VISIBLE; + } } diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java index 3fa79b6..aa73de4 100644 --- a/policy/src/com/android/internal/policy/impl/GlobalActions.java +++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java @@ -16,14 +16,12 @@ package com.android.internal.policy.impl; -import com.android.internal.app.ShutdownThread; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.R; import android.app.ActivityManagerNative; import android.app.AlertDialog; -import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; @@ -48,6 +46,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.view.WindowManagerPolicy.WindowManagerFuncs; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; @@ -68,6 +67,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac private static final boolean SHOW_SILENT_TOGGLE = true; private final Context mContext; + private final WindowManagerFuncs mWindowManagerFuncs; private final AudioManager mAudioManager; private ArrayList<Action> mItems; @@ -88,8 +88,9 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac /** * @param context everything needs a context :( */ - public GlobalActions(Context context) { + public GlobalActions(Context context, WindowManagerFuncs windowManagerFuncs) { mContext = context; + mWindowManagerFuncs = windowManagerFuncs; mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); // receive broadcasts @@ -186,11 +187,11 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac public void onPress() { // shutdown by making sure radio and power are handled accordingly. - ShutdownThread.shutdown(mContext, true); + mWindowManagerFuncs.shutdown(); } public boolean onLongPress() { - ShutdownThread.rebootSafeMode(mContext, true); + mWindowManagerFuncs.rebootSafeMode(); return true; } diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index f34f9a9..8ea334e 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -129,6 +129,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen { // Get the target position for the given resource. Returns -1 if not found. public int getTargetPosition(int resourceId); + + // Clean up when this widget is going away + public void cleanUp(); } class SlidingTabMethods implements SlidingTab.OnTriggerListener, UnlockWidgetCommonMethods { @@ -197,6 +200,10 @@ class LockScreen extends LinearLayout implements KeyguardScreen { public int getTargetPosition(int resourceId) { return -1; // Not supported } + + public void cleanUp() { + mSlidingTab.setOnTriggerListener(null); + } } class WaveViewMethods implements WaveView.OnTriggerListener, UnlockWidgetCommonMethods { @@ -240,6 +247,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen { public int getTargetPosition(int resourceId) { return -1; // Not supported } + public void cleanUp() { + mWaveView.setOnTriggerListener(null); + } } private Intent getAssistIntent() { @@ -374,6 +384,10 @@ class LockScreen extends LinearLayout implements KeyguardScreen { public int getTargetPosition(int resourceId) { return mMultiWaveView.getTargetPosition(resourceId); } + + public void cleanUp() { + mMultiWaveView.setOnTriggerListener(null); + } } private void requestUnlockScreen() { @@ -592,6 +606,7 @@ class LockScreen extends LinearLayout implements KeyguardScreen { public void cleanUp() { mUpdateMonitor.removeCallback(mInfoCallback); // this must be first mUpdateMonitor.removeCallback(mSimStateCallback); + mUnlockWidgetMethods.cleanUp(); mLockPatternUtils = null; mUpdateMonitor = null; mCallback = null; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 794ed15..8e187cd 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -60,7 +60,6 @@ import android.os.Vibrator; import android.provider.Settings; import com.android.internal.R; -import com.android.internal.app.ShutdownThread; import com.android.internal.policy.PolicyManager; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.telephony.ITelephony; @@ -727,7 +726,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mPowerKeyHandled = true; performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); - ShutdownThread.shutdown(mContext, true); + mWindowManagerFuncs.shutdown(); break; } } @@ -741,7 +740,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { void showGlobalActionsDialog() { if (mGlobalActions == null) { - mGlobalActions = new GlobalActions(mContext); + mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs); } final boolean keyguardShowing = keyguardIsShowingTq(); mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 289ab2a..2cc2704 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -17,8 +17,8 @@ package com.android.server; import com.android.internal.app.IBatteryStats; -import com.android.internal.app.ShutdownThread; import com.android.server.am.BatteryStatsService; +import com.android.server.pm.ShutdownThread; import android.app.ActivityManagerNative; import android.app.IActivityManager; @@ -47,7 +47,6 @@ import android.os.IBinder; import android.os.IPowerManager; import android.os.LocalPowerManager; import android.os.Message; -import android.os.Power; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; @@ -71,6 +70,7 @@ import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE; import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE; import java.io.FileDescriptor; +import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; @@ -84,6 +84,12 @@ public class PowerManagerService extends IPowerManager.Stub private static final String TAG = "PowerManagerService"; static final String PARTIAL_NAME = "PowerManagerService"; + // Wake lock that ensures that the CPU is running. The screen might not be on. + private static final int PARTIAL_WAKE_LOCK_ID = 1; + + // Wake lock that ensures that the screen is on. + private static final int FULL_WAKE_LOCK_ID = 2; + static final boolean DEBUG_SCREEN_ON = false; private static final boolean LOG_PARTIAL_WL = false; @@ -134,6 +140,10 @@ public class PowerManagerService extends IPowerManager.Stub // Screen brightness should always have a value, but just in case... private static final int DEFAULT_SCREEN_BRIGHTNESS = 192; + // Threshold for BRIGHTNESS_LOW_BATTERY (percentage) + // Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD + private static final int LOW_BATTERY_THRESHOLD = 10; + // flags for setPowerState private static final int ALL_LIGHTS_OFF = 0x00000000; private static final int SCREEN_ON_BIT = 0x00000001; @@ -175,8 +185,8 @@ public class PowerManagerService extends IPowerManager.Stub // we should read them from the driver, but our current hardware returns 0 // for the initial value. Oops! static final int INITIAL_SCREEN_BRIGHTNESS = 255; - static final int INITIAL_BUTTON_BRIGHTNESS = Power.BRIGHTNESS_OFF; - static final int INITIAL_KEYBOARD_BRIGHTNESS = Power.BRIGHTNESS_OFF; + static final int INITIAL_BUTTON_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF; + static final int INITIAL_KEYBOARD_BRIGHTNESS = PowerManager.BRIGHTNESS_OFF; private final int MY_UID; private final int MY_PID; @@ -296,6 +306,11 @@ public class PowerManagerService extends IPowerManager.Stub private native void nativeInit(); private native void nativeSetPowerState(boolean screenOn, boolean screenBright); private native void nativeStartSurfaceFlingerAnimation(int mode); + private static native void nativeAcquireWakeLock(int lock, String id); + private static native void nativeReleaseWakeLock(String id); + private static native int nativeSetScreenState(boolean on); + private static native void nativeShutdown(); + private static native void nativeReboot(String reason) throws IOException; /* static PrintStream mLog; @@ -515,14 +530,13 @@ public class PowerManagerService extends IPowerManager.Stub MY_PID = Process.myPid(); Binder.restoreCallingIdentity(token); - // XXX remove this when the kernel doesn't timeout wake locks - Power.setLastUserActivityTimeout(7*24*3600*1000); // one week - // assume nothing is on yet mUserState = mPowerState = 0; // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); + + nativeInit(); } private ContentQueryMap mSettings; @@ -541,11 +555,6 @@ public class PowerManagerService extends IPowerManager.Stub mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION); mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); - nativeInit(); - synchronized (mLocks) { - updateNativePowerStateLocked(); - } - mInitComplete = false; mScreenBrightnessAnimator = new ScreenBrightnessAnimator("mScreenBrightnessUpdaterThread", Process.THREAD_PRIORITY_DISPLAY); @@ -581,8 +590,6 @@ public class PowerManagerService extends IPowerManager.Stub } } - nativeInit(); - Power.powerInitNative(); synchronized (mLocks) { updateNativePowerStateLocked(); // We make sure to start out with the screen on due to user activity. @@ -686,6 +693,26 @@ public class PowerManagerService extends IPowerManager.Stub } } + /** + * Low-level function turn the device off immediately, without trying + * to be clean. Most people should use + * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown. + */ + public static void lowLevelShutdown() { + nativeShutdown(); + } + + /** + * Low-level function to reboot the device. + * + * @param reason code to pass to the kernel (e.g. "recovery"), or null. + * @throws IOException if reboot fails for some reason (eg, lack of + * permission) + */ + public static void lowLevelReboot(String reason) throws IOException { + nativeReboot(reason); + } + private class WakeLock implements IBinder.DeathRecipient { WakeLock(int f, IBinder b, String t, int u, int p) { @@ -926,7 +953,7 @@ public class PowerManagerService extends IPowerManager.Stub if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag); } } - Power.acquireWakeLock(Power.PARTIAL_WAKE_LOCK,PARTIAL_NAME); + nativeAcquireWakeLock(PARTIAL_WAKE_LOCK_ID, PARTIAL_NAME); } if (diffsource) { @@ -1010,7 +1037,7 @@ public class PowerManagerService extends IPowerManager.Stub mPartialCount--; if (mPartialCount == 0) { if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 0, wl.tag); - Power.releaseWakeLock(PARTIAL_NAME); + nativeReleaseWakeLock(PARTIAL_NAME); } } // Unlink the lock from the binder. @@ -1719,10 +1746,10 @@ public class PowerManagerService extends IPowerManager.Stub + " mSkippedScreenOn=" + mSkippedScreenOn); } mScreenBrightnessHandler.removeMessages(ScreenBrightnessAnimator.ANIMATE_LIGHTS); - mScreenBrightnessAnimator.animateTo(Power.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0); + mScreenBrightnessAnimator.animateTo(PowerManager.BRIGHTNESS_OFF, SCREEN_BRIGHT_BIT, 0); } } - int err = Power.setScreenState(on); + int err = nativeSetScreenState(on); if (err == 0) { mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0); if (mUseSoftwareAutoBrightness) { @@ -1934,7 +1961,7 @@ public class PowerManagerService extends IPowerManager.Stub private boolean batteryIsLow() { return (!mIsPowered && - mBatteryService.getBatteryLevel() <= Power.LOW_BATTERY_THRESHOLD); + mBatteryService.getBatteryLevel() <= LOW_BATTERY_THRESHOLD); } private boolean shouldDeferScreenOnLocked() { @@ -2024,7 +2051,7 @@ public class PowerManagerService extends IPowerManager.Stub nominalCurrentValue = mScreenBrightnessDim; break; case 0: - nominalCurrentValue = Power.BRIGHTNESS_OFF; + nominalCurrentValue = PowerManager.BRIGHTNESS_OFF; break; case SCREEN_BRIGHT_BIT: default: @@ -2050,7 +2077,7 @@ public class PowerManagerService extends IPowerManager.Stub // was dim steps = (int)(ANIM_STEPS*ratio*scale); } - brightness = Power.BRIGHTNESS_OFF; + brightness = PowerManager.BRIGHTNESS_OFF; } else { if ((oldState & SCREEN_ON_BIT) != 0) { // was bright @@ -2101,13 +2128,13 @@ public class PowerManagerService extends IPowerManager.Stub if (offMask != 0) { if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask); - setLightBrightness(offMask, Power.BRIGHTNESS_OFF); + setLightBrightness(offMask, PowerManager.BRIGHTNESS_OFF); } if (dimMask != 0) { int brightness = mScreenBrightnessDim; if ((newState & BATTERY_LOW_BIT) != 0 && - brightness > Power.BRIGHTNESS_LOW_BATTERY) { - brightness = Power.BRIGHTNESS_LOW_BATTERY; + brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) { + brightness = PowerManager.BRIGHTNESS_LOW_BATTERY; } if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask); setLightBrightness(dimMask, brightness); @@ -2115,8 +2142,8 @@ public class PowerManagerService extends IPowerManager.Stub if (onMask != 0) { int brightness = getPreferredBrightness(); if ((newState & BATTERY_LOW_BIT) != 0 && - brightness > Power.BRIGHTNESS_LOW_BATTERY) { - brightness = Power.BRIGHTNESS_LOW_BATTERY; + brightness > PowerManager.BRIGHTNESS_LOW_BATTERY) { + brightness = PowerManager.BRIGHTNESS_LOW_BATTERY; } if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask); setLightBrightness(onMask, brightness); @@ -2198,8 +2225,8 @@ public class PowerManagerService extends IPowerManager.Stub if (elapsed < duration) { int delta = endValue - startValue; newValue = startValue + delta * elapsed / duration; - newValue = Math.max(Power.BRIGHTNESS_OFF, newValue); - newValue = Math.min(Power.BRIGHTNESS_ON, newValue); + newValue = Math.max(PowerManager.BRIGHTNESS_OFF, newValue); + newValue = Math.min(PowerManager.BRIGHTNESS_ON, newValue); } else { newValue = endValue; mInitialAnimation = false; @@ -2249,7 +2276,7 @@ public class PowerManagerService extends IPowerManager.Stub if (target != currentValue) { final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0; - final boolean turningOff = endValue == Power.BRIGHTNESS_OFF; + final boolean turningOff = endValue == PowerManager.BRIGHTNESS_OFF; if (turningOff && doScreenAnim) { // Cancel all pending animations since we're turning off mScreenBrightnessHandler.removeCallbacksAndMessages(null); @@ -2353,7 +2380,7 @@ public class PowerManagerService extends IPowerManager.Stub private boolean isScreenTurningOffLocked() { return (mScreenBrightnessAnimator.isAnimating() - && mScreenBrightnessAnimator.endValue == Power.BRIGHTNESS_OFF); + && mScreenBrightnessAnimator.endValue == PowerManager.BRIGHTNESS_OFF); } private boolean shouldLog(long time) { diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/java/com/android/server/ShutdownActivity.java index c9d4d01..d85abe6 100644 --- a/services/java/com/android/server/ShutdownActivity.java +++ b/services/java/com/android/server/ShutdownActivity.java @@ -22,7 +22,8 @@ import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.util.Slog; -import com.android.internal.app.ShutdownThread; + +import com.android.server.pm.ShutdownThread; public class ShutdownActivity extends Activity { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 849281d..d9833ab 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -46,7 +46,6 @@ import android.util.Log; import android.util.Slog; import android.view.WindowManager; -import com.android.internal.app.ShutdownThread; import com.android.internal.os.BinderInternal; import com.android.internal.os.SamplingProfilerIntegration; import com.android.internal.widget.LockSettingsService; @@ -56,6 +55,7 @@ import com.android.server.input.InputManagerService; import com.android.server.net.NetworkPolicyManagerService; import com.android.server.net.NetworkStatsService; import com.android.server.pm.PackageManagerService; +import com.android.server.pm.ShutdownThread; import com.android.server.usb.UsbService; import com.android.server.wm.WindowManagerService; diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/services/java/com/android/server/pm/ShutdownThread.java index d867ff9..1d6e068 100644 --- a/core/java/com/android/internal/app/ShutdownThread.java +++ b/services/java/com/android/server/pm/ShutdownThread.java @@ -15,7 +15,7 @@ */ -package com.android.internal.app; +package com.android.server.pm; import android.app.ActivityManagerNative; import android.app.AlertDialog; @@ -32,7 +32,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; -import android.os.Power; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; @@ -44,6 +43,8 @@ import android.os.storage.IMountService; import android.os.storage.IMountShutdownObserver; import com.android.internal.telephony.ITelephony; +import com.android.server.PowerManagerService; + import android.util.Log; import android.view.WindowManager; @@ -456,7 +457,7 @@ public final class ShutdownThread extends Thread { if (reboot) { Log.i(TAG, "Rebooting, reason: " + reason); try { - Power.reboot(reason); + PowerManagerService.lowLevelReboot(reason); } catch (Exception e) { Log.e(TAG, "Reboot failed, will attempt shutdown instead", e); } @@ -479,6 +480,6 @@ public final class ShutdownThread extends Thread { // Shutdown power Log.i(TAG, "Performing low-level shutdown..."); - Power.shutdown(); + PowerManagerService.lowLevelShutdown(); } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 2efcb8e..8c917c1 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -34,7 +34,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import com.android.internal.app.IBatteryStats; -import com.android.internal.app.ShutdownThread; import com.android.internal.policy.PolicyManager; import com.android.internal.policy.impl.PhoneWindowManager; import com.android.internal.view.IInputContext; @@ -48,6 +47,7 @@ import com.android.server.Watchdog; import com.android.server.am.BatteryStatsService; import com.android.server.input.InputFilter; import com.android.server.input.InputManagerService; +import com.android.server.pm.ShutdownThread; import android.Manifest; import android.app.ActivityManagerNative; @@ -82,7 +82,6 @@ import android.os.Looper; import android.os.Message; import android.os.Parcel; import android.os.ParcelFileDescriptor; -import android.os.Power; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; @@ -3222,28 +3221,23 @@ public class WindowManagerService extends IWindowManager.Stub // Entering app zooms out from the center of the thumbnail. float scaleW = thumbWidth / mAppDisplayWidth; float scaleH = thumbHeight / mAppDisplayHeight; - AnimationSet set = new AnimationSet(true); Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1, computePivot(mNextAppTransitionStartX, scaleW), computePivot(mNextAppTransitionStartY, scaleH)); scale.setDuration(duration); scale.setFillBefore(true); - set.addAnimation(scale); - // Need to set an alpha animation on the entering app window - // in case it appears one frame before the thumbnail window - // (this solves flicker) - Animation alpha = new AlphaAnimation(0, 1); - alpha.setDuration(1); - alpha.setFillAfter(true); - set.addAnimation(alpha); - a = set; if (delayDuration > 0) { - a.setStartOffset(delayDuration); + scale.setStartOffset(delayDuration); } + a = scale; } else { - a = createExitAnimationLocked(transit, duration); - if (delayDuration > 0) { - a.setStartOffset(delayDuration); + if (delayed) { + a = new AlphaAnimation(1, 0); + a.setStartOffset(0); + a.setDuration(delayDuration - 50); + a.setBackgroundColor(0xFF000000); + } else { + a = createExitAnimationLocked(transit, duration); } } a.setFillAfter(true); @@ -5025,6 +5019,18 @@ public class WindowManagerService extends IWindowManager.Stub return mInputManager.monitorInput(inputChannelName); } + // Called by window manager policy. Not exposed externally. + @Override + public void shutdown() { + ShutdownThread.shutdown(mContext, true); + } + + // Called by window manager policy. Not exposed externally. + @Override + public void rebootSafeMode() { + ShutdownThread.rebootSafeMode(mContext, true); + } + public void setInputFilter(InputFilter filter) { mInputManager.setInputFilter(filter); } @@ -8700,13 +8706,13 @@ public class WindowManagerService extends IWindowManager.Stub mPowerManager.setScreenBrightnessOverride(-1); } else { mPowerManager.setScreenBrightnessOverride((int) - (mInnerFields.mScreenBrightness * Power.BRIGHTNESS_ON)); + (mInnerFields.mScreenBrightness * PowerManager.BRIGHTNESS_ON)); } if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) { mPowerManager.setButtonBrightnessOverride(-1); } else { mPowerManager.setButtonBrightnessOverride((int) - (mInnerFields.mButtonBrightness * Power.BRIGHTNESS_ON)); + (mInnerFields.mButtonBrightness * PowerManager.BRIGHTNESS_ON)); } } if (mInnerFields.mHoldScreen != mHoldingScreenOn) { diff --git a/services/jni/Android.mk b/services/jni/Android.mk index e2bd622..e0a14af 100644 --- a/services/jni/Android.mk +++ b/services/jni/Android.mk @@ -23,7 +23,10 @@ LOCAL_C_INCLUDES += \ frameworks/base/services \ frameworks/base/core/jni \ external/skia/include/core \ - libcore/include + libcore/include \ + libcore/include/libsuspend \ + $(call include-path-for, libhardware)/hardware \ + $(call include-path-for, libhardware_legacy)/hardware_legacy \ LOCAL_SHARED_LIBRARIES := \ libandroid_runtime \ @@ -38,7 +41,8 @@ LOCAL_SHARED_LIBRARIES := \ libinput \ libskia \ libgui \ - libusbhost + libusbhost \ + libsuspend ifeq ($(WITH_MALLOC_LEAK_CHECK),true) LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp index ce80c1f..a47f8fd 100644 --- a/services/jni/com_android_server_PowerManagerService.cpp +++ b/services/jni/com_android_server_PowerManagerService.cpp @@ -24,8 +24,14 @@ #include <limits.h> #include <android_runtime/AndroidRuntime.h> -#include <utils/Timers.h> #include <gui/ISurfaceComposer.h> +#include <utils/Timers.h> +#include <utils/misc.h> +#include <utils/String8.h> +#include <hardware/power.h> +#include <hardware_legacy/power.h> +#include <cutils/android_reboot.h> +#include <suspend/autosuspend.h> #include <private/gui/ComposerService.h> @@ -43,6 +49,7 @@ static struct { // ---------------------------------------------------------------------------- static jobject gPowerManagerServiceObj; +static struct power_module* gPowerModule; static Mutex gPowerManagerLock; static bool gScreenOn; @@ -76,6 +83,13 @@ bool android_server_PowerManagerService_isScreenBright() { } void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) { + if (gPowerModule) { + // Tell the power HAL when user activity occurs. + if (gPowerModule->powerHint) { + gPowerModule->powerHint(gPowerModule, POWER_HINT_INTERACTION, NULL); + } + } + if (gPowerManagerServiceObj) { // Throttle calls into user activity by event type. // We're a little conservative about argument checking here in case the caller @@ -112,33 +126,115 @@ void android_server_PowerManagerService_goToSleep(nsecs_t eventTime) { // ---------------------------------------------------------------------------- -static void android_server_PowerManagerService_nativeInit(JNIEnv* env, jobject obj) { +static void nativeInit(JNIEnv* env, jobject obj) { gPowerManagerServiceObj = env->NewGlobalRef(obj); + + status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID, + (hw_module_t const**)&gPowerModule); + if (err) { + String8 msg; + msg.appendFormat("Couldn't load %s module (%s)", + POWER_HARDWARE_MODULE_ID, strerror(-err)); + ALOGE("%s", msg.string()); + jniThrowRuntimeException(env, msg.string()); + return; + } + + gPowerModule->init(gPowerModule); } -static void android_server_PowerManagerService_nativeSetPowerState(JNIEnv* env, +static void nativeSetPowerState(JNIEnv* env, jobject serviceObj, jboolean screenOn, jboolean screenBright) { AutoMutex _l(gPowerManagerLock); gScreenOn = screenOn; gScreenBright = screenBright; } -static void android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation(JNIEnv* env, +static void nativeStartSurfaceFlingerAnimation(JNIEnv* env, jobject obj, jint mode) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); s->turnElectronBeamOff(mode); } +static void nativeAcquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj) { + if (idObj == NULL) { + jniThrowNullPointerException(env, "id is null"); + return; + } + + const char *id = env->GetStringUTFChars(idObj, NULL); + + acquire_wake_lock(lock, id); + + env->ReleaseStringUTFChars(idObj, id); +} + +static void nativeReleaseWakeLock(JNIEnv *env, jobject clazz, jstring idObj) { + if (idObj == NULL) { + jniThrowNullPointerException(env, "id is null"); + return ; + } + + const char *id = env->GetStringUTFChars(idObj, NULL); + + release_wake_lock(id); + + env->ReleaseStringUTFChars(idObj, id); + +} + +static int nativeSetScreenState(JNIEnv *env, jobject clazz, jboolean on) { + if (on) { + autosuspend_disable(); + if (gPowerModule) { + gPowerModule->setInteractive(gPowerModule, true); + } + } else { + if (gPowerModule) { + gPowerModule->setInteractive(gPowerModule, false); + } + autosuspend_enable(); + } + + return 0; +} + +static void nativeShutdown(JNIEnv *env, jobject clazz) { + android_reboot(ANDROID_RB_POWEROFF, 0, 0); +} + +static void nativeReboot(JNIEnv *env, jobject clazz, jstring reason) { + if (reason == NULL) { + android_reboot(ANDROID_RB_RESTART, 0, 0); + } else { + const char *chars = env->GetStringUTFChars(reason, NULL); + android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars); + env->ReleaseStringUTFChars(reason, chars); // In case it fails. + } + jniThrowIOException(env, errno); +} + + // ---------------------------------------------------------------------------- static JNINativeMethod gPowerManagerServiceMethods[] = { /* name, signature, funcPtr */ { "nativeInit", "()V", - (void*) android_server_PowerManagerService_nativeInit }, + (void*) nativeInit }, { "nativeSetPowerState", "(ZZ)V", - (void*) android_server_PowerManagerService_nativeSetPowerState }, + (void*) nativeSetPowerState }, { "nativeStartSurfaceFlingerAnimation", "(I)V", - (void*) android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation }, + (void*) nativeStartSurfaceFlingerAnimation }, + { "nativeAcquireWakeLock", "(ILjava/lang/String;)V", + (void*) nativeAcquireWakeLock }, + { "nativeReleaseWakeLock", "(Ljava/lang/String;)V", + (void*) nativeReleaseWakeLock }, + { "nativeSetScreenState", "(Z)I", + (void*) nativeSetScreenState }, + { "nativeShutdown", "()V", + (void*) nativeShutdown }, + { "nativeReboot", "(Ljava/lang/String;)V", + (void*) nativeReboot }, }; #define FIND_CLASS(var, className) \ @@ -175,6 +271,8 @@ int register_android_server_PowerManagerService(JNIEnv* env) { } gScreenOn = true; gScreenBright = true; + gPowerManagerServiceObj = NULL; + gPowerModule = NULL; return 0; } diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java index 92024cd..d738d7b 100644 --- a/telephony/java/com/android/internal/telephony/IccCard.java +++ b/telephony/java/com/android/internal/telephony/IccCard.java @@ -26,7 +26,6 @@ import android.content.res.Resources; import android.os.AsyncResult; import android.os.Handler; import android.os.Message; -import android.os.Power; import android.os.PowerManager; import android.os.Registrant; import android.os.RegistrantList; |
