summaryrefslogtreecommitdiffstats
path: root/services/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java')
-rw-r--r--services/core/java/com/android/server/AnyMotionDetector.java14
-rw-r--r--services/core/java/com/android/server/BatteryService.java286
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java3
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java27
-rw-r--r--services/core/java/com/android/server/DeviceIdleController.java182
-rw-r--r--services/core/java/com/android/server/EventLogTags.logtags10
-rw-r--r--services/core/java/com/android/server/InputMethodManagerService.java65
-rw-r--r--services/core/java/com/android/server/LockSettingsService.java7
-rw-r--r--services/core/java/com/android/server/ThemeService.java1277
-rw-r--r--services/core/java/com/android/server/ThermalObserver.java146
-rw-r--r--services/core/java/com/android/server/VibratorService.java34
-rwxr-xr-xservices/core/java/com/android/server/am/ActiveServices.java67
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java57
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java14
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java114
-rw-r--r--services/core/java/com/android/server/am/LockTaskNotify.java22
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java6
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java27
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java41
-rw-r--r--services/core/java/com/android/server/display/LiveDisplayController.java280
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java3
-rw-r--r--services/core/java/com/android/server/dreams/DreamManagerService.java3
-rw-r--r--services/core/java/com/android/server/location/GpsLocationProvider.java4
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java130
-rw-r--r--[-rwxr-xr-x]services/core/java/com/android/server/notification/NotificationManagerService.java57
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java36
-rw-r--r--services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java25
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java60
-rw-r--r--services/core/java/com/android/server/pm/UserContentObserver.java92
-rw-r--r--services/core/java/com/android/server/policy/BurnInProtectionHelper.java9
-rw-r--r--services/core/java/com/android/server/policy/GlobalActions.java160
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java145
-rw-r--r--services/core/java/com/android/server/policy/WindowOrientationListener.java7
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java73
-rw-r--r--services/core/java/com/android/server/power/ShutdownThread.java3
-rw-r--r--services/core/java/com/android/server/wm/CircularDisplayMask.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java16
-rw-r--r--services/core/java/com/android/server/wm/DisplaySettings.java11
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java9
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java38
40 files changed, 1705 insertions, 1857 deletions
diff --git a/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java
index 6a67316..a0b5c15 100644
--- a/services/core/java/com/android/server/AnyMotionDetector.java
+++ b/services/core/java/com/android/server/AnyMotionDetector.java
@@ -58,9 +58,6 @@ public class AnyMotionDetector {
/** Current measurement state. */
private int mState;
- /** Threshold angle in degrees beyond which the device is considered moving. */
- private final float THRESHOLD_ANGLE = 2f;
-
/** Threshold energy above which the device is considered moving. */
private final float THRESHOLD_ENERGY = 5f;
@@ -88,6 +85,9 @@ public class AnyMotionDetector {
private SensorManager mSensorManager;
private PowerManager.WakeLock mWakeLock;
+ /** Threshold angle in degrees beyond which the device is considered moving. */
+ private final float mThresholdAngle;
+
/** The minimum number of samples required to detect AnyMotion. */
private int mNumSufficientSamples;
@@ -106,7 +106,7 @@ public class AnyMotionDetector {
private DeviceIdleCallback mCallback = null;
public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm,
- DeviceIdleCallback callback) {
+ DeviceIdleCallback callback, float thresholdAngle) {
if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated.");
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.setReferenceCounted(false);
@@ -116,6 +116,7 @@ public class AnyMotionDetector {
mMeasurementInProgress = false;
mState = STATE_INACTIVE;
mCallback = callback;
+ mThresholdAngle = thresholdAngle;
mRunningStats = new RunningSignalStats();
mNumSufficientSamples = (int) Math.ceil(
((double)ORIENTATION_MEASUREMENT_DURATION_MILLIS / SAMPLING_INTERVAL_MILLIS));
@@ -224,8 +225,9 @@ public class AnyMotionDetector {
Vector3 previousGravityVectorNormalized = mPreviousGravityVector.normalized();
Vector3 currentGravityVectorNormalized = mCurrentGravityVector.normalized();
float angle = previousGravityVectorNormalized.angleBetween(currentGravityVectorNormalized);
- if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle);
- if ((angle < THRESHOLD_ANGLE) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) {
+ if (DEBUG) Slog.d(TAG, "getStationaryStatus: angle = " + angle
+ + " energy = " + mRunningStats.getEnergy());
+ if ((angle < mThresholdAngle) && (mRunningStats.getEnergy() < THRESHOLD_ENERGY)) {
return RESULT_STATIONARY;
} else if (Float.isNaN(angle)) {
/**
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 63c3e97..f20cfe9 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +26,7 @@ import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
import android.app.ActivityManagerNative;
+import android.app.IBatteryService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -87,6 +89,21 @@ import cyanogenmod.providers.CMSettings;
* a degree Centigrade</p>
* <p>&quot;technology&quot; - String, the type of battery installed, e.g. "Li-ion"</p>
*
+ * <p>If a dock battery is present, then this Intent data will be present too related
+ * to dock battery information:</p>
+ * <p>&quot;dock_scale&quot; - int, the maximum value for the charge level</p>
+ * <p>&quot;dock_level&quot; - int, charge level, from 0 through &quot;scale&quot; inclusive</p>
+ * <p>&quot;dock_status&quot; - String, the current charging status.<br />
+ * <p>&quot;dock_health&quot; - String, the current battery health.<br />
+ * <p>&quot;dock_present&quot; - boolean, true if the battery is present<br />
+ * <p>&quot;dock_icon-small&quot; - int, suggested small icon to use for this state</p>
+ * <p>&quot;dock_plugged&quot; - int, 0 if the device is not plugged in; 1 if plugged
+ * into an AC power adapter; 2 if plugged in via USB.</p>
+ * <p>&quot;dock_voltage&quot; - int, current battery voltage in millivolts</p>
+ * <p>&quot;dock_temperature&quot; - int, current battery temperature in tenths of
+ * a degree Centigrade</p>
+ * <p>&quot;dock_technology&quot; - String, the type of battery installed, e.g. "Li-ion"</p>
+ *
* <p>
* The battery service may be called by the power manager while holding its locks so
* we take care to post all outcalls into the activity manager to a handler.
@@ -135,6 +152,14 @@ public final class BatteryService extends SystemService {
private boolean mLastBatteryLevelCritical;
private int mLastMaxChargingCurrent;
+ private boolean mDockBatterySupported;
+ private int mLastDockBatteryStatus;
+ private int mLastDockBatteryHealth;
+ private boolean mLastDockBatteryPresent;
+ private int mLastDockBatteryLevel;
+ private int mLastDockBatteryVoltage;
+ private int mLastDockBatteryTemperature;
+
private int mInvalidCharger;
private int mLastInvalidCharger;
@@ -150,8 +175,11 @@ public final class BatteryService extends SystemService {
private int mPlugType;
private int mLastPlugType = -1; // Extra state so we can detect first run
+ private int mDockPlugType;
+ private int mLastDockPlugType = -1; // Extra state so we can detect first run
private boolean mBatteryLevelLow;
+ private boolean mDockBatteryLevelLow;
private long mDischargeStartTime;
private int mDischargeStartLevel;
@@ -180,6 +208,10 @@ public final class BatteryService extends SystemService {
mLed = new Led(context, getLocalService(LightsManager.class));
mBatteryStats = BatteryStatsService.getService();
+ // By default dock battery are not supported. The first events will refresh
+ // this status from the battery property bag
+ mDockBatterySupported = false;
+
mCriticalBatteryLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
mLowBatteryWarningLevel = mContext.getResources().getInteger(
@@ -209,7 +241,7 @@ public final class BatteryService extends SystemService {
// Should never happen.
}
- publishBinderService("battery", new BinderService());
+ publishBinderService(Context.BATTERY_SERVICE, new BinderService());
publishLocalService(BatteryManagerInternal.class, new LocalService());
}
@@ -344,21 +376,31 @@ public final class BatteryService extends SystemService {
boolean logOutlier = false;
long dischargeDuration = 0;
+ mDockBatterySupported = mBatteryProps.dockBatterySupported;
+
mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
+ mPlugType = BATTERY_PLUGGED_NONE;
if (mBatteryProps.chargerAcOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
} else if (mBatteryProps.chargerUsbOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
} else if (mBatteryProps.chargerWirelessOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
- } else {
- mPlugType = BATTERY_PLUGGED_NONE;
+ }
+ mDockPlugType = BATTERY_PLUGGED_NONE;
+ if (mBatteryProps.chargerDockAcOnline && mBatteryProps.chargerAcOnline) {
+ mDockPlugType = BatteryManager.BATTERY_DOCK_PLUGGED_AC;
+ } else if (mBatteryProps.chargerDockAcOnline && mBatteryProps.chargerUsbOnline) {
+ mDockPlugType = BatteryManager.BATTERY_DOCK_PLUGGED_USB;
}
if (DEBUG) {
- Slog.d(TAG, "Processing new values: "
- + "chargerAcOnline=" + mBatteryProps.chargerAcOnline
- + ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
+ String msg = "Processing new values: "
+ + "chargerAcOnline=" + mBatteryProps.chargerAcOnline;
+ if (mDockBatterySupported) {
+ msg += ", chargerDockAcOnline=" + mBatteryProps.chargerDockAcOnline;
+ }
+ msg += ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
+ ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
+ ", maxChargingCurrent" + mBatteryProps.maxChargingCurrent
+ ", batteryStatus=" + mBatteryProps.batteryStatus
@@ -368,8 +410,22 @@ public final class BatteryService extends SystemService {
+ ", batteryTechnology=" + mBatteryProps.batteryTechnology
+ ", batteryVoltage=" + mBatteryProps.batteryVoltage
+ ", batteryTemperature=" + mBatteryProps.batteryTemperature
- + ", mBatteryLevelCritical=" + mBatteryLevelCritical
- + ", mPlugType=" + mPlugType);
+ + ", mBatteryLevelCritical=" + mBatteryLevelCritical;
+ if (mDockBatterySupported) {
+ msg += ", dockBatteryStatus=" + mBatteryProps.dockBatteryStatus
+ + ", dockBatteryHealth=" + mBatteryProps.dockBatteryHealth
+ + ", dockBatteryPresent=" + mBatteryProps.dockBatteryPresent
+ + ", dockBatteryLevel=" + mBatteryProps.dockBatteryLevel
+ + ", dockBatteryTechnology=" + mBatteryProps.dockBatteryTechnology
+ + ", dockBatteryVoltage=" + mBatteryProps.dockBatteryVoltage
+ + ", dockBatteryTemperature=" + mBatteryProps.dockBatteryTemperature;
+ }
+ msg += ", mPlugType=" + mPlugType;
+ if (mDockBatterySupported) {
+ msg += ", mDockPlugType=" + mDockPlugType;
+ }
+
+ Slog.d(TAG, msg);
}
// Let the battery stats keep track of the current level.
@@ -380,19 +436,40 @@ public final class BatteryService extends SystemService {
} catch (RemoteException e) {
// Should never happen.
}
+ if (mDockBatterySupported) {
+ try {
+ mBatteryStats.setDockBatteryState(mBatteryProps.dockBatteryStatus,
+ mBatteryProps.dockBatteryHealth, mDockPlugType,
+ mBatteryProps.dockBatteryLevel, mBatteryProps.dockBatteryTemperature,
+ mBatteryProps.dockBatteryVoltage);
+ } catch (RemoteException e) {
+ // Should never happen.
+ }
+ }
shutdownIfNoPowerLocked();
shutdownIfOverTempLocked();
- if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
+ final boolean batteryChanged = mBatteryProps.batteryStatus != mLastBatteryStatus ||
mBatteryProps.batteryHealth != mLastBatteryHealth ||
mBatteryProps.batteryPresent != mLastBatteryPresent ||
mBatteryProps.batteryLevel != mLastBatteryLevel ||
mPlugType != mLastPlugType ||
mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
- mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent ||
- mInvalidCharger != mLastInvalidCharger)) {
+ mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent;
+
+ final boolean dockBatteryChanged = mDockBatterySupported &&
+ (mBatteryProps.dockBatteryStatus != mLastDockBatteryStatus ||
+ mBatteryProps.dockBatteryHealth != mLastDockBatteryHealth ||
+ mBatteryProps.dockBatteryPresent != mLastDockBatteryPresent ||
+ mBatteryProps.dockBatteryLevel != mLastDockBatteryLevel ||
+ mDockPlugType != mLastDockPlugType ||
+ mBatteryProps.dockBatteryVoltage != mLastDockBatteryVoltage ||
+ mBatteryProps.dockBatteryTemperature != mLastDockBatteryTemperature);
+
+ if (force || batteryChanged || dockBatteryChanged ||
+ mInvalidCharger != mLastInvalidCharger) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -422,12 +499,30 @@ public final class BatteryService extends SystemService {
mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ? 1 : 0,
mPlugType, mBatteryProps.batteryTechnology);
}
+ if (mDockBatterySupported &&
+ (mBatteryProps.dockBatteryStatus != mLastDockBatteryStatus ||
+ mBatteryProps.dockBatteryHealth != mLastDockBatteryHealth ||
+ mBatteryProps.dockBatteryPresent != mLastDockBatteryPresent ||
+ mDockPlugType != mLastDockPlugType)) {
+ EventLog.writeEvent(EventLogTags.DOCK_BATTERY_STATUS,
+ mBatteryProps.dockBatteryStatus, mBatteryProps.dockBatteryHealth,
+ mBatteryProps.dockBatteryPresent ? 1 : 0,
+ mDockPlugType, mBatteryProps.dockBatteryTechnology);
+ }
if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
// Don't do this just from voltage or temperature changes, that is
// too noisy.
EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,
mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature);
}
+ if (mDockBatterySupported &&
+ (mBatteryProps.dockBatteryLevel != mLastDockBatteryLevel)) {
+ // Don't do this just from voltage or temperature changes, that is
+ // too noisy.
+ EventLog.writeEvent(EventLogTags.DOCK_BATTERY_LEVEL,
+ mBatteryProps.dockBatteryLevel, mBatteryProps.dockBatteryVoltage,
+ mBatteryProps.dockBatteryTemperature);
+ }
if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
mPlugType == BATTERY_PLUGGED_NONE) {
// We want to make sure we log discharge cycle outliers
@@ -454,13 +549,34 @@ public final class BatteryService extends SystemService {
mBatteryLevelLow = false;
}
}
+ if (mDockBatterySupported) {
+ if (!mDockBatteryLevelLow) {
+ // Should we now switch in to low battery mode?
+ if (mDockPlugType == BATTERY_PLUGGED_NONE
+ && mBatteryProps.dockBatteryLevel <= mLowBatteryWarningLevel) {
+ mDockBatteryLevelLow = true;
+ }
+ } else {
+ // Should we now switch out of low battery mode?
+ if (mDockPlugType != BATTERY_PLUGGED_NONE) {
+ mDockBatteryLevelLow = false;
+ } else if (mBatteryProps.dockBatteryLevel >= mLowBatteryCloseWarningLevel) {
+ mDockBatteryLevelLow = false;
+ } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
+ // If being forced, the previous state doesn't matter, we will just
+ // absolutely check to see if we are now above the warning level.
+ mDockBatteryLevelLow = false;
+ }
+ }
+ }
sendIntentLocked();
// Separate broadcast is sent for power connected / not connected
// since the standard intent will not wake any applications and some
// applications may want to have smart behavior based on this.
- if (mPlugType != 0 && mLastPlugType == 0) {
+ if (mPlugType != 0 && mLastPlugType == 0 ||
+ (mLastPlugType == 0 && mDockPlugType != 0 && mLastDockPlugType == 0)) {
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -470,7 +586,8 @@ public final class BatteryService extends SystemService {
}
});
}
- else if (mPlugType == 0 && mLastPlugType != 0) {
+ else if (mPlugType == 0 && mLastPlugType != 0 ||
+ (mLastPlugType != 0 && mDockPlugType == 0 && mLastDockPlugType != 0)) {
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -526,6 +643,14 @@ public final class BatteryService extends SystemService {
mLastBatteryTemperature = mBatteryProps.batteryTemperature;
mLastMaxChargingCurrent = mBatteryProps.maxChargingCurrent;
mLastBatteryLevelCritical = mBatteryLevelCritical;
+ mLastDockBatteryStatus = mBatteryProps.dockBatteryStatus;
+ mLastDockBatteryHealth = mBatteryProps.dockBatteryHealth;
+ mLastDockBatteryPresent = mBatteryProps.dockBatteryPresent;
+ mLastDockBatteryLevel = mBatteryProps.dockBatteryLevel;
+ mLastDockPlugType = mDockPlugType;
+ mLastDockBatteryVoltage = mBatteryProps.dockBatteryVoltage;
+ mLastDockBatteryTemperature = mBatteryProps.dockBatteryTemperature;
+
mLastInvalidCharger = mInvalidCharger;
}
}
@@ -537,6 +662,7 @@ public final class BatteryService extends SystemService {
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
int icon = getIconLocked(mBatteryProps.batteryLevel);
+ int dockIcon = 0;
intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus);
intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
@@ -551,19 +677,62 @@ public final class BatteryService extends SystemService {
intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
+ if (mDockBatterySupported) {
+ dockIcon = getDockIconLocked(mBatteryProps.dockBatteryLevel);
+
+ intent.putExtra(BatteryManager.EXTRA_DOCK_STATUS, mBatteryProps.dockBatteryStatus);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_HEALTH, mBatteryProps.dockBatteryHealth);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_PRESENT, mBatteryProps.dockBatteryPresent);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_LEVEL, mBatteryProps.dockBatteryLevel);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_SCALE, BATTERY_SCALE);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_ICON_SMALL, dockIcon);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_PLUGGED, mDockPlugType);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_VOLTAGE, mBatteryProps.dockBatteryVoltage);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_TEMPERATURE,
+ mBatteryProps.dockBatteryTemperature);
+ intent.putExtra(BatteryManager.EXTRA_DOCK_TECHNOLOGY,
+ mBatteryProps.dockBatteryTechnology);
+
+ // EEPAD legacy data
+ intent.putExtra("usb_wakeup", mBatteryProps.chargerUsbOnline);
+ intent.putExtra("ac_online", mBatteryProps.chargerAcOnline);
+ intent.putExtra("dock_ac_online", mBatteryProps.chargerDockAcOnline);
+ }
+
+
if (DEBUG) {
- Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. level:" + mBatteryProps.batteryLevel +
- ", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus +
+ String msg = "Sending ACTION_BATTERY_CHANGED. level:" + mBatteryProps.batteryLevel +
+ ", scale:" + BATTERY_SCALE +
+ ", status:" + mBatteryProps.batteryStatus +
", health:" + mBatteryProps.batteryHealth +
", present:" + mBatteryProps.batteryPresent +
", voltage: " + mBatteryProps.batteryVoltage +
", temperature: " + mBatteryProps.batteryTemperature +
", technology: " + mBatteryProps.batteryTechnology +
- ", AC powered:" + mBatteryProps.chargerAcOnline +
- ", USB powered:" + mBatteryProps.chargerUsbOnline +
- ", Wireless powered:" + mBatteryProps.chargerWirelessOnline +
- ", icon:" + icon + ", invalid charger:" + mInvalidCharger +
- ", maxChargingCurrent:" + mBatteryProps.maxChargingCurrent);
+ ", maxChargingCurrent:" + mBatteryProps.maxChargingCurrent;
+
+ if (mDockBatterySupported) {
+ msg += ", dock_level:" + mBatteryProps.dockBatteryLevel +
+ ", dock_status:" + mBatteryProps.dockBatteryStatus +
+ ", dock_health:" + mBatteryProps.dockBatteryHealth +
+ ", dock_present:" + mBatteryProps.dockBatteryPresent +
+ ", dock_voltage: " + mBatteryProps.dockBatteryVoltage +
+ ", dock_temperature: " + mBatteryProps.dockBatteryTemperature +
+ ", dock_technology: " + mBatteryProps.dockBatteryTechnology;
+ }
+ msg += ", AC powered:" + mBatteryProps.chargerAcOnline;
+ if (mDockBatterySupported) {
+ msg += ", Dock AC powered:" + mBatteryProps.chargerDockAcOnline;
+ }
+ msg += ", USB powered:" + mBatteryProps.chargerUsbOnline +
+ ", Wireless powered:" + mBatteryProps.chargerWirelessOnline;
+ msg += ", icon:" + icon;
+ if (mDockBatterySupported) {
+ msg += ", dock_icon:" + dockIcon;
+ }
+ msg += ", invalid charger:" + mInvalidCharger;
+
+ Slog.d(TAG, msg);
}
mHandler.post(new Runnable() {
@@ -658,6 +827,22 @@ public final class BatteryService extends SystemService {
}
}
+ private int getDockIconLocked(int level) {
+ if (mBatteryProps.dockBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
+ return com.android.internal.R.drawable.stat_sys_battery_charge;
+ } else if (mBatteryProps.dockBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) {
+ return com.android.internal.R.drawable.stat_sys_battery;
+ } else if (mBatteryProps.dockBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING
+ || mBatteryProps.dockBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
+ if (isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)
+ && mBatteryProps.dockBatteryLevel >= 100) {
+ return com.android.internal.R.drawable.stat_sys_battery_charge;
+ }
+ return com.android.internal.R.drawable.stat_sys_battery;
+ }
+ return com.android.internal.R.drawable.stat_sys_battery_unknown;
+ }
+
private void dumpInternal(PrintWriter pw, String[] args) {
synchronized (mLock) {
if (args == null || args.length == 0 || "-a".equals(args[0])) {
@@ -666,6 +851,9 @@ public final class BatteryService extends SystemService {
pw.println(" (UPDATES STOPPED -- use 'reset' to restart)");
}
pw.println(" AC powered: " + mBatteryProps.chargerAcOnline);
+ if (mDockBatterySupported) {
+ pw.println(" Dock AC powered: " + mBatteryProps.chargerDockAcOnline);
+ }
pw.println(" USB powered: " + mBatteryProps.chargerUsbOnline);
pw.println(" Wireless powered: " + mBatteryProps.chargerWirelessOnline);
pw.println(" Max charging current: " + mBatteryProps.maxChargingCurrent);
@@ -677,7 +865,15 @@ public final class BatteryService extends SystemService {
pw.println(" voltage: " + mBatteryProps.batteryVoltage);
pw.println(" temperature: " + mBatteryProps.batteryTemperature);
pw.println(" technology: " + mBatteryProps.batteryTechnology);
-
+ if (mDockBatterySupported) {
+ pw.println(" dock_status: " + mBatteryProps.dockBatteryStatus);
+ pw.println(" dock_health: " + mBatteryProps.dockBatteryHealth);
+ pw.println(" dock_present: " + mBatteryProps.dockBatteryPresent);
+ pw.println(" dock_level: " + mBatteryProps.dockBatteryLevel);
+ pw.println(" dock_voltage: " + mBatteryProps.dockBatteryVoltage);
+ pw.println(" dock_temperature: " + mBatteryProps.dockBatteryTemperature);
+ pw.println(" dock_technology: " + mBatteryProps.dockBatteryTechnology);
+ }
} else if ("unplug".equals(args[0])) {
if (!mUpdatesStopped) {
mLastBatteryProps.set(mBatteryProps);
@@ -703,6 +899,8 @@ public final class BatteryService extends SystemService {
boolean update = true;
if ("ac".equals(key)) {
mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
+ } else if (mDockBatterySupported && "dockac".equals(key)) {
+ mBatteryProps.chargerDockAcOnline = Integer.parseInt(value) != 0;
} else if ("usb".equals(key)) {
mBatteryProps.chargerUsbOnline = Integer.parseInt(value) != 0;
} else if ("wireless".equals(key)) {
@@ -711,6 +909,10 @@ public final class BatteryService extends SystemService {
mBatteryProps.batteryStatus = Integer.parseInt(value);
} else if ("level".equals(key)) {
mBatteryProps.batteryLevel = Integer.parseInt(value);
+ } else if (mDockBatterySupported && "dockstatus".equals(key)) {
+ mBatteryProps.dockBatteryStatus = Integer.parseInt(value);
+ } else if (mDockBatterySupported && "docklevel".equals(key)) {
+ mBatteryProps.dockBatteryLevel = Integer.parseInt(value);
} else if ("invalid".equals(key)) {
mInvalidCharger = Integer.parseInt(value);
} else {
@@ -743,7 +945,12 @@ public final class BatteryService extends SystemService {
}
} else {
pw.println("Dump current battery state, or:");
- pw.println(" set [ac|usb|wireless|status|level|invalid] <value>");
+ if (mDockBatterySupported) {
+ pw.println(" set [ac|dockac|usb|wireless|status|level|dockstatus" +
+ "|docklevel|invalid] <value>");
+ } else {
+ pw.println(" set [ac|usb|wireless|status|level|invalid] <value>");
+ }
pw.println(" unplug");
pw.println(" reset");
}
@@ -935,7 +1142,12 @@ public final class BatteryService extends SystemService {
}
}
- private final class BinderService extends Binder {
+ private final class BinderService extends IBatteryService.Stub {
+ @Override
+ public boolean isDockBatterySupported() throws RemoteException {
+ return getLocalService(BatteryManagerInternal.class).isDockBatterySupported();
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -981,11 +1193,39 @@ public final class BatteryService extends SystemService {
}
@Override
+ public int getDockPlugType() {
+ synchronized (mLock) {
+ return mDockPlugType;
+ }
+ }
+
+ @Override
+ public int getDockBatteryLevel() {
+ synchronized (mLock) {
+ return mBatteryProps.dockBatteryLevel;
+ }
+ }
+
+ @Override
+ public boolean getDockBatteryLevelLow() {
+ synchronized (mLock) {
+ return mDockBatteryLevelLow;
+ }
+ }
+
+ @Override
public int getInvalidCharger() {
synchronized (mLock) {
return mInvalidCharger;
}
}
+
+ @Override
+ public boolean isDockBatterySupported() {
+ synchronized (mLock) {
+ return mDockBatterySupported;
+ }
+ }
}
class SettingsObserver extends ContentObserver {
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 6067bd2..5a76227 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -266,7 +266,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
sysUiUid = mContext.getPackageManager().getPackageUid("com.android.systemui",
UserHandle.USER_OWNER);
} catch (PackageManager.NameNotFoundException e) {
- Log.wtf(TAG, "Unable to resolve SystemUI's UID.", e);
+ // Some platforms, such as wearables do not have a system ui.
+ Log.w(TAG, "Unable to resolve SystemUI's UID.", e);
}
mSystemUiUid = sysUiUid;
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b053c3a..2a47460 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -171,6 +171,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private static final boolean VDBG = false;
private static final boolean LOGD_RULES = false;
+ private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
// TODO: create better separation between radio types and network types
@@ -964,6 +965,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
+ if (ni == null || !LOGD_BLOCKED_NETWORKINFO) return;
+ boolean removed = false;
+ boolean added = false;
+ synchronized (mBlockedAppUids) {
+ if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
+ added = true;
+ } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
+ removed = true;
+ }
+ }
+ if (added) log("Returning blocked NetworkInfo to uid=" + uid);
+ else if (removed) log("Returning unblocked NetworkInfo to uid=" + uid);
+ }
+
/**
* Return a filtered {@link NetworkInfo}, potentially marked
* {@link DetailedState#BLOCKED} based on
@@ -974,10 +990,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
// network is blocked; clone and override state
info = new NetworkInfo(info);
info.setDetailedState(DetailedState.BLOCKED, null, null);
- if (VDBG) {
- log("returning Blocked NetworkInfo for ifname=" +
- lp.getInterfaceName() + ", uid=" + uid);
- }
}
if (info != null && mLockdownTracker != null) {
info = mLockdownTracker.augmentNetworkInfo(info);
@@ -998,7 +1010,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
enforceAccessPermission();
final int uid = Binder.getCallingUid();
NetworkState state = getUnfilteredActiveNetworkState(uid);
- return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+ NetworkInfo ni = getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+ maybeLogBlockedNetworkInfo(ni, uid);
+ return ni;
}
@Override
@@ -3927,6 +3941,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
new HashMap<Messenger, NetworkAgentInfo>();
+ @GuardedBy("mBlockedAppUids")
+ private final HashSet<Integer> mBlockedAppUids = new HashSet();
+
// Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
private final NetworkRequest mDefaultRequest;
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index abe8f5c..71650c3 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -31,6 +31,8 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorManager;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
import android.hardware.TriggerEvent;
import android.hardware.TriggerEventListener;
import android.hardware.display.DisplayManager;
@@ -111,7 +113,7 @@ public class DeviceIdleController extends SystemService
private INetworkPolicyManager mNetworkPolicyManager;
private DisplayManager mDisplayManager;
private SensorManager mSensorManager;
- private Sensor mSigMotionSensor;
+ private Sensor mMotionSensor;
private LocationManager mLocationManager;
private LocationRequest mLocationRequest;
private PendingIntent mSensingAlarmIntent;
@@ -123,12 +125,12 @@ public class DeviceIdleController extends SystemService
private boolean mForceIdle;
private boolean mScreenOn;
private boolean mCharging;
- private boolean mSigMotionActive;
private boolean mSensing;
private boolean mNotMoving;
private boolean mLocating;
private boolean mLocated;
- private boolean mHaveGps;
+ private boolean mHasGps;
+ private boolean mHasNetworkLocation;
private Location mLastGenericLocation;
private Location mLastGpsLocation;
@@ -275,13 +277,57 @@ public class DeviceIdleController extends SystemService
}
};
- private final TriggerEventListener mSigMotionListener = new TriggerEventListener() {
- @Override public void onTrigger(TriggerEvent event) {
+ private final class MotionListener extends TriggerEventListener
+ implements SensorEventListener {
+
+ boolean active = false;
+
+ @Override
+ public void onTrigger(TriggerEvent event) {
synchronized (DeviceIdleController.this) {
- significantMotionLocked();
+ active = false;
+ motionLocked();
}
}
- };
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ synchronized (DeviceIdleController.this) {
+ mSensorManager.unregisterListener(this, mMotionSensor);
+ active = false;
+ motionLocked();
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+
+ public boolean registerLocked() {
+ boolean success = false;
+ if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
+ success = mSensorManager.requestTriggerSensor(mMotionListener, mMotionSensor);
+ } else {
+ success = mSensorManager.registerListener(
+ mMotionListener, mMotionSensor, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+ if (success) {
+ active = true;
+ } else {
+ Slog.e(TAG, "Unable to register for " + mMotionSensor);
+ }
+ return success;
+ }
+
+ public void unregisterLocked() {
+ if (mMotionSensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
+ mSensorManager.cancelTriggerSensor(mMotionListener, mMotionSensor);
+ } else {
+ mSensorManager.unregisterListener(mMotionListener);
+ }
+ active = false;
+ }
+ }
+ private final MotionListener mMotionListener = new MotionListener();
private final LocationListener mGenericLocationListener = new LocationListener() {
@Override
@@ -356,7 +402,7 @@ public class DeviceIdleController extends SystemService
* This is the time, after becoming inactive, at which we start looking at the
* motion sensor to determine if the device is being left alone. We don't do this
* immediately after going inactive just because we don't want to be continually running
- * the significant motion sensor whenever the screen is off.
+ * the motion sensor whenever the screen is off.
* @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_INACTIVE_TIMEOUT
*/
@@ -399,7 +445,7 @@ public class DeviceIdleController extends SystemService
/**
* This is the time, after the inactive timeout elapses, that we will wait looking
- * for significant motion until we truly consider the device to be idle.
+ * for motion until we truly consider the device to be idle.
* @see Settings.Global#DEVICE_IDLE_CONSTANTS
* @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
*/
@@ -896,17 +942,38 @@ public class DeviceIdleController extends SystemService
mDisplayManager = (DisplayManager) getContext().getSystemService(
Context.DISPLAY_SERVICE);
mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
- mSigMotionSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
- mLocationManager = (LocationManager) getContext().getSystemService(
- Context.LOCATION_SERVICE);
- mLocationRequest = new LocationRequest()
- .setQuality(LocationRequest.ACCURACY_FINE)
- .setInterval(0)
- .setFastestInterval(0)
- .setNumUpdates(1);
+ int sigMotionSensorId = getContext().getResources().getInteger(
+ com.android.internal.R.integer.config_autoPowerModeAnyMotionSensor);
+ if (sigMotionSensorId > 0) {
+ mMotionSensor = mSensorManager.getDefaultSensor(sigMotionSensorId, true);
+ }
+ if (mMotionSensor == null && getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_autoPowerModePreferWristTilt)) {
+ mMotionSensor = mSensorManager.getDefaultSensor(
+ Sensor.TYPE_WRIST_TILT_GESTURE, true);
+ }
+ if (mMotionSensor == null) {
+ // As a last ditch, fall back to SMD.
+ mMotionSensor = mSensorManager.getDefaultSensor(
+ Sensor.TYPE_SIGNIFICANT_MOTION, true);
+ }
+
+ if (getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
+ mLocationManager = (LocationManager) getContext().getSystemService(
+ Context.LOCATION_SERVICE);
+ mLocationRequest = new LocationRequest()
+ .setQuality(LocationRequest.ACCURACY_FINE)
+ .setInterval(0)
+ .setFastestInterval(0)
+ .setNumUpdates(1);
+ }
+
+ float angleThreshold = getContext().getResources().getInteger(
+ com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
mAnyMotionDetector = new AnyMotionDetector(
(PowerManager) getContext().getSystemService(Context.POWER_SERVICE),
- mHandler, mSensorManager, this);
+ mHandler, mSensorManager, this, angleThreshold);
Intent intent = new Intent(ACTION_STEP_IDLE_STATE)
.setPackage("android")
@@ -1242,7 +1309,7 @@ public class DeviceIdleController extends SystemService
cancelAlarmLocked();
cancelSensingAlarmLocked();
cancelLocatingLocked();
- stopMonitoringSignificantMotion();
+ stopMonitoringMotionLocked();
mAnyMotionDetector.stop();
}
@@ -1271,8 +1338,8 @@ public class DeviceIdleController extends SystemService
switch (mState) {
case STATE_INACTIVE:
// We have now been inactive long enough, it is time to start looking
- // for significant motion and sleep some more while doing so.
- startMonitoringSignificantMotion();
+ // for motion and sleep some more while doing so.
+ startMonitoringMotionLocked();
scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
// Reset the upcoming idle delays.
mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
@@ -1298,17 +1365,30 @@ public class DeviceIdleController extends SystemService
if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
EventLogTags.writeDeviceIdle(mState, "step");
scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT);
- mLocating = true;
- mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener,
- mHandler.getLooper());
- if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
- mHaveGps = true;
+ if (mLocationManager != null
+ && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
+ mLocationManager.requestLocationUpdates(mLocationRequest,
+ mGenericLocationListener, mHandler.getLooper());
+ mLocating = true;
+ } else {
+ mHasNetworkLocation = false;
+ }
+ if (mLocationManager != null
+ && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
+ mHasGps = true;
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
mGpsLocationListener, mHandler.getLooper());
+ mLocating = true;
} else {
- mHaveGps = false;
+ mHasGps = false;
}
- break;
+ // If we have a location provider, we're all set, the listeners will move state
+ // forward.
+ if (mLocating) {
+ break;
+ }
+
+ // Otherwise, we have to move from locating into idle maintenance.
case STATE_LOCATING:
cancelSensingAlarmLocked();
cancelLocatingLocked();
@@ -1338,17 +1418,16 @@ public class DeviceIdleController extends SystemService
}
}
- void significantMotionLocked() {
- if (DEBUG) Slog.d(TAG, "significantMotionLocked()");
- // When the sensor goes off, its trigger is automatically removed.
- mSigMotionActive = false;
+ void motionLocked() {
+ if (DEBUG) Slog.d(TAG, "motionLocked()");
+ // The motion sensor will have been disabled at this point
handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
}
void handleMotionDetectedLocked(long timeout, String type) {
// The device is not yet active, so we want to go back to the pending idle
- // state to wait again for no motion. Note that we only monitor for significant
- // motion after moving out of the inactive state, so no need to worry about that.
+ // state to wait again for no motion. Note that we only monitor for motion
+ // after moving out of the inactive state, so no need to worry about that.
if (mState != STATE_ACTIVE) {
scheduleReportActiveLocked(type, Process.myUid());
mState = STATE_ACTIVE;
@@ -1366,7 +1445,7 @@ public class DeviceIdleController extends SystemService
}
if (DEBUG) Slog.d(TAG, "Generic location: " + location);
mLastGenericLocation = new Location(location);
- if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHaveGps) {
+ if (location.getAccuracy() > mConstants.LOCATION_ACCURACY && mHasGps) {
return;
}
mLocated = true;
@@ -1391,19 +1470,17 @@ public class DeviceIdleController extends SystemService
}
}
- void startMonitoringSignificantMotion() {
- if (DEBUG) Slog.d(TAG, "startMonitoringSignificantMotion()");
- if (mSigMotionSensor != null && !mSigMotionActive) {
- mSensorManager.requestTriggerSensor(mSigMotionListener, mSigMotionSensor);
- mSigMotionActive = true;
+ void startMonitoringMotionLocked() {
+ if (DEBUG) Slog.d(TAG, "startMonitoringMotionLocked()");
+ if (mMotionSensor != null && !mMotionListener.active) {
+ mMotionListener.registerLocked();
}
}
- void stopMonitoringSignificantMotion() {
- if (DEBUG) Slog.d(TAG, "stopMonitoringSignificantMotion()");
- if (mSigMotionActive) {
- mSensorManager.cancelTriggerSensor(mSigMotionListener, mSigMotionSensor);
- mSigMotionActive = false;
+ void stopMonitoringMotionLocked() {
+ if (DEBUG) Slog.d(TAG, "stopMonitoringMotionLocked()");
+ if (mMotionSensor != null && mMotionListener.active) {
+ mMotionListener.unregisterLocked();
}
}
@@ -1432,10 +1509,10 @@ public class DeviceIdleController extends SystemService
void scheduleAlarmLocked(long delay, boolean idleUntil) {
if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
- if (mSigMotionSensor == null) {
- // If there is no significant motion sensor on this device, then we won't schedule
+ if (mMotionSensor == null) {
+ // If there is no motion sensor on this device, then we won't schedule
// alarms, because we can't determine if the device is not moving. This effectively
- // turns off normal exeuction of device idling, although it is still possible to
+ // turns off normal execution of device idling, although it is still possible to
// manually poke it by pretending like the alarm is going off.
return;
}
@@ -1917,15 +1994,16 @@ public class DeviceIdleController extends SystemService
pw.print(" mEnabled="); pw.println(mEnabled);
pw.print(" mForceIdle="); pw.println(mForceIdle);
- pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor);
+ pw.print(" mMotionSensor="); pw.println(mMotionSensor);
pw.print(" mCurDisplay="); pw.println(mCurDisplay);
pw.print(" mScreenOn="); pw.println(mScreenOn);
pw.print(" mCharging="); pw.println(mCharging);
- pw.print(" mSigMotionActive="); pw.println(mSigMotionActive);
+ pw.print(" mMotionActive="); pw.println(mMotionListener.active);
pw.print(" mSensing="); pw.print(mSensing); pw.print(" mNotMoving=");
pw.println(mNotMoving);
- pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHaveGps=");
- pw.print(mHaveGps); pw.print(" mLocated="); pw.println(mLocated);
+ pw.print(" mLocating="); pw.print(mLocating); pw.print(" mHasGps=");
+ pw.print(mHasGps); pw.print(" mHasNetwork=");
+ pw.print(mHasNetworkLocation); pw.print(" mLocated="); pw.println(mLocated);
if (mLastGenericLocation != null) {
pw.print(" mLastGenericLocation="); pw.println(mLastGenericLocation);
}
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index ab2ea8b..8bb158e 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -11,6 +11,10 @@ option java_package com.android.server
# It lets us count the total amount of time between charges and the discharge level
2730 battery_discharge (duration|2|3),(minLevel|1|6),(maxLevel|1|6)
+# dock battery
+2738 dock_battery_level (level|1|6),(voltage|1|1),(temperature|1|1)
+2739 dock_battery_status (status|1|5),(health|1|5),(present|1|5),(plugged|1|5),(technology|3)
+
# ---------------------------
# PowerManagerService.java
@@ -29,9 +33,13 @@ option java_package com.android.server
# This is logged when the partial wake lock (keeping the device awake
# regardless of whether the screen is off) is acquired or released.
2729 power_partial_wake_state (releasedorAcquired|1|5),(tag|3)
+# The device is being asked to go into a soft sleep (typically by the ungaze gesture).
+# It logs the time remaining before the device would've normally gone to sleep without the request.
+2731 power_soft_sleep_requested (savedwaketimems|2)
#
-# Leave IDs through 2739 for more power logs (2730 used by battery_discharge above)
+# Leave IDs through 2739 for more power logs (2730 used by battery_discharge and
+# 2738-2739 used by dock battery above)
#
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 4f9f972..a9f6e40 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -143,6 +143,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
+import cyanogenmod.hardware.CMHardwareManager;
import cyanogenmod.providers.CMSettings;
import org.cyanogenmod.internal.util.QSUtils;
@@ -239,6 +240,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private boolean mShowOngoingImeSwitcherForPhones;
private boolean mNotificationShown;
private final boolean mImeSelectedOnBoot;
+ private CMHardwareManager mCMHardware;
static class SessionState {
final ClientState client;
@@ -506,15 +508,32 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}, userId);
+ if (mCMHardware.isSupported(CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY)) {
+ resolver.registerContentObserver(CMSettings.System.getUriFor(
+ CMSettings.System.HIGH_TOUCH_SENSITIVITY_ENABLE), false, this, userId);
+ }
+ if (mCMHardware.isSupported(CMHardwareManager.FEATURE_TOUCH_HOVERING)) {
+ resolver.registerContentObserver(CMSettings.Secure.getUriFor(
+ CMSettings.Secure.FEATURE_TOUCH_HOVERING), false, this, userId);
+ }
+
mRegistered = true;
}
@Override public void onChange(boolean selfChange, Uri uri) {
final Uri showImeUri =
Settings.Secure.getUriFor(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
+ final Uri touchSensitivityUri =
+ CMSettings.System.getUriFor(CMSettings.System.HIGH_TOUCH_SENSITIVITY_ENABLE);
+ final Uri touchHoveringUri =
+ CMSettings.Secure.getUriFor(CMSettings.Secure.FEATURE_TOUCH_HOVERING);
synchronized (mMethodMap) {
if (showImeUri.equals(uri)) {
updateKeyboardFromSettingsLocked();
+ } else if (touchSensitivityUri.equals(uri)) {
+ updateTouchSensitivity();
+ } else if (touchHoveringUri.equals(uri)) {
+ updateTouchHovering();
} else {
boolean enabledChanged = false;
String newEnabled = mSettings.getEnabledInputMethodsStr();
@@ -943,11 +962,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- synchronized (mMethodMap) {
- mSettingsObserver.registerContentObserverLocked(userId);
- updateFromSettingsLocked(true);
- }
-
// IMMS wants to receive Intent.ACTION_LOCALE_CHANGED in order to update the current IME
// according to the new system locale.
final IntentFilter filter = new IntentFilter();
@@ -1072,6 +1086,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mContext.getBasePackageName());
}
+ updateTouchHovering();
+ updateTouchSensitivity();
+
if (DEBUG) Slog.d(TAG, "Switching user stage 3/3. newUserId=" + newUserId
+ " selectedIme=" + mSettings.getSelectedInputMethod());
}
@@ -1108,6 +1125,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
if (!mSystemReady) {
mSystemReady = true;
+ // Must happen before registerContentObserverLocked
+ mCMHardware = CMHardwareManager.getInstance(mContext);
+
+ mSettingsObserver.registerContentObserverLocked(
+ mSettings.getCurrentUserId());
+ updateFromSettingsLocked(true);
+
+ updateTouchHovering();
+ updateTouchSensitivity();
+
mKeyguardManager =
(KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mNotificationManager = (NotificationManager)
@@ -1836,8 +1863,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
com.android.internal.R.string.select_input_method,
mImeSwitcherNotification.build(), UserHandle.ALL);
mNotificationShown = true;
- publishImeSelectorCustomTile(imi);
}
+ publishImeSelectorCustomTile(imi);
} else {
if (mNotificationShown && mNotificationManager != null) {
if (DEBUG) {
@@ -1846,8 +1873,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mNotificationManager.cancelAsUser(null,
com.android.internal.R.string.select_input_method, UserHandle.ALL);
mNotificationShown = false;
- unpublishImeSelectorCustomTile();
}
+ unpublishImeSelectorCustomTile();
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -1970,6 +1997,26 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
+ private void updateTouchSensitivity() {
+ if (!mCMHardware.isSupported(CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY)) {
+ return;
+ }
+ boolean touchSensitivityEnable = CMSettings.System.getInt(mContext.getContentResolver(),
+ CMSettings.System.HIGH_TOUCH_SENSITIVITY_ENABLE, 0) == 1;
+ mCMHardware.set(CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY,
+ touchSensitivityEnable);
+ }
+
+ private void updateTouchHovering() {
+ if (!mCMHardware.isSupported(CMHardwareManager.FEATURE_TOUCH_HOVERING)) {
+ return;
+ }
+ boolean touchHovering = CMSettings.Secure.getInt(mContext.getContentResolver(),
+ CMSettings.Secure.FEATURE_TOUCH_HOVERING, 0) == 1;
+ mCMHardware.set(CMHardwareManager.FEATURE_TOUCH_HOVERING,
+ touchHovering);
+ }
+
public void updateKeyboardFromSettingsLocked() {
mShowImeWithHardKeyboard = mSettings.isShowImeWithHardKeyboardEnabled();
if (mSwitchingDialog != null
@@ -3633,9 +3680,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
imi = mMethodMap.get(mCurMethodId);
}
}
- final boolean hasInputMethod = isIMEVisible && imi != null && mCurrentSubtype != null;
- boolean enabled = hasInputMethod;
- if (enabled) {
+ if (shouldShowImeSwitcherLocked(isIMEVisible ? 1 : 0)) {
publishImeSelectorCustomTile(imi);
} else {
unpublishImeSelectorCustomTile();
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index bb0615d..274adf8 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -61,6 +61,8 @@ import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
+import cyanogenmod.providers.CMSettings;
+
/**
* Keeps the lock pattern/password data and related settings for each user.
* Used by LockPatternUtils. Needs to be a service because Settings app also needs
@@ -356,6 +358,10 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
+ if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
+ key = Settings.Secure.LOCK_PATTERN_ENABLED;
+ }
+
return mStorage.readKeyValue(key, defaultValue, userId);
}
@@ -810,6 +816,7 @@ public class LockSettingsService extends ILockSettings.Stub {
Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
Secure.LOCK_PATTERN_VISIBLE,
Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
+ CMSettings.Secure.LOCK_PASS_TO_SECURITY_VIEW,
Secure.LOCK_PATTERN_SIZE,
Secure.LOCK_DOTS_VISIBLE,
Secure.LOCK_SHOW_ERROR_PATH,
diff --git a/services/core/java/com/android/server/ThemeService.java b/services/core/java/com/android/server/ThemeService.java
deleted file mode 100644
index 96d1c5d..0000000
--- a/services/core/java/com/android/server/ThemeService.java
+++ /dev/null
@@ -1,1277 +0,0 @@
-/*
- * Copyright (C) 2014 The CyanogenMod 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 com.android.server;
-
-import android.Manifest;
-import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.WallpaperManager;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ThemeUtils;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.IThemeProcessingListener;
-import android.content.res.ThemeChangeRequest;
-import android.content.res.ThemeConfig;
-import android.content.res.IThemeChangeListener;
-import android.content.res.IThemeService;
-import android.graphics.Bitmap;
-import android.media.RingtoneManager;
-import android.os.Binder;
-import android.os.Environment;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.provider.ThemesContract;
-import android.provider.ThemesContract.MixnMatchColumns;
-import android.provider.ThemesContract.ThemesColumns;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.R;
-import com.android.internal.util.cm.ImageUtils;
-import cyanogenmod.providers.CMSettings;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import static android.content.pm.ThemeUtils.SYSTEM_THEME_PATH;
-import static android.content.pm.ThemeUtils.THEME_BOOTANIMATION_PATH;
-import static android.content.res.ThemeConfig.SYSTEM_DEFAULT;
-
-import java.util.List;
-
-/**
- * {@hide}
- */
-public class ThemeService extends IThemeService.Stub {
- private static final String TAG = ThemeService.class.getName();
-
- private static final boolean DEBUG = false;
-
- private static final String GOOGLE_SETUPWIZARD_PACKAGE = "com.google.android.setupwizard";
- private static final String CM_SETUPWIZARD_PACKAGE = "com.cyanogenmod.setupwizard";
- private static final String MANAGED_PROVISIONING_PACKAGE = "com.android.managedprovisioning";
-
- private static final long MAX_ICON_CACHE_SIZE = 33554432L; // 32MB
- private static final long PURGED_ICON_CACHE_SIZE = 25165824L; // 24 MB
-
- // Defines a min and max compatible api level for themes on this system.
- private static final int MIN_COMPATIBLE_VERSION = 21;
-
- private HandlerThread mWorker;
- private ThemeWorkerHandler mHandler;
- private ResourceProcessingHandler mResourceProcessingHandler;
- private Context mContext;
- private PackageManager mPM;
- private int mProgress;
- private boolean mWallpaperChangedByUs = false;
- private long mIconCacheSize = 0L;
- private int mCurrentUserId = UserHandle.USER_OWNER;
-
- private boolean mIsThemeApplying = false;
-
- private final RemoteCallbackList<IThemeChangeListener> mClients =
- new RemoteCallbackList<IThemeChangeListener>();
-
- private final RemoteCallbackList<IThemeProcessingListener> mProcessingListeners =
- new RemoteCallbackList<IThemeProcessingListener>();
-
- final private ArrayList<String> mThemesToProcessQueue = new ArrayList<String>(0);
-
- private class ThemeWorkerHandler extends Handler {
- private static final int MESSAGE_CHANGE_THEME = 1;
- private static final int MESSAGE_APPLY_DEFAULT_THEME = 2;
- private static final int MESSAGE_REBUILD_RESOURCE_CACHE = 3;
-
- public ThemeWorkerHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_CHANGE_THEME:
- final ThemeChangeRequest request = (ThemeChangeRequest) msg.obj;
- doApplyTheme(request, msg.arg1 == 1);
- break;
- case MESSAGE_APPLY_DEFAULT_THEME:
- doApplyDefaultTheme();
- break;
- case MESSAGE_REBUILD_RESOURCE_CACHE:
- doRebuildResourceCache();
- break;
- default:
- Log.w(TAG, "Unknown message " + msg.what);
- break;
- }
- }
- }
-
- private class ResourceProcessingHandler extends Handler {
- private static final int MESSAGE_QUEUE_THEME_FOR_PROCESSING = 3;
- private static final int MESSAGE_DEQUEUE_AND_PROCESS_THEME = 4;
-
- public ResourceProcessingHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_QUEUE_THEME_FOR_PROCESSING:
- String pkgName = (String) msg.obj;
- synchronized (mThemesToProcessQueue) {
- if (!mThemesToProcessQueue.contains(pkgName)) {
- if (DEBUG) Log.d(TAG, "Adding " + pkgName + " for processing");
- mThemesToProcessQueue.add(pkgName);
- if (mThemesToProcessQueue.size() == 1) {
- this.sendEmptyMessage(MESSAGE_DEQUEUE_AND_PROCESS_THEME);
- }
- }
- }
- break;
- case MESSAGE_DEQUEUE_AND_PROCESS_THEME:
- synchronized (mThemesToProcessQueue) {
- pkgName = mThemesToProcessQueue.get(0);
- }
- if (pkgName != null) {
- if (DEBUG) Log.d(TAG, "Processing " + pkgName);
- String name;
- try {
- PackageInfo pi = mPM.getPackageInfo(pkgName, 0);
- name = getThemeName(pi);
- } catch (PackageManager.NameNotFoundException e) {
- name = null;
- }
-
- int result = mPM.processThemeResources(pkgName);
- if (result < 0) {
- postFailedThemeInstallNotification(name != null ? name : pkgName);
- }
- sendThemeResourcesCachedBroadcast(pkgName, result);
-
- synchronized (mThemesToProcessQueue) {
- mThemesToProcessQueue.remove(0);
- if (mThemesToProcessQueue.size() > 0 &&
- !hasMessages(MESSAGE_DEQUEUE_AND_PROCESS_THEME)) {
- this.sendEmptyMessage(MESSAGE_DEQUEUE_AND_PROCESS_THEME);
- }
- }
- postFinishedProcessing(pkgName);
- }
- break;
- default:
- Log.w(TAG, "Unknown message " + msg.what);
- break;
- }
- }
- }
-
- public ThemeService(Context context) {
- super();
- mContext = context;
- mWorker = new HandlerThread("ThemeServiceWorker", Process.THREAD_PRIORITY_BACKGROUND);
- mWorker.start();
- mHandler = new ThemeWorkerHandler(mWorker.getLooper());
- Log.i(TAG, "Spawned worker thread");
-
- HandlerThread processingThread = new HandlerThread("ResourceProcessingThread",
- Process.THREAD_PRIORITY_BACKGROUND);
- processingThread.start();
- mResourceProcessingHandler =
- new ResourceProcessingHandler(processingThread.getLooper());
-
- // create the theme directory if it does not exist
- ThemeUtils.createThemeDirIfNotExists();
- ThemeUtils.createFontDirIfNotExists();
- ThemeUtils.createAlarmDirIfNotExists();
- ThemeUtils.createNotificationDirIfNotExists();
- ThemeUtils.createRingtoneDirIfNotExists();
- ThemeUtils.createIconCacheDirIfNotExists();
- }
-
- public void systemRunning() {
- // listen for wallpaper changes
- IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
- mContext.registerReceiver(mWallpaperChangeReceiver, filter);
-
- filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
- mContext.registerReceiver(mUserChangeReceiver, filter);
-
- mPM = mContext.getPackageManager();
-
- processInstalledThemes();
-
- if (!isThemeApiUpToDate()) {
- Log.d(TAG, "The system has been upgraded to a theme new api, " +
- "checking if currently set theme is compatible");
- removeObsoleteThemeOverlayIfExists();
- updateThemeApi();
- }
- }
-
- private void removeObsoleteThemeOverlayIfExists() {
- // Get the current overlay theme so we can see it it's overlay should be unapplied
- final IActivityManager am = ActivityManagerNative.getDefault();
- ThemeConfig config = null;
- try {
- if (am != null) {
- config = am.getConfiguration().themeConfig;
- } else {
- Log.e(TAG, "ActivityManager getDefault() " +
- "returned null, cannot remove obsolete theme");
- }
- } catch(RemoteException e) {
- Log.e(TAG, "Failed to get the theme config ", e);
- }
- if (config == null) return; // No need to unapply a theme if one isn't set
-
- // Populate the currentTheme map for the components we care about, we'll look
- // at the compatibility of each pkg below.
- HashMap<String, String> currentThemeMap = new HashMap<String, String>();
- currentThemeMap.put(ThemesColumns.MODIFIES_STATUS_BAR, config.getOverlayForStatusBar());
- currentThemeMap.put(ThemesColumns.MODIFIES_NAVIGATION_BAR,
- config.getOverlayForNavBar());
- currentThemeMap.put(ThemesColumns.MODIFIES_OVERLAYS, config.getOverlayPkgName());
-
- // Look at each component's theme (that we care about at least) and check compatibility
- // of the pkg with the system. If it is not compatible then we will add it to a theme
- // change request.
- Map<String, String> defaults = ThemeUtils.getDefaultComponents(mContext);
- ThemeChangeRequest.Builder builder = new ThemeChangeRequest.Builder();
- for(Map.Entry<String, String> entry : currentThemeMap.entrySet()) {
- String component = entry.getKey();
- String pkgName = entry.getValue();
- String defaultPkg = defaults.get(component);
-
- // Check that the default overlay theme is not currently set
- if (defaultPkg.equals(pkgName)) {
- Log.d(TAG, "Current overlay theme is same as default. " +
- "Not doing anything for " + component);
- continue;
- }
-
- // No need to unapply a system theme since it is always compatible
- if (ThemeConfig.SYSTEM_DEFAULT.equals(pkgName)) {
- Log.d(TAG, "Current overlay theme for "
- + component + " was system. no need to unapply");
- continue;
- }
-
- if (!isThemeCompatibleWithUpgradedApi(pkgName)) {
- Log.d(TAG, pkgName + "is incompatible with latest theme api for component " +
- component + ", Applying " + defaultPkg);
- builder.setComponent(component, pkgName);
- }
- }
-
- // Now actually unapply the incompatible themes
- ThemeChangeRequest request = builder.build();
- if (!request.getThemeComponentsMap().isEmpty()) {
- try {
- requestThemeChange(request, true);
- } catch(RemoteException e) {
- // This cannot happen
- }
- } else {
- Log.d(TAG, "Current theme is compatible with the system. Not unapplying anything");
- }
- }
-
- private boolean isThemeCompatibleWithUpgradedApi(String pkgName) {
- // Note this function does not cover the case of a downgrade. That case is out of scope and
- // would require predicting whether the future API levels will be compatible or not.
- boolean compatible = false;
- try {
- PackageInfo pi = mPM.getPackageInfo(pkgName, 0);
- Log.d(TAG, "Comparing theme target: " + pi.applicationInfo.targetSdkVersion +
- "to " + android.os.Build.VERSION.SDK_INT);
- compatible = pi.applicationInfo.targetSdkVersion >= MIN_COMPATIBLE_VERSION;
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Unable to get package info for " + pkgName, e);
- }
- return compatible;
- }
-
- private boolean isThemeApiUpToDate() {
- // We can't be 100% sure its an upgrade. If the field is undefined it
- // could have been a factory reset.
- final ContentResolver resolver = mContext.getContentResolver();
- int recordedApiLevel = android.os.Build.VERSION.SDK_INT;
- try {
- recordedApiLevel = CMSettings.Secure.getInt(resolver,
- CMSettings.Secure.THEME_PREV_BOOT_API_LEVEL);
- } catch (CMSettings.CMSettingNotFoundException e) {
- recordedApiLevel = -1;
- Log.d(TAG, "Previous api level not found. First time booting?");
- }
- Log.d(TAG, "Prev api level was: " + recordedApiLevel
- + ", api is now: " + android.os.Build.VERSION.SDK_INT);
-
- return recordedApiLevel == android.os.Build.VERSION.SDK_INT;
- }
-
- private void updateThemeApi() {
- final ContentResolver resolver = mContext.getContentResolver();
- boolean success = CMSettings.Secure.putInt(resolver,
- CMSettings.Secure.THEME_PREV_BOOT_API_LEVEL, android.os.Build.VERSION.SDK_INT);
- if (!success) {
- Log.e(TAG, "Unable to store latest API level to secure settings");
- }
- }
-
- private void doApplyTheme(ThemeChangeRequest request, boolean removePerAppTheme) {
- synchronized(this) {
- mProgress = 0;
- }
-
- if (request == null || request.getNumChangesRequested() == 0) {
- postFinish(true, request, 0);
- return;
- }
- mIsThemeApplying = true;
- long updateTime = System.currentTimeMillis();
-
- incrementProgress(5);
-
- // TODO: provide progress updates that reflect the time needed for each component
- final int progressIncrement = 75 / request.getNumChangesRequested();
-
- if (request.getIconsThemePackageName() != null) {
- updateIcons(request.getIconsThemePackageName());
- incrementProgress(progressIncrement);
- }
-
- if (request.getWallpaperThemePackageName() != null) {
- if (updateWallpaper(request.getWallpaperThemePackageName(),
- request.getWallpaperId())) {
- mWallpaperChangedByUs = true;
- }
- incrementProgress(progressIncrement);
- }
-
- if (request.getLockWallpaperThemePackageName() != null) {
- updateLockscreen(request.getLockWallpaperThemePackageName());
- incrementProgress(progressIncrement);
- }
-
- Environment.setUserRequired(false);
- if (request.getNotificationThemePackageName() != null) {
- updateNotifications(request.getNotificationThemePackageName());
- incrementProgress(progressIncrement);
- }
-
- if (request.getAlarmThemePackageName() != null) {
- updateAlarms(request.getAlarmThemePackageName());
- incrementProgress(progressIncrement);
- }
-
- if (request.getRingtoneThemePackageName() != null) {
- updateRingtones(request.getRingtoneThemePackageName());
- incrementProgress(progressIncrement);
- }
- Environment.setUserRequired(true);
-
- if (request.getBootanimationThemePackageName() != null) {
- updateBootAnim(request.getBootanimationThemePackageName());
- incrementProgress(progressIncrement);
- }
-
- if (request.getFontThemePackageName() != null) {
- updateFonts(request.getFontThemePackageName());
- incrementProgress(progressIncrement);
- }
-
- if (request.getLiveLockScreenThemePackageName() != null) {
- updateLiveLockScreen(request.getLiveLockScreenThemePackageName());
- incrementProgress(progressIncrement);
- }
-
- try {
- updateProvider(request, updateTime);
- } catch(IllegalArgumentException e) {
- // Safeguard against provider not being ready yet.
- Log.e(TAG, "Not updating the theme provider since it is unavailable");
- }
-
- if (shouldUpdateConfiguration(request)) {
- updateConfiguration(request, removePerAppTheme);
- }
-
- killLaunchers(request);
-
- postFinish(true, request, updateTime);
- mIsThemeApplying = false;
- }
-
- private void doApplyDefaultTheme() {
- final ContentResolver resolver = mContext.getContentResolver();
- final String defaultThemePkg = CMSettings.Secure.getString(resolver,
- CMSettings.Secure.DEFAULT_THEME_PACKAGE);
- if (!TextUtils.isEmpty(defaultThemePkg)) {
- String defaultThemeComponents = CMSettings.Secure.getString(resolver,
- CMSettings.Secure.DEFAULT_THEME_COMPONENTS);
- List<String> components;
- if (TextUtils.isEmpty(defaultThemeComponents)) {
- components = ThemeUtils.getAllComponents();
- } else {
- components = new ArrayList<String>(
- Arrays.asList(defaultThemeComponents.split("\\|")));
- }
- ThemeChangeRequest.Builder builder = new ThemeChangeRequest.Builder();
- for (String component : components) {
- builder.setComponent(component, defaultThemePkg);
- }
- try {
- requestThemeChange(builder.build(), true);
- } catch (RemoteException e) {
- Log.w(TAG, "Unable to set default theme", e);
- }
- }
- }
-
- private void doRebuildResourceCache() {
- FileUtils.deleteContents(new File(ThemeUtils.RESOURCE_CACHE_DIR));
- processInstalledThemes();
- }
-
- private void updateProvider(ThemeChangeRequest request, long updateTime) {
- ContentValues values = new ContentValues();
- values.put(MixnMatchColumns.COL_UPDATE_TIME, updateTime);
- Map<String, String> componentMap = request.getThemeComponentsMap();
- for (String component : componentMap.keySet()) {
- values.put(ThemesContract.MixnMatchColumns.COL_VALUE, componentMap.get(component));
- String where = ThemesContract.MixnMatchColumns.COL_KEY + "=?";
- String[] selectionArgs = { MixnMatchColumns.componentToMixNMatchKey(component) };
- if (selectionArgs[0] == null) {
- continue; // No equivalence between mixnmatch and theme
- }
-
- // Add component ID for multiwallpaper
- if (ThemesColumns.MODIFIES_LAUNCHER.equals(component)) {
- values.put(MixnMatchColumns.COL_COMPONENT_ID, request.getWallpaperId());
- }
-
- mContext.getContentResolver().update(MixnMatchColumns.CONTENT_URI, values, where,
- selectionArgs);
- }
- }
-
- private boolean updateIcons(String pkgName) {
- ThemeUtils.clearIconCache();
- try {
- if (pkgName.equals(SYSTEM_DEFAULT)) {
- mPM.updateIconMaps(null);
- } else {
- mPM.updateIconMaps(pkgName);
- }
- } catch (Exception e) {
- Log.w(TAG, "Changing icons failed", e);
- return false;
- }
- return true;
- }
-
- private boolean updateFonts(String pkgName) {
- //Clear the font dir
- FileUtils.deleteContents(new File(ThemeUtils.SYSTEM_THEME_FONT_PATH));
-
- if (!pkgName.equals(SYSTEM_DEFAULT)) {
- //Get Font Assets
- Context themeCtx;
- String[] assetList;
- try {
- themeCtx = mContext.createPackageContext(pkgName, Context.CONTEXT_IGNORE_SECURITY);
- AssetManager assetManager = themeCtx.getAssets();
- assetList = assetManager.list("fonts");
- } catch (Exception e) {
- Log.e(TAG, "There was an error getting assets for pkg " + pkgName, e);
- return false;
- }
- if (assetList == null || assetList.length == 0) {
- Log.e(TAG, "Could not find any font assets");
- return false;
- }
-
- //Copy font assets to font dir
- for(String asset : assetList) {
- InputStream is = null;
- OutputStream os = null;
- try {
- is = ThemeUtils.getInputStreamFromAsset(themeCtx,
- "file:///android_asset/fonts/" + asset);
- File outFile = new File(ThemeUtils.SYSTEM_THEME_FONT_PATH, asset);
- FileUtils.copyToFile(is, outFile);
- FileUtils.setPermissions(outFile,
- FileUtils.S_IRWXU|FileUtils.S_IRGRP|FileUtils.S_IRWXO, -1, -1);
- } catch (Exception e) {
- Log.e(TAG, "There was an error installing the new fonts for pkg " + pkgName, e);
- return false;
- } finally {
- ThemeUtils.closeQuietly(is);
- ThemeUtils.closeQuietly(os);
- }
- }
- }
-
- //Notify zygote that themes need a refresh
- SystemProperties.set("sys.refresh_theme", "1");
- return true;
- }
-
- private boolean updateBootAnim(String pkgName) {
- if (SYSTEM_DEFAULT.equals(pkgName)) {
- clearBootAnimation();
- return true;
- }
-
- try {
- final ApplicationInfo ai = mPM.getApplicationInfo(pkgName, 0);
- applyBootAnimation(ai.sourceDir);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Changing boot animation failed", e);
- return false;
- }
- return true;
- }
-
- private boolean updateAlarms(String pkgName) {
- return updateAudible(ThemeUtils.SYSTEM_THEME_ALARM_PATH, "alarms",
- RingtoneManager.TYPE_ALARM, pkgName);
- }
-
- private boolean updateNotifications(String pkgName) {
- return updateAudible(ThemeUtils.SYSTEM_THEME_NOTIFICATION_PATH, "notifications",
- RingtoneManager.TYPE_NOTIFICATION, pkgName);
- }
-
- private boolean updateRingtones(String pkgName) {
- return updateAudible(ThemeUtils.SYSTEM_THEME_RINGTONE_PATH, "ringtones",
- RingtoneManager.TYPE_RINGTONE, pkgName);
- }
-
- private boolean updateAudible(String dirPath, String assetPath, int type, String pkgName) {
- //Clear the dir
- ThemeUtils.clearAudibles(mContext, dirPath);
- if (pkgName.equals(SYSTEM_DEFAULT)) {
- if (!ThemeUtils.setDefaultAudible(mContext, type)) {
- Log.e(TAG, "There was an error installing the default audio file");
- return false;
- }
- return true;
- }
-
- PackageInfo pi = null;
- try {
- pi = mPM.getPackageInfo(pkgName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Unable to update audible " + dirPath, e);
- return false;
- }
-
- //Get theme Assets
- Context themeCtx;
- String[] assetList;
- try {
- themeCtx = mContext.createPackageContext(pkgName, Context.CONTEXT_IGNORE_SECURITY);
- AssetManager assetManager = themeCtx.getAssets();
- assetList = assetManager.list(assetPath);
- } catch (Exception e) {
- Log.e(TAG, "There was an error getting assets for pkg " + pkgName, e);
- return false;
- }
- if (assetList == null || assetList.length == 0) {
- Log.e(TAG, "Could not find any audio assets");
- return false;
- }
-
- // TODO: right now we just load the first file but this will need to be changed
- // in the future if multiple audio files are supported.
- final String asset = assetList[0];
- if (!ThemeUtils.isValidAudible(asset)) return false;
-
- InputStream is = null;
- OutputStream os = null;
- try {
- is = ThemeUtils.getInputStreamFromAsset(themeCtx, "file:///android_asset/"
- + assetPath + File.separator + asset);
- File outFile = new File(dirPath, asset);
- FileUtils.copyToFile(is, outFile);
- FileUtils.setPermissions(outFile,
- FileUtils.S_IRWXU|FileUtils.S_IRGRP|FileUtils.S_IRWXO,-1, -1);
- ThemeUtils.setAudible(mContext, outFile, type, pi.themeInfo.name);
- } catch (Exception e) {
- Log.e(TAG, "There was an error installing the new audio file for pkg " + pkgName, e);
- return false;
- } finally {
- ThemeUtils.closeQuietly(is);
- ThemeUtils.closeQuietly(os);
- }
- return true;
- }
-
- private boolean updateLockscreen(String pkgName) {
- boolean success;
- success = setCustomLockScreenWallpaper(pkgName);
-
- if (success) {
- mContext.sendBroadcastAsUser(new Intent(Intent.ACTION_KEYGUARD_WALLPAPER_CHANGED),
- UserHandle.ALL);
- }
- return success;
- }
-
- private boolean setCustomLockScreenWallpaper(String pkgName) {
- WallpaperManager wm = WallpaperManager.getInstance(mContext);
- try {
- if (SYSTEM_DEFAULT.equals(pkgName) || TextUtils.isEmpty(pkgName)) {
- wm.clearKeyguardWallpaper();
- } else {
- InputStream in = ImageUtils.getCroppedKeyguardStream(pkgName, mContext);
- if (in != null) {
- wm.setKeyguardStream(in);
- ThemeUtils.closeQuietly(in);
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "There was an error setting lockscreen wp for pkg " + pkgName, e);
- return false;
- }
- return true;
- }
-
- private boolean updateWallpaper(String pkgName, long id) {
- WallpaperManager wm = WallpaperManager.getInstance(mContext);
- if (SYSTEM_DEFAULT.equals(pkgName)) {
- try {
- wm.clear();
- } catch (IOException e) {
- return false;
- }
- } else if (TextUtils.isEmpty(pkgName)) {
- try {
- wm.clear(false);
- } catch (IOException e) {
- return false;
- }
- } else {
- InputStream in = null;
- try {
- in = ImageUtils.getCroppedWallpaperStream(pkgName, id, mContext);
- if (in != null)
- wm.setStream(in);
- } catch (Exception e) {
- return false;
- } finally {
- ThemeUtils.closeQuietly(in);
- }
- }
- return true;
- }
-
- private boolean updateLiveLockScreen(String pkgName) {
- // TODO: do something meaningful here once ready
- return true;
- }
-
- private boolean updateConfiguration(ThemeChangeRequest request,
- boolean removePerAppThemes) {
- final IActivityManager am = ActivityManagerNative.getDefault();
- if (am != null) {
- final long token = Binder.clearCallingIdentity();
- try {
- Configuration config = am.getConfiguration();
- ThemeConfig.Builder themeBuilder = createBuilderFrom(config, request, null,
- removePerAppThemes);
- ThemeConfig newConfig = themeBuilder.build();
-
- config.themeConfig = newConfig;
- am.updateConfiguration(config);
- } catch (RemoteException e) {
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- return true;
- }
-
- private boolean updateConfiguration(ThemeConfig themeConfig) {
- final IActivityManager am = ActivityManagerNative.getDefault();
- if (am != null) {
- final long token = Binder.clearCallingIdentity();
- try {
- Configuration config = am.getConfiguration();
-
- config.themeConfig = themeConfig;
- am.updateConfiguration(config);
- } catch (RemoteException e) {
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- return true;
- }
-
- private boolean shouldUpdateConfiguration(ThemeChangeRequest request) {
- return request.getOverlayThemePackageName() != null ||
- request.getFontThemePackageName() != null ||
- request.getIconsThemePackageName() != null ||
- request.getStatusBarThemePackageName() != null ||
- request.getNavBarThemePackageName() != null ||
- request.getPerAppOverlays().size() > 0;
- }
-
- private static ThemeConfig.Builder createBuilderFrom(Configuration config,
- ThemeChangeRequest request, String pkgName, boolean removePerAppThemes) {
- ThemeConfig.Builder builder = new ThemeConfig.Builder(config.themeConfig);
-
- if (removePerAppThemes) removePerAppThemesFromConfig(builder, config.themeConfig);
-
- if (request.getIconsThemePackageName() != null) {
- builder.defaultIcon(pkgName == null ? request.getIconsThemePackageName() : pkgName);
- }
-
- if (request.getOverlayThemePackageName() != null) {
- builder.defaultOverlay(pkgName == null ?
- request.getOverlayThemePackageName() : pkgName);
- }
-
- if (request.getFontThemePackageName() != null) {
- builder.defaultFont(pkgName == null ? request.getFontThemePackageName() : pkgName);
- }
-
- if (request.getStatusBarThemePackageName() != null) {
- builder.overlay(ThemeConfig.SYSTEMUI_STATUS_BAR_PKG, pkgName == null ?
- request.getStatusBarThemePackageName() : pkgName);
- }
-
- if (request.getNavBarThemePackageName() != null) {
- builder.overlay(ThemeConfig.SYSTEMUI_NAVBAR_PKG, pkgName == null ?
- request.getNavBarThemePackageName() : pkgName);
- }
-
- // check for any per app overlays being applied
- Map<String, String> appOverlays = request.getPerAppOverlays();
- for (String appPkgName : appOverlays.keySet()) {
- if (appPkgName != null) {
- builder.overlay(appPkgName, appOverlays.get(appPkgName));
- }
- }
-
- builder.setLastThemeChangeRequestType(request.getReqeustType());
-
- return builder;
- }
-
- private static void removePerAppThemesFromConfig(ThemeConfig.Builder builder,
- ThemeConfig themeConfig) {
- if (themeConfig != null) {
- Map<String, ThemeConfig.AppTheme> themes = themeConfig.getAppThemes();
- for (String appPkgName : themes.keySet()) {
- if (ThemeUtils.isPerAppThemeComponent(appPkgName)) {
- builder.overlay(appPkgName, null);
- }
- }
- }
- }
-
- // Kill the current Home process, they tend to be evil and cache
- // drawable references in all apps
- private void killLaunchers(ThemeChangeRequest request) {
- if (request.getOverlayThemePackageName() == null
- && request.getIconsThemePackageName() == null) {
- return;
- }
-
- final ActivityManager am =
- (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
-
- Intent homeIntent = new Intent();
- homeIntent.setAction(Intent.ACTION_MAIN);
- homeIntent.addCategory(Intent.CATEGORY_HOME);
-
- List<ResolveInfo> infos = mPM.queryIntentActivities(homeIntent, 0);
- List<ResolveInfo> themeChangeInfos = mPM.queryBroadcastReceivers(
- new Intent(ThemeUtils.ACTION_THEME_CHANGED), 0);
- for(ResolveInfo info : infos) {
- if (info.activityInfo != null && info.activityInfo.applicationInfo != null &&
- !isSetupActivity(info) && !handlesThemeChanges(
- info.activityInfo.applicationInfo.packageName, themeChangeInfos)) {
- String pkgToStop = info.activityInfo.applicationInfo.packageName;
- Log.d(TAG, "Force stopping " + pkgToStop + " for theme change");
- try {
- am.forceStopPackage(pkgToStop);
- } catch(Exception e) {
- Log.e(TAG, "Unable to force stop package, did you forget platform signature?",
- e);
- }
- }
- }
- }
-
- private boolean isSetupActivity(ResolveInfo info) {
- return GOOGLE_SETUPWIZARD_PACKAGE.equals(info.activityInfo.packageName) ||
- MANAGED_PROVISIONING_PACKAGE.equals(info.activityInfo.packageName) ||
- CM_SETUPWIZARD_PACKAGE.equals(info.activityInfo.packageName);
- }
-
- private boolean handlesThemeChanges(String pkgName, List<ResolveInfo> infos) {
- if (infos != null && infos.size() > 0) {
- for (ResolveInfo info : infos) {
- if (info.activityInfo.applicationInfo.packageName.equals(pkgName)) {
- return true;
- }
- }
- }
- return false;
- }
-
- private void postProgress() {
- int N = mClients.beginBroadcast();
- for(int i=0; i < N; i++) {
- IThemeChangeListener listener = mClients.getBroadcastItem(0);
- try {
- listener.onProgress(mProgress);
- } catch(RemoteException e) {
- Log.w(TAG, "Unable to post progress to client listener", e);
- }
- }
- mClients.finishBroadcast();
- }
-
- private void postFinish(boolean isSuccess, ThemeChangeRequest request, long updateTime) {
- synchronized(this) {
- mProgress = 0;
- }
-
- int N = mClients.beginBroadcast();
- for(int i=0; i < N; i++) {
- IThemeChangeListener listener = mClients.getBroadcastItem(0);
- try {
- listener.onFinish(isSuccess);
- } catch(RemoteException e) {
- Log.w(TAG, "Unable to post progress to client listener", e);
- }
- }
- mClients.finishBroadcast();
-
- // if successful, broadcast that the theme changed
- if (isSuccess) {
- broadcastThemeChange(request, updateTime);
- }
- }
-
- private void postFinishedProcessing(String pkgName) {
- int N = mProcessingListeners.beginBroadcast();
- for(int i=0; i < N; i++) {
- IThemeProcessingListener listener = mProcessingListeners.getBroadcastItem(0);
- try {
- listener.onFinishedProcessing(pkgName);
- } catch(RemoteException e) {
- Log.w(TAG, "Unable to post progress to listener", e);
- }
- }
- mProcessingListeners.finishBroadcast();
- }
-
- private void broadcastThemeChange(ThemeChangeRequest request, long updateTime) {
- Map<String, String> componentMap = request.getThemeComponentsMap();
- if (componentMap == null || componentMap.size() == 0) return;
-
- final Intent intent = new Intent(ThemeUtils.ACTION_THEME_CHANGED);
- ArrayList componentsArrayList = new ArrayList(componentMap.keySet());
- intent.putStringArrayListExtra(ThemeUtils.EXTRA_COMPONENTS, componentsArrayList);
- intent.putExtra(ThemeUtils.EXTRA_REQUEST_TYPE, request.getReqeustType().ordinal());
- intent.putExtra(ThemeUtils.EXTRA_UPDATE_TIME, updateTime);
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- private void incrementProgress(int increment) {
- synchronized(this) {
- mProgress += increment;
- if (mProgress > 100) mProgress = 100;
- }
- postProgress();
- }
-
- @Override
- public void requestThemeChangeUpdates(IThemeChangeListener listener) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- mClients.register(listener);
- }
-
- @Override
- public void removeUpdates(IThemeChangeListener listener) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- mClients.unregister(listener);
- }
-
- @Override
- public void requestThemeChange(ThemeChangeRequest request, boolean removePerAppThemes)
- throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- Message msg;
-
- /**
- * Since the ThemeService handles compiling theme resource we need to make sure that any
- * of the components we are trying to apply are either already processed or put to the
- * front of the queue and handled before the theme change takes place.
- *
- * TODO: create a callback that can be sent to any ThemeChangeListeners to notify them that
- * the theme will be applied once the processing is done.
- */
- synchronized (mThemesToProcessQueue) {
- Map<String, String> componentMap = request.getThemeComponentsMap();
- for (Object key : componentMap.keySet()) {
- if (ThemesColumns.MODIFIES_OVERLAYS.equals(key) ||
- ThemesColumns.MODIFIES_NAVIGATION_BAR.equals(key) ||
- ThemesColumns.MODIFIES_STATUS_BAR.equals(key) ||
- ThemesColumns.MODIFIES_ICONS.equals(key)) {
- String pkgName = (String) componentMap.get(key);
- if (mThemesToProcessQueue.indexOf(pkgName) > 0) {
- mThemesToProcessQueue.remove(pkgName);
- mThemesToProcessQueue.add(0, pkgName);
- // We want to make sure these resources are taken care of first so
- // send the dequeue message and place it in the front of the queue
- msg = mResourceProcessingHandler.obtainMessage(
- ResourceProcessingHandler.MESSAGE_DEQUEUE_AND_PROCESS_THEME);
- mResourceProcessingHandler.sendMessageAtFrontOfQueue(msg);
- }
- }
- }
- }
- msg = Message.obtain();
- msg.what = ThemeWorkerHandler.MESSAGE_CHANGE_THEME;
- msg.obj = request;
- msg.arg1 = removePerAppThemes ? 1 : 0;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void applyDefaultTheme() {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- Message msg = Message.obtain();
- msg.what = ThemeWorkerHandler.MESSAGE_APPLY_DEFAULT_THEME;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public boolean isThemeApplying() throws RemoteException {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_THEME_MANAGER, null);
- return mIsThemeApplying;
- }
-
- @Override
- public int getProgress() throws RemoteException {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_THEME_MANAGER, null);
- synchronized(this) {
- return mProgress;
- }
- }
-
- @Override
- public boolean cacheComposedIcon(Bitmap icon, String fileName) throws RemoteException {
- final long token = Binder.clearCallingIdentity();
- boolean success;
- FileOutputStream os;
- final File cacheDir = new File(ThemeUtils.SYSTEM_THEME_ICON_CACHE_DIR);
- if (cacheDir.listFiles().length == 0) {
- mIconCacheSize = 0;
- }
- try {
- File outFile = new File(cacheDir, fileName);
- os = new FileOutputStream(outFile);
- icon.compress(Bitmap.CompressFormat.PNG, 90, os);
- os.close();
- FileUtils.setPermissions(outFile,
- FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH,
- -1, -1);
- mIconCacheSize += outFile.length();
- if (mIconCacheSize > MAX_ICON_CACHE_SIZE) {
- purgeIconCache();
- }
- success = true;
- } catch (Exception e) {
- success = false;
- Log.w(TAG, "Unable to cache icon " + fileName, e);
- }
- Binder.restoreCallingIdentity(token);
- return success;
- }
-
- @Override
- public boolean processThemeResources(String themePkgName) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- try {
- mPM.getPackageInfo(themePkgName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- // Package doesn't exist so nothing to process
- return false;
- }
- // Obtain a message and send it to the handler to process this theme
- Message msg = mResourceProcessingHandler.obtainMessage(
- ResourceProcessingHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING, 0, 0, themePkgName);
- mResourceProcessingHandler.sendMessage(msg);
- return true;
- }
-
- @Override
- public boolean isThemeBeingProcessed(String themePkgName) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- synchronized (mThemesToProcessQueue) {
- return mThemesToProcessQueue.contains(themePkgName);
- }
- }
-
- @Override
- public void registerThemeProcessingListener(IThemeProcessingListener listener)
- throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- mProcessingListeners.register(listener);
- }
-
- @Override
- public void unregisterThemeProcessingListener(IThemeProcessingListener listener)
- throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- mProcessingListeners.unregister(listener);
- }
-
- @Override
- public void rebuildResourceCache() throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- mHandler.sendEmptyMessage(ThemeWorkerHandler.MESSAGE_REBUILD_RESOURCE_CACHE);
- }
-
- private void purgeIconCache() {
- Log.d(TAG, "Purging icon cahe of size " + mIconCacheSize);
- File cacheDir = new File(ThemeUtils.SYSTEM_THEME_ICON_CACHE_DIR);
- File[] files = cacheDir.listFiles();
- Arrays.sort(files, mOldestFilesFirstComparator);
- for (File f : files) {
- if (!f.isDirectory()) {
- final long size = f.length();
- if(f.delete()) mIconCacheSize -= size;
- }
- if (mIconCacheSize <= PURGED_ICON_CACHE_SIZE) break;
- }
- }
-
- private boolean applyBootAnimation(String themePath) {
- boolean success = false;
- try {
- ZipFile zip = new ZipFile(new File(themePath));
- ZipEntry ze = zip.getEntry(THEME_BOOTANIMATION_PATH);
- if (ze != null) {
- clearBootAnimation();
- BufferedInputStream is = new BufferedInputStream(zip.getInputStream(ze));
- final String bootAnimationPath = SYSTEM_THEME_PATH + File.separator
- + "bootanimation.zip";
- ThemeUtils.copyAndScaleBootAnimation(mContext, is, bootAnimationPath);
- FileUtils.setPermissions(bootAnimationPath,
- FileUtils.S_IRWXU|FileUtils.S_IRGRP|FileUtils.S_IROTH, -1, -1);
- }
- zip.close();
- success = true;
- } catch (Exception e) {
- Log.w(TAG, "Unable to load boot animation for " + themePath, e);
- }
-
- return success;
- }
-
- private void clearBootAnimation() {
- File anim = new File(SYSTEM_THEME_PATH + File.separator + "bootanimation.zip");
- if (anim.exists())
- anim.delete();
- }
-
- private BroadcastReceiver mWallpaperChangeReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!mWallpaperChangedByUs) {
- // In case the mixnmatch table has a mods_launcher entry, we'll clear it
- ThemeChangeRequest.Builder builder = new ThemeChangeRequest.Builder();
- builder.setWallpaper("");
- updateProvider(builder.build(), System.currentTimeMillis());
- } else {
- mWallpaperChangedByUs = false;
- }
- }
- };
-
- private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
- if (userHandle >= 0 && userHandle != mCurrentUserId) {
- mCurrentUserId = userHandle;
- ThemeConfig config = ThemeConfig.getBootThemeForUser(mContext.getContentResolver(),
- userHandle);
- if (DEBUG) {
- Log.d(TAG,
- "Changing theme for user " + userHandle + " to " + config.toString());
- }
- ThemeChangeRequest request = new ThemeChangeRequest.Builder(config).build();
- try {
- requestThemeChange(request, true);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to change theme for user change", e);
- }
- }
- }
- };
-
- private Comparator<File> mOldestFilesFirstComparator = new Comparator<File>() {
- @Override
- public int compare(File lhs, File rhs) {
- return (int) (lhs.lastModified() - rhs.lastModified());
- }
- };
-
- private void processInstalledThemes() {
- final String defaultTheme = getDefaultThemePackageName(mContext);
- Message msg;
- // Make sure the default theme is the first to get processed!
- if (!ThemeConfig.SYSTEM_DEFAULT.equals(defaultTheme)) {
- msg = mHandler.obtainMessage(
- ResourceProcessingHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING,
- 0, 0, defaultTheme);
- mResourceProcessingHandler.sendMessage(msg);
- }
- // Iterate over all installed packages and queue up the ones that are themes or icon packs
- List<PackageInfo> packages = mPM.getInstalledPackages(0);
- for (PackageInfo info : packages) {
- if (!defaultTheme.equals(info.packageName) &&
- (info.isThemeApk || info.isLegacyIconPackApk)) {
- msg = mHandler.obtainMessage(
- ResourceProcessingHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING,
- 0, 0, info.packageName);
- mResourceProcessingHandler.sendMessage(msg);
- }
- }
- }
-
- private void sendThemeResourcesCachedBroadcast(String themePkgName, int resultCode) {
- final Intent intent = new Intent(Intent.ACTION_THEME_RESOURCES_CACHED);
- intent.putExtra(Intent.EXTRA_THEME_PACKAGE_NAME, themePkgName);
- intent.putExtra(Intent.EXTRA_THEME_RESULT, resultCode);
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- /**
- * Posts a notification to let the user know the theme was not installed.
- * @param name
- */
- private void postFailedThemeInstallNotification(String name) {
- NotificationManager nm =
- (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- Notification notice = new Notification.Builder(mContext)
- .setAutoCancel(true)
- .setOngoing(false)
- .setContentTitle(
- mContext.getString(R.string.theme_install_error_title))
- .setContentText(String.format(mContext.getString(
- R.string.theme_install_error_message),
- name))
- .setSmallIcon(android.R.drawable.stat_notify_error)
- .setWhen(System.currentTimeMillis())
- .build();
- nm.notify(name.hashCode(), notice);
- }
-
- private String getThemeName(PackageInfo pi) {
- if (pi.themeInfo != null) {
- return pi.themeInfo.name;
- } else if (pi.isLegacyIconPackApk) {
- return pi.applicationInfo.name;
- }
-
- return null;
- }
-
- /**
- * Get the default theme package name
- * Historically this was done using {@link ThemeUtils#getDefaultThemePackageName(Context)} but
- * the setting that is queried in that method uses the AOSP settings provider but the setting
- * is now in CMSettings. Since {@link ThemeUtils} is in the core framework we cannot access
- * CMSettings.
- * @param context
- * @return Default theme package name
- */
- private static String getDefaultThemePackageName(Context context) {
- final String defaultThemePkg = CMSettings.Secure.getString(context.getContentResolver(),
- CMSettings.Secure.DEFAULT_THEME_PACKAGE);
- if (!TextUtils.isEmpty(defaultThemePkg)) {
- PackageManager pm = context.getPackageManager();
- try {
- if (pm.getPackageInfo(defaultThemePkg, 0) != null) {
- return defaultThemePkg;
- }
- } catch (PackageManager.NameNotFoundException e) {
- // doesn't exist so system will be default
- Log.w(TAG, "Default theme " + defaultThemePkg + " not found", e);
- }
- }
-
- return SYSTEM_DEFAULT;
- }
-}
diff --git a/services/core/java/com/android/server/ThermalObserver.java b/services/core/java/com/android/server/ThermalObserver.java
new file mode 100644
index 0000000..aee28fb
--- /dev/null
+++ b/services/core/java/com/android/server/ThermalObserver.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2015 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 com.android.server;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.UEventObserver;
+import android.os.UserHandle;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * ThermalObserver for monitoring temperature changes.
+ */
+public class ThermalObserver extends SystemService {
+ private static final String TAG = "ThermalObserver";
+
+ private static final String CALLSTATE_UEVENT_MATCH =
+ "DEVPATH=/devices/virtual/switch/thermalstate";
+
+ private static final int MSG_THERMAL_STATE_CHANGED = 0;
+
+ private static final int SWITCH_STATE_NORMAL = 0;
+ private static final int SWITCH_STATE_WARNING = 1;
+ private static final int SWITCH_STATE_EXCEEDED = 2;
+
+ private final PowerManager mPowerManager;
+ private final PowerManager.WakeLock mWakeLock;
+
+ private final Object mLock = new Object();
+ private Integer mLastState;
+
+ private final UEventObserver mThermalWarningObserver = new UEventObserver() {
+ @Override
+ public void onUEvent(UEventObserver.UEvent event) {
+ updateLocked(Integer.parseInt(event.get("SWITCH_STATE")));
+ }
+ };
+
+ private final Handler mHandler = new Handler(true /*async*/) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_THERMAL_STATE_CHANGED:
+ handleThermalStateChange(msg.arg1);
+ mWakeLock.release();
+ break;
+ }
+ }
+ };
+
+ public ThermalObserver(Context context) {
+ super(context);
+ mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+
+ mThermalWarningObserver.startObserving(CALLSTATE_UEVENT_MATCH);
+ }
+
+ private void updateLocked(int state) {
+ Message message = new Message();
+ message.what = MSG_THERMAL_STATE_CHANGED;
+ message.arg1 = state;
+
+ mWakeLock.acquire();
+ mHandler.sendMessage(message);
+ }
+
+ private void handleThermalStateChange(int state) {
+ synchronized (mLock) {
+ mLastState = state;
+ Intent intent = new Intent(Intent.ACTION_THERMAL_EVENT);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+
+ final int thermalState;
+
+ switch (state) {
+ case SWITCH_STATE_WARNING:
+ thermalState = Intent.EXTRA_THERMAL_STATE_WARNING;
+ break;
+ case SWITCH_STATE_EXCEEDED:
+ thermalState = Intent.EXTRA_THERMAL_STATE_EXCEEDED;
+ break;
+ case SWITCH_STATE_NORMAL:
+ default:
+ thermalState = Intent.EXTRA_THERMAL_STATE_NORMAL;
+ break;
+ }
+
+ intent.putExtra(Intent.EXTRA_THERMAL_STATE, thermalState);
+
+ getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
+ }
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(TAG, new BinderService());
+ }
+
+ private final class BinderService extends Binder {
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump thermal observer service from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ if (args == null || args.length == 0 || "-a".equals(args[0])) {
+ pw.println("Current Thermal Observer Service state:");
+ pw.println(" last state change: "
+ + (mLastState != null ? mLastState : "none"));
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index c228422..f637c4f 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -24,6 +24,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
+import android.net.Uri;
import android.os.BatteryStats;
import android.os.Handler;
import android.os.IVibratorService;
@@ -55,6 +56,9 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
+import cyanogenmod.hardware.CMHardwareManager;
+import cyanogenmod.providers.CMSettings;
+
public class VibratorService extends IVibratorService.Stub
implements InputManager.InputDeviceListener {
private static final String TAG = "VibratorService";
@@ -86,6 +90,10 @@ public class VibratorService extends IVibratorService.Stub
private int mCurVibUid = -1;
private boolean mLowPowerMode;
private SettingsObserver mSettingObserver;
+ private CMHardwareManager mHardware;
+ private int mMinVibratorIntensity;
+ private int mMaxVibratorIntensity;
+ private int mVibratorIntensity;
native static boolean vibratorExists();
native static void vibratorOn(long milliseconds);
@@ -241,9 +249,20 @@ public class VibratorService extends IVibratorService.Stub
@Override
public void onReceive(Context context, Intent intent) {
updateInputDeviceVibrators();
+ updateVibratorIntensity();
}
}, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mH);
+ mHardware = CMHardwareManager.getInstance(mContext);
+ if (mHardware.isSupported(CMHardwareManager.FEATURE_VIBRATOR)) {
+ mContext.getContentResolver().registerContentObserver(
+ CMSettings.Secure.getUriFor(CMSettings.Secure.VIBRATOR_INTENSITY),
+ true, mSettingObserver, UserHandle.USER_ALL);
+ mMinVibratorIntensity = mHardware.getVibratorMinIntensity();
+ mMaxVibratorIntensity = mHardware.getVibratorMaxIntensity();
+ updateVibratorIntensity();
+ }
+
updateInputDeviceVibrators();
}
@@ -253,11 +272,22 @@ public class VibratorService extends IVibratorService.Stub
}
@Override
- public void onChange(boolean SelfChange) {
- updateInputDeviceVibrators();
+ public void onChange(boolean selfChange, Uri uri) {
+ if (uri.equals(CMSettings.Secure.getUriFor(CMSettings.Secure.VIBRATOR_INTENSITY))) {
+ updateVibratorIntensity();
+ } else {
+ updateInputDeviceVibrators();
+ }
}
}
+ private void updateVibratorIntensity() {
+ mVibratorIntensity = CMSettings.Secure.getIntForUser(mContext.getContentResolver(),
+ CMSettings.Secure.VIBRATOR_INTENSITY, mHardware.getVibratorDefaultIntensity(),
+ UserHandle.USER_CURRENT);
+ mHardware.setVibratorIntensity(mVibratorIntensity);
+ }
+
@Override // Binder call
public boolean hasVibrator() {
return doVibratorExists();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 542268e..db3d474 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -121,6 +121,10 @@ public final class ActiveServices {
// at the same time.
final int mMaxStartingBackground;
+ // Flag to reschedule the services during app launch. Disable by default.
+ private static final boolean SERVICE_RESCHEDULE
+ = SystemProperties.getBoolean("ro.am.reschedule_service", false);
+
final SparseArray<ServiceMap> mServiceMap = new SparseArray<>();
/**
@@ -1229,6 +1233,14 @@ public final class ActiveServices {
r.pendingStarts.add(0, si);
long dur = SystemClock.uptimeMillis() - si.deliveredTime;
dur *= 2;
+ if (SERVICE_RESCHEDULE && DEBUG_DELAYED_SERVICE) {
+ Slog.w(TAG,"Can add more delay !!!"
+ +" si.deliveredTime "+si.deliveredTime
+ +" dur "+dur
+ +" si.deliveryCount "+si.deliveryCount
+ +" si.doneExecutingCount "+si.doneExecutingCount
+ +" allowCancel "+allowCancel);
+ }
if (minDuration < dur) minDuration = dur;
if (resetTime < dur) resetTime = dur;
} else {
@@ -1241,6 +1253,13 @@ public final class ActiveServices {
}
r.totalRestartCount++;
+ if (SERVICE_RESCHEDULE && DEBUG_DELAYED_SERVICE) {
+ Slog.w(TAG,"r.name "+r.name+" N "+N+" minDuration "+minDuration
+ +" resetTime "+resetTime+" now "+now
+ +" r.restartDelay "+r.restartDelay
+ +" r.restartTime+resetTime "+(r.restartTime+resetTime)
+ +" allowCancel "+allowCancel);
+ }
if (r.restartDelay == 0) {
r.restartCount++;
r.restartDelay = minDuration;
@@ -1262,6 +1281,14 @@ public final class ActiveServices {
}
r.nextRestartTime = now + r.restartDelay;
+ if (SERVICE_RESCHEDULE && DEBUG_DELAYED_SERVICE) {
+ Slog.w(TAG,"r.name "+r.name+" N "+N+" minDuration "+minDuration
+ +" resetTime "+resetTime+" now "+now
+ +" r.restartDelay "+r.restartDelay
+ +" r.restartTime+resetTime "+(r.restartTime+resetTime)
+ +" r.nextRestartTime "+r.nextRestartTime
+ +" allowCancel "+allowCancel);
+ }
// Make sure that we don't end up restarting a bunch of services
// all at the same time.
@@ -1304,6 +1331,15 @@ public final class ActiveServices {
r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Slog.w(TAG, "Scheduling restart of crashed service "
+ r.shortName + " in " + r.restartDelay + "ms");
+
+ if (SERVICE_RESCHEDULE && DEBUG_DELAYED_SERVICE) {
+ for (int i=mRestartingServices.size()-1; i>=0; i--) {
+ ServiceRecord r2 = mRestartingServices.get(i);
+ Slog.w(TAG,"Restarting list - i "+i+" r2.nextRestartTime "
+ +r2.nextRestartTime+" r2.name "+r2.name);
+ }
+ }
+
EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
r.userId, r.shortName, r.restartDelay);
@@ -1324,7 +1360,31 @@ public final class ActiveServices {
return;
}
try {
- bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
+ if(SERVICE_RESCHEDULE == true) {
+ boolean shouldDelay = false;
+ ActivityRecord top_rc = null;
+ ActivityStack stack = mAm.getFocusedStack();
+ if(stack != null) {
+ top_rc = stack.topRunningActivityLocked(null);
+ }
+ if(top_rc != null) {
+ if(!top_rc.nowVisible && !r.shortName.contains(top_rc.packageName)) {
+ shouldDelay = true;
+ }
+ }
+ if(!shouldDelay) {
+ bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
+ } else {
+ if (DEBUG_DELAYED_SERVICE) {
+ Slog.v(TAG, "Reschedule service restart due to app launch"
+ +" r.shortName "+r.shortName+" r.app = "+r.app);
+ }
+ r.resetRestartCounter();
+ scheduleServiceRestartLocked(r, true);
+ }
+ } else {
+ bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
+ }
} catch (TransactionTooLargeException e) {
// Ignore, it's been logged and nothing upstack cares.
}
@@ -1547,6 +1607,11 @@ public final class ActiveServices {
if (newService) {
app.services.remove(r);
r.app = null;
+ if (SERVICE_RESCHEDULE && DEBUG_DELAYED_SERVICE) {
+ Slog.w(TAG, " Failed to create Service !!!! ."
+ +"This will introduce huge delay... "
+ +r.shortName + " in " + r.restartDelay + "ms");
+ }
}
// Retry.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f6c3bf5..def4c59 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -174,7 +174,6 @@ import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
-import android.content.pm.ThemeUtils;
import android.content.pm.UserInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PathPermission;
@@ -268,6 +267,8 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.Date;
import java.text.SimpleDateFormat;
+import org.cyanogenmod.internal.util.ThemeUtils;
+
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
@@ -333,6 +334,11 @@ public final class ActivityManagerService extends ActivityManagerNative
// before we decide it must be hung.
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
+ // How long we will retain processes hosting content providers in the "last activity"
+ // state before allowing them to drop down to the regular cached LRU list. This is
+ // to avoid thrashing of provider processes under low memory situations.
+ static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
+
// How long we wait for a launched process to attach to the activity manager
// before we decide it's never going to come up for real, when the process was
// started with a wrapper for instrumentation (such as Valgrind) because it
@@ -1400,6 +1406,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int POST_PRIVACY_NOTIFICATION_MSG = 60;
static final int CANCEL_PRIVACY_NOTIFICATION_MSG = 61;
static final int POST_COMPONENT_PROTECTED_MSG = 62;
+ static final int CANCEL_PROTECTED_APP_NOTIFICATION = 63;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -2237,6 +2244,20 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Unable to create context for protected app notification", e);
}
} break;
+ case CANCEL_PROTECTED_APP_NOTIFICATION: {
+ INotificationManager inm = NotificationManager.getService();
+ if (inm == null) {
+ return;
+ }
+ try {
+ inm.cancelNotificationWithTag("android", null,
+ R.string.notify_package_component_protected_title, msg.arg1);
+ } catch (RuntimeException e) {
+ Slog.w(ActivityManagerService.TAG,
+ "Error canceling notification for service", e);
+ } catch (RemoteException e) {
+ }
+ } break;
}
}
};
@@ -8584,6 +8605,14 @@ public final class ActivityManagerService extends ActivityManagerNative
return list;
}
+ @Override
+ public boolean isPackageInForeground(String packageName) {
+ synchronized (this) {
+ ActivityRecord activity = mStackSupervisor.topRunningActivityLocked();
+ return activity != null && activity.packageName.equals(packageName);
+ }
+ }
+
/**
* Creates a new RecentTaskInfo from a TaskRecord.
*/
@@ -9693,6 +9722,14 @@ public final class ActivityManagerService extends ActivityManagerNative
if (conn.stableCount == 0 && conn.unstableCount == 0) {
cpr.connections.remove(conn);
conn.client.conProviders.remove(conn);
+ if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
+ // The client is more important than last activity -- note the time this
+ // is happening, so we keep the old provider process around a bit as last
+ // activity to avoid thrashing it.
+ if (cpr.proc != null) {
+ cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
+ }
+ }
stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
return true;
}
@@ -12272,7 +12309,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
private void sendAppFailureBroadcast(String pkgName) {
- Intent intent = new Intent(Intent.ACTION_APP_FAILURE,
+ Intent intent = new Intent(cyanogenmod.content.Intent.ACTION_APP_FAILURE,
(pkgName != null)? Uri.fromParts("package", pkgName, null) : null);
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT_OR_SELF);
}
@@ -15382,6 +15419,10 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
- totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- memInfo.getKernelUsedSizeKb()); pw.println(" kB");
+ } else {
+ pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
+ - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+ - memInfo.getKernelUsedSizeKb());
}
if (!brief) {
if (memInfo.getZramTotalSizeKb() != 0) {
@@ -18539,6 +18580,18 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
+ if (adj > ProcessList.PREVIOUS_APP_ADJ) {
+ adj = ProcessList.PREVIOUS_APP_ADJ;
+ schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
+ app.cached = false;
+ app.adjType = "provider";
+ }
+ if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
+ procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+ }
+ }
+
if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
// A client of one of our services or providers is in the top state. We
// *may* want to be in the top state, but not if we are already running in
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index f48b448..f439966 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -25,6 +25,7 @@ import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+import android.text.TextUtils;
import android.util.ArraySet;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
@@ -271,6 +272,8 @@ final class ActivityStack {
}
private final PerformanceManagerInternal mPerf;
+ private static final String PROTECTED_APPS_TARGET_VALIDATION_COMPONENT =
+ "com.android.settings/com.android.settings.applications.ProtectedAppsActivity";
final Handler mHandler;
@@ -1144,6 +1147,7 @@ final class ActivityStack {
}
updatePrivacyGuardNotificationLocked(next);
+ updateProtectedAppNotificationLocked(next);
}
private void setVisible(ActivityRecord r, boolean visible) {
@@ -2100,6 +2104,16 @@ final class ActivityStack {
updateTaskMovement(task, true);
}
+ private final void updateProtectedAppNotificationLocked(ActivityRecord next) {
+ ComponentName componentName = ComponentName.unflattenFromString(next.shortComponentName);
+ if (TextUtils.equals(componentName.flattenToString(),
+ PROTECTED_APPS_TARGET_VALIDATION_COMPONENT)) {
+ Message msg = mService.mHandler.obtainMessage(
+ ActivityManagerService.CANCEL_PROTECTED_APP_NOTIFICATION, next);
+ msg.sendToTarget();
+ }
+ }
+
private final void updatePrivacyGuardNotificationLocked(ActivityRecord next) {
String privacyGuardPackageName = mStackSupervisor.mPrivacyGuardPackageName;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 62768c3..5fd3510 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006-2007 The Android Open Source Project
+ * Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,6 +51,8 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.DockBatteryStatsImpl;
+
import com.android.internal.os.PowerProfile;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -75,6 +78,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub
static IBatteryStats sService;
final BatteryStatsImpl mStats;
+ // The dock stats only collect statistics about battery (no wakelocks, no counters, ...),
+ // just the dock battery history
+ final DockBatteryStatsImpl mDockStats;
final BatteryStatsHandler mHandler;
Context mContext;
PowerManagerInternal mPowerManagerInternal;
@@ -167,6 +173,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
// BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
mStats = new BatteryStatsImpl(systemDir, handler, mHandler);
+ mDockStats = new DockBatteryStatsImpl(systemDir, handler, mHandler);
}
public void publish(Context context) {
@@ -196,6 +203,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub
synchronized (mStats) {
mStats.shutdownLocked();
}
+ synchronized (mDockStats) {
+ mDockStats.shutdownLocked();
+ }
}
public static IBatteryStats getService() {
@@ -231,6 +241,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub
mHandler.sendEmptyMessage(BatteryStatsHandler.MSG_WRITE_TO_DISK);
}
+ /**
+ * @return the current dock statistics object, which may be modified
+ * to reflect events that affect battery usage. You must lock the
+ * stats object before doing anything with it.
+ * @hide
+ */
+ public BatteryStatsImpl getActiveDockStatistics() {
+ return mDockStats;
+ }
+
// These are for direct use by the activity manager...
/**
@@ -327,6 +347,48 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
}
+ /** @hide */
+ public byte[] getDockStatistics() {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.BATTERY_STATS, null);
+ //Slog.i("foo", "SENDING DOCK BATTERY INFO:");
+ //mDockStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
+ Parcel out = Parcel.obtain();
+ mDockStats.writeToParcel(out, 0);
+ byte[] data = out.marshall();
+ out.recycle();
+ return data;
+ }
+
+ /** @hide */
+ public ParcelFileDescriptor getDockStatisticsStream() {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.BATTERY_STATS, null);
+ //Slog.i("foo", "SENDING DOCK BATTERY INFO:");
+ //mDockStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
+ Parcel out = Parcel.obtain();
+ mDockStats.writeToParcel(out, 0);
+ byte[] data = out.marshall();
+ out.recycle();
+ try {
+ return ParcelFileDescriptor.fromData(data, "dock-battery-stats");
+ } catch (IOException e) {
+ Slog.w(TAG, "Unable to create shared memory", e);
+ return null;
+ }
+ }
+
+ public void resetStatistics() {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.RESET_BATTERY_STATS, null);
+ synchronized (mStats) {
+ mStats.resetAllStatsCmdLocked();
+ }
+ synchronized (mDockStats) {
+ mDockStats.resetAllStatsCmdLocked();
+ }
+ }
+
public long computeBatteryTimeRemaining() {
synchronized (mStats) {
long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
@@ -901,6 +963,31 @@ public final class BatteryStatsService extends IBatteryStats.Stub
return mStats.getAwakeTimePlugged();
}
+ /** @hide */
+ public boolean isOnDockBattery() {
+ return mDockStats.isOnBattery();
+ }
+
+ /** @hide */
+ public void setDockBatteryState(int status, int health, int plugType, int level,
+ int temp, int volt) {
+ enforceCallingPermission();
+ mDockStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
+ }
+
+ /** @hide */
+ public long getAwakeTimeDockBattery() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.BATTERY_STATS, null);
+ return mDockStats.getAwakeTimeBattery();
+ }
+
+ public long getAwakeTimeDockPlugged() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.BATTERY_STATS, null);
+ return mDockStats.getAwakeTimePlugged();
+ }
+
public void enforceCallingPermission() {
if (Binder.getCallingPid() == Process.myPid()) {
return;
@@ -1065,6 +1152,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
} else if ("--reset".equals(arg)) {
synchronized (mStats) {
mStats.resetAllStatsCmdLocked();
+ mDockStats.resetAllStatsCmdLocked();
pw.println("Battery stats reset.");
noOutput = true;
}
@@ -1073,6 +1161,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
updateExternalStats("dump", UPDATE_ALL);
synchronized (mStats) {
mStats.writeSyncLocked();
+ mDockStats.writeSyncLocked();
pw.println("Battery stats written.");
noOutput = true;
}
@@ -1176,19 +1265,44 @@ public final class BatteryStatsService extends IBatteryStats.Stub
+ mStats.mCheckinFile.getBaseFile(), e);
}
}
+ if (mDockStats.mCheckinFile.exists()) {
+ try {
+ byte[] raw = mDockStats.mCheckinFile.readFully();
+ if (raw != null) {
+ Parcel in = Parcel.obtain();
+ in.unmarshall(raw, 0, raw.length);
+ in.setDataPosition(0);
+ DockBatteryStatsImpl checkinStats = new DockBatteryStatsImpl(
+ null, mStats.mHandler, null);
+ checkinStats.readSummaryFromParcel(in);
+ in.recycle();
+ checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
+ historyStart);
+ mDockStats.mCheckinFile.delete();
+ return;
+ }
+ } catch (IOException e) {
+ Slog.w(TAG, "Failure reading dock checkin file "
+ + mDockStats.mCheckinFile.getBaseFile(), e);
+ }
+ }
}
}
synchronized (mStats) {
mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
+ mDockStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
if (writeData) {
mStats.writeAsyncLocked();
+ mDockStats.writeAsyncLocked();
}
}
} else {
synchronized (mStats) {
mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
+ mDockStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
if (writeData) {
mStats.writeAsyncLocked();
+ mDockStats.writeAsyncLocked();
}
}
}
diff --git a/services/core/java/com/android/server/am/LockTaskNotify.java b/services/core/java/com/android/server/am/LockTaskNotify.java
index d1917db..055e33e 100644
--- a/services/core/java/com/android/server/am/LockTaskNotify.java
+++ b/services/core/java/com/android/server/am/LockTaskNotify.java
@@ -21,13 +21,13 @@ import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
-import android.view.IWindowManager;
+import android.os.UserHandle;
import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
import com.android.internal.R;
+import cyanogenmod.providers.CMSettings;
/**
* Helper to manage showing/hiding a image to notify them that they are entering
@@ -40,23 +40,19 @@ public class LockTaskNotify {
private final H mHandler;
private AccessibilityManager mAccessibilityManager;
private Toast mLastToast;
- private final IWindowManager mWindowManagerService;
public LockTaskNotify(Context context) {
mContext = context;
mAccessibilityManager = (AccessibilityManager)
mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
mHandler = new H();
- mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
}
private boolean hasNavigationBar() {
- try {
- return mWindowManagerService.hasNavigationBar();
- } catch (RemoteException e) {
- //ignore
- }
- return false;
+ return mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_showNavigationBar)
+ || CMSettings.Secure.getIntForUser(mContext.getContentResolver(),
+ CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR, 0, UserHandle.USER_CURRENT) == 1;
}
public void showToast(int lockTaskModeState) {
@@ -67,9 +63,9 @@ public class LockTaskNotify {
final int textResId;
if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_LOCKED) {
textResId = R.string.lock_to_app_toast_locked;
- } else if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_PINNED) {
- textResId = mAccessibilityManager.isEnabled()
- ? R.string.lock_to_app_toast_accessible : R.string.lock_to_app_toast;
+ } else if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_PINNED &&
+ mAccessibilityManager.isEnabled() && hasNavigationBar()) {
+ textResId = R.string.lock_to_app_toast_accessible;
} else {
textResId = hasNavigationBar()
? R.string.lock_to_app_toast : R.string.lock_to_app_toast_no_navbar;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 9cab95b..33f1a1c 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -136,6 +136,7 @@ final class ProcessRecord {
long curCpuTime; // How long proc has run CPU most recently
long lastRequestedGc; // When we last asked the app to do a gc
long lastLowMemory; // When we last told the app that memory is low
+ long lastProviderTime; // The last time someone else was using a provider in this process.
boolean reportLowMemory; // Set to true when waiting to report low mem
boolean empty; // Is this an empty background process?
boolean cached; // Is this a cached process?
@@ -317,6 +318,11 @@ final class ProcessRecord {
pw.print(" foregroundActivities="); pw.print(foregroundActivities);
pw.print(" (rep="); pw.print(repForegroundActivities); pw.println(")");
}
+ if (lastProviderTime > 0) {
+ pw.print(prefix); pw.print("lastProviderTime=");
+ TimeUtils.formatDuration(lastProviderTime, now, pw);
+ pw.println();
+ }
if (hasStartedServices) {
pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 82c658e..92643ba 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -35,6 +35,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;
@@ -713,6 +714,7 @@ public class AudioService extends IAudioService.Stub {
intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+ intentFilter.addAction(Intent.ACTION_SHUTDOWN);
// TODO merge orientation and rotation
mMonitorOrientation = SystemProperties.getBoolean("ro.audio.monitorOrientation", false);
if (mMonitorOrientation) {
@@ -5083,12 +5085,18 @@ public class AudioService extends IAudioService.Stub {
connType = AudioRoutesInfo.MAIN_HEADSET;
intent.setAction(Intent.ACTION_HEADSET_PLUG);
intent.putExtra("microphone", 1);
+ if (state == 1) {
+ startMusicPlayer();
+ }
} else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE ||
device == AudioSystem.DEVICE_OUT_LINE) {
/*do apps care about line-out vs headphones?*/
connType = AudioRoutesInfo.MAIN_HEADPHONES;
intent.setAction(Intent.ACTION_HEADSET_PLUG);
intent.putExtra("microphone", 0);
+ if (state == 1) {
+ startMusicPlayer();
+ }
} else if (device == AudioSystem.DEVICE_OUT_HDMI ||
device == AudioSystem.DEVICE_OUT_HDMI_ARC) {
connType = AudioRoutesInfo.MAIN_HDMI;
@@ -5121,6 +5129,23 @@ public class AudioService extends IAudioService.Stub {
}
}
+ private void startMusicPlayer() {
+ boolean launchPlayer = CMSettings.System.getIntForUser(mContext.getContentResolver(),
+ CMSettings.System.HEADSET_CONNECT_PLAYER, 0, UserHandle.USER_CURRENT) != 0;
+ TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+
+ if (launchPlayer && !tm.isInCall()) {
+ try {
+ Intent playerIntent = new Intent(Intent.ACTION_MAIN);
+ playerIntent.addCategory(Intent.CATEGORY_APP_MUSIC);
+ playerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(playerIntent);
+ } catch (ActivityNotFoundException | IllegalArgumentException e) {
+ Log.w(TAG, "No music player Activity could be found");
+ }
+ }
+ }
+
private void onSetWiredDeviceConnectionState(int device, int state, String address,
String deviceName, String caller) {
if (DEBUG_DEVICES) {
@@ -5378,6 +5403,8 @@ public class AudioService extends IAudioService.Stub {
int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
UserManagerService.getInstance().setSystemControlledUserRestriction(
UserManager.DISALLOW_RECORD_AUDIO, false, userId);
+ } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
+ AudioSystem.setParameters("dev_shutdown=true");
}
}
} // end class AudioServiceBroadcastReceiver
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 3ec0bee..ef086da 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -2604,32 +2604,17 @@ public class SyncManager {
}
continue;
}
- if (!isOperationValidLocked(op)) {
- operationIterator.remove();
- mSyncStorageEngine.deleteFromPending(op.pendingOperation);
- continue;
- }
- // If the next run time is in the future, even given the flexible scheduling,
- // return the time.
- if (op.effectiveRunTime - op.flexTime > now) {
- if (nextReadyToRunTime > op.effectiveRunTime) {
- nextReadyToRunTime = op.effectiveRunTime;
- }
- if (isLoggable) {
- Log.v(TAG, " Not running sync operation: Sync too far in future."
- + "effective: " + op.effectiveRunTime + " flex: " + op.flexTime
- + " now: " + now);
- }
- continue;
- }
String packageName = getPackageName(op.target);
ApplicationInfo ai = null;
if (packageName != null) {
try {
ai = mContext.getPackageManager().getApplicationInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES
- | PackageManager.GET_DISABLED_COMPONENTS);
+ | PackageManager.GET_DISABLED_COMPONENTS);
} catch (NameNotFoundException e) {
+ operationIterator.remove();
+ mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+ continue;
}
}
// If app is considered idle, then skip for now and backoff
@@ -2644,6 +2629,24 @@ public class SyncManager {
} else {
op.appIdle = false;
}
+ if (!isOperationValidLocked(op)) {
+ operationIterator.remove();
+ mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+ continue;
+ }
+ // If the next run time is in the future, even given the flexible scheduling,
+ // return the time.
+ if (op.effectiveRunTime - op.flexTime > now) {
+ if (nextReadyToRunTime > op.effectiveRunTime) {
+ nextReadyToRunTime = op.effectiveRunTime;
+ }
+ if (isLoggable) {
+ Log.v(TAG, " Not running sync operation: Sync too far in future."
+ + "effective: " + op.effectiveRunTime + " flex: " + op.flexTime
+ + " now: " + now);
+ }
+ continue;
+ }
// Add this sync to be run.
operations.add(op);
}
diff --git a/services/core/java/com/android/server/display/LiveDisplayController.java b/services/core/java/com/android/server/display/LiveDisplayController.java
index 9e6da2d..28f2432 100644
--- a/services/core/java/com/android/server/display/LiveDisplayController.java
+++ b/services/core/java/com/android/server/display/LiveDisplayController.java
@@ -42,19 +42,23 @@ import android.util.Slog;
import com.android.server.LocalServices;
import com.android.server.accessibility.DisplayAdjustmentUtils;
+import com.android.server.pm.UserContentObserver;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
import cyanogenmod.hardware.CMHardwareManager;
import cyanogenmod.providers.CMSettings;
+import cyanogenmod.util.ColorUtils;
import java.io.PrintWriter;
+import java.util.List;
public class LiveDisplayController {
private static final String TAG = "LiveDisplay";
+ private static final String DELIMITER = "|";
private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 1;
private static final int OFF_TEMPERATURE = 6500;
@@ -133,13 +137,6 @@ public class LiveDisplayController {
mDefaultOutdoorLux = mContext.getResources().getInteger(
org.cyanogenmod.platform.internal.R.integer.config_outdoorAmbientLux);
- // Counter used to determine when we should tell the user about this feature.
- // If it's not used after 3 sunsets, we'll show the hint once.
- mHintCounter = CMSettings.System.getIntForUser(mContext.getContentResolver(),
- CMSettings.System.LIVE_DISPLAY_HINTED,
- -3,
- UserHandle.USER_CURRENT);
-
mUseOutdoorMode =
mHardware.isSupported(CMHardwareManager.FEATURE_SUNLIGHT_ENHANCEMENT);
mOutdoorModeIsSelfManaged = mUseOutdoorMode ?
@@ -186,6 +183,12 @@ public class LiveDisplayController {
CMSettings.System.DISPLAY_TEMPERATURE_MODE,
MODE_OFF,
UserHandle.USER_CURRENT);
+ // Counter used to determine when we should tell the user about this feature.
+ // If it's not used after 3 sunsets, we'll show the hint once.
+ mHintCounter = CMSettings.System.getIntForUser(mContext.getContentResolver(),
+ CMSettings.System.LIVE_DISPLAY_HINTED,
+ -3,
+ UserHandle.USER_CURRENT);
// Clear the hint forever
if (mMode != MODE_OFF) {
@@ -213,9 +216,33 @@ public class LiveDisplayController {
}
updateLiveDisplay(mCurrentLux);
+ updateGamma();
+ }
+
+ private void updateGamma() {
+ if (!mHardware.isSupported(CMHardwareManager.FEATURE_DISPLAY_GAMMA_CALIBRATION)) {
+ return;
+ }
+ ContentResolver contentResolver = mContext.getContentResolver();
+ for (int i = 0; i < mHardware.getNumGammaControls(); i++) {
+ List<String> gammaValue = CMSettings.Secure.getDelimitedStringAsList(
+ contentResolver, DELIMITER,
+ CMSettings.Secure.DISPLAY_GAMMA_CALIBRATION_PREFIX + i);
+ if (gammaValue != null) {
+ mHardware.setDisplayGammaCalibration(i, stringArrayToIntArray(gammaValue));
+ }
+ }
}
- private final class SettingsObserver extends ContentObserver {
+ private int[] stringArrayToIntArray(List<String> value) {
+ int[] result = new int[value.size()];
+ for (int i = 0; i < value.size(); i++) {
+ result[i] = Integer.parseInt(value.get(i));
+ }
+ return result;
+ }
+
+ private final class SettingsObserver extends UserContentObserver {
private final Uri DISPLAY_TEMPERATURE_DAY_URI =
CMSettings.System.getUriFor(CMSettings.System.DISPLAY_TEMPERATURE_DAY);
private final Uri DISPLAY_TEMPERATURE_NIGHT_URI =
@@ -244,14 +271,22 @@ public class LiveDisplayController {
cr.registerContentObserver(DISPLAY_LOW_POWER_URI, false, this, UserHandle.USER_ALL);
cr.registerContentObserver(DISPLAY_COLOR_ENHANCE_URI, false, this, UserHandle.USER_ALL);
cr.registerContentObserver(DISPLAY_COLOR_ADJUSTMENT_URI, false, this, UserHandle.USER_ALL);
+ if (mHardware.isSupported(CMHardwareManager.FEATURE_DISPLAY_GAMMA_CALIBRATION)) {
+ for (int i = 0; i < mHardware.getNumGammaControls(); i++) {
+ Uri gammaUri = CMSettings.Secure.getUriFor(
+ CMSettings.Secure.DISPLAY_GAMMA_CALIBRATION_PREFIX + i);
+ cr.registerContentObserver(gammaUri, false, this, UserHandle.USER_ALL);
+ }
+ }
+ observe();
} else {
cr.unregisterContentObserver(this);
+ unobserve();
}
}
@Override
- public void onChange(boolean selfChange, Uri uri) {
- super.onChange(selfChange, uri);
+ protected void update() {
updateSettings();
}
}
@@ -293,7 +328,7 @@ public class LiveDisplayController {
private synchronized void setDisplayTemperature(int temperature) {
mColorTemperature = temperature;
- final float[] rgb = temperatureToRGB(temperature);
+ final float[] rgb = ColorUtils.temperatureToRGB(temperature);
if (!mLowPerformance) {
rgb[0] *= mColorAdjustment[0];
@@ -431,25 +466,6 @@ public class LiveDisplayController {
}
/**
- * Convert a color temperature value (in Kelvin) to a RGB units as floats.
- * This can be used in a transform matrix or hardware gamma control.
- *
- * @param tempK
- * @return
- */
- private static float[] temperatureToRGB(int degreesK) {
- int k = MathUtils.constrain(degreesK, 1000, 20000);
- float a = (k % 100) / 100.0f;
- int i = ((k - 1000)/ 100) * 3;
-
- return new float[] { interp(i, a), interp(i+1, a), interp(i+2, a) };
- }
-
- private static float interp(int i, float a) {
- return MathUtils.lerp((float)sColorTable[i], (float)sColorTable[i+3], a);
- }
-
- /**
* Where is the sun anyway? This calculation determines day or night, and scales
* the value around sunset/sunrise for a smooth transition.
*
@@ -563,7 +579,8 @@ public class LiveDisplayController {
.setStyle(new Notification.BigTextStyle().bigText(mContext.getResources()
.getString(
org.cyanogenmod.platform.internal.R.string.live_display_hint)))
- .setContentIntent(result);
+ .setContentIntent(result)
+ .setAutoCancel(true);
NotificationManager nm =
(NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -630,205 +647,4 @@ public class LiveDisplayController {
pw.println(" mColorEnhancement=" + (mUseColorEnhancement ? mColorEnhancement : "N/A"));
pw.println(" mLowPower=" + (mUseLowPower ? mLowPower : "N/A"));
}
-
- /**
- * This table is a modified version of the original blackbody chart, found here:
- * http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html
- *
- * Created by Ingo Thiel.
- */
- private static final double[] sColorTable = new double[] {
- 1.00000000, 0.18172716, 0.00000000,
- 1.00000000, 0.25503671, 0.00000000,
- 1.00000000, 0.30942099, 0.00000000,
- 1.00000000, 0.35357379, 0.00000000,
- 1.00000000, 0.39091524, 0.00000000,
- 1.00000000, 0.42322816, 0.00000000,
- 1.00000000, 0.45159884, 0.00000000,
- 1.00000000, 0.47675916, 0.00000000,
- 1.00000000, 0.49923747, 0.00000000,
- 1.00000000, 0.51943421, 0.00000000,
- 1.00000000, 0.54360078, 0.08679949,
- 1.00000000, 0.56618736, 0.14065513,
- 1.00000000, 0.58734976, 0.18362641,
- 1.00000000, 0.60724493, 0.22137978,
- 1.00000000, 0.62600248, 0.25591950,
- 1.00000000, 0.64373109, 0.28819679,
- 1.00000000, 0.66052319, 0.31873863,
- 1.00000000, 0.67645822, 0.34786758,
- 1.00000000, 0.69160518, 0.37579588,
- 1.00000000, 0.70602449, 0.40267128,
- 1.00000000, 0.71976951, 0.42860152,
- 1.00000000, 0.73288760, 0.45366838,
- 1.00000000, 0.74542112, 0.47793608,
- 1.00000000, 0.75740814, 0.50145662,
- 1.00000000, 0.76888303, 0.52427322,
- 1.00000000, 0.77987699, 0.54642268,
- 1.00000000, 0.79041843, 0.56793692,
- 1.00000000, 0.80053332, 0.58884417,
- 1.00000000, 0.81024551, 0.60916971,
- 1.00000000, 0.81957693, 0.62893653,
- 1.00000000, 0.82854786, 0.64816570,
- 1.00000000, 0.83717703, 0.66687674,
- 1.00000000, 0.84548188, 0.68508786,
- 1.00000000, 0.85347859, 0.70281616,
- 1.00000000, 0.86118227, 0.72007777,
- 1.00000000, 0.86860704, 0.73688797,
- 1.00000000, 0.87576611, 0.75326132,
- 1.00000000, 0.88267187, 0.76921169,
- 1.00000000, 0.88933596, 0.78475236,
- 1.00000000, 0.89576933, 0.79989606,
- 1.00000000, 0.90198230, 0.81465502,
- 1.00000000, 0.90963069, 0.82838210,
- 1.00000000, 0.91710889, 0.84190889,
- 1.00000000, 0.92441842, 0.85523742,
- 1.00000000, 0.93156127, 0.86836903,
- 1.00000000, 0.93853986, 0.88130458,
- 1.00000000, 0.94535695, 0.89404470,
- 1.00000000, 0.95201559, 0.90658983,
- 1.00000000, 0.95851906, 0.91894041,
- 1.00000000, 0.96487079, 0.93109690,
- 1.00000000, 0.97107439, 0.94305985,
- 1.00000000, 0.97713351, 0.95482993,
- 1.00000000, 0.98305189, 0.96640795,
- 1.00000000, 0.98883326, 0.97779486,
- 1.00000000, 0.99448139, 0.98899179,
- 1.00000000, 1.00000000, 1.00000000,
- 0.98947904, 0.99348723, 1.00000000,
- 0.97940448, 0.98722715, 1.00000000,
- 0.96975025, 0.98120637, 1.00000000,
- 0.96049223, 0.97541240, 1.00000000,
- 0.95160805, 0.96983355, 1.00000000,
- 0.94303638, 0.96443333, 1.00000000,
- 0.93480451, 0.95923080, 1.00000000,
- 0.92689056, 0.95421394, 1.00000000,
- 0.91927697, 0.94937330, 1.00000000,
- 0.91194747, 0.94470005, 1.00000000,
- 0.90488690, 0.94018594, 1.00000000,
- 0.89808115, 0.93582323, 1.00000000,
- 0.89151710, 0.93160469, 1.00000000,
- 0.88518247, 0.92752354, 1.00000000,
- 0.87906581, 0.92357340, 1.00000000,
- 0.87315640, 0.91974827, 1.00000000,
- 0.86744421, 0.91604254, 1.00000000,
- 0.86191983, 0.91245088, 1.00000000,
- 0.85657444, 0.90896831, 1.00000000,
- 0.85139976, 0.90559011, 1.00000000,
- 0.84638799, 0.90231183, 1.00000000,
- 0.84153180, 0.89912926, 1.00000000,
- 0.83682430, 0.89603843, 1.00000000,
- 0.83225897, 0.89303558, 1.00000000,
- 0.82782969, 0.89011714, 1.00000000,
- 0.82353066, 0.88727974, 1.00000000,
- 0.81935641, 0.88452017, 1.00000000,
- 0.81530175, 0.88183541, 1.00000000,
- 0.81136180, 0.87922257, 1.00000000,
- 0.80753191, 0.87667891, 1.00000000,
- 0.80380769, 0.87420182, 1.00000000,
- 0.80018497, 0.87178882, 1.00000000,
- 0.79665980, 0.86943756, 1.00000000,
- 0.79322843, 0.86714579, 1.00000000,
- 0.78988728, 0.86491137, 1.00000000,
- 0.78663296, 0.86273225, 1.00000000,
- 0.78346225, 0.86060650, 1.00000000,
- 0.78037207, 0.85853224, 1.00000000,
- 0.77735950, 0.85650771, 1.00000000,
- 0.77442176, 0.85453121, 1.00000000,
- 0.77155617, 0.85260112, 1.00000000,
- 0.76876022, 0.85071588, 1.00000000,
- 0.76603147, 0.84887402, 1.00000000,
- 0.76336762, 0.84707411, 1.00000000,
- 0.76076645, 0.84531479, 1.00000000,
- 0.75822586, 0.84359476, 1.00000000,
- 0.75574383, 0.84191277, 1.00000000,
- 0.75331843, 0.84026762, 1.00000000,
- 0.75094780, 0.83865816, 1.00000000,
- 0.74863017, 0.83708329, 1.00000000,
- 0.74636386, 0.83554194, 1.00000000,
- 0.74414722, 0.83403311, 1.00000000,
- 0.74197871, 0.83255582, 1.00000000,
- 0.73985682, 0.83110912, 1.00000000,
- 0.73778012, 0.82969211, 1.00000000,
- 0.73574723, 0.82830393, 1.00000000,
- 0.73375683, 0.82694373, 1.00000000,
- 0.73180765, 0.82561071, 1.00000000,
- 0.72989845, 0.82430410, 1.00000000,
- 0.72802807, 0.82302316, 1.00000000,
- 0.72619537, 0.82176715, 1.00000000,
- 0.72439927, 0.82053539, 1.00000000,
- 0.72263872, 0.81932722, 1.00000000,
- 0.72091270, 0.81814197, 1.00000000,
- 0.71922025, 0.81697905, 1.00000000,
- 0.71756043, 0.81583783, 1.00000000,
- 0.71593234, 0.81471775, 1.00000000,
- 0.71433510, 0.81361825, 1.00000000,
- 0.71276788, 0.81253878, 1.00000000,
- 0.71122987, 0.81147883, 1.00000000,
- 0.70972029, 0.81043789, 1.00000000,
- 0.70823838, 0.80941546, 1.00000000,
- 0.70678342, 0.80841109, 1.00000000,
- 0.70535469, 0.80742432, 1.00000000,
- 0.70395153, 0.80645469, 1.00000000,
- 0.70257327, 0.80550180, 1.00000000,
- 0.70121928, 0.80456522, 1.00000000,
- 0.69988894, 0.80364455, 1.00000000,
- 0.69858167, 0.80273941, 1.00000000,
- 0.69729688, 0.80184943, 1.00000000,
- 0.69603402, 0.80097423, 1.00000000,
- 0.69479255, 0.80011347, 1.00000000,
- 0.69357196, 0.79926681, 1.00000000,
- 0.69237173, 0.79843391, 1.00000000,
- 0.69119138, 0.79761446, 1.00000000,
- 0.69003044, 0.79680814, 1.00000000,
- 0.68888844, 0.79601466, 1.00000000,
- 0.68776494, 0.79523371, 1.00000000,
- 0.68665951, 0.79446502, 1.00000000,
- 0.68557173, 0.79370830, 1.00000000,
- 0.68450119, 0.79296330, 1.00000000,
- 0.68344751, 0.79222975, 1.00000000,
- 0.68241029, 0.79150740, 1.00000000,
- 0.68138918, 0.79079600, 1.00000000,
- 0.68038380, 0.79009531, 1.00000000,
- 0.67939381, 0.78940511, 1.00000000,
- 0.67841888, 0.78872517, 1.00000000,
- 0.67745866, 0.78805526, 1.00000000,
- 0.67651284, 0.78739518, 1.00000000,
- 0.67558112, 0.78674472, 1.00000000,
- 0.67466317, 0.78610368, 1.00000000,
- 0.67375872, 0.78547186, 1.00000000,
- 0.67286748, 0.78484907, 1.00000000,
- 0.67198916, 0.78423512, 1.00000000,
- 0.67112350, 0.78362984, 1.00000000,
- 0.67027024, 0.78303305, 1.00000000,
- 0.66942911, 0.78244457, 1.00000000,
- 0.66859988, 0.78186425, 1.00000000,
- 0.66778228, 0.78129191, 1.00000000,
- 0.66697610, 0.78072740, 1.00000000,
- 0.66618110, 0.78017057, 1.00000000,
- 0.66539706, 0.77962127, 1.00000000,
- 0.66462376, 0.77907934, 1.00000000,
- 0.66386098, 0.77854465, 1.00000000,
- 0.66310852, 0.77801705, 1.00000000,
- 0.66236618, 0.77749642, 1.00000000,
- 0.66163375, 0.77698261, 1.00000000,
- 0.66091106, 0.77647551, 1.00000000,
- 0.66019791, 0.77597498, 1.00000000,
- 0.65949412, 0.77548090, 1.00000000,
- 0.65879952, 0.77499315, 1.00000000,
- 0.65811392, 0.77451161, 1.00000000,
- 0.65743716, 0.77403618, 1.00000000,
- 0.65676908, 0.77356673, 1.00000000,
- 0.65610952, 0.77310316, 1.00000000,
- 0.65545831, 0.77264537, 1.00000000,
- 0.65481530, 0.77219324, 1.00000000,
- 0.65418036, 0.77174669, 1.00000000,
- 0.65355332, 0.77130560, 1.00000000,
- 0.65293404, 0.77086988, 1.00000000,
- 0.65232240, 0.77043944, 1.00000000,
- 0.65171824, 0.77001419, 1.00000000,
- 0.65112144, 0.76959404, 1.00000000,
- 0.65053187, 0.76917889, 1.00000000,
- 0.64994941, 0.76876866, 1.00000000,
- 0.64937392, 0.76836326, 1.00000000
- };
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index b2207f3..7a28f48 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -192,6 +192,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
for (int j = 0; j < colorTransforms.size(); j++) {
if (colorTransforms.get(j).getColorTransform() == info.colorTransform) {
existingMode = true;
+ if (i == activeDisplayInfo) {
+ activeColorTransform = colorTransforms.get(j);
+ }
break;
}
}
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 7d1dbe1..c986e74 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -247,6 +247,9 @@ public final class DreamManagerService extends SystemService {
private void setLidStateInternal(int state) {
synchronized (mLock) {
+ if (mLidState == state) {
+ return;
+ }
mLidState = state;
}
switch (state) {
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 11de1a2..bdb77db 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -781,6 +781,10 @@ public class GpsLocationProvider implements LocationProviderInterface {
&& mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
if (mNetworkAvailable) {
String apnName = info.getExtraInfo();
+ // APN wasn't found in the intent, try to get it from the content provider.
+ if (apnName == null) {
+ apnName = getSelectedApn();
+ }
if (apnName == null) {
/* Assign a dummy value in the case of C2K as otherwise we will have a runtime
exception in the following call to native_agps_data_conn_open*/
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index bf7560e..da62313 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -203,6 +203,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int VERSION_LATEST = VERSION_SWITCH_UID;
@VisibleForTesting
+ public static final int TYPE_NONE = 0;
+ @VisibleForTesting
public static final int TYPE_WARNING = 0x1;
@VisibleForTesting
public static final int TYPE_LIMIT = 0x2;
@@ -247,6 +249,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
private static final int MSG_SCREEN_ON_CHANGED = 8;
+ private static final int MSG_PROCESS_LOW_POWER_CHANGED = 9;
private final Context mContext;
private final IActivityManager mActivityManager;
@@ -262,6 +265,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private PowerManagerInternal mPowerManagerInternal;
private IDeviceIdleController mDeviceIdleController;
+ private final ComponentName mNotificationComponent;
+ private int mNotificationSequenceNumber;
+
final Object mRulesLock = new Object();
volatile boolean mSystemReady;
@@ -363,6 +369,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
mAppOps = context.getSystemService(AppOpsManager.class);
+
+ final String notificationComponent = context.getString(
+ R.string.config_networkPolicyNotificationComponent);
+ mNotificationComponent = notificationComponent != null
+ ? ComponentName.unflattenFromString(notificationComponent) : null;
}
public void bindConnectivityManager(IConnectivityManager connManager) {
@@ -437,13 +448,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mPowerManagerInternal.registerLowPowerModeObserver(
new PowerManagerInternal.LowPowerModeListener() {
@Override
- public void onLowPowerModeChanged(boolean enabled) {
- synchronized (mRulesLock) {
- if (mRestrictPower != enabled) {
- mRestrictPower = enabled;
- updateRulesForGlobalChangeLocked(true);
- }
- }
+ public void onLowPowerModeChanged(final boolean enabled) {
+ mHandler.removeMessages(MSG_PROCESS_LOW_POWER_CHANGED);
+ Message msg = Message.obtain(mHandler, MSG_PROCESS_LOW_POWER_CHANGED, enabled);
+ mHandler.sendMessage(msg);
}
});
mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled();
@@ -778,6 +786,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs);
mActiveNotifs.clear();
+ // increment the sequence number so custom components know
+ // this update is new
+ mNotificationSequenceNumber++;
+ boolean hasNotifications = false;
+
// TODO: when switching to kernel notifications, compute next future
// cycle boundary to recompute notifications.
@@ -794,6 +807,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final long totalBytes = getTotalBytes(policy.template, start, end);
if (policy.isOverLimit(totalBytes)) {
+ hasNotifications = true;
if (policy.lastLimitSnooze >= start) {
enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
} else {
@@ -807,10 +821,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start
&& policy.limitBytes != LIMIT_DISABLED) {
enqueueNotification(policy, TYPE_WARNING, totalBytes);
+ hasNotifications = true;
}
}
}
+ // right now we don't care about restricted background notifications
+ // in the custom notification component, so trigger an update now
+ // if we didn't update anything this pass
+ if (!hasNotifications) {
+ sendNotificationToCustomComponent(null, TYPE_NONE, 0);
+ }
+
// ongoing notification when restricting background data
if (mRestrictBackground) {
enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND);
@@ -857,6 +879,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
*/
private void notifyOverLimitLocked(NetworkTemplate template) {
+ if (mNotificationComponent != null) {
+ // It is the job of the notification component to handle UI,
+ // so we do nothing here
+ return;
+ }
+
if (!mOverLimitNotified.contains(template)) {
mContext.startActivity(buildNetworkOverLimitIntent(template));
mOverLimitNotified.add(template);
@@ -875,11 +903,55 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
return TAG + ":" + policy.template.hashCode() + ":" + type;
}
+ private boolean sendNotificationToCustomComponent(
+ NetworkPolicy policy,
+ int type,
+ long totalBytes) {
+ if (mNotificationComponent == null) {
+ return false;
+ }
+
+ Intent intent = new Intent();
+ intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.setComponent(mNotificationComponent);
+
+ int notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_NONE;
+ switch (type) {
+ case TYPE_WARNING:
+ notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_WARNING;
+ break;
+ case TYPE_LIMIT:
+ notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_REACHED_LIMIT;
+ break;
+ case TYPE_LIMIT_SNOOZED:
+ notificationType = NetworkPolicyManager.NOTIFICATION_TYPE_USAGE_EXCEEDED_LIMIT;
+ break;
+ }
+
+ intent.setAction(NetworkPolicyManager.ACTION_SHOW_NETWORK_POLICY_NOTIFICATION);
+ intent.putExtra(NetworkPolicyManager.EXTRA_NOTIFICATION_TYPE, notificationType);
+ intent.putExtra(
+ NetworkPolicyManager.EXTRA_NOTIFICATION_SEQUENCE_NUMBER,
+ mNotificationSequenceNumber);
+
+ if (notificationType != NetworkPolicyManager.NOTIFICATION_TYPE_NONE) {
+ intent.putExtra(NetworkPolicyManager.EXTRA_NETWORK_POLICY, policy);
+ intent.putExtra(NetworkPolicyManager.EXTRA_BYTES_USED, totalBytes);
+ }
+
+ mContext.sendBroadcast(intent);
+ return true;
+ }
+
/**
* Show notification for combined {@link NetworkPolicy} and specific type,
* like {@link #TYPE_LIMIT}. Okay to call multiple times.
*/
private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
+ if (sendNotificationToCustomComponent(policy, type, totalBytes)) {
+ return;
+ }
+
final String tag = buildNotificationTag(policy, type);
final Notification.Builder builder = new Notification.Builder(mContext);
builder.setOnlyAlertOnce(true);
@@ -1739,6 +1811,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ @Override
+ public void snoozeWarning(NetworkTemplate template) {
+ mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ // TODO: this seems like a race condition? (along with snoozeLimit above)
+ performSnooze(template, TYPE_WARNING);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
void performSnooze(NetworkTemplate template, int type) {
maybeRefreshTrustedTime();
final long currentTime = currentTimeMillis();
@@ -2137,12 +2222,23 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
uidRules.clear();
// Fully update the app idle firewall chain.
+ final IPackageManager ipm = AppGlobals.getPackageManager();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
for (int uid : idleUids) {
if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
+ // quick check: if this uid doesn't have INTERNET permission, it
+ // doesn't have network access anyway, so it is a waste to mess
+ // with it here.
+ try {
+ if (ipm.checkUidPermission(Manifest.permission.INTERNET, uid)
+ != PackageManager.PERMISSION_GRANTED) {
+ continue;
+ }
+ } catch (RemoteException e) {
+ }
uidRules.put(uid, FIREWALL_RULE_DENY);
}
}
@@ -2227,11 +2323,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private boolean isUidIdle(int uid) {
final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
- final int userId = UserHandle.getUserId(uid);
- for (String packageName : packages) {
- if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
- return false;
+ if (packages != null) {
+ final int userId = UserHandle.getUserId(uid);
+ for (String packageName : packages) {
+ if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
+ return false;
+ }
}
}
return true;
@@ -2430,6 +2528,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
updateScreenOn();
return true;
}
+ case MSG_PROCESS_LOW_POWER_CHANGED: {
+ boolean enabled = (Boolean) msg.obj;
+ synchronized (mRulesLock) {
+ if (mRestrictPower != enabled) {
+ mRestrictPower = enabled;
+ updateRulesForGlobalChangeLocked(true);
+ }
+ }
+ return true;
+ }
default: {
return false;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8429cc8..36818b5 100755..100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -58,6 +58,7 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.graphics.drawable.Drawable;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
@@ -124,6 +125,7 @@ import com.android.server.notification.ManagedServices.UserProfiles;
import com.android.server.statusbar.StatusBarManagerInternal;
import cyanogenmod.providers.CMSettings;
+import cyanogenmod.util.ColorUtils;
import libcore.io.IoUtils;
@@ -248,6 +250,8 @@ public class NotificationManagerService extends SystemService {
private boolean mMultipleNotificationLeds;
private boolean mMultipleLedsEnabledSetting = false;
+ private boolean mAutoGenerateNotificationColor = true;
+
private boolean mScreenOnEnabled = false;
private boolean mScreenOnDefault = false;
@@ -287,6 +291,8 @@ public class NotificationManagerService extends SystemService {
private boolean mNotificationPulseEnabled;
private HashMap<String, NotificationLedValues> mNotificationPulseCustomLedValues;
private Map<String, String> mPackageNameMappings;
+ private final Map<String, Integer> mGeneratedPackageLedColors =
+ new HashMap<String, Integer>();
// for checking lockscreen status
private KeyguardManager mKeyguardManager;
@@ -1001,6 +1007,9 @@ public class NotificationManagerService extends SystemService {
resolver.registerContentObserver(CMSettings.Global.getUriFor(
CMSettings.Global.ZEN_DISABLE_DUCKING_DURING_MEDIA_PLAYBACK), false,
this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(CMSettings.System.getUriFor(
+ CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO), false,
+ this, UserHandle.USER_ALL);
if (mAdjustableNotificationLedBrightness) {
resolver.registerContentObserver(CMSettings.System.getUriFor(
CMSettings.System.NOTIFICATION_LIGHT_BRIGHTNESS_LEVEL),
@@ -1025,6 +1034,11 @@ public class NotificationManagerService extends SystemService {
mNotificationPulseEnabled = Settings.System.getIntForUser(resolver,
Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT) != 0;
+ // Automatically pick a color for LED if not set
+ mAutoGenerateNotificationColor = CMSettings.System.getIntForUser(resolver,
+ CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO,
+ 1, UserHandle.USER_CURRENT) != 0;
+
// LED default color
mDefaultNotificationColor = CMSettings.System.getIntForUser(resolver,
CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR,
@@ -1040,6 +1054,9 @@ public class NotificationManagerService extends SystemService {
CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF,
mDefaultNotificationLedOff, UserHandle.USER_CURRENT);
+ // LED generated notification colors
+ mGeneratedPackageLedColors.clear();
+
// LED custom notification colors
mNotificationPulseCustomLedValues.clear();
if (CMSettings.System.getIntForUser(resolver,
@@ -1219,6 +1236,7 @@ public class NotificationManagerService extends SystemService {
mDisableNotificationEffects = true;
}
mZenModeHelper.initZenMode();
+ mZenModeHelper.readAllowLightsFromSettings();
mInterruptionFilter = mZenModeHelper.getZenModeListenerInterruptionFilter();
mUserProfiles.updateCache(getContext());
@@ -1578,10 +1596,11 @@ public class NotificationManagerService extends SystemService {
Binder.getCallingUid(), incomingUserId, true, false,
"getAppActiveNotifications", pkg);
- final int N = mNotificationList.size();
- final ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>(N);
+ final ArrayList<StatusBarNotification> list
+ = new ArrayList<StatusBarNotification>(mNotificationList.size());
synchronized (mNotificationList) {
+ final int N = mNotificationList.size();
for (int i = 0; i < N; i++) {
final StatusBarNotification sbn = mNotificationList.get(i).sbn;
if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId) {
@@ -2768,8 +2787,9 @@ public class NotificationManagerService extends SystemService {
// light
// release the light
boolean wasShowLights = mLights.remove(record.getKey());
- final boolean aboveThresholdWithLight = aboveThreshold || isLedNotificationForcedOn(record);
- if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && aboveThresholdWithLight) {
+ final boolean canInterruptWithLight = canInterrupt || isLedNotificationForcedOn(record)
+ || (!canInterrupt && mZenModeHelper.getAllowLights());
+ if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && canInterruptWithLight) {
mLights.add(record.getKey());
updateLightsLocked();
if (mUseAttentionLight) {
@@ -3433,7 +3453,7 @@ public class NotificationManagerService extends SystemService {
ledOnMS = ledValues.onMS >= 0 ? ledValues.onMS : mDefaultNotificationLedOn;
ledOffMS = ledValues.offMS >= 0 ? ledValues.offMS : mDefaultNotificationLedOff;
} else if ((ledno.defaults & Notification.DEFAULT_LIGHTS) != 0) {
- ledARGB = mDefaultNotificationColor;
+ ledARGB = generateLedColorForNotification(ledNotification);
ledOnMS = mDefaultNotificationLedOn;
ledOffMS = mDefaultNotificationLedOff;
} else {
@@ -3494,6 +3514,33 @@ public class NotificationManagerService extends SystemService {
return mNotificationPulseCustomLedValues.get(mapPackage(packageName));
}
+ private int generateLedColorForNotification(NotificationRecord ledNotification) {
+ if (!mAutoGenerateNotificationColor) {
+ return mDefaultNotificationColor;
+ }
+ final String packageName = ledNotification.sbn.getPackageName();
+ final String mapping = mapPackage(packageName);
+ int color = mDefaultNotificationColor;
+
+ if (mGeneratedPackageLedColors.containsKey(mapping)) {
+ return mGeneratedPackageLedColors.get(mapping);
+ }
+
+ PackageManager pm = getContext().getPackageManager();
+ Drawable icon;
+ try {
+ icon = pm.getApplicationIcon(mapping);
+ } catch (NameNotFoundException e) {
+ Slog.e(TAG, e.getMessage(), e);
+ return color;
+ }
+
+ color = ColorUtils.generateAlertColorFromDrawable(icon);
+ mGeneratedPackageLedColors.put(mapping, color);
+
+ return color;
+ }
+
private String mapPackage(String pkg) {
if (!mPackageNameMappings.containsKey(pkg)) {
return pkg;
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 461c3a2..468ef8d 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -53,6 +53,7 @@ import android.util.SparseArray;
import com.android.internal.R;
import com.android.internal.logging.MetricsLogger;
import com.android.server.LocalServices;
+import cyanogenmod.providers.CMSettings;
import libcore.io.IoUtils;
@@ -89,6 +90,7 @@ public class ZenModeHelper {
private ZenModeConfig mConfig;
private AudioManagerInternal mAudioManager;
private boolean mEffectsSuppressed;
+ private boolean mAllowLights;
public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
mContext = context;
@@ -378,6 +380,7 @@ public class ZenModeHelper {
ZenLog.traceSetZenMode(zen, reason);
mZenMode = zen;
updateRingerModeAffectedStreams();
+ readAllowLightsFromSettings();
setZenModeSetting(mZenMode);
if (setRingerMode) {
applyZenToRingerMode();
@@ -407,6 +410,24 @@ public class ZenModeHelper {
return zen;
}
+ public boolean getAllowLights() {
+ return mAllowLights;
+ }
+
+ public void readAllowLightsFromSettings() {
+ switch (mZenMode) {
+ case Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Global.ZEN_MODE_ALARMS:
+ mAllowLights = CMSettings.System.getInt(mContext.getContentResolver(),
+ CMSettings.System.ZEN_ALLOW_LIGHTS, 1) == 1;
+ break;
+ case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+ mAllowLights = CMSettings.System.getInt(mContext.getContentResolver(),
+ CMSettings.System.ZEN_PRIORITY_ALLOW_LIGHTS, 1) == 1;
+ break;
+ }
+ }
+
private void applyRestrictions() {
final boolean zen = mZenMode != Global.ZEN_MODE_OFF;
@@ -415,13 +436,14 @@ public class ZenModeHelper {
applyRestrictions(muteNotifications, USAGE_NOTIFICATION);
// call restrictions
- final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers
- || mEffectsSuppressed;
+ final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers;
applyRestrictions(muteCalls, USAGE_NOTIFICATION_RINGTONE);
// alarm restrictions
final boolean muteAlarms = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
applyRestrictions(muteAlarms, USAGE_ALARM);
+
+ readAllowLightsFromSettings();
}
private void applyRestrictions(boolean mute, int usage) {
@@ -692,6 +714,10 @@ public class ZenModeHelper {
private final class SettingsObserver extends ContentObserver {
private final Uri ZEN_MODE = Global.getUriFor(Global.ZEN_MODE);
+ private final Uri ZEN_ALLOW_LIGHTS = CMSettings.System.getUriFor(
+ CMSettings.System.ZEN_ALLOW_LIGHTS);
+ private final Uri ZEN_PRIORITY_ALLOW_LIGHTS = CMSettings.System.getUriFor(
+ CMSettings.System.ZEN_PRIORITY_ALLOW_LIGHTS);
public SettingsObserver(Handler handler) {
super(handler);
@@ -700,6 +726,10 @@ public class ZenModeHelper {
public void observe() {
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(ZEN_MODE, false /*notifyForDescendents*/, this);
+ resolver.registerContentObserver(
+ ZEN_ALLOW_LIGHTS, false /*notifyForDescendents*/, this);
+ resolver.registerContentObserver(
+ ZEN_PRIORITY_ALLOW_LIGHTS, false /*notifyForDescendents*/, this);
update(null);
}
@@ -714,6 +744,8 @@ public class ZenModeHelper {
if (DEBUG) Log.d(TAG, "Fixing zen mode setting");
setZenModeSetting(mZenMode);
}
+ } else if (ZEN_ALLOW_LIGHTS.equals(uri) || ZEN_PRIORITY_ALLOW_LIGHTS.equals(uri)) {
+ readAllowLightsFromSettings();
}
}
}
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index df023fd..29e9fa6 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -572,6 +572,26 @@ final class DefaultPermissionGrantPolicy {
grantRuntimePermissionsLPw(musicPackage, STORAGE_PERMISSIONS, userId);
}
+ // Android Wear Home
+ if (mService.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN);
+ homeIntent.addCategory(Intent.CATEGORY_HOME_MAIN);
+
+ PackageParser.Package wearHomePackage = getDefaultSystemHandlerActivityPackageLPr(
+ homeIntent, userId);
+
+ if (wearHomePackage != null
+ && doesPackageSupportRuntimePermissions(wearHomePackage)) {
+ grantRuntimePermissionsLPw(wearHomePackage, CONTACTS_PERMISSIONS, false,
+ userId);
+ grantRuntimePermissionsLPw(wearHomePackage, PHONE_PERMISSIONS, true, userId);
+ grantRuntimePermissionsLPw(wearHomePackage, MICROPHONE_PERMISSIONS, false,
+ userId);
+ grantRuntimePermissionsLPw(wearHomePackage, LOCATION_PERMISSIONS, false,
+ userId);
+ }
+ }
+
mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
}
}
@@ -579,7 +599,10 @@ final class DefaultPermissionGrantPolicy {
private void grantDefaultPermissionsToDefaultSystemDialerAppLPr(
PackageParser.Package dialerPackage, int userId) {
if (doesPackageSupportRuntimePermissions(dialerPackage)) {
- grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId);
+ boolean isPhonePermFixed =
+ mService.hasSystemFeature(PackageManager.FEATURE_WATCH);
+ grantRuntimePermissionsLPw(
+ dialerPackage, PHONE_PERMISSIONS, isPhonePermFixed, userId);
grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8abb9f0..d5c58df 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17,7 +17,6 @@
package com.android.server.pm;
-import static android.Manifest.permission.ACCESS_THEME_MANAGER;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
@@ -92,6 +91,7 @@ import android.content.res.Configuration;
import android.Manifest;
+import cyanogenmod.app.CMContextConstants;
import cyanogenmod.app.suggest.AppSuggestManager;
import android.app.ActivityManager;
@@ -156,14 +156,12 @@ import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import android.content.pm.UserInfo;
import android.content.pm.ManifestDigest;
-import android.content.pm.ThemeUtils;
import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VerifierInfo;
import android.content.res.Resources;
import android.content.res.AssetManager;
import android.content.res.ThemeConfig;
-import android.content.res.ThemeManager;
import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.Debug;
@@ -222,6 +220,8 @@ import android.util.Xml;
import android.view.Display;
import cyanogenmod.providers.CMSettings;
+import cyanogenmod.themes.IThemeService;
+
import dalvik.system.DexFile;
import dalvik.system.VMRuntime;
@@ -254,6 +254,7 @@ import com.android.server.pm.Settings.DatabaseVersion;
import com.android.server.pm.Settings.VersionInfo;
import com.android.server.storage.DeviceStorageMonitorInternal;
+import org.cyanogenmod.internal.util.ThemeUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -303,8 +304,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
/**
* Keep track of all those .apks everywhere.
@@ -463,6 +462,9 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final long COMMON_RESOURCE_EXPIRATION = 3*60*1000; // 3 minutes
+ private static final String PROTECTED_APPS_TARGET_VALIDATION_COMPONENT =
+ "com.android.settings/com.android.settings.applications.ProtectedAppsActivity";
+
/**
* The offset in bytes to the beginning of the hashes in an idmap
*/
@@ -1462,7 +1464,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
String category = null;
if(res.pkg.mIsThemeApk) {
- category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ category = cyanogenmod.content.Intent
+ .CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
packageName, null, extras, null, null, updateUsers);
@@ -8269,7 +8272,8 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean hasCommonResources = (hasCommonResources(pkg) && !COMMON_OVERLAY.equals(target));
PackageParser.Package targetPkg = mPackages.get(target);
- String appPath = targetPkg != null ? targetPkg.baseCodePath : "";
+ String appPath = targetPkg != null ? targetPkg.baseCodePath :
+ Environment.getRootDirectory() + "/framework/framework-res.apk";
if (mInstaller.aapt(pkg.baseCodePath, internalPath, resPath, sharedGid, pkgId,
pkg.applicationInfo.targetSdkVersion,
@@ -13538,7 +13542,8 @@ public class PackageManagerService extends IPackageManager.Stub {
String category = null;
if (info.isThemeApk) {
- category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ category = cyanogenmod.content.Intent
+ .CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, category,
@@ -13583,7 +13588,8 @@ public class PackageManagerService extends IPackageManager.Stub {
if (removedPackage != null) {
String category = null;
if (isThemeApk) {
- category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ category = cyanogenmod.content.Intent
+ .CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, category,
extras, null, null, removedUsers);
@@ -17223,6 +17229,11 @@ public class PackageManagerService extends IPackageManager.Stub {
return false;
}
+ if (TextUtils.equals(PROTECTED_APPS_TARGET_VALIDATION_COMPONENT,
+ componentName.flattenToString())) {
+ return false;
+ }
+
PackageSetting pkgSetting;
ArraySet<String> components;
@@ -17698,8 +17709,11 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public int processThemeResources(String themePkgName) {
mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_THEME_MANAGER, null);
- PackageParser.Package pkg = mPackages.get(themePkgName);
+ cyanogenmod.platform.Manifest.permission.ACCESS_THEME_MANAGER, null);
+ PackageParser.Package pkg;
+ synchronized (mPackages) {
+ pkg = mPackages.get(themePkgName);
+ }
if (pkg == null) {
Log.w(TAG, "Unable to get pkg for processing " + themePkgName);
return 0;
@@ -17720,11 +17734,15 @@ public class PackageManagerService extends IPackageManager.Stub {
// Generate Idmaps and res tables if pkg is a theme
Iterator<String> iterator = pkg.mOverlayTargets.iterator();
- while(iterator.hasNext()) {
+ while (iterator.hasNext()) {
String target = iterator.next();
Exception failedException = null;
+ PackageParser.Package targetPkg;
+ synchronized (mPackages) {
+ targetPkg = mPackages.get(target);
+ }
try {
- compileResourcesAndIdmapIfNeeded(mPackages.get(target), pkg);
+ compileResourcesAndIdmapIfNeeded(targetPkg, pkg);
} catch (IdmapException e) {
failedException = e;
} catch (AaptException e) {
@@ -17735,7 +17753,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (failedException != null) {
Slog.w(TAG, "Unable to process theme " + pkg.packageName + " for " + target,
- failedException);
+ failedException);
// remove target from mOverlayTargets
iterator.remove();
}
@@ -17745,10 +17763,16 @@ public class PackageManagerService extends IPackageManager.Stub {
}
private void processThemeResourcesInThemeService(String pkgName) {
- ThemeManager tm =
- (ThemeManager) mContext.getSystemService(Context.THEME_SERVICE);
- if (tm != null) {
- tm.processThemeResources(pkgName);
+ IThemeService ts = IThemeService.Stub.asInterface(ServiceManager.getService(
+ CMContextConstants.CM_THEME_SERVICE));
+ if (ts == null) {
+ Slog.e(TAG, "Theme service not available");
+ return;
+ }
+ try {
+ ts.processThemeResources(pkgName);
+ } catch (RemoteException e) {
+ /* ignore */
}
}
diff --git a/services/core/java/com/android/server/pm/UserContentObserver.java b/services/core/java/com/android/server/pm/UserContentObserver.java
new file mode 100644
index 0000000..6145c3b
--- /dev/null
+++ b/services/core/java/com/android/server/pm/UserContentObserver.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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 com.android.server.pm;
+
+import android.app.ActivityManagerNative;
+import android.app.IUserSwitchObserver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Simple extension of ContentObserver that also listens for user switch events to call update
+ */
+public abstract class UserContentObserver extends ContentObserver {
+ private static final String TAG = "UserContentObserver";
+
+ private Runnable mUpdateRunnable;
+
+ private IUserSwitchObserver mUserSwitchObserver = new IUserSwitchObserver.Stub() {
+ @Override
+ public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+ }
+ @Override
+ public void onUserSwitchComplete(int newUserId) throws RemoteException {
+ mHandler.post(mUpdateRunnable);
+ }
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ }
+ };
+
+ private Handler mHandler;
+
+ /**
+ * Content observer that tracks user switches
+ * to allow clients to re-load settings for current user
+ */
+ public UserContentObserver(Handler handler) {
+ super(handler);
+ mHandler = handler;
+ mUpdateRunnable = new Runnable() {
+ @Override
+ public void run() {
+ update();
+ }
+ };
+ }
+
+ protected void observe() {
+ try {
+ ActivityManagerNative.getDefault().registerUserSwitchObserver(mUserSwitchObserver);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to register user switch observer!", e);
+ }
+ }
+
+ protected void unobserve() {
+ try {
+ mHandler.removeCallbacks(mUpdateRunnable);
+ ActivityManagerNative.getDefault().unregisterUserSwitchObserver(mUserSwitchObserver);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to unregister user switch observer!", e);
+ }
+ }
+
+ /**
+ * Called to notify of registered uri changes and user switches.
+ * Always invoked on the handler passed in at construction
+ */
+ protected abstract void update();
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ update();
+ }
+}
diff --git a/services/core/java/com/android/server/policy/BurnInProtectionHelper.java b/services/core/java/com/android/server/policy/BurnInProtectionHelper.java
index fef1e57..e6ec6a6 100644
--- a/services/core/java/com/android/server/policy/BurnInProtectionHelper.java
+++ b/services/core/java/com/android/server/policy/BurnInProtectionHelper.java
@@ -72,6 +72,9 @@ public class BurnInProtectionHelper implements DisplayManager.DisplayListener,
/* 1 means increasing, -1 means decreasing */
private int mYOffsetDirection = 1;
+ private int mAppliedBurnInXOffset = 0;
+ private int mAppliedBurnInYOffset = 0;
+
private final AlarmManager mAlarmManager;
private final PendingIntent mBurnInProtectionIntent;
private final DisplayManagerInternal mDisplayManagerInternal;
@@ -139,6 +142,8 @@ public class BurnInProtectionHelper implements DisplayManager.DisplayListener,
mFirstUpdate = false;
} else {
adjustOffsets();
+ mAppliedBurnInXOffset = mLastBurnInXOffset;
+ mAppliedBurnInYOffset = mLastBurnInYOffset;
mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(),
mLastBurnInXOffset, mLastBurnInYOffset);
}
@@ -258,6 +263,8 @@ public class BurnInProtectionHelper implements DisplayManager.DisplayListener,
@Override
public void onAnimationEnd(Animator animator) {
if (animator == mCenteringAnimator && !mBurnInProtectionActive) {
+ mAppliedBurnInXOffset = 0;
+ mAppliedBurnInYOffset = 0;
// No matter how the animation finishes, we want to zero the offsets.
mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(), 0, 0);
}
@@ -276,7 +283,7 @@ public class BurnInProtectionHelper implements DisplayManager.DisplayListener,
if (!mBurnInProtectionActive) {
final float value = (Float) valueAnimator.getAnimatedValue();
mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(),
- (int) (mLastBurnInXOffset * value), (int) (mLastBurnInYOffset * value));
+ (int) (mAppliedBurnInXOffset * value), (int) (mAppliedBurnInYOffset * value));
}
}
}
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index 8c42917..9b5f5d0 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -22,12 +22,14 @@ import com.android.internal.app.AlertController.AlertParams;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.R;
+import com.android.internal.util.UserIcons;
import com.android.internal.widget.LockPatternUtils;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.INotificationManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -35,10 +37,17 @@ import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ThemeUtils;
import android.content.pm.UserInfo;
import android.content.ServiceConnection;
import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.Manifest;
import android.media.AudioManager;
@@ -58,6 +67,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
+import android.provider.Settings.Global;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.telephony.PhoneStateListener;
@@ -84,12 +94,15 @@ import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ListView;
import android.widget.TextView;
+
import cyanogenmod.providers.CMSettings;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import org.cyanogenmod.internal.util.ThemeUtils;
+
import static com.android.internal.util.cm.PowerMenuConstants.*;
/**
@@ -163,6 +176,9 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mShowSilentToggle = SHOW_SILENT_TOGGLE && !mContext.getResources().getBoolean(
com.android.internal.R.bool.config_useFixedVolume);
+ // Set the initial status of airplane mode toggle
+ mAirplaneState = getUpdatedAirplaneToggleState();
+
updatePowerMenuActions();
}
@@ -612,16 +628,24 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
if (um.isUserSwitcherEnabled()) {
List<UserInfo> users = um.getUsers();
UserInfo currentUser = getCurrentUser();
+ final int avatarSize = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.global_actions_avatar_size);
for (final UserInfo user : users) {
if (user.supportsSwitchTo()) {
boolean isCurrentUser = currentUser == null
? user.id == 0 : (currentUser.id == user.id);
- Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
- : null;
+ Drawable avatar = null;
+ Bitmap rawAvatar = um.getUserIcon(user.id);
+ if (rawAvatar == null) {
+ rawAvatar = UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(
+ user.isGuest() ? UserHandle.USER_NULL : user.id, /*light=*/ false));
+ }
+ avatar = new BitmapDrawable(mContext.getResources(),
+ createCircularClip(rawAvatar, avatarSize, avatarSize));
+
SinglePressAction switchToUser = new SinglePressAction(
- com.android.internal.R.drawable.ic_lock_user, icon,
- (user.name != null ? user.name : "Primary")
- + (isCurrentUser ? " \u2714" : "")) {
+ com.android.internal.R.drawable.ic_lock_user, avatar,
+ (user.name != null ? user.name : "Primary")) {
public void onPress() {
try {
ActivityManagerNative.getDefault().switchUser(user.id);
@@ -638,6 +662,10 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
return false;
}
};
+ if (isCurrentUser) {
+ switchToUser.setStatus(mContext.getString(
+ R.string.global_action_current_user));
+ }
items.add(switchToUser);
}
}
@@ -721,7 +749,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
@Override
public void onServiceDisconnected(ComponentName name) {}
};
- if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
+ if (mContext.bindServiceAsUser(
+ intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
mScreenshotConnection = conn;
mHandler.postDelayed(mScreenshotTimeout, 10000);
}
@@ -890,6 +919,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private final Drawable mIcon;
private final int mMessageResId;
private final CharSequence mMessage;
+ private CharSequence mStatusMessage;
protected SinglePressAction(int iconResId, int messageResId) {
mIconResId = iconResId;
@@ -916,8 +946,12 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
return true;
}
- public String getStatus() {
- return null;
+ public CharSequence getStatus() {
+ return mStatusMessage;
+ }
+
+ public void setStatus(CharSequence status) {
+ mStatusMessage = status;
}
abstract public void onPress();
@@ -938,7 +972,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
TextView messageView = (TextView) v.findViewById(R.id.message);
TextView statusView = (TextView) v.findViewById(R.id.status);
- final String status = getStatus();
+ final CharSequence status = getStatus();
if (!TextUtils.isEmpty(status)) {
statusView.setText(status);
} else {
@@ -946,7 +980,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
if (mIcon != null) {
icon.setImageDrawable(mIcon);
- icon.setScaleType(ScaleType.CENTER_CROP);
+ icon.setScaleType(ScaleType.CENTER);
} else if (mIconResId != 0) {
icon.setImageDrawable(context.getDrawable(mIconResId));
}
@@ -1116,9 +1150,9 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
}
- private static class SilentModeTriStateAction implements Action, View.OnClickListener {
+ private final class SilentModeTriStateAction implements Action, View.OnClickListener {
- private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
+ private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3, R.id.option4 };
private final AudioManager mAudioManager;
private final Handler mHandler;
@@ -1130,14 +1164,15 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mContext = context;
}
- private int ringerModeToIndex(int ringerMode) {
- // They just happen to coincide
- return ringerMode;
- }
-
private int indexToRingerMode(int index) {
- // They just happen to coincide
- return index;
+ if (index == 2) {
+ if (mHasVibrator) {
+ return AudioManager.RINGER_MODE_VIBRATE;
+ } else {
+ return AudioManager.RINGER_MODE_NORMAL;
+ }
+ }
+ return AudioManager.RINGER_MODE_NORMAL;
}
@Override
@@ -1149,9 +1184,28 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
LayoutInflater inflater) {
View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
- int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
- for (int i = 0; i < 3; i++) {
+ int ringerMode = mAudioManager.getRingerModeInternal();
+ int zenMode = Global.getInt(mContext.getContentResolver(), Global.ZEN_MODE,
+ Global.ZEN_MODE_OFF);
+ int selectedIndex = 0;
+ if (zenMode != Global.ZEN_MODE_OFF) {
+ if (zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
+ selectedIndex = 0;
+ } else if (zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
+ selectedIndex = 1;
+ }
+ } else if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
+ selectedIndex = 2;
+ } else if (ringerMode == AudioManager.RINGER_MODE_NORMAL) {
+ selectedIndex = 3;
+ }
+
+ for (int i = 0; i < ITEM_IDS.length; i++) {
View itemView = v.findViewById(ITEM_IDS[i]);
+ if (!mHasVibrator && i == 2) {
+ itemView.setVisibility(View.GONE);
+ continue;
+ }
itemView.setSelected(selectedIndex == i);
// Set up click handler
itemView.setTag(i);
@@ -1182,7 +1236,28 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
if (!(v.getTag() instanceof Integer)) return;
int index = (Integer) v.getTag();
- mAudioManager.setRingerMode(indexToRingerMode(index));
+ if (index == 0 || index == 1) {
+ int zenMode = index == 0
+ ? Global.ZEN_MODE_NO_INTERRUPTIONS
+ : Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ // ZenModeHelper will revert zen mode back to the previous value if we just
+ // put the value into the Settings db, so use INotificationManager instead
+ INotificationManager noMan = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ try {
+ noMan.setZenMode(zenMode, null, TAG);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to set zen mode", e);
+ }
+ } else {
+ Global.putInt(mContext.getContentResolver(), Global.ZEN_MODE, Global.ZEN_MODE_OFF);
+ }
+
+ if (index == 2 || index == 3) {
+ int ringerMode = indexToRingerMode(index);
+ mAudioManager.setRingerModeInternal(ringerMode);
+ }
+ mAdapter.notifyDataSetChanged();
mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);
}
}
@@ -1274,15 +1349,17 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
};
+ private ToggleAction.State getUpdatedAirplaneToggleState() {
+ return (Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) == 1) ?
+ ToggleAction.State.On : ToggleAction.State.Off;
+ }
+
private void onAirplaneModeChanged() {
// Let the service state callbacks handle the state.
if (mHasTelephony) return;
- boolean airplaneModeOn = Settings.Global.getInt(
- mContext.getContentResolver(),
- Settings.Global.AIRPLANE_MODE_ON,
- 0) == 1;
- mAirplaneState = airplaneModeOn ? ToggleAction.State.On : ToggleAction.State.Off;
+ mAirplaneState = getUpdatedAirplaneToggleState();
mAirplaneModeOn.updateState(mAirplaneState);
}
@@ -1303,6 +1380,33 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
}
+ /**
+ * Generate a new bitmap (width x height pixels, ARGB_8888) with the input bitmap scaled
+ * to fit and clipped to an inscribed circle.
+ * @param input Bitmap to resize and clip
+ * @param width Width of output bitmap (and diameter of circle)
+ * @param height Height of output bitmap
+ * @return A shiny new bitmap for you to use
+ */
+ private static Bitmap createCircularClip(Bitmap input, int width, int height) {
+ if (input == null) return null;
+
+ final int inWidth = input.getWidth();
+ final int inHeight = input.getHeight();
+ final Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(output);
+ final Paint paint = new Paint();
+ paint.setShader(new BitmapShader(input, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
+ paint.setAntiAlias(true);
+ final RectF srcRect = new RectF(0, 0, inWidth, inHeight);
+ final RectF dstRect = new RectF(0, 0, width, height);
+ final Matrix m = new Matrix();
+ m.setRectToRect(srcRect, dstRect, Matrix.ScaleToFit.CENTER);
+ canvas.setMatrix(m);
+ canvas.drawCircle(inWidth / 2, inHeight / 2, inWidth / 2, paint);
+ return output;
+ }
+
private static final class GlobalActionsDialog extends Dialog implements DialogInterface {
private final Context mContext;
private final int mWindowTouchSlop;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 58f26fa..9cb969c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -83,10 +83,11 @@ import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
-import android.service.gesture.EdgeGestureManager;
import com.android.internal.os.DeviceKeyHandler;
import com.android.internal.util.cm.ActionUtils;
+
+import cyanogenmod.hardware.CMHardwareManager;
import cyanogenmod.providers.CMSettings;
import dalvik.system.DexClassLoader;
import android.util.DisplayMetrics;
@@ -129,8 +130,6 @@ import com.android.internal.R;
import com.android.internal.policy.IKeyguardService;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ScreenShapeHelper;
-import com.android.internal.util.gesture.EdgeGesturePosition;
-import com.android.internal.util.gesture.EdgeServiceConstants;
import com.android.internal.view.RotationPolicy;
import com.android.internal.widget.PointerLocationView;
import com.android.server.GestureLauncherService;
@@ -749,6 +748,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private boolean mHasPermanentMenuKey;
private boolean mClearedBecauseOfForceShow;
private boolean mTopWindowIsKeyguard;
+ private CMHardwareManager mCMHardware;
private class PolicyHandler extends Handler {
@Override
@@ -899,9 +899,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
CMSettings.System.VOLBTN_MUSIC_CONTROLS), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(CMSettings.System.getUriFor(
- CMSettings.System.USE_EDGE_SERVICE_FOR_GESTURES), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(CMSettings.System.getUriFor(
CMSettings.System.BACK_WAKE_SCREEN), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(CMSettings.System.getUriFor(
@@ -995,67 +992,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private SystemGesturesPointerEventListener mSystemGestures;
- private EdgeGestureManager.EdgeGestureActivationListener mEdgeGestureActivationListener
- = new EdgeGestureManager.EdgeGestureActivationListener() {
-
- @Override
- public void onEdgeGestureActivation(int touchX, int touchY,
- EdgeGesturePosition position, int flags) {
- WindowState target = null;
-
- if (position == EdgeGesturePosition.TOP) {
- target = mStatusBar;
- } else if (position == EdgeGesturePosition.BOTTOM && mNavigationBarOnBottom) {
- target = mNavigationBar;
- } else if (position == EdgeGesturePosition.LEFT
- && !mNavigationBarOnBottom && mNavigationBarLeftInLandscape) {
- target = mNavigationBar;
- } else if (position == EdgeGesturePosition.RIGHT && !mNavigationBarOnBottom) {
- target = mNavigationBar;
- }
-
- if (target != null) {
- requestTransientBars(target);
- dropEventsUntilLift();
- mEdgeListenerActivated = true;
- } else {
- restoreListenerState();
- }
- }
- };
- private EdgeGestureManager mEdgeGestureManager = null;
- private int mLastEdgePositions = 0;
- private boolean mEdgeListenerActivated = false;
- private boolean mUsingEdgeGestureServiceForGestures = false;
-
- private void updateEdgeGestureListenerState() {
- int flags = 0;
- if (mUsingEdgeGestureServiceForGestures) {
- flags = EdgeServiceConstants.LONG_LIVING | EdgeServiceConstants.UNRESTRICTED;
- if (mStatusBar != null && !mStatusBar.isVisibleLw()) {
- flags |= EdgeGesturePosition.TOP.FLAG;
- }
- if (mNavigationBar != null && !mNavigationBar.isVisibleLw() && !isStatusBarKeyguard()) {
- if (mNavigationBarOnBottom) {
- flags |= EdgeGesturePosition.BOTTOM.FLAG;
- } else if (mNavigationBarLeftInLandscape) {
- flags |= EdgeGesturePosition.LEFT.FLAG;
- } else {
- flags |= EdgeGesturePosition.RIGHT.FLAG;
- }
- }
- }
- if (mEdgeListenerActivated) {
- mEdgeGestureActivationListener.restoreListenerState();
- mEdgeListenerActivated = false;
- }
- if (flags != mLastEdgePositions) {
- mEdgeGestureManager.updateEdgeGestureActivationListener(mEdgeGestureActivationListener,
- flags);
- mLastEdgePositions = flags;
- }
- }
-
IStatusBarService getStatusBarService() {
synchronized (mServiceAquireLock) {
if (mStatusBarService == null) {
@@ -1634,6 +1570,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+ mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
// Init display burn-in protection
boolean burnInProtectionEnabled = context.getResources().getBoolean(
@@ -1677,7 +1614,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mOrientationListener.setCurrentRotation(windowManager.getRotation());
} catch (RemoteException ex) { }
mSettingsObserver = new SettingsObserver(mHandler);
- mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context);
mUiMode = context.getResources().getInteger(
com.android.internal.R.integer.config_defaultUiModeType);
@@ -2186,23 +2122,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
updateWakeGestureListenerLp();
}
- final boolean useEdgeService = CMSettings.System.getIntForUser(resolver,
- CMSettings.System.USE_EDGE_SERVICE_FOR_GESTURES, 0, UserHandle.USER_CURRENT) == 1;
- if (useEdgeService ^ mUsingEdgeGestureServiceForGestures && mSystemReady) {
- if (!mUsingEdgeGestureServiceForGestures && useEdgeService) {
- mUsingEdgeGestureServiceForGestures = true;
- mWindowManagerFuncs.unregisterPointerEventListener(mSystemGestures);
- } else if (mUsingEdgeGestureServiceForGestures && !useEdgeService) {
- mUsingEdgeGestureServiceForGestures = false;
- mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
- }
- updateEdgeGestureListenerState();
- }
-
boolean devForceNavbar = CMSettings.Secure.getIntForUser(resolver,
CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR, 0, UserHandle.USER_CURRENT) == 1;
if (devForceNavbar != mDevForceNavbar) {
mDevForceNavbar = devForceNavbar;
+ if (mCMHardware.isSupported(CMHardwareManager.FEATURE_KEY_DISABLE)) {
+ mCMHardware.set(CMHardwareManager.FEATURE_KEY_DISABLE, mDevForceNavbar);
+ }
}
mNavigationBarLeftInLandscape = CMSettings.System.getIntForUser(resolver,
@@ -3167,19 +3093,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ " canceled=" + canceled);
}
- // If the boot mode is power off alarm, we should not dispatch the several physical keys
- // in power off alarm UI to avoid pausing power off alarm UI.
- int isPowerOffAlarmMode = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.POWER_OFF_ALARM_MODE, 0);
- if (DEBUG_INPUT) { Log.d(TAG, "intercept Dispatching isPowerOffAlarmMode = " +
- isPowerOffAlarmMode); }
-
- if (isPowerOffAlarmMode == 1 && (keyCode == KeyEvent.KEYCODE_HOME
- || keyCode == KeyEvent.KEYCODE_SEARCH
- || keyCode == KeyEvent.KEYCODE_MENU)) {
- return -1; // ignore the physical key here
- }
-
// If we think we might have a volume down & power key chord on the way
// but we're not sure, then tell the dispatcher to wait a little while and
// try again later before dispatching.
@@ -4042,8 +3955,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
mRecentsVisible = (visibility & View.RECENT_APPS_VISIBLE) > 0;
- updateEdgeGestureListenerState();
-
// Reset any bits in mForceClearingStatusBarVisibility that
// are now clear.
mResettingSystemUiFlags &= visibility;
@@ -5372,7 +5283,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// update since mAllowLockscreenWhenOn might have changed
updateLockScreenTimeout();
- updateEdgeGestureListenerState();
return changes;
}
@@ -5661,7 +5571,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
if (isWakeKey) {
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
+ wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
+ "android.policy:KEY", true);
}
return result;
}
@@ -5924,6 +5835,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
}
+ case KeyEvent.KEYCODE_SOFT_SLEEP: {
+ result &= ~ACTION_PASS_TO_USER;
+ isWakeKey = false;
+ if (!down) {
+ mPowerManagerInternal.setUserInactiveOverrideFromWindowManager();
+ }
+ break;
+ }
+
case KeyEvent.KEYCODE_WAKEUP: {
result &= ~ACTION_PASS_TO_USER;
isWakeKey = true;
@@ -5999,7 +5919,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
if (isWakeKey) {
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
+ wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY", true);
}
return result;
@@ -6136,11 +6056,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
private boolean shouldDispatchInputWhenNonInteractive() {
- if (mDisplay == null || mDisplay.getState() == Display.STATE_OFF) {
- return false;
- }
- // Send events to keyguard while the screen is on and it's showing.
- if (isKeyguardShowingAndNotOccluded()) {
+ // Send events to keyguard while the screen is on.
+ if (isKeyguardShowingAndNotOccluded() && mDisplay != null
+ && mDisplay.getState() != Display.STATE_OFF) {
return true;
}
@@ -6439,10 +6357,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
private void wakeUpFromPowerKey(long eventTime) {
- wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER");
+ wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER", true);
}
private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) {
+ return wakeUp(wakeTime, wakeInTheaterMode, reason, false);
+ }
+
+ private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason,
+ boolean withProximityCheck) {
final boolean theaterModeEnabled = isTheaterModeEnabled();
if (!wakeInTheaterMode && theaterModeEnabled) {
return false;
@@ -6453,7 +6376,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Settings.Global.THEATER_MODE_ON, 0);
}
- mPowerManager.wakeUp(wakeTime, reason);
+ if (withProximityCheck) {
+ mPowerManager.wakeUpWithProximityCheck(wakeTime, reason);
+ } else {
+ mPowerManager.wakeUp(wakeTime, reason);
+ }
return true;
}
@@ -6968,8 +6895,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
mKeyguardDelegate.onSystemReady();
- mEdgeGestureManager = EdgeGestureManager.getInstance();
- mEdgeGestureManager.setEdgeGestureActivationListener(mEdgeGestureActivationListener);
+ mCMHardware = CMHardwareManager.getInstance(mContext);
+ // Ensure observe happens in systemReady() since we need
+ // CMHardwareService to be up and running
+ mSettingsObserver.observe();
readCameraLensCoverState();
updateUiMode();
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 9916223..651ee22 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -55,6 +55,7 @@ public abstract class WindowOrientationListener {
private boolean mEnabled;
private int mRate;
private String mSensorType;
+ private boolean mUseSystemClockforRotationSensor;
private Sensor mSensor;
private OrientationJudge mOrientationJudge;
private int mCurrentRotation = -1;
@@ -90,6 +91,9 @@ public abstract class WindowOrientationListener {
mSensorType = context.getResources().getString(
com.android.internal.R.string.config_orientationSensorType);
+ mUseSystemClockforRotationSensor = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_useSystemClockforRotationSensor);
+
if (!TextUtils.isEmpty(mSensorType)) {
List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
final int N = sensors.size();
@@ -598,7 +602,8 @@ public abstract class WindowOrientationListener {
// Reset the orientation listener state if the samples are too far apart in time
// or when we see values of (0, 0, 0) which indicates that we polled the
// accelerometer too soon after turning it on and we don't have any data yet.
- final long now = event.timestamp;
+ final long now = mUseSystemClockforRotationSensor
+ ? SystemClock.elapsedRealtimeNanos() : event.timestamp;
final long then = mLastFilteredTimestampNanos;
final float timeDeltaMS = (now - then) * 0.000001f;
final boolean skipSample;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 05ab6b6..1fd1fbd 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -434,6 +434,14 @@ public final class PowerManagerService extends SystemService
// Use -1 to disable.
private int mButtonBrightnessOverrideFromWindowManager = -1;
+ // The window manager has determined the user to be inactive via other means.
+ // Set this to false to disable.
+ private boolean mUserInactiveOverrideFromWindowManager;
+
+ // The next possible user activity timeout after being explicitly told the user is inactive.
+ // Set to -1 when not told the user is inactive since the last period spent dozing or asleep.
+ private long mOverriddenTimeout = -1;
+
// The user activity timeout override from the window manager
// to allow the current foreground activity to override the user activity timeout.
// Use -1 to disable.
@@ -516,6 +524,7 @@ public final class PowerManagerService extends SystemService
private boolean mProximityWakeSupported;
android.os.PowerManager.WakeLock mProximityWakeLock;
SensorEventListener mProximityListener;
+ private boolean mForceNavbar;
private PerformanceManagerInternal mPerf;
@@ -690,6 +699,9 @@ public final class PowerManagerService extends SystemService
resolver.registerContentObserver(CMSettings.Global.getUriFor(
CMSettings.Global.WAKE_WHEN_PLUGGED_OR_UNPLUGGED),
false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(CMSettings.Secure.getUriFor(
+ CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR),
+ false, mSettingsObserver, UserHandle.USER_ALL);
// Go.
readConfigurationLocked();
@@ -834,7 +846,8 @@ public final class PowerManagerService extends SystemService
mKeyboardBrightness = CMSettings.Secure.getIntForUser(resolver,
CMSettings.Secure.KEYBOARD_BRIGHTNESS, mKeyboardBrightnessSettingDefault,
UserHandle.USER_CURRENT);
-
+ mForceNavbar = CMSettings.Secure.getIntForUser(resolver,
+ CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR, 0, UserHandle.USER_CURRENT) == 1;
mDirty |= DIRTY_SETTINGS;
}
@@ -1151,6 +1164,11 @@ public final class PowerManagerService extends SystemService
mNotifier.onUserActivity(event, uid);
+ if (mUserInactiveOverrideFromWindowManager) {
+ mUserInactiveOverrideFromWindowManager = false;
+ mOverriddenTimeout = -1;
+ }
+
if (mWakefulness == WAKEFULNESS_ASLEEP
|| mWakefulness == WAKEFULNESS_DOZING
|| (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
@@ -1366,12 +1384,28 @@ public final class PowerManagerService extends SystemService
}
}
+ /**
+ * Logs the time the device would have spent awake before user activity timeout,
+ * had the system not been told the user was inactive.
+ */
+ private void logSleepTimeoutRecapturedLocked() {
+ final long now = SystemClock.uptimeMillis();
+ final long savedWakeTimeMs = mOverriddenTimeout - now;
+ if (savedWakeTimeMs >= 0) {
+ EventLog.writeEvent(EventLogTags.POWER_SOFT_SLEEP_REQUESTED, savedWakeTimeMs);
+ mOverriddenTimeout = -1;
+ }
+ }
+
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
if (mWakefulness == WAKEFULNESS_DOZING
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
return; // wait until dream has enabled dozing
}
+ if (mWakefulness == WAKEFULNESS_DOZING || mWakefulness == WAKEFULNESS_ASLEEP) {
+ logSleepTimeoutRecapturedLocked();
+ }
mWakefulnessChanging = false;
mNotifier.onWakefulnessChangeFinished();
}
@@ -1657,6 +1691,7 @@ public final class PowerManagerService extends SystemService
final int sleepTimeout = getSleepTimeoutLocked();
final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
+ final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
mUserActivitySummary = 0;
if (mLastUserActivityTime >= mLastWakeTime) {
@@ -1670,7 +1705,11 @@ public final class PowerManagerService extends SystemService
buttonBrightness = mButtonBrightnessOverrideFromWindowManager;
keyboardBrightness = mButtonBrightnessOverrideFromWindowManager;
} else {
- buttonBrightness = mButtonBrightness;
+ if (!mForceNavbar) {
+ buttonBrightness = mButtonBrightness;
+ } else {
+ buttonBrightness = 0;
+ }
keyboardBrightness = mKeyboardBrightness;
}
@@ -1710,6 +1749,7 @@ public final class PowerManagerService extends SystemService
}
}
}
+
if (mUserActivitySummary == 0) {
if (sleepTimeout >= 0) {
final long anyUserActivity = Math.max(mLastUserActivityTime,
@@ -1725,6 +1765,20 @@ public final class PowerManagerService extends SystemService
nextTimeout = -1;
}
}
+
+ if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {
+ if ((mUserActivitySummary &
+ (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
+ // Device is being kept awake by recent user activity
+ if (nextTimeout >= now && mOverriddenTimeout == -1) {
+ // Save when the next timeout would have occurred
+ mOverriddenTimeout = nextTimeout;
+ }
+ }
+ mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
+ nextTimeout = -1;
+ }
+
if (mUserActivitySummary != 0 && nextTimeout >= 0) {
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
msg.setAsynchronous(true);
@@ -2654,6 +2708,14 @@ public final class PowerManagerService extends SystemService
}
}
+ private void setUserInactiveOverrideFromWindowManagerInternal() {
+ synchronized (mLock) {
+ mUserInactiveOverrideFromWindowManager = true;
+ mDirty |= DIRTY_USER_ACTIVITY;
+ updatePowerStateLocked();
+ }
+ }
+
private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
synchronized (mLock) {
if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
@@ -2843,6 +2905,8 @@ public final class PowerManagerService extends SystemService
+ mScreenBrightnessOverrideFromWindowManager);
pw.println(" mUserActivityTimeoutOverrideFromWindowManager="
+ mUserActivityTimeoutOverrideFromWindowManager);
+ pw.println(" mUserInactiveOverrideFromWindowManager="
+ + mUserInactiveOverrideFromWindowManager);
pw.println(" mTemporaryScreenBrightnessSettingOverride="
+ mTemporaryScreenBrightnessSettingOverride);
pw.println(" mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
@@ -3839,6 +3903,11 @@ public final class PowerManagerService extends SystemService
}
@Override
+ public void setUserInactiveOverrideFromWindowManager() {
+ setUserInactiveOverrideFromWindowManagerInternal();
+ }
+
+ @Override
public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
}
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 9b8ea14..34b6e2b 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -26,7 +26,6 @@ import android.app.KeyguardManager;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothManager;
-import android.content.pm.ThemeUtils;
import android.media.AudioAttributes;
import android.nfc.NfcAdapter;
import android.nfc.INfcAdapter;
@@ -78,6 +77,8 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
+import org.cyanogenmod.internal.util.ThemeUtils;
+
public final class ShutdownThread extends Thread {
// constants
private static final String TAG = "ShutdownThread";
diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java
index 7c2da2d..be3e922 100644
--- a/services/core/java/com/android/server/wm/CircularDisplayMask.java
+++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java
@@ -56,7 +56,7 @@ class CircularDisplayMask {
int screenOffset, int maskThickness) {
mScreenSize = new Point();
display.getSize(mScreenSize);
- if (mScreenSize.x != mScreenSize.y) {
+ if (mScreenSize.x != mScreenSize.y + screenOffset) {
Slog.w(TAG, "Screen dimensions of displayId = " + display.getDisplayId() +
"are not equal, circularMask will not be drawn.");
mDimensionsUnequal = true;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 331ddbf..2edf552 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -116,6 +116,7 @@ class DisplayContent {
display.getDisplayInfo(mDisplayInfo);
isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY;
mService = service;
+ initializeDisplayBaseInfo();
}
int getDisplayId() {
@@ -176,6 +177,21 @@ class DisplayContent {
}
}
+ void initializeDisplayBaseInfo() {
+ synchronized(mDisplaySizeLock) {
+ // Bootstrap the default logical display from the display manager.
+ final DisplayInfo newDisplayInfo =
+ mService.mDisplayManagerInternal.getDisplayInfo(mDisplayId);
+ if (newDisplayInfo != null) {
+ mDisplayInfo.copyFrom(newDisplayInfo);
+ }
+ mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
+ mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
+ mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
+ mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
+ }
+ }
+
void getLogicalDisplayRect(Rect out) {
// Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
final int orientation = mDisplayInfo.rotation;
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index 01f878c..80526f2 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -79,17 +79,20 @@ public class DisplaySettings {
}
}
- public void setOverscanLocked(String name, int left, int top, int right, int bottom) {
+ public void setOverscanLocked(String uniqueId, String name, int left, int top, int right,
+ int bottom) {
if (left == 0 && top == 0 && right == 0 && bottom == 0) {
// Right now all we are storing is overscan; if there is no overscan,
// we have no need for the entry.
+ mEntries.remove(uniqueId);
+ // Legacy name might have been in used, so we need to clear it.
mEntries.remove(name);
return;
}
- Entry entry = mEntries.get(name);
+ Entry entry = mEntries.get(uniqueId);
if (entry == null) {
- entry = new Entry(name);
- mEntries.put(name, entry);
+ entry = new Entry(uniqueId);
+ mEntries.put(uniqueId, entry);
}
entry.overscanLeft = left;
entry.overscanTop = top;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 480da44..7e437c7 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -399,7 +399,9 @@ public class TaskStack {
void resetAnimationBackgroundAnimator() {
mAnimationBackgroundAnimator = null;
- mAnimationBackgroundSurface.hide();
+ if (mAnimationBackgroundSurface != null) {
+ mAnimationBackgroundSurface.hide();
+ }
}
private long getBlurBehindFadeDuration(long duration) {
@@ -468,11 +470,14 @@ public class TaskStack {
}
boolean isDimming() {
+ if (mDimLayer == null) {
+ return false;
+ }
return mDimLayer.isDimming();
}
boolean isDimming(WindowStateAnimator winAnimator) {
- return mDimWinAnimator == winAnimator && mDimLayer.isDimming();
+ return mDimWinAnimator == winAnimator && isDimming();
}
void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1d5f64c..dcb1e18 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1015,7 +1015,6 @@ public class WindowManagerService extends IWindowManager.Stub
// Load hardware rotation from prop
mSfHwRotation = android.os.SystemProperties.getInt("ro.sf.hwrotation",0) / 90;
- updateCircularDisplayMaskIfNeeded();
showEmulatorDisplayOverlayIfNeeded();
}
@@ -4490,13 +4489,8 @@ public class WindowManagerService extends IWindowManager.Stub
+ " ShowWallpaper="
+ ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false));
- final boolean windowIsTranslucentDefined = ent.array.hasValue(
- com.android.internal.R.styleable.Window_windowIsTranslucent);
- final boolean windowIsTranslucent = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsTranslucent, false);
- final boolean windowSwipeToDismiss = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
- if (windowIsTranslucent || (!windowIsTranslucentDefined && windowSwipeToDismiss)) {
+ if (ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
return;
}
if (ent.array.getBoolean(
@@ -6003,7 +5997,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- public void updateCircularDisplayMaskIfNeeded() {
+ private void updateCircularDisplayMaskIfNeeded() {
// we're fullscreen and not hosted in an ActivityView
if (mContext.getResources().getConfiguration().isScreenRound()
&& mContext.getResources().getBoolean(
@@ -6043,8 +6037,8 @@ public class WindowManagerService extends IWindowManager.Stub
if (visible) {
// TODO(multi-display): support multiple displays
if (mCircularDisplayMask == null) {
- int screenOffset = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.circular_display_mask_offset);
+ int screenOffset = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_windowOutsetBottom);
int maskThickness = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.circular_display_mask_thickness);
@@ -7726,6 +7720,8 @@ public class WindowManagerService extends IWindowManager.Stub
mActivityManager.updateConfiguration(null);
} catch (RemoteException e) {
}
+
+ updateCircularDisplayMaskIfNeeded();
}
private void displayReady(int displayId) {
@@ -7733,22 +7729,7 @@ public class WindowManagerService extends IWindowManager.Stub
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
mAnimator.addDisplayLocked(displayId);
- synchronized(displayContent.mDisplaySizeLock) {
- // Bootstrap the default logical display from the display manager.
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- DisplayInfo newDisplayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
- if (newDisplayInfo != null) {
- displayInfo.copyFrom(newDisplayInfo);
- }
- displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
- displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
- displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
- displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
- displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
- displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
- displayContent.mBaseDisplayRect.set(0, 0,
- displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight);
- }
+ displayContent.initializeDisplayBaseInfo();
}
}
}
@@ -8787,7 +8768,8 @@ public class WindowManagerService extends IWindowManager.Stub
displayInfo.overscanBottom = bottom;
}
- mDisplaySettings.setOverscanLocked(displayInfo.uniqueId, left, top, right, bottom);
+ mDisplaySettings.setOverscanLocked(displayInfo.uniqueId, displayInfo.name, left, top,
+ right, bottom);
mDisplaySettings.writeSettingsLocked();
reconfigureDisplayLocked(displayContent);