diff options
Diffstat (limited to 'services/java/com')
4 files changed, 119 insertions, 58 deletions
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index c18fe0e..e7e4f87 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -304,6 +304,8 @@ class AppWidgetService extends IAppWidgetService.Stub @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); + // Dump the state of all the app widget providers synchronized (mAppWidgetServices) { IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index c5016e6..6948927 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -609,10 +609,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } /** - * Throw SecurityException if caller has neither COARSE or FINE. - * Otherwise, return the best permission. + * Returns the best permission available to the caller. */ - private String checkPermission() { + private String getBestCallingPermission() { if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { return ACCESS_FINE_LOCATION; @@ -620,9 +619,20 @@ public class LocationManagerService extends ILocationManager.Stub implements Run PackageManager.PERMISSION_GRANTED) { return ACCESS_COARSE_LOCATION; } + return null; + } - throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" + - " ACCESS_FINE_LOCATION permission"); + /** + * Throw SecurityException if caller has neither COARSE or FINE. + * Otherwise, return the best permission. + */ + private String checkPermission() { + String perm = getBestCallingPermission(); + if (perm == null) { + throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" + + " ACCESS_FINE_LOCATION permission"); + } + return perm; } /** @@ -635,19 +645,15 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } } - private boolean isAllowedProviderSafe(String provider) { + private String getMinimumPermissionForProvider(String provider) { if (LocationManager.GPS_PROVIDER.equals(provider) || LocationManager.PASSIVE_PROVIDER.equals(provider)) { // gps and passive providers require FINE permission - return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED; + return ACCESS_FINE_LOCATION; } else if (LocationManager.NETWORK_PROVIDER.equals(provider) || LocationManager.FUSED_PROVIDER.equals(provider)) { // network and fused providers are ok with COARSE or FINE - return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED) || - (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) - == PackageManager.PERMISSION_GRANTED); + return ACCESS_COARSE_LOCATION; } else { // mock providers LocationProviderInterface lp = mMockProviders.get(provider); @@ -656,20 +662,43 @@ public class LocationManagerService extends ILocationManager.Stub implements Run if (properties != null) { if (properties.mRequiresSatellite) { // provider requiring satellites require FINE permission - return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED; + return ACCESS_FINE_LOCATION; } 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 ACCESS_COARSE_LOCATION; } } } } - return false; + return null; + } + + private boolean isPermissionSufficient(String perm, String minPerm) { + if (ACCESS_FINE_LOCATION.equals(minPerm)) { + return ACCESS_FINE_LOCATION.equals(perm); + } else if (ACCESS_COARSE_LOCATION.equals(minPerm)) { + return ACCESS_FINE_LOCATION.equals(perm) || + ACCESS_COARSE_LOCATION.equals(perm); + } else { + return false; + } + } + + private void checkPermissionForProvider(String perm, String provider) { + String minPerm = getMinimumPermissionForProvider(provider); + if (!isPermissionSufficient(perm, minPerm)) { + if (ACCESS_FINE_LOCATION.equals(minPerm)) { + throw new SecurityException("Location provider \"" + provider + + "\" requires ACCESS_FINE_LOCATION permission."); + } else if (ACCESS_COARSE_LOCATION.equals(minPerm)) { + throw new SecurityException("Location provider \"" + provider + + "\" requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission."); + } else { + throw new SecurityException("Insufficient permission for location provider \"" + + provider + "\"."); + } + } } /** @@ -703,6 +732,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run @Override public List<String> getProviders(Criteria criteria, boolean enabledOnly) { ArrayList<String> out; + String perm = getBestCallingPermission(); int callingUserId = UserHandle.getCallingUserId(); long identity = Binder.clearCallingIdentity(); try { @@ -713,7 +743,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run if (LocationManager.FUSED_PROVIDER.equals(name)) { continue; } - if (isAllowedProviderSafe(name)) { + if (isPermissionSufficient(perm, getMinimumPermissionForProvider(name))) { if (enabledOnly && !isAllowedBySettingsLocked(name, callingUserId)) { continue; } @@ -980,26 +1010,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run return receiver; } - private boolean isProviderAllowedByCoarsePermission(String provider) { - if (LocationManager.FUSED_PROVIDER.equals(provider)) { - return true; - } - if (LocationManager.PASSIVE_PROVIDER.equals(provider)) { - return true; - } - if (LocationManager.NETWORK_PROVIDER.equals(provider)) { - return true; - } - return false; - } - private String checkPermissionAndRequest(LocationRequest request) { - String perm = checkPermission(); + String perm = getBestCallingPermission(); + String provider = request.getProvider(); + checkPermissionForProvider(perm, provider); if (ACCESS_COARSE_LOCATION.equals(perm)) { - if (!isProviderAllowedByCoarsePermission(request.getProvider())) { - throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); - } switch (request.getQuality()) { case LocationRequest.ACCURACY_FINE: request.setQuality(LocationRequest.ACCURACY_BLOCK); @@ -1324,7 +1340,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run */ @Override public ProviderProperties getProviderProperties(String provider) { - checkPermission(); + checkPermissionForProvider(getBestCallingPermission(), provider); LocationProviderInterface p; synchronized (mLock) { @@ -1337,13 +1353,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run @Override public boolean isProviderEnabled(String provider) { - String perms = checkPermission(); + checkPermissionForProvider(getBestCallingPermission(), provider); if (LocationManager.FUSED_PROVIDER.equals(provider)) return false; - if (ACCESS_COARSE_LOCATION.equals(perms) && - !isProviderAllowedByCoarsePermission(provider)) { - throw new SecurityException("The \"" + provider + - "\" provider requires ACCESS_FINE_LOCATION permission"); - } long identity = Binder.clearCallingIdentity(); try { diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java index 3e541dd..c441b02 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -198,6 +198,12 @@ final class WifiDisplayAdapter extends DisplayAdapter { updateRememberedDisplaysLocked(); scheduleStatusChangedBroadcastLocked(); } + + if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address) + && mDisplayDevice != null) { + mDisplayDevice.setNameLocked(mActiveDisplay.getFriendlyDisplayName()); + sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED); + } } public void requestForgetLocked(String address) { @@ -397,7 +403,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { }; private final class WifiDisplayDevice extends DisplayDevice { - private final String mName; + private String mName; private final int mWidth; private final int mHeight; private final float mRefreshRate; @@ -423,6 +429,11 @@ final class WifiDisplayAdapter extends DisplayAdapter { sendTraversalRequestLocked(); } + public void setNameLocked(String name) { + mName = name; + mInfo = null; + } + @Override public void performTraversalInTransactionLocked() { setSurfaceInTransactionLocked(mSurface); diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java index b76ad45..4e692a2 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/java/com/android/server/power/PowerManagerService.java @@ -162,6 +162,11 @@ public final class PowerManagerService extends IPowerManager.Stub // Poll interval in milliseconds for watching boot animation finished. private static final int BOOT_ANIMATION_POLL_INTERVAL = 200; + // If the battery level drops by this percentage and the user activity timeout + // has expired, then assume the device is receiving insufficient current to charge + // effectively and terminate the dream. + private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5; + private Context mContext; private LightsService mLightsService; private BatteryService mBatteryService; @@ -256,6 +261,14 @@ public final class PowerManagerService extends IPowerManager.Stub // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS. private int mPlugType; + // The current battery level percentage. + private int mBatteryLevel; + + // The battery level percentage at the time the dream started. + // This is used to terminate a dream and go to sleep if the battery is + // draining faster than it is charging and the user activity timeout has expired. + private int mBatteryLevelWhenDreamStarted; + // True if the device should wake up when plugged or unplugged. private boolean mWakeUpWhenPluggedOrUnpluggedConfig; @@ -1067,12 +1080,14 @@ public final class PowerManagerService extends IPowerManager.Stub final int oldPlugType = mPlugType; mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); mPlugType = mBatteryService.getPlugType(); + mBatteryLevel = mBatteryService.getBatteryLevel(); if (DEBUG) { Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered + ", mIsPowered=" + mIsPowered + ", oldPlugType=" + oldPlugType - + ", mPlugType=" + mPlugType); + + ", mPlugType=" + mPlugType + + ", mBatteryLevel=" + mBatteryLevel); } if (wasPowered != mIsPowered || oldPlugType != mPlugType) { @@ -1126,8 +1141,7 @@ public final class PowerManagerService extends IPowerManager.Stub } if (!wasPowered && mIsPowered && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS - && mBatteryService.getBatteryLevel() >= - WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) { + && mBatteryLevel >= WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) { return false; } @@ -1403,7 +1417,7 @@ public final class PowerManagerService extends IPowerManager.Stub mSandmanScheduled = false; boolean canDream = canDreamLocked(); if (DEBUG_SPEW) { - Log.d(TAG, "handleSandman: canDream=" + canDream + Slog.d(TAG, "handleSandman: canDream=" + canDream + ", mWakefulness=" + wakefulnessToString(mWakefulness)); } @@ -1431,10 +1445,24 @@ public final class PowerManagerService extends IPowerManager.Stub if (mWakefulness == WAKEFULNESS_NAPPING) { mWakefulness = WAKEFULNESS_DREAMING; mDirty |= DIRTY_WAKEFULNESS; + mBatteryLevelWhenDreamStarted = mBatteryLevel; updatePowerStateLocked(); continueDreaming = true; } else if (mWakefulness == WAKEFULNESS_DREAMING) { - continueDreaming = true; + if (!isBeingKeptAwakeLocked() + && mBatteryLevel < mBatteryLevelWhenDreamStarted + - DREAM_BATTERY_LEVEL_DRAIN_CUTOFF) { + // If the user activity timeout expired and the battery appears + // to be draining faster than it is charging then stop dreaming + // and go to sleep. + Slog.i(TAG, "Stopping dream because the battery appears to " + + "be draining faster than it is charging. " + + "Battery level when dream started: " + + mBatteryLevelWhenDreamStarted + "%. " + + "Battery level now: " + mBatteryLevel + "%."); + } else { + continueDreaming = true; + } } } if (!continueDreaming) { @@ -1704,8 +1732,11 @@ public final class PowerManagerService extends IPowerManager.Stub } /** - * Reboot the device, passing 'reason' (may be null) - * to the underlying __reboot system call. Should not return. + * Reboots the device. + * + * @param confirm If true, shows a reboot confirmation dialog. + * @param reason The reason for the reboot, or null if none. + * @param wait If true, this call waits for the reboot to complete and does not return. */ @Override // Binder call public void reboot(boolean confirm, String reason, boolean wait) { @@ -1713,15 +1744,17 @@ public final class PowerManagerService extends IPowerManager.Stub final long ident = Binder.clearCallingIdentity(); try { - rebootInternal(false, confirm, reason, wait); + shutdownOrRebootInternal(false, confirm, reason, wait); } finally { Binder.restoreCallingIdentity(ident); } } /** - * Shutdown the devic, passing 'reason' (may be null) - * to the underlying __reboot system call. Should not return. + * Shuts down the device. + * + * @param confirm If true, shows a shutdown confirmation dialog. + * @param wait If true, this call waits for the shutdown to complete and does not return. */ @Override // Binder call public void shutdown(boolean confirm, boolean wait) { @@ -1729,19 +1762,20 @@ public final class PowerManagerService extends IPowerManager.Stub final long ident = Binder.clearCallingIdentity(); try { - rebootInternal(true, confirm, null, wait); + shutdownOrRebootInternal(true, confirm, null, wait); } finally { Binder.restoreCallingIdentity(ident); } } - private void rebootInternal(final boolean shutdown, final boolean confirm, + private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm, final String reason, boolean wait) { if (mHandler == null || !mSystemReady) { - throw new IllegalStateException("Too early to call reboot()"); + throw new IllegalStateException("Too early to call shutdown() or reboot()"); } Runnable runnable = new Runnable() { + @Override public void run() { synchronized (this) { if (shutdown) { @@ -1789,6 +1823,7 @@ public final class PowerManagerService extends IPowerManager.Stub private void crashInternal(final String message) { Thread t = new Thread("PowerManagerService.crash()") { + @Override public void run() { throw new RuntimeException(message); } @@ -2087,6 +2122,8 @@ public final class PowerManagerService extends IPowerManager.Stub pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness)); pw.println(" mIsPowered=" + mIsPowered); pw.println(" mPlugType=" + mPlugType); + pw.println(" mBatteryLevel=" + mBatteryLevel); + pw.println(" mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted); pw.println(" mStayOn=" + mStayOn); pw.println(" mProximityPositive=" + mProximityPositive); pw.println(" mBootCompleted=" + mBootCompleted); |