Merge "MediaRouter/Wireless Display - correct initial state" into jb-mr1-dev
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index fb02c0a..7e11c22 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -178,6 +178,16 @@
/**
* Wake lock level: Turns the screen off when the proximity sensor activates.
* <p>
+ * If the proximity sensor detects that an object is nearby, the screen turns off
+ * immediately. Shortly after the object moves away, the screen turns on again.
+ * </p><p>
+ * A proximity wake lock does not prevent the device from falling asleep
+ * unlike {@link #FULL_WAKE_LOCK}, {@link #SCREEN_BRIGHT_WAKE_LOCK} and
+ * {@link #SCREEN_DIM_WAKE_LOCK}. If there is no user activity and no other
+ * wake locks are held, then the device will fall asleep (and lock) as usual.
+ * However, the device will not fall asleep while the screen has been turned off
+ * by the proximity sensor because it effectively counts as ongoing user activity.
+ * </p><p>
* Since not all devices have proximity sensors, use {@link #isWakeLockLevelSupported}
* to determine whether this wake lock level is supported.
* </p>
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index f4f7b09..cb291ea 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -369,7 +369,15 @@
* @return the same object, so that setters can be chained
*/
public LocationRequest setExpireIn(long millis) {
- mExpireAt = millis + SystemClock.elapsedRealtime();
+ long elapsedRealtime = SystemClock.elapsedRealtime();
+
+ // Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
+ if (millis > Long.MAX_VALUE - elapsedRealtime) {
+ mExpireAt = Long.MAX_VALUE;
+ } else {
+ mExpireAt = millis + elapsedRealtime;
+ }
+
if (mExpireAt < 0) mExpireAt = 0;
return this;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 1701f6e..76a5022 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -849,7 +849,6 @@
if (TABLE_FAVORITES.equals(args.table)) {
return null;
}
- checkWritePermissions(args);
// Special case LOCATION_PROVIDERS_ALLOWED.
// Support enabling/disabling a single provider (using "+" or "-" prefix)
@@ -869,6 +868,9 @@
}
}
+ // Check write permissions only after determining which table the insert will touch
+ checkWritePermissions(args);
+
// The global table is stored under the owner, always
if (TABLE_GLOBAL.equals(args.table)) {
desiredUserHandle = UserHandle.USER_OWNER;
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 3cea295..0087b57 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -325,6 +325,7 @@
* @param userId the new active user's UserId
*/
private void switchUser(int userId) {
+ mBlacklist.switchUser(userId);
//Log.d("LocationManagerService", "switchUser(" + mCurrentUserId + " -> " + userId + ")"); // TODO: remove this
synchronized (mLock) {
// TODO: inform previous user's Receivers that they will no longer receive updates
@@ -639,7 +640,27 @@
== PackageManager.PERMISSION_GRANTED) ||
(mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED);
+ } else {
+ // mock providers
+ LocationProviderInterface lp = mMockProviders.get(provider);
+ if (lp != null) {
+ ProviderProperties properties = lp.getProperties();
+ if (properties != null) {
+ if (properties.mRequiresSatellite) {
+ // provider requiring satellites require FINE permission
+ return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED;
+ } else if (properties.mRequiresNetwork || properties.mRequiresCell) {
+ // provider requiring network and or cell require COARSE or FINE
+ return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED) ||
+ (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED);
+ }
+ }
+ }
}
+
return false;
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 4225913..98f561c 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -38,6 +38,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.os.Binder;
import android.os.Bundle;
@@ -53,6 +54,7 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.os.UserManager;
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
import android.service.wallpaper.IWallpaperService;
@@ -511,6 +513,9 @@
wallpaper = new WallpaperData(userId);
mWallpaperMap.put(userId, wallpaper);
loadSettingsLocked(userId);
+ }
+ // Not started watching yet, in case wallpaper data was loaded for other reasons.
+ if (wallpaper.wallpaperObserver == null) {
wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
wallpaper.wallpaperObserver.startWatching();
}
@@ -580,9 +585,21 @@
public boolean hasNamedWallpaper(String name) {
synchronized (mLock) {
- for (int i=0; i<mWallpaperMap.size(); i++) {
- WallpaperData wd = mWallpaperMap.valueAt(i);
- if (name.equals(wd.name)) {
+ List<UserInfo> users;
+ long ident = Binder.clearCallingIdentity();
+ try {
+ users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE)).getUsers();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ for (UserInfo user: users) {
+ WallpaperData wd = mWallpaperMap.get(user.id);
+ if (wd == null) {
+ // User hasn't started yet, so load her settings to peek at the wallpaper
+ loadSettingsLocked(user.id);
+ wd = mWallpaperMap.get(user.id);
+ }
+ if (wd != null && name.equals(wd.name)) {
return true;
}
}
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index b38d617..e4a7ead 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -454,7 +454,8 @@
if (mTetheredNotification.icon == icon) {
return;
}
- notificationManager.cancel(mTetheredNotification.icon);
+ notificationManager.cancelAsUser(null, mTetheredNotification.icon,
+ UserHandle.ALL);
}
Intent intent = new Intent();
diff --git a/services/java/com/android/server/location/LocationBlacklist.java b/services/java/com/android/server/location/LocationBlacklist.java
index 6ad1a92e..2437a37 100644
--- a/services/java/com/android/server/location/LocationBlacklist.java
+++ b/services/java/com/android/server/location/LocationBlacklist.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.database.ContentObserver;
import android.os.Handler;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
@@ -48,6 +49,8 @@
// all fields below synchronized on mLock
private String[] mWhitelist = new String[0];
private String[] mBlacklist = new String[0];
+
+ private int mCurrentUserId = UserHandle.USER_OWNER;
public LocationBlacklist(Context context, Handler handler) {
super(handler);
@@ -56,20 +59,22 @@
public void init() {
mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
- BLACKLIST_CONFIG_NAME), false, this);
+ BLACKLIST_CONFIG_NAME), false, this, UserHandle.USER_ALL);
// mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
-// WHITELIST_CONFIG_NAME), false, this);
+// WHITELIST_CONFIG_NAME), false, this, UserHandle.USER_ALL);
reloadBlacklist();
}
+ private void reloadBlacklistLocked() {
+ mWhitelist = getStringArrayLocked(WHITELIST_CONFIG_NAME);
+ Slog.i(TAG, "whitelist: " + Arrays.toString(mWhitelist));
+ mBlacklist = getStringArrayLocked(BLACKLIST_CONFIG_NAME);
+ Slog.i(TAG, "blacklist: " + Arrays.toString(mBlacklist));
+ }
+
private void reloadBlacklist() {
- String blacklist[] = getStringArray(BLACKLIST_CONFIG_NAME);
- String whitelist[] = getStringArray(WHITELIST_CONFIG_NAME);
synchronized (mLock) {
- mWhitelist = whitelist;
- Slog.i(TAG, "whitelist: " + Arrays.toString(mWhitelist));
- mBlacklist = blacklist;
- Slog.i(TAG, "blacklist: " + Arrays.toString(mBlacklist));
+ reloadBlacklistLocked();
}
}
@@ -78,7 +83,6 @@
* (package name matches blacklist, and does not match whitelist)
*/
public boolean isBlacklisted(String packageName) {
- /*
synchronized (mLock) {
for (String black : mBlacklist) {
if (packageName.startsWith(black)) {
@@ -92,7 +96,6 @@
}
}
}
- */
return false;
}
@@ -113,8 +116,19 @@
reloadBlacklist();
}
- private String[] getStringArray(String key) {
- String flatString = Settings.Secure.getString(mContext.getContentResolver(), key);
+ public void switchUser(int userId) {
+ synchronized(mLock) {
+ mCurrentUserId = userId;
+ reloadBlacklistLocked();
+ }
+ }
+
+ private String[] getStringArrayLocked(String key) {
+ String flatString;
+ synchronized(mLock) {
+ flatString = Settings.Secure.getStringForUser(mContext.getContentResolver(), key,
+ mCurrentUserId);
+ }
if (flatString == null) {
return new String[0];
}
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index 4f8cdde..d0e758f 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -117,8 +117,9 @@
private static final int PROXIMITY_NEGATIVE = 0;
private static final int PROXIMITY_POSITIVE = 1;
- // Proximity sensor debounce delay in milliseconds.
- private static final int PROXIMITY_SENSOR_DEBOUNCE_DELAY = 250;
+ // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
+ private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
+ private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 500;
// Trigger proximity if distance is less than 5 cm.
private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
@@ -562,6 +563,7 @@
if (!mScreenOffBecauseOfProximity
&& mProximity == PROXIMITY_POSITIVE) {
mScreenOffBecauseOfProximity = true;
+ sendOnProximityPositive();
setScreenOn(false);
}
} else if (mWaitingForNegativeProximity
@@ -734,8 +736,13 @@
// Only accept a proximity sensor reading if it remains
// stable for the entire debounce delay.
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
- mPendingProximity = positive ? PROXIMITY_POSITIVE : PROXIMITY_NEGATIVE;
- mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_DEBOUNCE_DELAY;
+ if (positive) {
+ mPendingProximity = PROXIMITY_POSITIVE;
+ mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
+ } else {
+ mPendingProximity = PROXIMITY_NEGATIVE;
+ mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
+ }
debounceProximitySensor();
}
@@ -973,6 +980,17 @@
}
};
+ private void sendOnProximityPositive() {
+ mCallbackHandler.post(mOnProximityPositiveRunnable);
+ }
+
+ private final Runnable mOnProximityPositiveRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mCallbacks.onProximityPositive();
+ }
+ };
+
private void sendOnProximityNegative() {
mCallbackHandler.post(mOnProximityNegativeRunnable);
}
@@ -1090,6 +1108,7 @@
*/
public interface Callbacks {
void onStateChanged();
+ void onProximityPositive();
void onProximityNegative();
}
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 9a01022..eecac07 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -98,6 +98,8 @@
private static final int DIRTY_STAY_ON = 1 << 7;
// Dirty bit: battery state changed
private static final int DIRTY_BATTERY_STATE = 1 << 8;
+ // Dirty bit: proximity state changed
+ private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
// Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
// The screen should be off or in the process of being turned off by the display controller.
@@ -258,6 +260,9 @@
// True if the device should stay on.
private boolean mStayOn;
+ // True if the proximity sensor reads a positive result.
+ private boolean mProximityPositive;
+
// Screen brightness setting limits.
private int mScreenBrightnessSettingMinimum;
private int mScreenBrightnessSettingMaximum;
@@ -1101,12 +1106,17 @@
*/
private void updateStayOnLocked(int dirty) {
if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
+ final boolean wasStayOn = mStayOn;
if (mStayOnWhilePluggedInSetting != 0
&& !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
mStayOn = mBatteryService.isPowered(mStayOnWhilePluggedInSetting);
} else {
mStayOn = false;
}
+
+ if (mStayOn != wasStayOn) {
+ mDirty |= DIRTY_STAY_ON;
+ }
}
}
@@ -1265,7 +1275,7 @@
private boolean updateWakefulnessLocked(int dirty) {
boolean changed = false;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
- | DIRTY_WAKEFULNESS | DIRTY_STAY_ON)) != 0) {
+ | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE)) != 0) {
if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
@@ -1288,17 +1298,17 @@
* to being fully awake or else go to sleep for good.
*/
private boolean isItBedTimeYetLocked() {
- return mBootCompleted && !isScreenBeingKeptOnLocked();
+ return mBootCompleted && !isBeingKeptAwakeLocked();
}
/**
- * Returns true if the screen is being kept on by a wake lock, user activity
+ * Returns true if the device is being kept awake by a wake lock, user activity
* or the stay on while powered setting.
*/
- private boolean isScreenBeingKeptOnLocked() {
+ private boolean isBeingKeptAwakeLocked() {
return mStayOn
- || (mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
- | WAKE_LOCK_PROXIMITY_SCREEN_OFF)) != 0
+ || mProximityPositive
+ || (mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0
|| (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
| USER_ACTIVITY_SCREEN_DIM)) != 0;
}
@@ -1314,6 +1324,7 @@
| DIRTY_SETTINGS
| DIRTY_IS_POWERED
| DIRTY_STAY_ON
+ | DIRTY_PROXIMITY_POSITIVE
| DIRTY_BATTERY_STATE)) != 0) {
scheduleSandmanLocked();
}
@@ -1401,7 +1412,7 @@
&& mDreamsEnabledSetting
&& mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
&& mBootCompleted
- && (mIsPowered || isScreenBeingKeptOnLocked());
+ && (mIsPowered || isBeingKeptAwakeLocked());
}
/**
@@ -1528,7 +1539,16 @@
}
@Override
+ public void onProximityPositive() {
+ mProximityPositive = true;
+ mDirty |= DIRTY_PROXIMITY_POSITIVE;
+ updatePowerStateLocked();
+ }
+
+ @Override
public void onProximityNegative() {
+ mProximityPositive = false;
+ mDirty |= DIRTY_PROXIMITY_POSITIVE;
userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
updatePowerStateLocked();
@@ -1986,6 +2006,7 @@
pw.println(" mIsPowered=" + mIsPowered);
pw.println(" mPlugType=" + mPlugType);
pw.println(" mStayOn=" + mStayOn);
+ pw.println(" mProximityPositive=" + mProximityPositive);
pw.println(" mBootCompleted=" + mBootCompleted);
pw.println(" mSystemReady=" + mSystemReady);
pw.println(" mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));