summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java26
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java76
-rw-r--r--services/core/java/com/android/server/DeviceIdleController.java80
-rw-r--r--services/core/java/com/android/server/InputMethodManagerService.java45
-rw-r--r--services/core/java/com/android/server/LocationManagerService.java14
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java169
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java39
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java160
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java3
-rw-r--r--services/core/java/com/android/server/am/UserState.java (renamed from services/core/java/com/android/server/am/UserStartedState.java)11
-rw-r--r--services/core/java/com/android/server/audio/MediaFocusControl.java10
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java10
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkMonitor.java18
-rw-r--r--services/core/java/com/android/server/content/ContentService.java15
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java4
-rw-r--r--services/core/java/com/android/server/location/FlpHardwareProvider.java25
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java18
-rw-r--r--services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java521
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java212
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java2
-rw-r--r--services/core/java/com/android/server/pm/SettingBase.java22
-rw-r--r--services/core/java/com/android/server/pm/Settings.java99
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java17
-rw-r--r--services/core/java/com/android/server/power/Notifier.java98
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java1
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java1
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java10
-rw-r--r--services/core/java/com/android/server/tv/PersistentDataStore.java4
-rw-r--r--services/core/java/com/android/server/tv/TvInputHal.java11
-rw-r--r--services/core/java/com/android/server/tv/TvInputHardwareManager.java70
-rw-r--r--services/core/java/com/android/server/tv/TvInputManagerService.java53
-rw-r--r--services/core/java/com/android/server/webkit/WebViewUpdateService.java21
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java19
-rw-r--r--services/java/com/android/server/SystemServer.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java271
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java83
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java17
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java2
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java24
39 files changed, 1726 insertions, 557 deletions
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index f9f6714..b33b10b 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -61,7 +61,7 @@ import java.util.HashMap;
import java.util.Map;
class BluetoothManagerService extends IBluetoothManager.Stub {
private static final String TAG = "BluetoothManagerService";
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
@@ -227,21 +227,23 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
}
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ if (DBG) Log.d(TAG, "Bluetooth user switched");
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_USER_SWITCHED,
intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
} else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+ if (DBG) Log.d(TAG, "Bluetooth boot completed");
synchronized(mReceiver) {
if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
//Enable
if (DBG) Log.d(TAG, "Auto-enabling Bluetooth.");
sendEnableMsg(mQuietEnableExternal);
}
- }
-
- if (!isNameAndAddressSet()) {
- // Sync the Bluetooth name and address from the Bluetooth Adapter
- if (DBG) Log.d(TAG,"Retrieving Bluetooth Adapter name and address...");
- getNameAndAddress();
+ if (!isNameAndAddressSet()) {
+ // Sync the Bluetooth name and address from the
+ // Bluetooth Adapter
+ if (DBG) Log.d(TAG, "Retrieving Bluetooth Adapter name and address...");
+ getNameAndAddress();
+ }
}
}
}
@@ -1099,7 +1101,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
boolean unbind = false;
if (DBG) Log.d(TAG,"MESSAGE_SAVE_NAME_AND_ADDRESS");
synchronized(mConnection) {
- if (!mEnable && mBluetooth != null) {
+ if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
try {
mBluetooth.enable();
} catch (RemoteException e) {
@@ -1107,7 +1109,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
}
}
- if (mBluetooth != null) waitForOnOff(true, false);
+ if (mBluetooth != null && !mConnection.isGetNameAddressOnly()) waitForOnOff(true, false);
synchronized(mConnection) {
if (mBluetooth != null) {
String name = null;
@@ -1137,7 +1139,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
}
}
- if (!mEnable) {
+ if (!mEnable && !mConnection.isGetNameAddressOnly()) {
try {
mBluetooth.disable();
} catch (RemoteException e) {
@@ -1152,7 +1154,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mHandler.sendMessage(getMsg);
}
}
- if (!mEnable && mBluetooth != null) waitForOnOff(false, true);
+ if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
+ waitForOnOff(false, true);
+ }
if (unbind) {
unbindAndFinish();
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 98f0b45..25d4d5e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -326,7 +326,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
/**
* used to add a network request with a pending intent
- * includes a NetworkRequestInfo
+ * obj = NetworkRequestInfo
*/
private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
@@ -356,6 +356,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private static final int EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON = 30;
+ /**
+ * used to add a network listener with a pending intent
+ * obj = NetworkRequestInfo
+ */
+ private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
+
/** Handler used for internal events. */
final private InternalHandler mHandler;
/** Handler used for incoming {@link NetworkStateTracker} events. */
@@ -2068,15 +2074,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
log(nai.name() + " got DISCONNECTED, was satisfying " + nai.networkRequests.size());
}
// A network agent has disconnected.
- if (nai.created) {
- // Tell netd to clean up the configuration for this network
- // (routing rules, DNS, etc).
- try {
- mNetd.removeNetwork(nai.network.netId);
- } catch (Exception e) {
- loge("Exception removing network: " + e);
- }
- }
// TODO - if we move the logic to the network agent (have them disconnect
// because they lost all their requests or because their score isn't good)
// then they would disconnect organically, report their new state and then
@@ -2095,8 +2092,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai);
synchronized (mNetworkForNetId) {
+ // Remove the NetworkAgent, but don't mark the netId as
+ // available until we've told netd to delete it below.
mNetworkForNetId.remove(nai.network.netId);
- mNetIdInUse.delete(nai.network.netId);
}
// Since we've lost the network, go through all the requests that
// it was satisfying and see if any other factory can satisfy them.
@@ -2138,9 +2136,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
rematchNetworkAndRequests(networkToActivate, NascentState.NOT_JUST_VALIDATED,
ReapUnvalidatedNetworks.DONT_REAP);
}
+ if (nai.created) {
+ // Tell netd to clean up the configuration for this network
+ // (routing rules, DNS, etc).
+ // This may be slow as it requires a lot of netd shelling out to ip and
+ // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
+ // after we've rematched networks with requests which should make a potential
+ // fallback network the default or requested a new network from the
+ // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
+ // long time.
+ try {
+ mNetd.removeNetwork(nai.network.netId);
+ } catch (Exception e) {
+ loge("Exception removing network: " + e);
+ }
+ }
+ synchronized (mNetworkForNetId) {
+ mNetIdInUse.delete(nai.network.netId);
+ }
+ } else {
+ NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo);
+ if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name);
}
- NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo);
- if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name);
}
// If this method proves to be too slow then we can maintain a separate
@@ -2185,7 +2202,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Not setting bestNetwork here as a listening NetworkRequest may be
// satisfied by multiple Networks. Instead the request is added to
// each satisfying Network and notified about each.
- network.addRequest(nri.request);
+ if (!network.addRequest(nri.request)) {
+ Slog.wtf(TAG, "BUG: " + network.name() + " already has " + nri.request);
+ }
notifyNetworkCallback(network, nri);
} else if (bestNetwork == null ||
bestNetwork.getCurrentScore() < network.getCurrentScore()) {
@@ -2196,7 +2215,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (bestNetwork != null) {
if (DBG) log("using " + bestNetwork.name());
unlinger(bestNetwork);
- bestNetwork.addRequest(nri.request);
+ if (!bestNetwork.addRequest(nri.request)) {
+ Slog.wtf(TAG, "BUG: " + bestNetwork.name() + " already has " + nri.request);
+ }
mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
notifyNetworkCallback(bestNetwork, nri);
if (nri.request.legacyType != TYPE_NONE) {
@@ -2480,7 +2501,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
break;
}
- case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: {
+ case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
+ case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
handleRegisterNetworkRequestWithIntent(msg);
break;
}
@@ -3689,6 +3711,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
PendingIntent operation) {
+ checkNotNull(operation, "PendingIntent cannot be null.");
+ if (!hasWifiNetworkListenPermission(networkCapabilities)) {
+ enforceAccessPermission();
+ }
+
+ NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
+ networkCapabilities), TYPE_NONE, nextNetworkRequestId());
+ if (DBG) log("pendingListenForNetwork for " + networkRequest + " to trigger " + operation);
+ NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
+ NetworkRequestInfo.LISTEN);
+
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
}
@Override
@@ -4197,6 +4231,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Find and migrate to this Network any NetworkRequests for
// which this network is now the best.
ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
+ ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<NetworkRequestInfo>();
if (VDBG) log(" network has: " + newNetwork.networkCapabilities);
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
@@ -4215,7 +4250,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (!nri.isRequest) {
// This is not a request, it's a callback listener.
// Add it to newNetwork regardless of score.
- newNetwork.addRequest(nri.request);
+ if (newNetwork.addRequest(nri.request)) addedRequests.add(nri);
continue;
}
@@ -4238,7 +4273,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
unlinger(newNetwork);
mNetworkForRequestId.put(nri.request.requestId, newNetwork);
- newNetwork.addRequest(nri.request);
+ if (!newNetwork.addRequest(nri.request)) {
+ Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request);
+ }
+ addedRequests.add(nri);
keep = true;
// Tell NetworkFactories about the new score, so they can stop
// trying to connect if they know they cannot match it.
@@ -4281,7 +4319,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// do this after the default net is switched, but
// before LegacyTypeTracker sends legacy broadcasts
- notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_AVAILABLE);
+ for (NetworkRequestInfo nri : addedRequests) notifyNetworkCallback(newNetwork, nri);
if (isNewDefault) {
// Maintain the illusion: since the legacy API only
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 8dd087a..dc203ff 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -45,6 +45,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -96,9 +97,6 @@ public class DeviceIdleController extends SystemService
private static final String ACTION_STEP_IDLE_STATE =
"com.android.server.device_idle.STEP_IDLE_STATE";
- private static final String ACTION_ENTER_INACTIVE_STATE =
- "com.android.server.device_idle.ENTER_INACTIVE_STATE";
-
private AlarmManager mAlarmManager;
private IBatteryStats mBatteryStats;
private PowerManagerInternal mLocalPowerManager;
@@ -111,7 +109,7 @@ public class DeviceIdleController extends SystemService
private Intent mIdleIntent;
private Display mCurDisplay;
private AnyMotionDetector mAnyMotionDetector;
- private boolean mIdleDisabled;
+ private boolean mEnabled;
private boolean mScreenOn;
private boolean mCharging;
private boolean mSigMotionActive;
@@ -190,10 +188,6 @@ public class DeviceIdleController extends SystemService
synchronized (DeviceIdleController.this) {
stepIdleStateLocked();
}
- } else if (ACTION_ENTER_INACTIVE_STATE.equals(intent.getAction())) {
- synchronized (DeviceIdleController.this) {
- enterInactiveStateLocked();
- }
}
}
};
@@ -487,7 +481,7 @@ public class DeviceIdleController extends SystemService
mLocalPowerManager.setDeviceIdleMode(true);
try {
mNetworkPolicyManager.setDeviceIdleMode(true);
- mBatteryStats.noteDeviceIdleMode(true, false, false);
+ mBatteryStats.noteDeviceIdleMode(true, null, Process.myUid());
} catch (RemoteException e) {
}
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
@@ -496,18 +490,19 @@ public class DeviceIdleController extends SystemService
mLocalPowerManager.setDeviceIdleMode(false);
try {
mNetworkPolicyManager.setDeviceIdleMode(false);
- mBatteryStats.noteDeviceIdleMode(false, false, false);
+ mBatteryStats.noteDeviceIdleMode(false, null, Process.myUid());
} catch (RemoteException e) {
}
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
} break;
case MSG_REPORT_ACTIVE: {
- boolean fromMotion = msg.arg1 != 0;
+ String activeReason = (String)msg.obj;
+ int activeUid = msg.arg1;
boolean needBroadcast = msg.arg2 != 0;
mLocalPowerManager.setDeviceIdleMode(false);
try {
mNetworkPolicyManager.setDeviceIdleMode(false);
- mBatteryStats.noteDeviceIdleMode(false, !fromMotion, fromMotion);
+ mBatteryStats.noteDeviceIdleMode(false, activeReason, activeUid);
} catch (RemoteException e) {
}
if (needBroadcast) {
@@ -578,6 +573,12 @@ public class DeviceIdleController extends SystemService
}
}
+ @Override public void exitIdle(String reason) {
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+ null);
+ exitIdleInternal(reason);
+ }
+
@Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
DeviceIdleController.this.dump(fd, pw, args);
}
@@ -604,6 +605,8 @@ public class DeviceIdleController extends SystemService
final PackageManager pm = getContext().getPackageManager();
synchronized (this) {
+ mEnabled = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_enableAutoPowerModes);
SystemConfig sysConfig = SystemConfig.getInstance();
ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
for (int i=0; i<allowPower.size(); i++) {
@@ -818,6 +821,12 @@ public class DeviceIdleController extends SystemService
}
}
+ public void exitIdleInternal(String reason) {
+ synchronized (this) {
+ becomeActiveLocked(reason, Binder.getCallingUid());
+ }
+ }
+
void updateDisplayLocked() {
mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
// We consider any situation where the display is showing something to be it on,
@@ -830,7 +839,7 @@ public class DeviceIdleController extends SystemService
becomeInactiveIfAppropriateLocked();
} else if (screenOn) {
mScreenOn = true;
- becomeActiveLocked("screen");
+ becomeActiveLocked("screen", Process.myUid());
}
}
@@ -841,21 +850,21 @@ public class DeviceIdleController extends SystemService
becomeInactiveIfAppropriateLocked();
} else if (charging) {
mCharging = charging;
- becomeActiveLocked("charging");
+ becomeActiveLocked("charging", Process.myUid());
}
}
- void scheduleReportActiveLocked(boolean fromMotion) {
- Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, fromMotion ? 1 : 0,
- mState == STATE_IDLE ? 1 : 0);
+ void scheduleReportActiveLocked(String activeReason, int activeUid) {
+ Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid,
+ mState == STATE_IDLE ? 1 : 0, activeReason);
mHandler.sendMessage(msg);
}
- void becomeActiveLocked(String reason) {
- if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + reason);
+ void becomeActiveLocked(String activeReason, int activeUid) {
+ if (DEBUG) Slog.i(TAG, "becomeActiveLocked, reason = " + activeReason);
if (mState != STATE_ACTIVE) {
- EventLogTags.writeDeviceIdle(STATE_ACTIVE, reason);
- scheduleReportActiveLocked(false);
+ EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
+ scheduleReportActiveLocked(activeReason, activeUid);
mState = STATE_ACTIVE;
mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
mNextIdlePendingDelay = 0;
@@ -867,7 +876,7 @@ public class DeviceIdleController extends SystemService
void becomeInactiveIfAppropriateLocked() {
if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
- if (!mScreenOn && !mCharging && !mIdleDisabled && mState == STATE_ACTIVE) {
+ if (!mScreenOn && !mCharging && mEnabled && mState == STATE_ACTIVE) {
// Screen has turned off; we are now going to become inactive and start
// waiting to see if we will ultimately go idle.
mState = STATE_INACTIVE;
@@ -896,7 +905,7 @@ public class DeviceIdleController extends SystemService
if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
// Whoops, there is an upcoming alarm. We don't actually want to go idle.
if (mState != STATE_ACTIVE) {
- becomeActiveLocked("alarm");
+ becomeActiveLocked("alarm", Process.myUid());
}
return;
}
@@ -954,7 +963,7 @@ public class DeviceIdleController extends SystemService
// 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.
if (mState != STATE_ACTIVE) {
- scheduleReportActiveLocked(true);
+ scheduleReportActiveLocked("motion", Process.myUid());
mState = STATE_ACTIVE;
mInactiveTimeout = mConstants.MOTION_INACTIVE_TIMEOUT;
EventLogTags.writeDeviceIdle(mState, "motion");
@@ -1202,8 +1211,12 @@ public class DeviceIdleController extends SystemService
pw.println(" Completely disable device idle mode.");
pw.println(" enable");
pw.println(" Re-enable device idle mode after it had previously been disabled.");
- pw.println(" whitelist");
+ pw.println(" enabled");
+ pw.println(" Print 1 if device idle mode is currently enabled, else 0.");
+ pw.println(" whitelist [package ...]");
pw.println(" Add (prefix with +) or remove (prefix with -) packages.");
+ pw.println(" tempwhitelist [package ..]");
+ pw.println(" Temporarily place packages in whitelist for 10 seconds.");
}
void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1238,22 +1251,27 @@ public class DeviceIdleController extends SystemService
return;
} else if ("disable".equals(arg)) {
synchronized (this) {
- if (!mIdleDisabled) {
- mIdleDisabled = true;
- becomeActiveLocked("disabled");
+ if (mEnabled) {
+ mEnabled = false;
+ becomeActiveLocked("disabled", Process.myUid());
pw.println("Idle mode disabled");
}
}
return;
} else if ("enable".equals(arg)) {
synchronized (this) {
- if (mIdleDisabled) {
- mIdleDisabled = false;
+ if (!mEnabled) {
+ mEnabled = true;
becomeInactiveIfAppropriateLocked();
pw.println("Idle mode enabled");
}
}
return;
+ } else if ("enabled".equals(arg)) {
+ synchronized (this) {
+ pw.println(mEnabled ? "1" : " 0");
+ }
+ return;
} else if ("whitelist".equals(arg)) {
i++;
while (i < args.length) {
@@ -1350,9 +1368,9 @@ public class DeviceIdleController extends SystemService
}
}
+ pw.print(" mEnabled="); pw.println(mEnabled);
pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor);
pw.print(" mCurDisplay="); pw.println(mCurDisplay);
- pw.print(" mIdleDisabled="); pw.println(mIdleDisabled);
pw.print(" mScreenOn="); pw.println(mScreenOn);
pw.print(" mCharging="); pw.println(mCharging);
pw.print(" mSigMotionActive="); pw.println(mSigMotionActive);
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 2f153a0..dbe8781 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
import android.annotation.NonNull;
+import android.content.pm.PackageManagerInternal;
import com.android.internal.content.PackageMonitor;
import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController;
import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
@@ -31,6 +32,7 @@ import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.InputBindResult;
+import com.android.server.pm.UserManagerService;
import com.android.server.statusbar.StatusBarManagerService;
import com.android.server.wm.WindowManagerService;
@@ -859,6 +861,38 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// mSettings should be created before buildInputMethodListLocked
mSettings = new InputMethodSettings(
mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
+
+ // Let the package manager query which are the default imes
+ // as they get certain permissions granted by default.
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ packageManagerInternal.setImePackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ synchronized (mMethodMap) {
+ final int currentUserId = mSettings.getCurrentUserId();
+ // TODO: We are switching the current user id in the settings
+ // object to query it and then revert the user id. Ideally, we
+ // should call a API in settings with the user id as an argument.
+ mSettings.setCurrentUserId(userId);
+ List<InputMethodInfo> imes = mSettings
+ .getEnabledInputMethodListLocked();
+ String[] packageNames = null;
+ if (imes != null) {
+ final int imeCount = imes.size();
+ packageNames = new String[imeCount];
+ for (int i = 0; i < imeCount; i++) {
+ InputMethodInfo ime = imes.get(i);
+ packageNames[i] = ime.getPackageName();
+ }
+ }
+ mSettings.setCurrentUserId(currentUserId);
+ return packageNames;
+ }
+ }
+ });
+
updateCurrentProfileIds();
mFileManager = new InputMethodFileManager(mMethodMap, userId);
synchronized (mMethodMap) {
@@ -1009,8 +1043,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
resetAllInternalStateLocked(false /* updateOnlyWhenLocaleChanged */,
initialUserSwitch /* needsToResetDefaultIme */);
if (initialUserSwitch) {
- InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mContext.getPackageManager(),
- mSettings.getEnabledInputMethodListLocked());
+ InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
+ mSettings.getEnabledInputMethodListLocked(), newUserId,
+ mContext.getBasePackageName());
}
if (DEBUG) Slog.d(TAG, "Switching user stage 3/3. newUserId=" + newUserId
@@ -1067,9 +1102,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (!mImeSelectedOnBoot) {
Slog.w(TAG, "Reset the default IME as \"Resource\" is ready here.");
resetStateIfCurrentLocaleChangedLocked();
- InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
- mContext.getPackageManager(),
- mSettings.getEnabledInputMethodListLocked());
+ InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
+ mSettings.getEnabledInputMethodListLocked(),
+ mSettings.getCurrentUserId(), mContext.getBasePackageName());
}
mLastSystemLocale = mRes.getConfiguration().locale;
try {
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 743aafb..61bedf5 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.content.pm.PackageManagerInternal;
import com.android.internal.content.PackageMonitor;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
@@ -218,6 +219,19 @@ public class LocationManagerService extends ILocationManager.Stub {
mContext = context;
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
+ // Let the package manager query which are the default location
+ // providers as they get certain permissions granted by default.
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ packageManagerInternal.setLocationPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ return mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_locationProviderPackageNames);
+ }
+ });
+
if (D) Log.d(TAG, "Constructed");
// most startup is deferred until systemReady()
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c4f460e..0301638 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -676,9 +676,9 @@ public final class ActivityManagerService extends ActivityManagerNative
final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
/**
- * Which uses have been started, so are allowed to run code.
+ * Which users have been started, so are allowed to run code.
*/
- final SparseArray<UserStartedState> mStartedUsers = new SparseArray<>();
+ final SparseArray<UserState> mStartedUsers = new SparseArray<>();
/**
* LRU list of history of current users. Most recently current is at the end.
@@ -1781,15 +1781,15 @@ public final class ActivityManagerService extends ActivityManagerNative
break;
}
case REPORT_USER_SWITCH_MSG: {
- dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
+ dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
}
case CONTINUE_USER_SWITCH_MSG: {
- continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
+ continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
}
case USER_SWITCH_TIMEOUT_MSG: {
- timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
+ timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
}
case IMMERSIVE_MODE_LOCK_MSG: {
@@ -2309,7 +2309,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
// User 0 is the first and only user that runs at boot.
- mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
+ mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
mUserLru.add(UserHandle.USER_OWNER);
updateStartedUserArrayLocked();
@@ -2488,10 +2488,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized(bstats) {
synchronized(mPidsSelfLocked) {
if (haveNewCpuStats) {
- final int perc = bstats.startAddingCpuLocked();
- if (perc >= 0) {
- int remainUTime = 0;
- int remainSTime = 0;
+ if (bstats.startAddingCpuLocked()) {
int totalUTime = 0;
int totalSTime = 0;
final int N = mProcessCpuTracker.countStats();
@@ -2501,10 +2498,6 @@ public final class ActivityManagerService extends ActivityManagerNative
continue;
}
ProcessRecord pr = mPidsSelfLocked.get(st.pid);
- int otherUTime = (st.rel_utime*perc)/100;
- int otherSTime = (st.rel_stime*perc)/100;
- remainUTime += otherUTime;
- remainSTime += otherSTime;
totalUTime += st.rel_utime;
totalSTime += st.rel_stime;
if (pr != null) {
@@ -2513,8 +2506,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
pr.info.uid, pr.processName);
}
- ps.addCpuTimeLocked(st.rel_utime - otherUTime,
- st.rel_stime - otherSTime);
+ ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
pr.curCpuTime += st.rel_utime + st.rel_stime;
} else {
BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
@@ -2522,8 +2514,7 @@ public final class ActivityManagerService extends ActivityManagerNative
st.batteryStats = ps = bstats.getProcessStatsLocked(
bstats.mapUid(st.uid), st.name);
}
- ps.addCpuTimeLocked(st.rel_utime - otherUTime,
- st.rel_stime - otherSTime);
+ ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
}
}
final int userTime = mProcessCpuTracker.getLastUserTime();
@@ -2532,9 +2523,8 @@ public final class ActivityManagerService extends ActivityManagerNative
final int irqTime = mProcessCpuTracker.getLastIrqTime();
final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
final int idleTime = mProcessCpuTracker.getLastIdleTime();
- bstats.finishAddingCpuLocked(perc, remainUTime,
- remainSTime, totalUTime, totalSTime, userTime, systemTime,
- iowaitTime, irqTime, softIrqTime, idleTime);
+ bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
+ systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
}
}
}
@@ -2754,13 +2744,19 @@ public final class ActivityManagerService extends ActivityManagerNative
return index;
}
+ private static void killProcessGroup(int uid, int pid) {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
+ Process.killProcessGroup(uid, pid);
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ }
+
final void removeLruProcessLocked(ProcessRecord app) {
int lrui = mLruProcesses.lastIndexOf(app);
if (lrui >= 0) {
if (!app.killed) {
Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
Process.killProcessQuiet(app.pid);
- Process.killProcessGroup(app.info.uid, app.pid);
+ killProcessGroup(app.info.uid, app.pid);
}
if (lrui <= mLruProcessActivityStart) {
mLruProcessActivityStart--;
@@ -3125,7 +3121,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// clean it up now.
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
checkTime(startTime, "startProcess: bad proc running, killing");
- Process.killProcessGroup(app.info.uid, app.pid);
+ killProcessGroup(app.info.uid, app.pid);
handleAppDiedLocked(app, true, true);
checkTime(startTime, "startProcess: done killing old proc");
}
@@ -3274,9 +3270,9 @@ public final class ActivityManagerService extends ActivityManagerNative
debugFlags |= Zygote.DEBUG_ENABLE_JIT;
}
}
- String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
- if ("true".equals(genCFIDebugProperty)) {
- debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+ String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
+ if ("true".equals(genDebugInfoProperty)) {
+ debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
}
if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
@@ -3589,6 +3585,8 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public int getPackageProcessState(String packageName) {
+ enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
+ "getPackageProcessState");
int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
synchronized (this) {
for (int i=mLruProcesses.size()-1; i>=0; i--) {
@@ -4611,7 +4609,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!fromBinderDied) {
Process.killProcessQuiet(pid);
}
- Process.killProcessGroup(app.info.uid, pid);
+ killProcessGroup(app.info.uid, pid);
app.killed = true;
}
@@ -5932,7 +5930,7 @@ public final class ActivityManagerService extends ActivityManagerNative
EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
if (pid > 0 && pid != MY_PID) {
Process.killProcessQuiet(pid);
- //TODO: Process.killProcessGroup(app.info.uid, pid);
+ //TODO: killProcessGroup(app.info.uid, pid);
} else {
try {
thread.scheduleExit();
@@ -6313,9 +6311,9 @@ public final class ActivityManagerService extends ActivityManagerNative
SystemProperties.set("dev.bootcomplete", "1");
}
for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
- if (uss.mState == UserStartedState.STATE_BOOTING) {
- uss.mState = UserStartedState.STATE_RUNNING;
+ UserState uss = mStartedUsers.valueAt(i);
+ if (uss.mState == UserState.STATE_BOOTING) {
+ uss.mState = UserState.STATE_RUNNING;
final int userId = mStartedUsers.keyAt(i);
Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
@@ -8278,7 +8276,7 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
allowed = true;
- Slog.w(TAG, caller + ": caller " + callingUid
+ if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
+ " is using old GET_TASKS but privileged; allowing");
}
} catch (RemoteException e) {
@@ -8286,7 +8284,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
if (!allowed) {
- Slog.w(TAG, caller + ": caller " + callingUid
+ if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
+ " does not hold REAL_GET_TASKS; limiting output");
}
return allowed;
@@ -9442,6 +9440,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
boolean success = updateOomAdjLocked(cpr.proc);
+ maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
// NOTE: there is still a race here where a signal could be
@@ -9831,6 +9830,8 @@ public final class ActivityManagerService extends ActivityManagerNative
dst.notifyAll();
}
updateOomAdjLocked(r);
+ maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
+ src.info.authority);
}
}
@@ -12397,7 +12398,7 @@ public final class ActivityManagerService extends ActivityManagerNative
} else {
// Huh.
Process.killProcess(pid);
- Process.killProcessGroup(uid, pid);
+ killProcessGroup(uid, pid);
}
}
return;
@@ -13343,7 +13344,7 @@ public final class ActivityManagerService extends ActivityManagerNative
needSep = false;
pw.println(" mStartedUsers:");
for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
+ UserState uss = mStartedUsers.valueAt(i);
pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
pw.print(": "); uss.dump("", pw);
}
@@ -18615,6 +18616,22 @@ public final class ActivityManagerService extends ActivityManagerNative
uidRec.pendingChange.processState = uidRec.setProcState;
}
+ private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
+ String authority) {
+ if (app == null) return;
+ if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
+ UserState userState = mStartedUsers.get(app.userId);
+ if (userState == null) return;
+ final long now = SystemClock.elapsedRealtime();
+ Long lastReported = userState.mProviderLastReportedFg.get(authority);
+ if (lastReported == null || lastReported < now - 60 * 1000L) {
+ mUsageStatsService.reportContentProviderUsage(
+ authority, providerPkgName, app.userId);
+ userState.mProviderLastReportedFg.put(authority, now);
+ }
+ }
+ }
+
private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
if (DEBUG_USAGE_STATS) {
Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
@@ -19602,7 +19619,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// If the user we are switching to is not currently started, then
// we need to start it now.
if (mStartedUsers.get(userId) == null) {
- mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
+ mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
updateStartedUserArrayLocked();
needStart = true;
}
@@ -19627,26 +19644,26 @@ public final class ActivityManagerService extends ActivityManagerNative
mUserLru.add(currentUserIdInt);
}
- final UserStartedState uss = mStartedUsers.get(userId);
+ final UserState uss = mStartedUsers.get(userId);
// Make sure user is in the started state. If it is currently
// stopping, we need to knock that off.
- if (uss.mState == UserStartedState.STATE_STOPPING) {
+ if (uss.mState == UserState.STATE_STOPPING) {
// If we are stopping, we haven't sent ACTION_SHUTDOWN,
// so we can just fairly silently bring the user back from
// the almost-dead.
- uss.mState = UserStartedState.STATE_RUNNING;
+ uss.mState = UserState.STATE_RUNNING;
updateStartedUserArrayLocked();
needStart = true;
- } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
+ } else if (uss.mState == UserState.STATE_SHUTDOWN) {
// This means ACTION_SHUTDOWN has been sent, so we will
// need to treat this as a new boot of the user.
- uss.mState = UserStartedState.STATE_BOOTING;
+ uss.mState = UserState.STATE_BOOTING;
updateStartedUserArrayLocked();
needStart = true;
}
- if (uss.mState == UserStartedState.STATE_BOOTING) {
+ if (uss.mState == UserState.STATE_BOOTING) {
// Booting up a new user, need to tell system services about it.
// Note that this is on the same handler as scheduling of broadcasts,
// which is important because it needs to go first.
@@ -19784,7 +19801,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
+ void dispatchUserSwitch(final UserState uss, final int oldUserId,
final int newUserId) {
final int N = mUserSwitchObservers.beginBroadcast();
if (N > 0) {
@@ -19821,21 +19838,21 @@ public final class ActivityManagerService extends ActivityManagerNative
mUserSwitchObservers.finishBroadcast();
}
- void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
+ void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
synchronized (this) {
Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
}
}
- void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
+ void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
mCurUserSwitchCallback = null;
mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
oldUserId, newUserId, uss));
}
- void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
+ void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
synchronized (this) {
if (foreground) {
moveUserToForeground(uss, oldUserId, newUserId);
@@ -19845,7 +19862,7 @@ public final class ActivityManagerService extends ActivityManagerNative
completeSwitchAndInitalize(uss, newUserId, true, false);
}
- void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
+ void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
if (homeInFront) {
startHomeActivityLocked(newUserId, "moveUserToFroreground");
@@ -19857,11 +19874,11 @@ public final class ActivityManagerService extends ActivityManagerNative
sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
}
- void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
+ void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
completeSwitchAndInitalize(uss, newUserId, false, true);
}
- void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
+ void completeSwitchAndInitalize(UserState uss, int newUserId,
boolean clearInitializing, boolean clearSwitching) {
boolean unfrozen = false;
synchronized (this) {
@@ -19898,10 +19915,10 @@ public final class ActivityManagerService extends ActivityManagerNative
final int num = mUserLru.size();
for (int i = 0; i < num; i++) {
Integer oldUserId = mUserLru.get(i);
- UserStartedState oldUss = mStartedUsers.get(oldUserId);
+ UserState oldUss = mStartedUsers.get(oldUserId);
if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
- || oldUss.mState == UserStartedState.STATE_STOPPING
- || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
+ || oldUss.mState == UserState.STATE_STOPPING
+ || oldUss.mState == UserState.STATE_SHUTDOWN) {
continue;
}
UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
@@ -19942,11 +19959,11 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- void finishUserBoot(UserStartedState uss) {
+ void finishUserBoot(UserState uss) {
synchronized (this) {
- if (uss.mState == UserStartedState.STATE_BOOTING
+ if (uss.mState == UserState.STATE_BOOTING
&& mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
- uss.mState = UserStartedState.STATE_RUNNING;
+ uss.mState = UserState.STATE_RUNNING;
final int userId = uss.mHandle.getIdentifier();
Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
@@ -19959,7 +19976,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- void finishUserSwitch(UserStartedState uss) {
+ void finishUserSwitch(UserState uss) {
synchronized (this) {
finishUserBoot(uss);
@@ -19969,15 +19986,15 @@ public final class ActivityManagerService extends ActivityManagerNative
int i = 0;
while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
Integer oldUserId = mUserLru.get(i);
- UserStartedState oldUss = mStartedUsers.get(oldUserId);
+ UserState oldUss = mStartedUsers.get(oldUserId);
if (oldUss == null) {
// Shouldn't happen, but be sane if it does.
mUserLru.remove(i);
num--;
continue;
}
- if (oldUss.mState == UserStartedState.STATE_STOPPING
- || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
+ if (oldUss.mState == UserState.STATE_STOPPING
+ || oldUss.mState == UserState.STATE_SHUTDOWN) {
// This user is already stopping, doesn't count.
num--;
i++;
@@ -20022,7 +20039,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return ActivityManager.USER_OP_IS_CURRENT;
}
- final UserStartedState uss = mStartedUsers.get(userId);
+ final UserState uss = mStartedUsers.get(userId);
if (uss == null) {
// User is not started, nothing to do... but we do need to
// callback if requested.
@@ -20044,9 +20061,9 @@ public final class ActivityManagerService extends ActivityManagerNative
uss.mStopCallbacks.add(callback);
}
- if (uss.mState != UserStartedState.STATE_STOPPING
- && uss.mState != UserStartedState.STATE_SHUTDOWN) {
- uss.mState = UserStartedState.STATE_STOPPING;
+ if (uss.mState != UserState.STATE_STOPPING
+ && uss.mState != UserState.STATE_SHUTDOWN) {
+ uss.mState = UserState.STATE_STOPPING;
updateStartedUserArrayLocked();
long ident = Binder.clearCallingIdentity();
@@ -20074,11 +20091,11 @@ public final class ActivityManagerService extends ActivityManagerNative
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
// On to the next.
synchronized (ActivityManagerService.this) {
- if (uss.mState != UserStartedState.STATE_STOPPING) {
+ if (uss.mState != UserState.STATE_STOPPING) {
// Whoops, we are being started back up. Abort, abort!
return;
}
- uss.mState = UserStartedState.STATE_SHUTDOWN;
+ uss.mState = UserState.STATE_SHUTDOWN;
}
mBatteryStatsService.noteEvent(
BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
@@ -20102,7 +20119,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return ActivityManager.USER_OP_SUCCESS;
}
- void finishUserStop(UserStartedState uss) {
+ void finishUserStop(UserState uss) {
final int userId = uss.mHandle.getIdentifier();
boolean stopped;
ArrayList<IStopUserCallback> callbacks;
@@ -20110,7 +20127,7 @@ public final class ActivityManagerService extends ActivityManagerNative
callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
if (mStartedUsers.get(userId) != uss) {
stopped = false;
- } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
+ } else if (uss.mState != UserState.STATE_SHUTDOWN) {
stopped = false;
} else {
stopped = true;
@@ -20184,15 +20201,15 @@ public final class ActivityManagerService extends ActivityManagerNative
}
boolean isUserRunningLocked(int userId, boolean orStopped) {
- UserStartedState state = mStartedUsers.get(userId);
+ UserState state = mStartedUsers.get(userId);
if (state == null) {
return false;
}
if (orStopped) {
return true;
}
- return state.mState != UserStartedState.STATE_STOPPING
- && state.mState != UserStartedState.STATE_SHUTDOWN;
+ return state.mState != UserState.STATE_STOPPING
+ && state.mState != UserState.STATE_SHUTDOWN;
}
@Override
@@ -20214,19 +20231,19 @@ public final class ActivityManagerService extends ActivityManagerNative
private void updateStartedUserArrayLocked() {
int num = 0;
for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
+ UserState uss = mStartedUsers.valueAt(i);
// This list does not include stopping users.
- if (uss.mState != UserStartedState.STATE_STOPPING
- && uss.mState != UserStartedState.STATE_SHUTDOWN) {
+ if (uss.mState != UserState.STATE_STOPPING
+ && uss.mState != UserState.STATE_SHUTDOWN) {
num++;
}
}
mStartedUserArray = new int[num];
num = 0;
for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
- if (uss.mState != UserStartedState.STATE_STOPPING
- && uss.mState != UserStartedState.STATE_SHUTDOWN) {
+ UserState uss = mStartedUsers.valueAt(i);
+ if (uss.mState != UserState.STATE_STOPPING
+ && uss.mState != UserState.STATE_SHUTDOWN) {
mStartedUserArray[num] = mStartedUsers.keyAt(i);
num++;
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 9e33f2a..f967aef 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -233,10 +233,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
/** Used on user changes */
- final ArrayList<UserStartedState> mStartingUsers = new ArrayList<>();
+ final ArrayList<UserState> mStartingUsers = new ArrayList<>();
/** Used to queue up any background users being started */
- final ArrayList<UserStartedState> mStartingBackgroundUsers = new ArrayList<>();
+ final ArrayList<UserState> mStartingBackgroundUsers = new ArrayList<>();
/** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
* is being brought in front of us. */
@@ -883,8 +883,18 @@ public final class ActivityStackSupervisor implements DisplayListener {
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
- startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null,
- 0, 0, 0, null, false, null, null, null);
+ startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
+ null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
+ null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
+ null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
+ 0 /* startFlags */, null /* options */, false /* componentSpecified */,
+ null /* outActivity */, null /* container */, null /* inTask */);
+ if (inResumeTopActivity) {
+ // If we are in resume section already, home activity will be initialized, but not
+ // resumed (to avoid recursive resume) and will stay that way until something pokes it
+ // again. We need to schedule another resume.
+ scheduleResumeTopActivities();
+ }
}
final int startActivityMayWait(IApplicationThread caller, int callingUid,
@@ -1915,7 +1925,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
ActivityRecord intentActivity = !launchSingleInstance ?
findTaskLocked(r) : findActivityLocked(intent, r.info);
if (intentActivity != null) {
- if (isLockTaskModeViolation(intentActivity.task)) {
+ // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused
+ // but still needs to be a lock task mode violation since the task gets
+ // cleared out and the device would otherwise leave the locked task.
+ if (isLockTaskModeViolation(intentActivity.task,
+ (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
+ == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
showLockTaskToast();
Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
@@ -2371,7 +2386,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
ArrayList<ActivityRecord> stops = null;
ArrayList<ActivityRecord> finishes = null;
- ArrayList<UserStartedState> startingUsers = null;
+ ArrayList<UserState> startingUsers = null;
int NS = 0;
int NF = 0;
boolean booting = false;
@@ -2468,7 +2483,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
// Complete starting up of background users
if (mStartingBackgroundUsers.size() > 0) {
- startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
+ startingUsers = new ArrayList<UserState>(mStartingBackgroundUsers);
mStartingBackgroundUsers.clear();
for (int i = 0; i < startingUsers.size(); i++) {
mService.finishUserBoot(startingUsers.get(i));
@@ -3230,7 +3245,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
- boolean switchUserLocked(int userId, UserStartedState uss) {
+ boolean switchUserLocked(int userId, UserState uss) {
mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId());
final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID);
mCurrentUser = userId;
@@ -3271,7 +3286,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
* @param userId The user being started in the background
* @param uss The state object for the user.
*/
- public void startBackgroundUserLocked(int userId, UserStartedState uss) {
+ public void startBackgroundUserLocked(int userId, UserState uss) {
mStartingBackgroundUsers.add(uss);
}
@@ -3780,7 +3795,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
boolean isLockTaskModeViolation(TaskRecord task) {
- if (getLockedTaskLocked() == task) {
+ return isLockTaskModeViolation(task, false);
+ }
+
+ boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
+ if (getLockedTaskLocked() == task && !isNewClearTask) {
return false;
}
final int lockTaskAuth = task.mLockTaskAuth;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c973386..3854e51 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -42,6 +42,7 @@ import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Slog;
+import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsHelper;
@@ -64,16 +65,22 @@ public final class BatteryStatsService extends IBatteryStats.Stub
implements PowerManagerInternal.LowPowerModeListener {
static final String TAG = "BatteryStatsService";
- private boolean mFirstExternalStatsUpdate = true;
static IBatteryStats sService;
final BatteryStatsImpl mStats;
final BatteryStatsHandler mHandler;
Context mContext;
PowerManagerInternal mPowerManagerInternal;
+ final int UPDATE_CPU = 0x01;
+ final int UPDATE_WIFI = 0x02;
+ final int UPDATE_RADIO = 0x04;
+ final int UPDATE_BT = 0x08;
+ final int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT;
+
class BatteryStatsHandler extends Handler implements BatteryStatsImpl.ExternalStatsSync {
public static final int MSG_SYNC_EXTERNAL_STATS = 1;
public static final int MSG_WRITE_TO_DISK = 2;
+ private int mUpdateFlags = 0;
public BatteryStatsHandler(Looper looper) {
super(looper);
@@ -83,11 +90,17 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SYNC_EXTERNAL_STATS:
- updateExternalStats((String)msg.obj, false);
+ final int updateFlags;
+ synchronized (this) {
+ removeMessages(MSG_SYNC_EXTERNAL_STATS);
+ updateFlags = mUpdateFlags;
+ mUpdateFlags = 0;
+ }
+ updateExternalStats((String)msg.obj, updateFlags);
break;
case MSG_WRITE_TO_DISK:
- updateExternalStats("write", true);
+ updateExternalStats("write", UPDATE_ALL);
synchronized (mStats) {
mStats.writeAsyncLocked();
}
@@ -97,9 +110,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub
@Override
public void scheduleSync(String reason) {
- if (!hasMessages(MSG_SYNC_EXTERNAL_STATS)) {
- Message msg = Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason);
- sendMessage(msg);
+ scheduleSyncImpl(reason, UPDATE_ALL);
+ }
+
+ @Override
+ public void scheduleWifiSync(String reason) {
+ scheduleSyncImpl(reason, UPDATE_WIFI);
+ }
+
+ private void scheduleSyncImpl(String reason, int updateFlags) {
+ synchronized (this) {
+ if (mUpdateFlags == 0) {
+ sendMessage(Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason));
+ }
+ mUpdateFlags |= updateFlags;
}
}
}
@@ -137,7 +161,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void shutdown() {
Slog.w("BatteryStats", "Writing battery stats before shutdown...");
- updateExternalStats("shutdown", true);
+ updateExternalStats("shutdown", UPDATE_ALL);
synchronized (mStats) {
mStats.shutdownLocked();
}
@@ -237,7 +261,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
- updateExternalStats("get-stats", true);
+ updateExternalStats("get-stats", UPDATE_ALL);
synchronized (mStats) {
mStats.writeToParcel(out, 0);
}
@@ -252,7 +276,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
- updateExternalStats("get-stats", true);
+ updateExternalStats("get-stats", UPDATE_ALL);
synchronized (mStats) {
mStats.writeToParcel(out, 0);
}
@@ -603,8 +627,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub
// There was a change in WiFi power state.
// Collect data now for the past activity.
- mHandler.scheduleSync("wifi-data");
synchronized (mStats) {
+ if (mStats.isOnBattery()) {
+ mHandler.scheduleWifiSync("wifi-data");
+ }
mStats.noteWifiRadioPowerState(powerState, tsNanos);
}
}
@@ -767,10 +793,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
@Override
- public void noteDeviceIdleMode(boolean enabled, boolean fromActive, boolean fromMotion) {
+ public void noteDeviceIdleMode(boolean enabled, String activeReason, int activeUid) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteDeviceIdleModeLocked(enabled, fromActive, fromMotion);
+ mStats.noteDeviceIdleModeLocked(enabled, activeReason, activeUid);
}
}
@@ -807,7 +833,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
// Sync external stats first as the battery has changed states. If we don't sync
// immediately here, we may not collect the relevant data later.
- updateExternalStats("battery-state", false);
+ updateExternalStats("battery-state", UPDATE_ALL);
synchronized (mStats) {
mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
}
@@ -961,9 +987,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub
pw.println("Battery stats reset.");
noOutput = true;
}
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
} else if ("--write".equals(arg)) {
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
synchronized (mStats) {
mStats.writeSyncLocked();
pw.println("Battery stats written.");
@@ -1027,7 +1053,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
}
// Fetch data from external sources and update the BatteryStatsImpl object with them.
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -1119,6 +1145,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub
return null;
}
+ final long timePeriodMs = info.mTimestamp - mLastInfo.mTimestamp;
+ final long lastIdleMs = mLastInfo.mControllerIdleTimeMs;
+ final long lastTxMs = mLastInfo.mControllerTxTimeMs;
+ final long lastRxMs = mLastInfo.mControllerRxTimeMs;
+ final long lastEnergy = mLastInfo.mControllerEnergyUsed;
+
// We will modify the last info object to be the delta, and store the new
// WifiActivityEnergyInfo object as our last one.
final WifiActivityEnergyInfo result = mLastInfo;
@@ -1126,19 +1158,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub
result.mStackState = info.getStackState();
// These times seem to be the most reliable.
- result.mControllerTxTimeMs =
- info.mControllerTxTimeMs - mLastInfo.mControllerTxTimeMs;
- result.mControllerRxTimeMs =
- info.mControllerRxTimeMs - mLastInfo.mControllerRxTimeMs;
+ result.mControllerTxTimeMs = info.mControllerTxTimeMs - lastTxMs;
+ result.mControllerRxTimeMs = info.mControllerRxTimeMs - lastRxMs;
// WiFi calculates the idle time as a difference from the on time and the various
// Rx + Tx times. There seems to be some missing time there because this sometimes
// becomes negative. Just cap it at 0 and move on.
// b/21613534
- result.mControllerIdleTimeMs =
- Math.max(0, info.mControllerIdleTimeMs - mLastInfo.mControllerIdleTimeMs);
+ result.mControllerIdleTimeMs = Math.max(0, info.mControllerIdleTimeMs - lastIdleMs);
result.mControllerEnergyUsed =
- Math.max(0, info.mControllerEnergyUsed - mLastInfo.mControllerEnergyUsed);
+ Math.max(0, info.mControllerEnergyUsed - lastEnergy);
if (result.mControllerTxTimeMs < 0 ||
result.mControllerRxTimeMs < 0) {
@@ -1151,6 +1180,34 @@ public final class BatteryStatsService extends IBatteryStats.Stub
Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + result);
}
+
+ final long totalTimeMs = result.mControllerIdleTimeMs + result.mControllerRxTimeMs +
+ result.mControllerTxTimeMs;
+ if (totalTimeMs > timePeriodMs) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Total time ");
+ TimeUtils.formatDuration(totalTimeMs, sb);
+ sb.append(" is longer than sample period ");
+ TimeUtils.formatDuration(timePeriodMs, sb);
+ sb.append(".\n");
+ sb.append("Previous WiFi snapshot: ").append("idle=");
+ TimeUtils.formatDuration(lastIdleMs, sb);
+ sb.append(" rx=");
+ TimeUtils.formatDuration(lastRxMs, sb);
+ sb.append(" tx=");
+ TimeUtils.formatDuration(lastTxMs, sb);
+ sb.append(" e=").append(lastEnergy);
+ sb.append("\n");
+ sb.append("Current WiFi snapshot: ").append("idle=");
+ TimeUtils.formatDuration(info.mControllerIdleTimeMs, sb);
+ sb.append(" rx=");
+ TimeUtils.formatDuration(info.mControllerRxTimeMs, sb);
+ sb.append(" tx=");
+ TimeUtils.formatDuration(info.mControllerTxTimeMs, sb);
+ sb.append(" e=").append(info.mControllerEnergyUsed);
+ Slog.wtf(TAG, sb.toString());
+ }
+
mLastInfo = info;
return result;
}
@@ -1184,15 +1241,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub
* We first grab a lock specific to this method, then once all the data has been collected,
* we grab the mStats lock and update the data.
*
- * TODO(adamlesinski): When we start distributing bluetooth data to apps, we'll want to
- * separate these external stats so that they can be collected individually and on different
- * intervals.
- *
* @param reason The reason why this collection was requested. Useful for debugging.
- * @param force If false, some stats may decide not to be collected for efficiency as their
- * results aren't needed immediately. When true, collect all stats unconditionally.
+ * @param updateFlags Which external stats to update. Can be a combination of
+ * {@link #UPDATE_CPU}, {@link #UPDATE_RADIO}, {@link #UPDATE_WIFI},
+ * and {@link #UPDATE_BT}.
*/
- void updateExternalStats(String reason, boolean force) {
+ void updateExternalStats(final String reason, final int updateFlags) {
synchronized (mExternalStatsLock) {
if (mContext == null) {
// We haven't started yet (which means the BatteryStatsImpl object has
@@ -1200,34 +1254,46 @@ public final class BatteryStatsService extends IBatteryStats.Stub
return;
}
- final WifiActivityEnergyInfo wifiEnergyInfo = pullWifiEnergyInfoLocked();
- final BluetoothActivityEnergyInfo bluetoothEnergyInfo;
- if (force) {
+ if (BatteryStatsImpl.DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating external stats: reason=" + reason);
+ }
+
+ WifiActivityEnergyInfo wifiEnergyInfo = null;
+ if ((updateFlags & UPDATE_WIFI) != 0) {
+ wifiEnergyInfo = pullWifiEnergyInfoLocked();
+ }
+
+ BluetoothActivityEnergyInfo bluetoothEnergyInfo = null;
+ if ((updateFlags & UPDATE_BT) != 0) {
// We only pull bluetooth stats when we have to, as we are not distributing its
// use amongst apps and the sampling frequency does not matter.
bluetoothEnergyInfo = pullBluetoothEnergyInfoLocked();
- } else {
- bluetoothEnergyInfo = null;
}
synchronized (mStats) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
if (mStats.mRecordAllHistory) {
- final long elapsedRealtime = SystemClock.elapsedRealtime();
- final long uptime = SystemClock.uptimeMillis();
mStats.addHistoryEventLocked(elapsedRealtime, uptime,
BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, reason, 0);
}
- mStats.updateCpuTimeLocked(mFirstExternalStatsUpdate);
- mStats.updateKernelWakelocksLocked();
- mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
- mStats.updateWifiStateLocked(wifiEnergyInfo);
- mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
- }
- if (mFirstExternalStatsUpdate) {
- // We have read the stats for the first time, which means we have a baseline
- // from which to calculate delta.
- mFirstExternalStatsUpdate = false;
+ if ((updateFlags & UPDATE_CPU) != 0) {
+ mStats.updateCpuTimeLocked();
+ mStats.updateKernelWakelocksLocked();
+ }
+
+ if ((updateFlags & UPDATE_RADIO) != 0) {
+ mStats.updateMobileRadioStateLocked(elapsedRealtime);
+ }
+
+ if ((updateFlags & UPDATE_WIFI) != 0) {
+ mStats.updateWifiStateLocked(wifiEnergyInfo);
+ }
+
+ if ((updateFlags & UPDATE_BT) != 0) {
+ mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 3acd3a3..bd31a21 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -40,6 +40,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.SystemClock;
+import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.PrintWriterPrinter;
@@ -536,6 +537,7 @@ final class ProcessRecord {
void kill(String reason, boolean noisy) {
if (!killedByAm) {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");
if (noisy) {
Slog.i(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason);
}
@@ -546,6 +548,7 @@ final class ProcessRecord {
killed = true;
killedByAm = true;
}
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
diff --git a/services/core/java/com/android/server/am/UserStartedState.java b/services/core/java/com/android/server/am/UserState.java
index d3e73d5..b3d82bc 100644
--- a/services/core/java/com/android/server/am/UserStartedState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -21,8 +21,9 @@ import java.util.ArrayList;
import android.app.IStopUserCallback;
import android.os.UserHandle;
+import android.util.ArrayMap;
-public final class UserStartedState {
+public final class UserState {
// User is first coming up.
public final static int STATE_BOOTING = 0;
// User is in the normal running state.
@@ -40,7 +41,13 @@ public final class UserStartedState {
public boolean switching;
public boolean initializing;
- public UserStartedState(UserHandle handle, boolean initial) {
+ /**
+ * The last time that a provider was reported to usage stats as being brought to important
+ * foreground procstate.
+ */
+ public final ArrayMap<String,Long> mProviderLastReportedFg = new ArrayMap<>();
+
+ public UserState(UserHandle handle, boolean initial) {
mHandle = handle;
}
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 4ccb5ad..f72b598 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -46,10 +46,12 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.speech.RecognizerIntent;
@@ -1086,6 +1088,14 @@ public class MediaFocusControl implements OnFinished {
voiceIntent = new Intent(android.speech.RecognizerIntent.ACTION_WEB_SEARCH);
Log.i(TAG, "voice-based interactions: about to use ACTION_WEB_SEARCH");
} else {
+ IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ if (dic != null) {
+ try {
+ dic.exitIdle("voice-search");
+ } catch (RemoteException e) {
+ }
+ }
voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE,
isLocked && mKeyguardManager.isKeyguardSecure());
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index eac748f..3bf1183 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -106,8 +106,16 @@ public class NetworkAgentInfo {
networkMisc = misc;
}
- public void addRequest(NetworkRequest networkRequest) {
+ /**
+ * Add {@code networkRequest} to this network as it's satisfied by this network.
+ * NOTE: This function must only be called on ConnectivityService's main thread.
+ * @return true if {@code networkRequest} was added or false if {@code networkRequest} was
+ * already present.
+ */
+ public boolean addRequest(NetworkRequest networkRequest) {
+ if (networkRequests.get(networkRequest.requestId) == networkRequest) return false;
networkRequests.put(networkRequest.requestId, networkRequest);
+ return true;
}
// Does this network satisfy request?
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index fc50e2c..99a0567 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -178,6 +178,13 @@ public class NetworkMonitor extends StateMachine {
*/
private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = BASE + 11;
+ /**
+ * Retest network to see if captive portal is still in place.
+ * arg1 = UID responsible for requesting this reeval. Will be billed for data.
+ * 0 indicates self-initiated, so nobody to blame.
+ */
+ private static final int CMD_CAPTIVE_PORTAL_RECHECK = BASE + 12;
+
private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
// Default to 30s linger time-out. Modifyable only for testing.
private static int DEFAULT_LINGER_DELAY_MS = 30000;
@@ -194,6 +201,8 @@ public class NetworkMonitor extends StateMachine {
private int mUidResponsibleForReeval = INVALID_UID;
// Stop blaming UID that requested re-evaluation after this many attempts.
private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5;
+ // Delay between reevaluations once a captive portal has been found.
+ private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10*60*1000;
private final Context mContext;
private final Handler mConnectivityServiceHandler;
@@ -287,6 +296,7 @@ public class NetworkMonitor extends StateMachine {
quit();
return HANDLED;
case CMD_FORCE_REEVALUATION:
+ case CMD_CAPTIVE_PORTAL_RECHECK:
if (DBG) log("Forcing reevaluation");
mUidResponsibleForReeval = message.arg1;
transitionTo(mEvaluatingState);
@@ -517,6 +527,9 @@ public class NetworkMonitor extends StateMachine {
mNetworkAgentInfo.network.netId,
mLaunchCaptivePortalAppBroadcastReceiver.getPendingIntent());
mConnectivityServiceHandler.sendMessage(message);
+ // Retest for captive portal occasionally.
+ sendMessageDelayed(CMD_CAPTIVE_PORTAL_RECHECK, 0 /* no UID */,
+ CAPTIVE_PORTAL_REEVALUATE_DELAY_MS);
}
@Override
@@ -524,6 +537,11 @@ public class NetworkMonitor extends StateMachine {
if (DBG) log(getName() + message.toString());
return NOT_HANDLED;
}
+
+ @Override
+ public void exit() {
+ removeMessages(CMD_CAPTIVE_PORTAL_RECHECK);
+ }
}
// Being in the LingeringState State indicates a Network's validated bit is true and it once
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index ea461e5..93ed2ee 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -506,6 +506,21 @@ public final class ContentService extends IContentService.Stub {
}
@Override
+ public String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) {
+ enforceCrossUserPermission(userId,
+ "no permission to read sync settings for user " + userId);
+ // This makes it so that future permission checks will be in the context of this
+ // process rather than the caller's process. We will restore this before returning.
+ final long identityToken = clearCallingIdentity();
+ try {
+ SyncManager syncManager = getSyncManager();
+ return syncManager.getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ @Override
public boolean getSyncAutomatically(Account account, String providerName) {
return getSyncAutomaticallyAsUser(account, providerName, UserHandle.getCallingUserId());
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 2eb8797..cd9c7fe 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -908,6 +908,10 @@ public class SyncManager {
return types;
}
+ public String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) {
+ return mSyncAdapters.getSyncAdapterPackagesForAuthority(authority, userId);
+ }
+
private void sendSyncAlarmMessage() {
if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_SYNC_ALARM");
mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_SYNC_ALARM);
diff --git a/services/core/java/com/android/server/location/FlpHardwareProvider.java b/services/core/java/com/android/server/location/FlpHardwareProvider.java
index 259ff1d..d4f3c4d 100644
--- a/services/core/java/com/android/server/location/FlpHardwareProvider.java
+++ b/services/core/java/com/android/server/location/FlpHardwareProvider.java
@@ -136,6 +136,10 @@ public class FlpHardwareProvider {
}
maybeSendCapabilities();
+
+ if (mGeofenceHardwareSink != null) {
+ mGeofenceHardwareSink.setVersion(getVersion());
+ }
}
private void onBatchingStatus(int status) {
@@ -152,10 +156,23 @@ public class FlpHardwareProvider {
}
}
+ // Returns the current version of the FLP HAL. This depends both on the version of the
+ // structure returned by the hardware layer, and whether or not we've received the
+ // capabilities callback on initialization. Assume original version until we get
+ // the new initialization callback.
+ private int getVersion() {
+ synchronized (mLocationSinkLock) {
+ if (mHaveBatchingCapabilities) {
+ return mVersion;
+ }
+ }
+ return 1;
+ }
+
private void setVersion(int version) {
mVersion = version;
if (mGeofenceHardwareSink != null) {
- mGeofenceHardwareSink.setVersion(version);
+ mGeofenceHardwareSink.setVersion(getVersion());
}
}
@@ -375,7 +392,7 @@ public class FlpHardwareProvider {
@Override
public void flushBatchedLocations() {
- if (mVersion >= FIRST_VERSION_WITH_FLUSH_LOCATIONS) {
+ if (getVersion() >= FIRST_VERSION_WITH_FLUSH_LOCATIONS) {
nativeFlushBatchedLocations();
} else {
Log.wtf(TAG,
@@ -405,7 +422,7 @@ public class FlpHardwareProvider {
@Override
public int getVersion() {
- return mVersion;
+ return FlpHardwareProvider.this.getVersion();
}
};
@@ -482,7 +499,7 @@ public class FlpHardwareProvider {
private GeofenceHardwareImpl getGeofenceHardwareSink() {
if (mGeofenceHardwareSink == null) {
mGeofenceHardwareSink = GeofenceHardwareImpl.getInstance(mContext);
- mGeofenceHardwareSink.setVersion(mVersion);
+ mGeofenceHardwareSink.setVersion(getVersion());
}
return mGeofenceHardwareSink;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 9c288be..0dcad82 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1969,6 +1969,9 @@ public class NotificationManagerService extends SystemService {
for (int i=0; i<N; i++) {
final NotificationRecord r = mNotificationList.get(i);
if (r.sbn.getPackageName().equals(pkg) && r.sbn.getUserId() == userId) {
+ if (r.sbn.getId() == id && TextUtils.equals(r.sbn.getTag(), tag)) {
+ break; // Allow updating existing notification
+ }
count++;
if (count >= MAX_PACKAGE_NOTIFICATIONS) {
Slog.e(TAG, "Package has already posted " + count
@@ -2999,19 +3002,8 @@ public class NotificationManagerService extends SystemService {
final int len = list.size();
for (int i=0; i<len; i++) {
NotificationRecord r = list.get(i);
- if (!notificationMatchesUserId(r, userId) || r.sbn.getId() != id) {
- continue;
- }
- if (tag == null) {
- if (r.sbn.getTag() != null) {
- continue;
- }
- } else {
- if (!tag.equals(r.sbn.getTag())) {
- continue;
- }
- }
- if (r.sbn.getPackageName().equals(pkg)) {
+ if (notificationMatchesUserId(r, userId) && r.sbn.getId() == id &&
+ TextUtils.equals(r.sbn.getTag(), tag) && r.sbn.getPackageName().equals(pkg)) {
return i;
}
}
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
new file mode 100644
index 0000000..fe3103b
--- /dev/null
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -0,0 +1,521 @@
+/*
+ * 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.pm;
+
+import android.Manifest;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal.PackagesProvider;
+import android.content.pm.PackageParser;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Build;
+import android.os.UserHandle;
+import android.provider.MediaStore;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static android.os.Process.FIRST_APPLICATION_UID;
+
+/**
+ * This class is the policy for granting runtime permissions to
+ * platform components and default handlers in the system such
+ * that the device is usable out-of-the-box. For example, the
+ * shell UID is a part of the system and the Phone app should
+ * have phone related permission by default.
+ */
+final class DefaultPermissionGrantPolicy {
+ private static final String TAG = "DefaultPermissionGrantPolicy";
+ private static final boolean DEBUG = false;
+
+ private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
+
+ private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>();
+ static {
+ PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE);
+ PHONE_PERMISSIONS.add(Manifest.permission.CALL_PHONE);
+ PHONE_PERMISSIONS.add( Manifest.permission.READ_CALL_LOG);
+ PHONE_PERMISSIONS.add(Manifest.permission.WRITE_CALL_LOG);
+ PHONE_PERMISSIONS.add(Manifest.permission.ADD_VOICEMAIL);
+ PHONE_PERMISSIONS.add(Manifest.permission.USE_SIP);
+ PHONE_PERMISSIONS.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
+ }
+
+ private static final Set<String> CONTACTS_PERMISSIONS = new ArraySet<>();
+ static {
+ CONTACTS_PERMISSIONS.add(Manifest.permission.READ_CONTACTS);
+ CONTACTS_PERMISSIONS.add(Manifest.permission.WRITE_CONTACTS);
+ }
+
+ private static final Set<String> LOCATION_PERMISSIONS = new ArraySet<>();
+ static {
+ LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_FINE_LOCATION);
+ LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
+ }
+
+ private static final Set<String> CALENDAR_PERMISSIONS = new ArraySet<>();
+ static {
+ CALENDAR_PERMISSIONS.add(Manifest.permission.READ_CALENDAR);
+ CALENDAR_PERMISSIONS.add(Manifest.permission.WRITE_CALENDAR);
+ }
+
+ private static final Set<String> SMS_PERMISSIONS = new ArraySet<>();
+ static {
+ SMS_PERMISSIONS.add(Manifest.permission.SEND_SMS);
+ SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_SMS);
+ SMS_PERMISSIONS.add(Manifest.permission.READ_SMS);
+ SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_WAP_PUSH);
+ SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_MMS);
+ SMS_PERMISSIONS.add(Manifest.permission.READ_CELL_BROADCASTS);
+ }
+
+ private static final Set<String> MICROPHONE_PERMISSIONS = new ArraySet<>();
+ static {
+ MICROPHONE_PERMISSIONS.add(Manifest.permission.RECORD_AUDIO);
+ }
+
+ private static final Set<String> CAMERA_PERMISSIONS = new ArraySet<>();
+ static {
+ CAMERA_PERMISSIONS.add(Manifest.permission.CAMERA);
+ }
+
+ private static final Set<String> SENSORS_PERMISSIONS = new ArraySet<>();
+ static {
+ SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS);
+ }
+
+ private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>();
+ static {
+// STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+ STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
+ }
+
+ private static final Set<String> SETTINGS_PERMISSIONS = new ArraySet<>();
+ static {
+ SETTINGS_PERMISSIONS.add(Manifest.permission.WRITE_SETTINGS);
+ }
+
+ private static final Set<String> INSTALLER_PERMISSIONS = new ArraySet<>();
+ static {
+ INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS);
+ INSTALLER_PERMISSIONS.add(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ INSTALLER_PERMISSIONS.add(Manifest.permission.CLEAR_APP_USER_DATA);
+ INSTALLER_PERMISSIONS.add(Manifest.permission.KILL_UID);
+ }
+
+ private static final Set<String> VERIFIER_PERMISSIONS = new ArraySet<>();
+ static {
+ INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS);
+ }
+
+ private final PackageManagerService mService;
+
+ private PackagesProvider mImePackagesProvider;
+ private PackagesProvider mLocationPackagesProvider;
+ private PackagesProvider mVoiceInteractionPackagesProvider;
+
+ public DefaultPermissionGrantPolicy(PackageManagerService service) {
+ mService = service;
+ }
+
+ public void setImePackagesProviderLPr(PackagesProvider provider) {
+ mImePackagesProvider = provider;
+ }
+
+ public void setLocationPackagesProviderLPw(PackagesProvider provider) {
+ mLocationPackagesProvider = provider;
+ }
+
+ public void setVoiceInteractionPackagesProviderLPw(PackagesProvider provider) {
+ mVoiceInteractionPackagesProvider = provider;
+ }
+
+ public void grantDefaultPermissions(int userId) {
+ grantPermissionsToSysComponentsAndPrivApps(userId);
+ grantDefaultSystemHandlerPermissions(userId);
+ }
+
+ private void grantPermissionsToSysComponentsAndPrivApps(int userId) {
+ Log.i(TAG, "Granting permissions to platform components");
+
+ synchronized (mService.mPackages) {
+ for (PackageParser.Package pkg : mService.mPackages.values()) {
+ if (!isSysComponentOrPersistentPrivApp(pkg)
+ || !doesPackageSupportRuntimePermissions(pkg)) {
+ continue;
+ }
+ final int permissionCount = pkg.requestedPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ String permission = pkg.requestedPermissions.get(i);
+ BasePermission bp = mService.mSettings.mPermissions.get(permission);
+ if (bp != null && bp.isRuntime()) {
+ final int flags = mService.getPermissionFlags(permission,
+ pkg.packageName, userId);
+ if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) {
+ mService.grantRuntimePermission(pkg.packageName, permission, userId);
+ mService.updatePermissionFlags(permission, pkg.packageName,
+ PackageManager.MASK_PERMISSION_FLAGS,
+ PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, userId);
+ if (DEBUG) {
+ Log.i(TAG, "Granted " + permission + " to system component "
+ + pkg.packageName);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void grantDefaultSystemHandlerPermissions(int userId) {
+ Log.i(TAG, "Granting permissions to default platform handlers");
+
+ final PackagesProvider imePackagesProvider;
+ final PackagesProvider locationPackagesProvider;
+ final PackagesProvider voiceInteractionPackagesProvider;
+
+ synchronized (mService.mPackages) {
+ imePackagesProvider = mImePackagesProvider;
+ locationPackagesProvider = mLocationPackagesProvider;
+ voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider;
+ }
+
+ String[] imePackageNames = (imePackagesProvider != null)
+ ? imePackagesProvider.getPackages(userId) : null;
+ String[] voiceInteractPackageNames = (voiceInteractionPackagesProvider != null)
+ ? voiceInteractionPackagesProvider.getPackages(userId) : null;
+ String[] locationPackageNames = (locationPackagesProvider != null)
+ ? locationPackagesProvider.getPackages(userId) : null;
+
+ synchronized (mService.mPackages) {
+ // Installers
+ Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
+ installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
+ installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")),
+ PACKAGE_MIME_TYPE);
+ List<PackageParser.Package> installerPackages =
+ getPrivilegedHandlerActivityPackagesLPr(installerIntent, userId);
+ final int installerCount = installerPackages.size();
+ for (int i = 0; i < installerCount; i++) {
+ PackageParser.Package installPackage = installerPackages.get(i);
+ grantInstallPermissionsLPw(installPackage, INSTALLER_PERMISSIONS, userId);
+ }
+
+ // Verifiers
+ Intent verifierIntent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+ verifierIntent.setType(PACKAGE_MIME_TYPE);
+ List<PackageParser.Package> verifierPackages =
+ getPrivilegedHandlerReceiverPackagesLPr(verifierIntent, userId);
+ final int verifierCount = verifierPackages.size();
+ for (int i = 0; i < verifierCount; i++) {
+ PackageParser.Package verifierPackage = verifierPackages.get(i);
+ grantInstallPermissionsLPw(verifierPackage, VERIFIER_PERMISSIONS, userId);
+ }
+
+ // SetupWizard
+ Intent setupIntent = new Intent(Intent.ACTION_MAIN);
+ setupIntent.addCategory(Intent.CATEGORY_HOME);
+ PackageParser.Package setupPackage = getDefaultSystemHandlerActvityPackageLPr(
+ setupIntent, userId);
+ if (setupPackage != null
+ && doesPackageSupportRuntimePermissions(setupPackage)) {
+ grantRuntimePermissionsLPw(setupPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(setupPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(setupPackage, SETTINGS_PERMISSIONS, userId);
+ }
+
+ // Phone
+ Intent dialerIntent = new Intent(Intent.ACTION_DIAL);
+ PackageParser.Package dialerPackage = getDefaultSystemHandlerActvityPackageLPr(
+ dialerIntent, userId);
+ if (dialerPackage != null
+ && doesPackageSupportRuntimePermissions(dialerPackage)) {
+ grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
+ }
+
+ // Camera
+ Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ PackageParser.Package cameraPackage = getDefaultSystemHandlerActvityPackageLPr(
+ cameraIntent, userId);
+ if (cameraPackage != null
+ && doesPackageSupportRuntimePermissions(cameraPackage)) {
+ grantRuntimePermissionsLPw(cameraPackage, CAMERA_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(cameraPackage, MICROPHONE_PERMISSIONS, userId);
+ }
+
+ // Messaging
+ Intent messagingIntent = new Intent(Intent.ACTION_MAIN);
+ messagingIntent.addCategory(Intent.CATEGORY_APP_MESSAGING);
+ PackageParser.Package messagingPackage = getDefaultSystemHandlerActvityPackageLPr(
+ messagingIntent, userId);
+ if (messagingPackage != null
+ && doesPackageSupportRuntimePermissions(messagingPackage)) {
+ grantRuntimePermissionsLPw(messagingPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(messagingPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(messagingPackage, SMS_PERMISSIONS, userId);
+ }
+
+ // Calendar
+ Intent calendarIntent = new Intent(Intent.ACTION_MAIN);
+ calendarIntent.addCategory(Intent.CATEGORY_APP_CALENDAR);
+ PackageParser.Package calendarPackage = getDefaultSystemHandlerActvityPackageLPr(
+ calendarIntent, userId);
+ if (calendarPackage != null
+ && doesPackageSupportRuntimePermissions(calendarPackage)) {
+ grantRuntimePermissionsLPw(calendarPackage, CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(calendarPackage, CONTACTS_PERMISSIONS, userId);
+ }
+
+ // Contacts
+ Intent contactsIntent = new Intent(Intent.ACTION_MAIN);
+ contactsIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
+ PackageParser.Package contactsPackage = getDefaultSystemHandlerActvityPackageLPr(
+ contactsIntent, userId);
+ if (contactsPackage != null
+ && doesPackageSupportRuntimePermissions(contactsPackage)) {
+ grantRuntimePermissionsLPw(contactsPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(contactsPackage, PHONE_PERMISSIONS, userId);
+ }
+
+ // Maps
+ Intent mapsIntent = new Intent(Intent.ACTION_MAIN);
+ mapsIntent.addCategory(Intent.CATEGORY_APP_MAPS);
+ PackageParser.Package mapsPackage = getDefaultSystemHandlerActvityPackageLPr(
+ mapsIntent, userId);
+ if (mapsPackage != null
+ && doesPackageSupportRuntimePermissions(mapsPackage)) {
+ grantRuntimePermissionsLPw(mapsPackage, LOCATION_PERMISSIONS, userId);
+ }
+
+ // Email
+ Intent emailIntent = new Intent(Intent.ACTION_MAIN);
+ emailIntent.addCategory(Intent.CATEGORY_APP_EMAIL);
+ PackageParser.Package emailPackage = getDefaultSystemHandlerActvityPackageLPr(
+ emailIntent, userId);
+ if (emailPackage != null
+ && doesPackageSupportRuntimePermissions(emailPackage)) {
+ grantRuntimePermissionsLPw(emailPackage, CONTACTS_PERMISSIONS, userId);
+ }
+
+ // Browser
+ Intent browserIntent = new Intent(Intent.ACTION_MAIN);
+ browserIntent.addCategory(Intent.CATEGORY_APP_BROWSER);
+ PackageParser.Package browserPackage = getDefaultSystemHandlerActvityPackageLPr(
+ browserIntent, userId);
+ if (browserPackage != null
+ && doesPackageSupportRuntimePermissions(browserPackage)) {
+ grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, userId);
+ }
+
+ // IME
+ if (imePackageNames != null) {
+ for (String imePackageName : imePackageNames) {
+ PackageParser.Package imePackage = getSystemPackageLPr(imePackageName);
+ if (imePackage != null
+ && doesPackageSupportRuntimePermissions(imePackage)) {
+ grantRuntimePermissionsLPw(imePackage, CONTACTS_PERMISSIONS, userId);
+ }
+ }
+ }
+
+ // Voice interaction
+ if (voiceInteractPackageNames != null) {
+ for (String voiceInteractPackageName : voiceInteractPackageNames) {
+ PackageParser.Package voiceInteractPackage = getSystemPackageLPr(
+ voiceInteractPackageName);
+ if (voiceInteractPackage != null
+ && doesPackageSupportRuntimePermissions(voiceInteractPackage)) {
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(voiceInteractPackage,
+ LOCATION_PERMISSIONS, userId);
+ }
+ }
+ }
+
+ // Location
+ if (locationPackageNames != null) {
+ for (String packageName : locationPackageNames) {
+ PackageParser.Package locationPackage = getSystemPackageLPr(packageName);
+ if (locationPackage != null
+ && doesPackageSupportRuntimePermissions(locationPackage)) {
+ grantRuntimePermissionsLPw(locationPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, LOCATION_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, CAMERA_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, SENSORS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(locationPackage, STORAGE_PERMISSIONS, userId);
+ }
+ }
+ }
+ }
+ }
+
+ private List<PackageParser.Package> getPrivilegedHandlerReceiverPackagesLPr(
+ Intent intent, int userId) {
+ List<ResolveInfo> handlers = mService.queryIntentReceivers(
+ intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()),
+ 0, userId);
+ return getPrivilegedPackages(handlers);
+ }
+
+ private List<PackageParser.Package> getPrivilegedHandlerActivityPackagesLPr(
+ Intent intent, int userId) {
+ List<ResolveInfo> handlers = mService.queryIntentActivities(
+ intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()),
+ 0, userId);
+ return getPrivilegedPackages(handlers);
+ }
+
+ private List<PackageParser.Package> getPrivilegedPackages(List<ResolveInfo> resolveInfos) {
+ List<PackageParser.Package> handlerPackages = new ArrayList<>();
+ final int handlerCount = resolveInfos.size();
+ for (int i = 0; i < handlerCount; i++) {
+ ResolveInfo handler = resolveInfos.get(i);
+ PackageParser.Package handlerPackage = getPrivilegedPackageLPr(
+ handler.activityInfo.packageName);
+ if (handlerPackage != null) {
+ handlerPackages.add(handlerPackage);
+ }
+ }
+ return handlerPackages;
+ }
+
+ private PackageParser.Package getDefaultSystemHandlerActvityPackageLPr(
+ Intent intent, int userId) {
+ List<ResolveInfo> handlers = mService.queryIntentActivities(intent, null, 0, userId);
+ final int handlerCount = handlers.size();
+ for (int i = 0; i < handlerCount; i++) {
+ ResolveInfo handler = handlers.get(i);
+ // TODO: This is a temporary hack to figure out the setup app.
+ PackageParser.Package handlerPackage = getSystemPackageLPr(
+ handler.activityInfo.packageName);
+ if (handlerPackage != null) {
+ return handlerPackage;
+ }
+ }
+ return null;
+ }
+
+ private PackageParser.Package getSystemPackageLPr(String packageName) {
+ PackageParser.Package pkg = mService.mPackages.get(packageName);
+ if (pkg != null && pkg.isSystemApp()) {
+ return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
+ }
+ return null;
+ }
+
+ private PackageParser.Package getPrivilegedPackageLPr(String packageName) {
+ PackageParser.Package pkg = mService.mPackages.get(packageName);
+ if (pkg != null && pkg.applicationInfo.isPrivilegedApp()) {
+ return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
+ }
+ return null;
+ }
+
+ private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
+ int userId) {
+ List<String> requestedPermissions = pkg.requestedPermissions;
+
+ if (pkg.isUpdatedSystemApp()) {
+ PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+ if (sysPs != null) {
+ requestedPermissions = sysPs.pkg.requestedPermissions;
+ }
+ }
+
+ final int permissionCount = requestedPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ String permission = requestedPermissions.get(i);
+ if (permissions.contains(permission)) {
+ final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId);
+
+ // If any flags are set to the permission, then it is either set in
+ // its current state by the system or device/profile owner or the user.
+ // In all these cases we do not want to clobber the current state.
+ if (flags == 0) {
+ mService.grantRuntimePermission(pkg.packageName, permission, userId);
+ if (DEBUG) {
+ Log.i(TAG, "Granted " + permission + " to default handler "
+ + pkg.packageName);
+ }
+ }
+ }
+ }
+ }
+
+ private void grantInstallPermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
+ int userId) {
+ List<String> requestedPermissions = pkg.requestedPermissions;
+
+ if (pkg.isUpdatedSystemApp()) {
+ PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+ if (sysPs != null) {
+ requestedPermissions = sysPs.pkg.requestedPermissions;
+ }
+ }
+
+ final int permissionCount = requestedPermissions.size();
+ for (int i = 0; i < permissionCount; i++) {
+ String permission = requestedPermissions.get(i);
+ if (permissions.contains(permission)) {
+ final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId);
+
+ // If any flags are set to the permission, then it is either set in
+ // its current state by the system or device/profile owner or the user.
+ // In all these cases we do not want to clobber the current state.
+ if (flags == 0) {
+ mService.grantInstallPermissionLPw(permission, pkg);
+ if (DEBUG) {
+ Log.i(TAG, "Granted install " + permission + " to " + pkg.packageName);
+ }
+ }
+ }
+ }
+ }
+
+ private static boolean isSysComponentOrPersistentPrivApp(PackageParser.Package pkg) {
+ return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
+ || ((pkg.applicationInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0
+ && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0);
+ }
+
+ private static boolean doesPackageSupportRuntimePermissions(PackageParser.Package pkg) {
+ return pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1;
+ }
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ef833cb..b593906 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -55,7 +55,6 @@ import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
import static android.content.pm.PackageParser.isApkFile;
-import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
import static android.system.OsConstants.O_CREAT;
@@ -111,6 +110,7 @@ import android.content.pm.PackageInfoLite;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.ActivityIntentInfo;
import android.content.pm.PackageParser.PackageLite;
@@ -281,6 +281,8 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final boolean DEBUG_DEXOPT = false;
private static final boolean DEBUG_ABI_SELECTION = false;
+ static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = Build.IS_DEBUGGABLE;
+
private static final int RADIO_UID = Process.PHONE_UID;
private static final int LOG_UID = Process.LOG_UID;
private static final int NFC_UID = Process.NFC_UID;
@@ -551,6 +553,9 @@ public class PackageManagerService extends IPackageManager.Stub {
final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
= new SparseArray<IntentFilterVerificationState>();
+ final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
+ new DefaultPermissionGrantPolicy(this);
+
private interface IntentFilterVerifier<T extends IntentFilter> {
boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
T filter, String packageName);
@@ -1592,6 +1597,11 @@ public class PackageManagerService extends IPackageManager.Stub {
grantRequestedRuntimePermissionsForUser(pkg, someUserId);
}
}
+
+ // We could have touched GID membership, so flush out packages.list
+ synchronized (mPackages) {
+ mSettings.writePackageListLPr();
+ }
}
private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) {
@@ -2200,6 +2210,9 @@ public class PackageManagerService extends IPackageManager.Stub {
// are all flushed. Not really needed, but keeps things nice and
// tidy.
Runtime.getRuntime().gc();
+
+ // Expose private service for system components to use.
+ LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
}
@Override
@@ -3156,7 +3169,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
@Override
- public void grantRuntimePermission(String packageName, String name, int userId) {
+ public void grantRuntimePermission(String packageName, String name, final int userId) {
if (!sUserManager.exists(userId)) {
Log.e(TAG, "No such user:" + userId);
return;
@@ -3169,7 +3182,6 @@ public class PackageManagerService extends IPackageManager.Stub {
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
"grantRuntimePermission");
- boolean gidsChanged = false;
final SettingBase sb;
synchronized (mPackages) {
@@ -3205,7 +3217,12 @@ public class PackageManagerService extends IPackageManager.Stub {
}
case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
- gidsChanged = true;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED);
+ }
+ });
} break;
}
@@ -3214,10 +3231,6 @@ public class PackageManagerService extends IPackageManager.Stub {
// Not critical if that is lost - app has to request again.
mSettings.writeRuntimePermissionsForUserLPr(userId, false);
}
-
- if (gidsChanged) {
- killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED);
- }
}
@Override
@@ -3324,15 +3337,14 @@ public class PackageManagerService extends IPackageManager.Stub {
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
"updatePermissionFlags");
- // Only the system can change policy flags.
+ // Only the system can change policy and system fixed flags.
if (getCallingUid() != Process.SYSTEM_UID) {
flagMask &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
flagValues &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
- }
- // Only the package manager can change system flags.
- flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
- flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+ flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+ flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+ }
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
@@ -3410,6 +3422,21 @@ public class PackageManagerService extends IPackageManager.Stub {
return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
}
+ void grantInstallPermissionLPw(String permission, PackageParser.Package pkg) {
+ BasePermission bp = mSettings.mPermissions.get(permission);
+ if (bp == null) {
+ throw new SecurityException("Missing " + permission + " permission");
+ }
+
+ SettingBase sb = (SettingBase) pkg.mExtras;
+ PermissionsState permissionsState = sb.getPermissionsState();
+
+ if (permissionsState.grantInstallPermission(bp) !=
+ PermissionsState.PERMISSION_OPERATION_FAILURE) {
+ scheduleWriteSettingsLocked();
+ }
+ }
+
@Override
public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
mContext.enforceCallingOrSelfPermission(
@@ -7725,7 +7752,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
}
-
+
if (pkgInfo != null) {
grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
}
@@ -7754,7 +7781,6 @@ public class PackageManagerService extends IPackageManager.Stub {
final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
- int[] upgradeUserIds = EMPTY_INT_ARRAY;
int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
boolean changedInstallPermission = false;
@@ -7811,32 +7837,11 @@ public class PackageManagerService extends IPackageManager.Stub {
if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
// For legacy apps dangerous permissions are install time ones.
grant = GRANT_INSTALL_LEGACY;
- } else if (ps.isSystem()) {
- final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds();
- if (origPermissions.hasInstallPermission(bp.name)) {
- // If a system app had an install permission, then the app was
- // upgraded and we grant the permissions as runtime to all users.
- grant = GRANT_UPGRADE;
- upgradeUserIds = currentUserIds;
- } else if (!Arrays.equals(updatedUserIds, currentUserIds)) {
- // If users changed since the last permissions update for a
- // system app, we grant the permission as runtime to the new users.
- grant = GRANT_UPGRADE;
- upgradeUserIds = currentUserIds;
- for (int userId : updatedUserIds) {
- upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId);
- }
- } else {
- // Otherwise, we grant the permission as runtime if the app
- // already had it, i.e. we preserve runtime permissions.
- grant = GRANT_RUNTIME;
- }
} else if (origPermissions.hasInstallPermission(bp.name)) {
// For legacy apps that became modern, install becomes runtime.
grant = GRANT_UPGRADE;
- upgradeUserIds = currentUserIds;
- } else if (replace) {
- // For upgraded modern apps keep runtime permissions unchanged.
+ } else {
+ // For modern apps keep runtime permissions unchanged.
grant = GRANT_RUNTIME;
}
} break;
@@ -7871,7 +7876,7 @@ public class PackageManagerService extends IPackageManager.Stub {
switch (grant) {
case GRANT_INSTALL: {
// Revoke this as runtime permission to handle the case of
- // a runtime permssion being downgraded to an install one.
+ // a runtime permission being downgraded to an install one.
for (int userId : UserManagerService.getInstance().getUserIds()) {
if (origPermissions.getRuntimePermissionState(
bp.name, userId) != null) {
@@ -7902,26 +7907,20 @@ public class PackageManagerService extends IPackageManager.Stub {
case GRANT_RUNTIME: {
// Grant previously granted runtime permissions.
for (int userId : UserManagerService.getInstance().getUserIds()) {
+ PermissionState permissionState = origPermissions
+ .getRuntimePermissionState(bp.name, userId);
+ final int flags = permissionState != null
+ ? permissionState.getFlags() : 0;
if (origPermissions.hasRuntimePermission(bp.name, userId)) {
- PermissionState permissionState = origPermissions
- .getRuntimePermissionState(bp.name, userId);
- final int flags = permissionState.getFlags();
if (permissionsState.grantRuntimePermission(bp, userId) ==
PermissionsState.PERMISSION_OPERATION_FAILURE) {
// If we cannot put the permission as it was, we have to write.
changedRuntimePermissionUserIds = ArrayUtils.appendInt(
changedRuntimePermissionUserIds, userId);
- } else {
- // System components not only get the permissions but
- // they are also fixed, so nothing can change that.
- final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg)
- ? flags
- : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
- // Propagate the permission flags.
- permissionsState.updatePermissionFlags(bp, userId,
- newFlags, newFlags);
}
}
+ // Propagate the permission flags.
+ permissionsState.updatePermissionFlags(bp, userId, flags, flags);
}
} break;
@@ -7931,25 +7930,23 @@ public class PackageManagerService extends IPackageManager.Stub {
.getInstallPermissionState(bp.name);
final int flags = permissionState != null ? permissionState.getFlags() : 0;
- origPermissions.revokeInstallPermission(bp);
- // We will be transferring the permission flags, so clear them.
- origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
- PackageManager.MASK_PERMISSION_FLAGS, 0);
+ if (origPermissions.revokeInstallPermission(bp)
+ != PermissionsState.PERMISSION_OPERATION_FAILURE) {
+ // We will be transferring the permission flags, so clear them.
+ origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
+ PackageManager.MASK_PERMISSION_FLAGS, 0);
+ changedInstallPermission = true;
+ }
// If the permission is not to be promoted to runtime we ignore it and
// also its other flags as they are not applicable to install permissions.
if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
- for (int userId : upgradeUserIds) {
+ for (int userId : currentUserIds) {
if (permissionsState.grantRuntimePermission(bp, userId) !=
PermissionsState.PERMISSION_OPERATION_FAILURE) {
- // System components not only get the permissions but
- // they are also fixed so nothing can change that.
- final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg)
- ? flags
- : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
// Transfer the permission flags.
permissionsState.updatePermissionFlags(bp, userId,
- newFlags, newFlags);
+ flags, flags);
// If we granted the permission, we have to write.
changedRuntimePermissionUserIds = ArrayUtils.appendInt(
changedRuntimePermissionUserIds, userId);
@@ -8001,11 +7998,9 @@ public class PackageManagerService extends IPackageManager.Stub {
ps.installPermissionsFixed = true;
}
- ps.setPermissionsUpdatedForUserIds(currentUserIds);
-
// Persist the runtime permissions state for users with changes.
for (int userId : changedRuntimePermissionUserIds) {
- mSettings.writeRuntimePermissionsForUserLPr(userId, true);
+ mSettings.writeRuntimePermissionsForUserLPr(userId, false);
}
}
@@ -8254,6 +8249,7 @@ public class PackageManagerService extends IPackageManager.Stub {
} else {
res.icon = info.icon;
}
+ res.iconResourceId = info.icon;
res.system = res.activityInfo.applicationInfo.isSystemApp();
return res;
}
@@ -11881,13 +11877,6 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- private boolean isSystemComponentOrPersistentPrivApp(PackageParser.Package pkg) {
- return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
- || ((pkg.applicationInfo.privateFlags
- & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0
- && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0);
- }
-
private static boolean isMultiArch(PackageSetting ps) {
return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
}
@@ -12500,6 +12489,8 @@ public class PackageManagerService extends IPackageManager.Stub {
if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
scheduleWritePackageRestrictionsLocked(removeUser);
}
+ revokeRuntimePermissionsAndClearAllFlagsLocked(ps.getPermissionsState(),
+ removeUser);
}
return true;
}
@@ -12706,17 +12697,44 @@ public class PackageManagerService extends IPackageManager.Stub {
| PackageManager.FLAG_PERMISSION_USER_FIXED
| PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
+ revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId, userSetFlags);
+ }
+
+ /**
+ * Revokes granted runtime permissions and clears all flags.
+ *
+ * @param permissionsState The permission state to reset.
+ * @param userId The device user for which to do a reset.
+ */
+ private void revokeRuntimePermissionsAndClearAllFlagsLocked(
+ PermissionsState permissionsState, int userId) {
+ revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId,
+ PackageManager.MASK_PERMISSION_FLAGS);
+ }
+
+ /**
+ * Revokes granted runtime permissions and clears certain flags.
+ *
+ * @param permissionsState The permission state to reset.
+ * @param userId The device user for which to do a reset.
+ * @param flags The flags that is going to be reset.
+ */
+ private void revokeRuntimePermissionsAndClearFlagsLocked(
+ PermissionsState permissionsState, int userId, int flags) {
boolean needsWrite = false;
for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) {
BasePermission bp = mSettings.mPermissions.get(state.getName());
if (bp != null) {
permissionsState.revokeRuntimePermission(bp, userId);
- permissionsState.updatePermissionFlags(bp, userId, userSetFlags, 0);
+ permissionsState.updatePermissionFlags(bp, userId, flags, 0);
needsWrite = true;
}
}
+ // Ensure default permissions are never cleared.
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+
if (needsWrite) {
mSettings.writeRuntimePermissionsForUserLPr(userId, true);
}
@@ -13680,6 +13698,14 @@ public class PackageManagerService extends IPackageManager.Stub {
}
sUserManager.systemReady();
+ // If we upgraded grant all default permissions before kicking off.
+ if (isFirstBoot() || (CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE && mIsUpgrade)) {
+ updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
+ for (int userId : UserManagerService.getInstance().getUserIds()) {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ }
+ }
+
// Kick off any messages waiting for system ready
if (mPostSystemReadyMessages != null) {
for (Message msg : mPostSystemReadyMessages) {
@@ -14091,7 +14117,9 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) {
+ if (!checkin
+ && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
+ && packageName == null) {
pw.println();
int count = mSettings.mPackages.size();
if (count == 0) {
@@ -15067,9 +15095,16 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- void newUserCreatedLILPw(int userHandle) {
- // Adding a user requires updating runtime permissions for system apps.
- updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
+ void newUserCreatedLILPw(final int userHandle) {
+ // We cannot grant the default permissions with a lock held as
+ // we query providers from other components for default handlers
+ // such as enabled IMEs, etc.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
+ }
+ });
}
@Override
@@ -15421,4 +15456,27 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
}
+
+ private class PackageManagerInternalImpl extends PackageManagerInternal {
+ @Override
+ public void setLocationPackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
+ }
+ }
+
+ @Override
+ public void setImePackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setImePackagesProviderLPr(provider);
+ }
+ }
+
+ @Override
+ public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index f62c00c..6f46f69 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -24,7 +24,6 @@ import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageUserState;
import android.os.storage.VolumeInfo;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.SparseArray;
@@ -223,7 +222,6 @@ abstract class PackageSettingBase extends SettingBase {
* Make a shallow copy of this package settings.
*/
public void copyFrom(PackageSettingBase base) {
- setPermissionsUpdatedForUserIds(base.getPermissionsUpdatedForUserIds());
mPermissionsState.copyFrom(base.mPermissionsState);
primaryCpuAbiString = base.primaryCpuAbiString;
secondaryCpuAbiString = base.secondaryCpuAbiString;
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index c35258a..5cf92a9 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -18,16 +18,11 @@ package com.android.server.pm;
import android.content.pm.ApplicationInfo;
-import java.util.Arrays;
-
abstract class SettingBase {
- private static final int[] USERS_NONE = new int[0];
-
int pkgFlags;
int pkgPrivateFlags;
protected final PermissionsState mPermissionsState;
- private int[] mPermissionsUpdatedForUserIds = USERS_NONE;
SettingBase(int pkgFlags, int pkgPrivateFlags) {
setFlags(pkgFlags);
@@ -39,29 +34,12 @@ abstract class SettingBase {
pkgFlags = base.pkgFlags;
pkgPrivateFlags = base.pkgPrivateFlags;
mPermissionsState = new PermissionsState(base.mPermissionsState);
- setPermissionsUpdatedForUserIds(base.mPermissionsUpdatedForUserIds);
}
public PermissionsState getPermissionsState() {
return mPermissionsState;
}
- public int[] getPermissionsUpdatedForUserIds() {
- return mPermissionsUpdatedForUserIds;
- }
-
- public void setPermissionsUpdatedForUserIds(int[] userIds) {
- if (Arrays.equals(mPermissionsUpdatedForUserIds, userIds)) {
- return;
- }
-
- if (userIds == USERS_NONE) {
- mPermissionsUpdatedForUserIds = userIds;
- } else {
- mPermissionsUpdatedForUserIds = Arrays.copyOf(userIds, userIds.length);
- }
- }
-
void setFlags(int pkgFlags) {
this.pkgFlags = pkgFlags
& (ApplicationInfo.FLAG_SYSTEM
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index cd50946..6415343 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1139,17 +1139,6 @@ final class Settings {
return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME);
}
- boolean isFirstRuntimePermissionsBoot() {
- return !getUserRuntimePermissionsFile(UserHandle.USER_OWNER).exists();
- }
-
- void deleteRuntimePermissionsFiles() {
- for (int userId : UserManagerService.getInstance().getUserIds()) {
- File file = getUserRuntimePermissionsFile(userId);
- file.delete();
- }
- }
-
private File getUserPackagesStateBackupFile(int userId) {
return new File(Environment.getUserSystemDirectory(userId),
"package-restrictions-backup.xml");
@@ -2098,7 +2087,7 @@ final class Settings {
}
final ApplicationInfo ai = pkg.pkg.applicationInfo;
- final String dataPath = ai.dataDir;
+ final String dataPath = new File(ai.dataDir).getCanonicalPath();
final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
final int[] gids = pkg.getPermissionsState().computeGids(userIds);
@@ -2466,6 +2455,22 @@ final class Settings {
} catch (NumberFormatException e) {
}
mFingerprint = parser.getAttributeValue(null, "fingerprint");
+
+ // If the build is setup to drop runtime permissions
+ // on update drop the files before loading them.
+ if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
+ if (!Build.FINGERPRINT.equals(mFingerprint)) {
+ if (users == null) {
+ mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(
+ UserHandle.USER_OWNER);
+ } else {
+ for (UserInfo user : users) {
+ mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(
+ user.id);
+ }
+ }
+ }
+ }
} else if (tagName.equals("database-version")) {
mInternalDatabaseVersion = mExternalDatabaseVersion = 0;
try {
@@ -2554,15 +2559,21 @@ final class Settings {
} else {
if (users == null) {
readPackageRestrictionsLPr(0);
- mRuntimePermissionsPersistence.readStateForUserSyncLPr(UserHandle.USER_OWNER);
} else {
for (UserInfo user : users) {
readPackageRestrictionsLPr(user.id);
- mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
}
}
}
+ if (users == null) {
+ mRuntimePermissionsPersistence.readStateForUserSyncLPr(UserHandle.USER_OWNER);
+ } else {
+ for (UserInfo user : users) {
+ mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
+ }
+ }
+
/*
* Make sure all the updated system packages have their shared users
* associated with them.
@@ -3056,18 +3067,6 @@ final class Settings {
}
}
- // We keep track for which users we granted permissions to be able
- // to grant runtime permissions to system apps for newly appeared
- // users or newly appeared system apps. If we supported runtime
- // permissions during the previous boot, then we already granted
- // permissions for all device users. In such a case we set the users
- // for which we granted permissions to avoid clobbering of runtime
- // permissions we granted to system apps but the user revoked later.
- if (!isFirstRuntimePermissionsBoot()) {
- final int[] userIds = UserManagerService.getInstance().getUserIds();
- ps.setPermissionsUpdatedForUserIds(userIds);
- }
-
mDisabledSysPackages.put(name, ps);
}
@@ -3364,18 +3363,6 @@ final class Settings {
XmlUtils.skipCurrentTag(parser);
}
}
-
- // We keep track for which users we granted permissions to be able
- // to grant runtime permissions to system apps for newly appeared
- // users or newly appeared system apps. If we supported runtime
- // permissions during the previous boot, then we already granted
- // permissions for all device users. In such a case we set the users
- // for which we granted permissions to avoid clobbering of runtime
- // permissions we granted to system apps but the user revoked later.
- if (!isFirstRuntimePermissionsBoot()) {
- final int[] userIds = UserManagerService.getInstance().getUserIds();
- packageSetting.setPermissionsUpdatedForUserIds(userIds);
- }
} else {
XmlUtils.skipCurrentTag(parser);
}
@@ -3493,18 +3480,6 @@ final class Settings {
XmlUtils.skipCurrentTag(parser);
}
}
-
- // We keep track for which users we granted permissions to be able
- // to grant runtime permissions to system apps for newly appeared
- // users or newly appeared system apps. If we supported runtime
- // permissions during the previous boot, then we already granted
- // permissions for all device users. In such a case we set the users
- // for which we granted permissions to avoid clobbering of runtime
- // permissions we granted to system apps but the user revoked later.
- if (!isFirstRuntimePermissionsBoot()) {
- final int[] userIds = UserManagerService.getInstance().getUserIds();
- su.setPermissionsUpdatedForUserIds(userIds);
- }
} else {
XmlUtils.skipCurrentTag(parser);
}
@@ -4364,8 +4339,6 @@ final class Settings {
Slog.wtf(PackageManagerService.TAG,
"Failed to write settings, restoring backup", t);
destination.failWrite(out);
- throw new IllegalStateException("Failed to write runtime permissions,"
- + " restoring backup", t);
} finally {
IoUtils.closeQuietly(out);
}
@@ -4397,6 +4370,10 @@ final class Settings {
}
}
+ public void deleteUserRuntimePermissionsFile(int userId) {
+ getUserRuntimePermissionsFile(userId).delete();
+ }
+
public void readStateForUserSyncLPr(int userId) {
File permissionsFile = getUserRuntimePermissionsFile(userId);
if (!permissionsFile.exists()) {
@@ -4489,22 +4466,12 @@ final class Settings {
? Integer.parseInt(flagsStr, 16) : 0;
if (granted) {
- if (permissionsState.grantRuntimePermission(bp, userId) ==
- PermissionsState.PERMISSION_OPERATION_FAILURE) {
- Slog.w(PackageManagerService.TAG, "Duplicate permission:" + name);
- } else {
- permissionsState.updatePermissionFlags(bp, userId,
+ permissionsState.grantRuntimePermission(bp, userId);
+ permissionsState.updatePermissionFlags(bp, userId,
PackageManager.MASK_PERMISSION_FLAGS, flags);
-
- }
} else {
- if (permissionsState.revokeRuntimePermission(bp, userId) ==
- PermissionsState.PERMISSION_OPERATION_FAILURE) {
- Slog.w(PackageManagerService.TAG, "Duplicate permission:" + name);
- } else {
- permissionsState.updatePermissionFlags(bp, userId,
- PackageManager.MASK_PERMISSION_FLAGS, flags);
- }
+ permissionsState.updatePermissionFlags(bp, userId,
+ PackageManager.MASK_PERMISSION_FLAGS, flags);
}
} break;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 6fb9a5c..bd545df 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -56,6 +56,7 @@ import android.os.Debug;
import android.os.FactoryTest;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
@@ -2734,6 +2735,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (!keyguardOn) {
voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
} else {
+ IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ if (dic != null) {
+ try {
+ dic.exitIdle("voice-search");
+ } catch (RemoteException e) {
+ }
+ }
voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true);
}
@@ -5192,6 +5201,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
void launchVoiceAssistWithWakeLock(boolean keyguardActive) {
+ IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+ if (dic != null) {
+ try {
+ dic.exitIdle("voice-search");
+ } catch (RemoteException e) {
+ }
+ }
Intent voiceIntent =
new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardActive);
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 5a391f4..d21c6d2 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -95,6 +95,9 @@ final class Notifier {
private final Intent mScreenOffIntent;
private final Intent mScreenBrightnessBoostIntent;
+ // True if the device should suspend when the screen is off due to proximity.
+ private final boolean mSuspendWhenScreenOffDueToProximityConfig;
+
// The current interactive state. This is set as soon as an interactive state
// transition begins so as to capture the reason that it happened. At some point
// this state will propagate to the pending state then eventually to the
@@ -143,6 +146,9 @@ final class Notifier {
mScreenBrightnessBoostIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+ mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
+
// Initialize interactive state for battery stats.
try {
mBatteryStats.noteInteractive(true);
@@ -161,22 +167,24 @@ final class Notifier {
+ ", workSource=" + workSource);
}
- try {
- final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
- boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
- && ownerUid == Process.SYSTEM_UID;
- if (workSource != null) {
- mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, historyTag,
- monitorType, unimportantForLogging);
- } else {
- mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
- monitorType, unimportantForLogging);
- // XXX need to deal with disabled operations.
- mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
- AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+ if (monitorType >= 0) {
+ try {
+ final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
+ && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
+ if (workSource != null) {
+ mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
+ historyTag, monitorType, unimportantForLogging);
+ } else {
+ mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
+ monitorType, unimportantForLogging);
+ // XXX need to deal with disabled operations.
+ mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
+ AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ }
+ } catch (RemoteException ex) {
+ // Ignore
}
- } catch (RemoteException ex) {
- // Ignore
}
}
@@ -188,17 +196,19 @@ final class Notifier {
int newFlags, String newTag, String newPackageName, int newOwnerUid,
int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
- if (workSource != null && newWorkSource != null) {
- final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
- final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
- boolean unimportantForLogging = (newFlags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
- && newOwnerUid == Process.SYSTEM_UID;
+ final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+ final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
+ if (workSource != null && newWorkSource != null
+ && monitorType >= 0 && newMonitorType >= 0) {
if (DEBUG) {
Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
+ "\", packageName=" + newPackageName
+ ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
+ ", workSource=" + newWorkSource);
}
+
+ final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
+ && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
try {
mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
@@ -225,28 +235,50 @@ final class Notifier {
+ ", workSource=" + workSource);
}
- try {
- final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
- if (workSource != null) {
- mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, historyTag,
- monitorType);
- } else {
- mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, historyTag, monitorType);
- mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
- AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+ if (monitorType >= 0) {
+ try {
+ if (workSource != null) {
+ mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
+ historyTag, monitorType);
+ } else {
+ mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
+ historyTag, monitorType);
+ mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
+ AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+ }
+ } catch (RemoteException ex) {
+ // Ignore
}
- } catch (RemoteException ex) {
- // Ignore
}
}
- private static int getBatteryStatsWakeLockMonitorType(int flags) {
+ private int getBatteryStatsWakeLockMonitorType(int flags) {
switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
case PowerManager.PARTIAL_WAKE_LOCK:
+ return BatteryStats.WAKE_TYPE_PARTIAL;
+
+ case PowerManager.SCREEN_DIM_WAKE_LOCK:
+ case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
+ return BatteryStats.WAKE_TYPE_FULL;
+
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
+ if (mSuspendWhenScreenOffDueToProximityConfig) {
+ return -1;
+ }
return BatteryStats.WAKE_TYPE_PARTIAL;
+
+ case PowerManager.DRAW_WAKE_LOCK:
+ return BatteryStats.WAKE_TYPE_DRAW;
+
+ case PowerManager.DOZE_WAKE_LOCK:
+ // Doze wake locks are an internal implementation detail of the
+ // communication between dream manager service and power manager
+ // service. They have no additive battery impact.
+ return -1;
+
default:
- return BatteryStats.WAKE_TYPE_FULL;
+ return -1;
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 3af97db..51bb36f 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -970,6 +970,7 @@ public final class PowerManagerService extends SystemService
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
case PowerManager.FULL_WAKE_LOCK:
case PowerManager.DOZE_WAKE_LOCK:
+ case PowerManager.DRAW_WAKE_LOCK:
return true;
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 58c3ea1..4692403 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -24,4 +24,5 @@ public interface StatusBarManagerInternal {
void notificationLightPulse(int argb, int onMillis, int offMillis);
void notificationLightOff();
void showScreenPinningRequest();
+ void showAssistDisclosure();
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 5669f30..a754379 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -154,6 +154,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
}
}
}
+
+ @Override
+ public void showAssistDisclosure() {
+ if (mBar != null) {
+ try {
+ mBar.showAssistDisclosure();
+ } catch (RemoteException e) {
+ }
+ }
+ }
};
// ================================================================================
diff --git a/services/core/java/com/android/server/tv/PersistentDataStore.java b/services/core/java/com/android/server/tv/PersistentDataStore.java
index f9b5b9a..f6b1705 100644
--- a/services/core/java/com/android/server/tv/PersistentDataStore.java
+++ b/services/core/java/com/android/server/tv/PersistentDataStore.java
@@ -111,8 +111,8 @@ final class PersistentDataStore {
public boolean isRatingBlocked(TvContentRating rating) {
loadIfNeeded();
synchronized (mBlockedRatings) {
- for (TvContentRating blcokedRating : mBlockedRatings) {
- if (rating.contains(blcokedRating)) {
+ for (TvContentRating blockedRating : mBlockedRatings) {
+ if (rating.contains(blockedRating)) {
return true;
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index de271b8..a035826 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -47,11 +47,10 @@ final class TvInputHal implements Handler.Callback {
public static final int EVENT_FIRST_FRAME_CAPTURED = 4;
public interface Callback {
- public void onDeviceAvailable(
- TvInputHardwareInfo info, TvStreamConfig[] configs);
- public void onDeviceUnavailable(int deviceId);
- public void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs);
- public void onFirstFrameCaptured(int deviceId, int streamId);
+ void onDeviceAvailable(TvInputHardwareInfo info, TvStreamConfig[] configs);
+ void onDeviceUnavailable(int deviceId);
+ void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs);
+ void onFirstFrameCaptured(int deviceId, int streamId);
}
private native long nativeOpen(MessageQueue queue);
@@ -152,7 +151,7 @@ final class TvInputHal implements Handler.Callback {
// Handler.Callback implementation
- private final Queue<Message> mPendingMessageQueue = new LinkedList<Message>();
+ private final Queue<Message> mPendingMessageQueue = new LinkedList<>();
@Override
public boolean handleMessage(Message msg) {
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 444969f..7f4c42b 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -252,13 +252,8 @@ class TvInputHardwareManager implements TvInputHal.Callback {
Connection connection, int callingUid, int resolvedUserId) {
Integer connectionCallingUid = connection.getCallingUidLocked();
Integer connectionResolvedUserId = connection.getResolvedUserIdLocked();
- if (connectionCallingUid == null || connectionResolvedUserId == null) {
- return true;
- }
- if (connectionCallingUid != callingUid || connectionResolvedUserId != resolvedUserId) {
- return true;
- }
- return false;
+ return connectionCallingUid == null || connectionResolvedUserId == null
+ || connectionCallingUid != callingUid || connectionResolvedUserId != resolvedUserId;
}
private int convertConnectedToState(boolean connected) {
@@ -303,7 +298,6 @@ class TvInputHardwareManager implements TvInputHal.Callback {
mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
convertConnectedToState(connection.getConfigsLocked().length > 0), 0,
info.getId()).sendToTarget();
- return;
}
}
}
@@ -435,7 +429,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
*/
public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId, int callingUid,
int resolvedUserId) {
- List<TvStreamConfig> configsList = new ArrayList<TvStreamConfig>();
+ List<TvStreamConfig> configsList = new ArrayList<>();
synchronized (mLock) {
int deviceId = findDeviceIdForInputIdLocked(inputId);
if (deviceId < 0) {
@@ -508,25 +502,31 @@ class TvInputHardwareManager implements TvInputHal.Callback {
private void handleVolumeChange(Context context, Intent intent) {
String action = intent.getAction();
- if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
- int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
- if (streamType != AudioManager.STREAM_MUSIC) {
- return;
+ switch (action) {
+ case AudioManager.VOLUME_CHANGED_ACTION: {
+ int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+ if (streamType != AudioManager.STREAM_MUSIC) {
+ return;
+ }
+ int index = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
+ if (index == mCurrentIndex) {
+ return;
+ }
+ mCurrentIndex = index;
+ break;
}
- int index = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
- if (index == mCurrentIndex) {
- return;
+ case AudioManager.STREAM_MUTE_CHANGED_ACTION: {
+ int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+ if (streamType != AudioManager.STREAM_MUSIC) {
+ return;
+ }
+ // volume index will be updated at onMediaStreamVolumeChanged() through
+ // updateVolume().
+ break;
}
- mCurrentIndex = index;
- } else if (action.equals(AudioManager.STREAM_MUTE_CHANGED_ACTION)) {
- int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
- if (streamType != AudioManager.STREAM_MUSIC) {
+ default:
+ Slog.w(TAG, "Unrecognized intent: " + intent);
return;
- }
- // volume index will be updated at onMediaStreamVolumeChanged() through updateVolume().
- } else {
- Slog.w(TAG, "Unrecognized intent: " + intent);
- return;
}
synchronized (mLock) {
for (int i = 0; i < mConnections.size(); ++i) {
@@ -691,7 +691,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
private void findAudioSinkFromAudioPolicy(List<AudioDevicePort> sinks) {
sinks.clear();
- ArrayList<AudioDevicePort> devicePorts = new ArrayList<AudioDevicePort>();
+ ArrayList<AudioDevicePort> devicePorts = new ArrayList<>();
if (mAudioManager.listAudioDevicePorts(devicePorts) != AudioManager.SUCCESS) {
return;
}
@@ -707,7 +707,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
if (type == AudioManager.DEVICE_NONE) {
return null;
}
- ArrayList<AudioDevicePort> devicePorts = new ArrayList<AudioDevicePort>();
+ ArrayList<AudioDevicePort> devicePorts = new ArrayList<>();
if (mAudioManager.listAudioDevicePorts(devicePorts) != AudioManager.SUCCESS) {
return null;
}
@@ -900,7 +900,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
mAudioManager.createAudioPatch(
audioPatchArray,
new AudioPortConfig[] { sourceConfig },
- sinkConfigs.toArray(new AudioPortConfig[0]));
+ sinkConfigs.toArray(new AudioPortConfig[sinkConfigs.size()]));
mAudioPatch = audioPatchArray[0];
if (sourceGainConfig != null) {
mAudioManager.setAudioPortGain(mAudioSource, sourceGainConfig);
@@ -1027,12 +1027,12 @@ class TvInputHardwareManager implements TvInputHal.Callback {
}
interface Listener {
- public void onStateChanged(String inputId, int state);
- public void onHardwareDeviceAdded(TvInputHardwareInfo info);
- public void onHardwareDeviceRemoved(TvInputHardwareInfo info);
- public void onHdmiDeviceAdded(HdmiDeviceInfo device);
- public void onHdmiDeviceRemoved(HdmiDeviceInfo device);
- public void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo device);
+ void onStateChanged(String inputId, int state);
+ void onHardwareDeviceAdded(TvInputHardwareInfo info);
+ void onHardwareDeviceRemoved(TvInputHardwareInfo info);
+ void onHdmiDeviceAdded(HdmiDeviceInfo device);
+ void onHdmiDeviceRemoved(HdmiDeviceInfo device);
+ void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo device);
}
private class ListenerHandler extends Handler {
@@ -1074,7 +1074,7 @@ class TvInputHardwareManager implements TvInputHal.Callback {
}
case HDMI_DEVICE_UPDATED: {
HdmiDeviceInfo info = (HdmiDeviceInfo) msg.obj;
- String inputId = null;
+ String inputId;
synchronized (mLock) {
inputId = mHdmiInputIdMap.get(info.getId());
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 4895d12..f5c5861 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -121,7 +121,7 @@ public final class TvInputManagerService extends SystemService {
private int mCurrentUserId = UserHandle.USER_OWNER;
// A map from user id to UserState.
- private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
+ private final SparseArray<UserState> mUserStates = new SparseArray<>();
private final WatchLogHandler mWatchLogHandler;
@@ -231,8 +231,7 @@ public final class TvInputManagerService extends SystemService {
}
}
- ArrayList<ContentProviderOperation> operations =
- new ArrayList<ContentProviderOperation>();
+ ArrayList<ContentProviderOperation> operations = new ArrayList<>();
String selection = TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME + "=?";
String[] selectionArgs = { packageName };
@@ -292,7 +291,7 @@ public final class TvInputManagerService extends SystemService {
new Intent(TvInputService.SERVICE_INTERFACE),
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
userId);
- List<TvInputInfo> inputList = new ArrayList<TvInputInfo>();
+ List<TvInputInfo> inputList = new ArrayList<>();
for (ResolveInfo ri : services) {
ServiceInfo si = ri.serviceInfo;
if (!android.Manifest.permission.BIND_TV_INPUT.equals(si.permission)) {
@@ -325,7 +324,7 @@ public final class TvInputManagerService extends SystemService {
userState.packageSet.add(si.packageName);
}
- Map<String, TvInputState> inputMap = new HashMap<String, TvInputState>();
+ Map<String, TvInputState> inputMap = new HashMap<>();
for (TvInputInfo info : inputList) {
if (DEBUG) {
Slog.d(TAG, "add " + info.getId());
@@ -777,7 +776,7 @@ public final class TvInputManagerService extends SystemService {
try {
synchronized (mLock) {
UserState userState = getUserStateLocked(resolvedUserId);
- List<TvInputInfo> inputList = new ArrayList<TvInputInfo>();
+ List<TvInputInfo> inputList = new ArrayList<>();
for (TvInputState state : userState.inputMap.values()) {
inputList.add(state.info);
}
@@ -934,7 +933,7 @@ public final class TvInputManagerService extends SystemService {
try {
synchronized (mLock) {
UserState userState = getUserStateLocked(resolvedUserId);
- List<String> ratings = new ArrayList<String>();
+ List<String> ratings = new ArrayList<>();
for (TvContentRating rating
: userState.persistentDataStore.getBlockedRatings()) {
ratings.add(rating.flattenToString());
@@ -1012,7 +1011,7 @@ public final class TvInputManagerService extends SystemService {
userState.serviceStateMap.put(info.getComponent(), serviceState);
}
// Send a null token immediately while reconnecting.
- if (serviceState.reconnecting == true) {
+ if (serviceState.reconnecting) {
sendSessionTokenToClientLocked(client, inputId, null, null, seq);
return;
}
@@ -1210,7 +1209,6 @@ public final class TvInputManagerService extends SystemService {
.sendToTarget();
} catch (RemoteException | SessionNotFoundException e) {
Slog.e(TAG, "error in tune", e);
- return;
}
}
} finally {
@@ -1658,10 +1656,9 @@ public final class TvInputManagerService extends SystemService {
UserState userState = getUserStateLocked(resolvedUserId);
if (userState.sessionStateMap.size() == 1) {
return true;
- }
- else if (userState.sessionStateMap.size() == 2) {
+ } else if (userState.sessionStateMap.size() == 2) {
SessionState[] sessionStates = userState.sessionStateMap.values().toArray(
- new SessionState[0]);
+ new SessionState[2]);
// Check if there is a wrapper input.
if (sessionStates[0].hardwareSessionToken != null
|| sessionStates[1].hardwareSessionToken != null) {
@@ -1800,30 +1797,26 @@ public final class TvInputManagerService extends SystemService {
private static final class UserState {
// A mapping from the TV input id to its TvInputState.
- private Map<String, TvInputState> inputMap = new HashMap<String, TvInputState>();
+ private Map<String, TvInputState> inputMap = new HashMap<>();
// A set of all TV input packages.
- private final Set<String> packageSet = new HashSet<String>();
+ private final Set<String> packageSet = new HashSet<>();
// A list of all TV content rating systems defined.
private final List<TvContentRatingSystemInfo>
- contentRatingSystemList = new ArrayList<TvContentRatingSystemInfo>();
+ contentRatingSystemList = new ArrayList<>();
// A mapping from the token of a client to its state.
- private final Map<IBinder, ClientState> clientStateMap =
- new HashMap<IBinder, ClientState>();
+ private final Map<IBinder, ClientState> clientStateMap = new HashMap<>();
// A mapping from the name of a TV input service to its state.
- private final Map<ComponentName, ServiceState> serviceStateMap =
- new HashMap<ComponentName, ServiceState>();
+ private final Map<ComponentName, ServiceState> serviceStateMap = new HashMap<>();
// A mapping from the token of a TV input session to its state.
- private final Map<IBinder, SessionState> sessionStateMap =
- new HashMap<IBinder, SessionState>();
+ private final Map<IBinder, SessionState> sessionStateMap = new HashMap<>();
// A set of callbacks.
- private final Set<ITvInputManagerCallback> callbackSet =
- new HashSet<ITvInputManagerCallback>();
+ private final Set<ITvInputManagerCallback> callbackSet = new HashSet<>();
// The token of a "main" TV input session.
private IBinder mainSessionToken = null;
@@ -1838,7 +1831,7 @@ public final class TvInputManagerService extends SystemService {
}
private final class ClientState implements IBinder.DeathRecipient {
- private final List<IBinder> sessionTokens = new ArrayList<IBinder>();
+ private final List<IBinder> sessionTokens = new ArrayList<>();
private IBinder clientToken;
private final int userId;
@@ -1871,11 +1864,11 @@ public final class TvInputManagerService extends SystemService {
}
private final class ServiceState {
- private final List<IBinder> sessionTokens = new ArrayList<IBinder>();
+ private final List<IBinder> sessionTokens = new ArrayList<>();
private final ServiceConnection connection;
private final ComponentName component;
private final boolean isHardware;
- private final List<TvInputInfo> inputList = new ArrayList<TvInputInfo>();
+ private final List<TvInputInfo> inputList = new ArrayList<>();
private ITvInputService service;
private ServiceCallback callback;
@@ -2125,13 +2118,13 @@ public final class TvInputManagerService extends SystemService {
}
@Override
- public void onSessionCreated(ITvInputSession session, IBinder harewareSessionToken) {
+ public void onSessionCreated(ITvInputSession session, IBinder hardwareSessionToken) {
if (DEBUG) {
Slog.d(TAG, "onSessionCreated(inputId=" + mSessionState.info.getId() + ")");
}
synchronized (mLock) {
mSessionState.session = session;
- mSessionState.hardwareSessionToken = harewareSessionToken;
+ mSessionState.hardwareSessionToken = hardwareSessionToken;
if (session != null && addSessionTokenToClientStateLocked(session)) {
sendSessionTokenToClientLocked(mSessionState.client,
mSessionState.info.getId(), mSessionState.sessionToken, mChannels[0],
@@ -2559,7 +2552,7 @@ public final class TvInputManagerService extends SystemService {
@Override
public void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo deviceInfo) {
synchronized (mLock) {
- Integer state = null;
+ Integer state;
switch (deviceInfo.getDevicePowerStatus()) {
case HdmiControlManager.POWER_STATUS_ON:
state = INPUT_STATE_CONNECTED;
@@ -2575,7 +2568,7 @@ public final class TvInputManagerService extends SystemService {
break;
}
if (state != null) {
- setStateLocked(inputId, state.intValue(), mCurrentUserId);
+ setStateLocked(inputId, state, mCurrentUserId);
}
}
}
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index ac79b36..d4c5f87 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -40,8 +40,6 @@ public class WebViewUpdateService extends SystemService {
private boolean mRelroReady32Bit = false;
private boolean mRelroReady64Bit = false;
- private String oldWebViewPackageName = null;
-
private BroadcastReceiver mWebViewUpdatedReceiver;
public WebViewUpdateService(Context context) {
@@ -53,22 +51,9 @@ public class WebViewUpdateService extends SystemService {
mWebViewUpdatedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
-
- for (String packageName : WebViewFactory.getWebViewPackageNames()) {
- String webviewPackage = "package:" + packageName;
-
- if (webviewPackage.equals(intent.getDataString())) {
- String usedPackageName =
- WebViewFactory.findPreferredWebViewPackage().packageName;
- // Only trigger update actions if the updated package is the one that
- // will be used, or the one that was in use before the update.
- if (packageName.equals(usedPackageName) ||
- packageName.equals(oldWebViewPackageName)) {
- onWebViewUpdateInstalled();
- oldWebViewPackageName = usedPackageName;
- }
- return;
- }
+ String webviewPackage = "package:" + WebViewFactory.getWebViewPackageName();
+ if (webviewPackage.equals(intent.getDataString())) {
+ onWebViewUpdateInstalled();
}
}
};
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 5064d8f..f1331e9 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1383,10 +1383,21 @@ class WindowStateAnimator {
// Adjust for surface insets.
final LayoutParams attrs = w.getAttrs();
- width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
- height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
- left -= attrs.surfaceInsets.left;
- top -= attrs.surfaceInsets.top;
+ final int displayId = w.getDisplayId();
+ float scale = 1.0f;
+ // Magnification is supported only for the default display.
+ if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
+ MagnificationSpec spec =
+ mService.mAccessibilityController.getMagnificationSpecForWindowLocked(w);
+ if (spec != null && !spec.isNop()) {
+ scale = spec.scale;
+ }
+ }
+
+ width += scale * (attrs.surfaceInsets.left + attrs.surfaceInsets.right);
+ height += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
+ left -= scale * attrs.surfaceInsets.left;
+ top -= scale * attrs.surfaceInsets.top;
final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
if (surfaceMoved) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 29c65db..76226b4 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -292,7 +292,7 @@ public final class SystemServer {
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
- mSystemContext.setTheme(android.R.style.Theme_Material_DayNight_DarkActionBar);
+ mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index b58c2e2..712db09 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -134,6 +134,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
private final NetworkInfo mNetworkInfo;
private final NetworkCapabilities mNetworkCapabilities;
private final Thread mThread;
+ private int mScore;
private NetworkAgent mNetworkAgent;
MockNetworkAgent(int transport) {
@@ -142,13 +143,12 @@ public class ConnectivityServiceTest extends AndroidTestCase {
mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
mNetworkCapabilities = new NetworkCapabilities();
mNetworkCapabilities.addTransportType(transport);
- final int score;
switch (transport) {
case TRANSPORT_WIFI:
- score = 60;
+ mScore = 60;
break;
case TRANSPORT_CELLULAR:
- score = 50;
+ mScore = 50;
break;
default:
throw new UnsupportedOperationException("unimplemented network type");
@@ -159,7 +159,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
Looper.prepare();
mNetworkAgent = new NetworkAgent(Looper.myLooper(), mServiceContext,
"Mock" + typeName, mNetworkInfo, mNetworkCapabilities,
- new LinkProperties(), score, new NetworkMisc()) {
+ new LinkProperties(), mScore, new NetworkMisc()) {
public void unwanted() {}
};
initComplete.open();
@@ -167,7 +167,12 @@ public class ConnectivityServiceTest extends AndroidTestCase {
}
};
mThread.start();
- initComplete.block();
+ waitFor(initComplete);
+ }
+
+ public void adjustScore(int change) {
+ mScore += change;
+ mNetworkAgent.sendNetworkScore(mScore);
}
/**
@@ -209,7 +214,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
if (validated) {
// Wait for network to validate.
- validatedCv.block();
+ waitFor(validatedCv);
mNetworkCapabilities.addCapability(NET_CAPABILITY_INTERNET);
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
}
@@ -330,6 +335,10 @@ public class ConnectivityServiceTest extends AndroidTestCase {
public boolean get();
}
+ /**
+ * Wait up to 500ms for {@code criteria.get()} to become true, polling.
+ * Fails if 500ms goes by before {@code criteria.get()} to become true.
+ */
static private void waitFor(Criteria criteria) {
int delays = 0;
while (!criteria.get()) {
@@ -341,6 +350,26 @@ public class ConnectivityServiceTest extends AndroidTestCase {
}
}
+ /**
+ * Wait up to 500ms for {@code conditonVariable} to open.
+ * Fails if 500ms goes by before {@code conditionVariable} opens.
+ */
+ static private void waitFor(ConditionVariable conditionVariable) {
+ assertTrue(conditionVariable.block(500));
+ }
+
+ /**
+ * This should only be used to verify that nothing happens, in other words that no unexpected
+ * changes occur. It should never be used to wait for a specific positive signal to occur.
+ */
+ private void shortSleep() {
+ // TODO: Instead of sleeping, instead wait for all message loops to idle.
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+ }
+
@Override
public void setUp() throws Exception {
super.setUp();
@@ -431,7 +460,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
// Test bringing up validated cellular.
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent.connect(true);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
assertEquals(2, mCm.getAllNetworks().length);
assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
@@ -441,7 +470,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
// Test bringing up validated WiFi.
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent.connect(true);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
assertEquals(2, mCm.getAllNetworks().length);
assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) ||
@@ -459,7 +488,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
// Test WiFi disconnect.
cv = waitForConnectivityBroadcasts(1);
mWiFiNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyNoNetwork();
}
@@ -469,38 +498,32 @@ public class ConnectivityServiceTest extends AndroidTestCase {
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mWiFiNetworkAgent.connect(false);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test bringing up unvalidated cellular
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(false);
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
+ shortSleep();
verifyActiveNetwork(TRANSPORT_WIFI);
// Test cellular disconnect.
mCellNetworkAgent.disconnect();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
+ shortSleep();
verifyActiveNetwork(TRANSPORT_WIFI);
// Test bringing up validated cellular
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
cv = waitForConnectivityBroadcasts(2);
mCellNetworkAgent.connect(true);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test cellular disconnect.
cv = waitForConnectivityBroadcasts(2);
mCellNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test WiFi disconnect.
cv = waitForConnectivityBroadcasts(1);
mWiFiNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyNoNetwork();
}
@@ -510,27 +533,209 @@ public class ConnectivityServiceTest extends AndroidTestCase {
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent.connect(false);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test bringing up unvalidated WiFi.
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent.connect(false);
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_WIFI);
// Test WiFi disconnect.
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyActiveNetwork(TRANSPORT_CELLULAR);
// Test cellular disconnect.
cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent.disconnect();
- cv.block();
+ waitFor(cv);
verifyNoNetwork();
}
@LargeTest
+ public void testCellularOutscoresWeakWifi() throws Exception {
+ // Test bringing up validated cellular.
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ mCellNetworkAgent.connect(true);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_CELLULAR);
+ // Test bringing up validated WiFi.
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent.connect(true);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_WIFI);
+ // Test WiFi getting really weak.
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent.adjustScore(-11);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_CELLULAR);
+ // Test WiFi restoring signal strength.
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent.adjustScore(11);
+ waitFor(cv);
+ verifyActiveNetwork(TRANSPORT_WIFI);
+ mCellNetworkAgent.disconnect();
+ mWiFiNetworkAgent.disconnect();
+ }
+
+ enum CallbackState {
+ NONE,
+ AVAILABLE,
+ LOSING,
+ LOST
+ }
+
+ private class TestNetworkCallback extends NetworkCallback {
+ private final ConditionVariable mConditionVariable = new ConditionVariable();
+ private CallbackState mLastCallback = CallbackState.NONE;
+
+ public void onAvailable(Network network) {
+ assertEquals(CallbackState.NONE, mLastCallback);
+ mLastCallback = CallbackState.AVAILABLE;
+ mConditionVariable.open();
+ }
+
+ public void onLosing(Network network, int maxMsToLive) {
+ assertEquals(CallbackState.NONE, mLastCallback);
+ mLastCallback = CallbackState.LOSING;
+ mConditionVariable.open();
+ }
+
+ public void onLost(Network network) {
+ assertEquals(CallbackState.NONE, mLastCallback);
+ mLastCallback = CallbackState.LOST;
+ mConditionVariable.open();
+ }
+
+ ConditionVariable getConditionVariable() {
+ mLastCallback = CallbackState.NONE;
+ mConditionVariable.close();
+ return mConditionVariable;
+ }
+
+ CallbackState getLastCallback() {
+ return mLastCallback;
+ }
+ }
+
+ @LargeTest
+ public void testStateChangeNetworkCallbacks() throws Exception {
+ final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
+ final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
+ final NetworkRequest wifiRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI).build();
+ final NetworkRequest cellRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_CELLULAR).build();
+ mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
+ mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+
+ // Test unvalidated networks
+ ConditionVariable cellCv = cellNetworkCallback.getConditionVariable();
+ ConditionVariable wifiCv = wifiNetworkCallback.getConditionVariable();
+ ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.connect(false);
+ waitFor(cellCv);
+ assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ waitFor(cv);
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ // This should not trigger spurious onAvailable() callbacks, b/21762680.
+ mCellNetworkAgent.adjustScore(-1);
+ shortSleep();
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(false);
+ waitFor(wifiCv);
+ assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ waitFor(cv);
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ cv = waitForConnectivityBroadcasts(2);
+ mWiFiNetworkAgent.disconnect();
+ waitFor(wifiCv);
+ assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ waitFor(cv);
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ cv = waitForConnectivityBroadcasts(1);
+ mCellNetworkAgent.disconnect();
+ waitFor(cellCv);
+ assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ waitFor(cv);
+
+ // Test validated networks
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ // Our method for faking successful validation generates an additional callback, so wait
+ // for broadcast instead.
+ cv = waitForConnectivityBroadcasts(1);
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.connect(true);
+ waitFor(cv);
+ waitFor(cellCv);
+ assertEquals(CallbackState.AVAILABLE, cellNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ // This should not trigger spurious onAvailable() callbacks, b/21762680.
+ mCellNetworkAgent.adjustScore(-1);
+ shortSleep();
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ // Our method for faking successful validation generates an additional callback, so wait
+ // for broadcast instead.
+ cv = waitForConnectivityBroadcasts(1);
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(true);
+ waitFor(cv);
+ waitFor(wifiCv);
+ assertEquals(CallbackState.AVAILABLE, wifiNetworkCallback.getLastCallback());
+ waitFor(cellCv);
+ assertEquals(CallbackState.LOSING, cellNetworkCallback.getLastCallback());
+ assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ mWiFiNetworkAgent.disconnect();
+ waitFor(wifiCv);
+ assertEquals(CallbackState.LOST, wifiNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, cellNetworkCallback.getLastCallback());
+
+ cellCv = cellNetworkCallback.getConditionVariable();
+ wifiCv = wifiNetworkCallback.getConditionVariable();
+ mCellNetworkAgent.disconnect();
+ waitFor(cellCv);
+ assertEquals(CallbackState.LOST, cellNetworkCallback.getLastCallback());
+ assertEquals(CallbackState.NONE, wifiNetworkCallback.getLastCallback());
+ }
+
+ @LargeTest
public void testNetworkFactoryRequests() throws Exception {
NetworkCapabilities filter = new NetworkCapabilities();
filter.addCapability(NET_CAPABILITY_INTERNET);
@@ -541,7 +746,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
testFactory.setScoreFilter(40);
ConditionVariable cv = testFactory.getNetworkStartedCV();
testFactory.register();
- cv.block();
+ waitFor(cv);
assertEquals(1, testFactory.getMyRequestCount());
assertEquals(true, testFactory.getMyStartRequested());
@@ -550,10 +755,10 @@ public class ConnectivityServiceTest extends AndroidTestCase {
cv = waitForConnectivityBroadcasts(1);
ConditionVariable cvRelease = testFactory.getNetworkStoppedCV();
testAgent.connect(true);
- cv.block();
+ waitFor(cv);
// part of the bringup makes another network request and then releases it
// wait for the release
- cvRelease.block();
+ waitFor(cvRelease);
assertEquals(false, testFactory.getMyStartRequested());
testFactory.waitForNetworkRequests(1);
@@ -579,7 +784,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
// drop the higher scored network
cv = waitForConnectivityBroadcasts(1);
testAgent.disconnect();
- cv.block();
+ waitFor(cv);
assertEquals(1, testFactory.getMyRequestCount());
assertEquals(true, testFactory.getMyStartRequested());
@@ -605,7 +810,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
//
// cv = waitForConnectivityBroadcasts(1);
// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// cv.block();
+// waitFor(cv);
//
// // verify that both routes were added
// int mobileNetId = mMobile.tracker.getNetwork().netId;
@@ -625,7 +830,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
//
// cv = waitForConnectivityBroadcasts(1);
// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// cv.block();
+// waitFor(cv);
//
// reset(mNetManager);
//
@@ -641,7 +846,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
//
// cv = waitForConnectivityBroadcasts(1);
// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget();
-// cv.block();
+// waitFor(cv);
//
// // verify that wifi routes added, and teardown requested
// int wifiNetId = mWifi.tracker.getNetwork().netId;
@@ -660,7 +865,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
//
// cv = waitForConnectivityBroadcasts(1);
// mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget();
-// cv.block();
+// waitFor(cv);
//
// verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4));
// verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6));
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3767fce..490236e 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -31,6 +31,7 @@ import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -69,8 +70,8 @@ import android.view.Display;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.os.SomeArgs;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.DeviceIdleController;
import com.android.server.SystemService;
import java.io.BufferedReader;
@@ -117,6 +118,7 @@ public class UsageStatsService extends SystemService implements
static final int MSG_CHECK_IDLE_STATES = 5;
static final int MSG_CHECK_PAROLE_TIMEOUT = 6;
static final int MSG_PAROLE_END_TIMEOUT = 7;
+ static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8;
private final Object mLock = new Object();
Handler mHandler;
@@ -133,6 +135,7 @@ public class UsageStatsService extends SystemService implements
long mRealTimeSnapshot;
long mSystemTimeSnapshot;
+ boolean mAppIdleEnabled;
boolean mAppIdleParoled;
private boolean mScreenOn;
private long mLastAppIdleParoledTime;
@@ -170,10 +173,15 @@ public class UsageStatsService extends SystemService implements
getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, userActions,
null, null);
- IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
- deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
- deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
- getContext().registerReceiver(new DeviceStateReceiver(), deviceStates);
+ mAppIdleEnabled = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_enableAutoPowerModes);
+ if (mAppIdleEnabled) {
+ IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
+ deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
+ deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
+ getContext().registerReceiver(new DeviceStateReceiver(), deviceStates);
+ }
+
synchronized (mLock) {
cleanUpRemovedUsersLocked();
}
@@ -181,7 +189,6 @@ public class UsageStatsService extends SystemService implements
mRealTimeSnapshot = SystemClock.elapsedRealtime();
mSystemTimeSnapshot = System.currentTimeMillis();
-
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
}
@@ -337,6 +344,10 @@ public class UsageStatsService extends SystemService implements
/** Check all running users' or specified user's apps to see if they enter an idle state. */
void checkIdleStates(int checkUserId) {
+ if (!mAppIdleEnabled) {
+ return;
+ }
+
final int[] userIds;
try {
if (checkUserId == UserHandle.USER_ALL) {
@@ -583,6 +594,29 @@ public class UsageStatsService extends SystemService implements
}
}
+ void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
+ // Get sync adapters for the authority
+ String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser(
+ authority, userId);
+ for (String packageName: packages) {
+ // Only force the sync adapters to active if the provider is not in the same package and
+ // the sync adapter is a system package.
+ try {
+ PackageInfo pi = AppGlobals.getPackageManager().getPackageInfo(
+ packageName, 0, userId);
+ if (pi == null || pi.applicationInfo == null
+ || !pi.applicationInfo.isSystemApp()) {
+ continue;
+ }
+ if (!packageName.equals(providerPkgName)) {
+ forceIdleState(packageName, userId, false);
+ }
+ } catch (RemoteException re) {
+ // Shouldn't happen
+ }
+ }
+ }
+
/**
* Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle,
* then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind
@@ -605,7 +639,7 @@ public class UsageStatsService extends SystemService implements
timeNow - (idle ? mAppIdleWallclockThresholdMillis : 0) - 5000);
// Inform listeners if necessary
if (previouslyIdle != idle) {
- // Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
+ // Slog.d(TAG, "Informing listeners of out-of-idle " + packageName);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ idle ? 1 : 0, packageName));
if (!idle) {
@@ -744,6 +778,10 @@ public class UsageStatsService extends SystemService implements
private boolean isAppIdleFiltered(String packageName, int userId,
UserUsageStatsService userService, long timeNow, long screenOnTime) {
if (packageName == null) return false;
+ // If not enabled at all, of course nobody is ever idle.
+ if (!mAppIdleEnabled) {
+ return false;
+ }
synchronized (mLock) {
// Temporary exemption, probably due to device charging or occasional allowance to
// be allowed to sync, etc.
@@ -872,6 +910,19 @@ public class UsageStatsService extends SystemService implements
pw.print(" mAppIdleParoleDurationMillis=");
TimeUtils.formatDuration(mAppIdleParoleDurationMillis, pw);
pw.println();
+
+ pw.println();
+ pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
+ pw.print(" mAppIdleParoled="); pw.print(mAppIdleParoled);
+ pw.print(" mScreenOn="); pw.println(mScreenOn);
+ pw.print("mLastAppIdleParoledTime=");
+ TimeUtils.formatDuration(mLastAppIdleParoledTime, pw);
+ pw.println();
+ pw.print("mScreenOnTime="); TimeUtils.formatDuration(mScreenOnTime, pw);
+ pw.println();
+ pw.print("mScreenOnSystemTimeSnapshot=");
+ TimeUtils.formatDuration(mScreenOnSystemTimeSnapshot, pw);
+ pw.println();
}
}
@@ -916,6 +967,14 @@ public class UsageStatsService extends SystemService implements
setAppIdleParoled(false);
break;
+ case MSG_REPORT_CONTENT_PROVIDER_USAGE:
+ SomeArgs args = (SomeArgs) msg.obj;
+ reportContentProviderUsage((String) args.arg1, // authority name
+ (String) args.arg2, // package name
+ (int) args.arg3); // userId
+ args.recycle();
+ break;
+
default:
super.handleMessage(msg);
break;
@@ -1177,6 +1236,16 @@ public class UsageStatsService extends SystemService implements
}
@Override
+ public void reportContentProviderUsage(String name, String packageName, int userId) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = name;
+ args.arg2 = packageName;
+ args.arg3 = userId;
+ mHandler.obtainMessage(MSG_REPORT_CONTENT_PROVIDER_USAGE, args)
+ .sendToTarget();
+ }
+
+ @Override
public boolean isAppIdle(String packageName, int userId) {
return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index fafe44a..b68abab 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -26,6 +26,7 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
@@ -57,6 +58,7 @@ import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.UiThread;
@@ -83,6 +85,21 @@ public class VoiceInteractionManagerService extends SystemService {
mDbHelper = new DatabaseHelper(context);
mSoundTriggerHelper = new SoundTriggerHelper(context);
mServiceStub = new VoiceInteractionManagerServiceStub();
+
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ packageManagerInternal.setVoiceInteractionPackagesProvider(
+ new PackageManagerInternal.PackagesProvider() {
+ @Override
+ public String[] getPackages(int userId) {
+ mServiceStub.initForUser(userId);
+ ComponentName interactor = mServiceStub.getCurInteractor(userId);
+ if (interactor != null) {
+ return new String[] {interactor.getPackageName()};
+ }
+ return null;
+ }
+ });
}
@Override
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index acd484d..af0ddbe 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -139,7 +139,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
IVoiceInteractionSessionShowCallback showCallback) {
if (mActiveSession == null) {
mActiveSession = new VoiceInteractionSessionConnection(mLock, mSessionComponentName,
- mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid);
+ mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid, mHandler);
}
return mActiveSession.showLocked(args, flags, showCallback);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 47a230a..cc6a9c5 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -32,6 +32,7 @@ import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -48,6 +49,8 @@ import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.IResultReceiver;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -63,6 +66,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
final Context mContext;
final Callback mCallback;
final int mCallingUid;
+ final Handler mHandler;
final IActivityManager mAm;
final IWindowManager mIWindowManager;
final AppOpsManager mAppOps;
@@ -141,13 +145,14 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
};
public VoiceInteractionSessionConnection(Object lock, ComponentName component, int user,
- Context context, Callback callback, int callingUid) {
+ Context context, Callback callback, int callingUid, Handler handler) {
mLock = lock;
mSessionComponentName = component;
mUser = user;
mContext = context;
mCallback = callback;
mCallingUid = callingUid;
+ mHandler = handler;
mAm = ActivityManagerNative.getDefault();
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
@@ -193,11 +198,13 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mShowArgs = args;
mShowFlags = flags;
mHaveAssistData = false;
+ boolean needDisclosure = false;
if ((flags& VoiceInteractionSession.SHOW_WITH_ASSIST) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_STRUCTURE, mCallingUid,
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
&& allDataEnabled) {
try {
+ needDisclosure = true;
mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
mAssistReceiver);
} catch (RemoteException e) {
@@ -215,6 +222,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
&& allDataEnabled) {
try {
+ needDisclosure = true;
mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
} catch (RemoteException e) {
}
@@ -225,6 +233,9 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
} else {
mScreenshot = null;
}
+ if (needDisclosure) {
+ mHandler.post(mShowAssistDisclosureRunnable);
+ }
if (mSession != null) {
try {
mSession.show(mShowArgs, mShowFlags, showCallback);
@@ -483,4 +494,15 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
pw.print(prefix); pw.print("mAssistData="); pw.println(mAssistData);
}
}
+
+ private Runnable mShowAssistDisclosureRunnable = new Runnable() {
+ @Override
+ public void run() {
+ StatusBarManagerInternal statusBarInternal = LocalServices.getService(
+ StatusBarManagerInternal.class);
+ if (statusBarInternal != null) {
+ statusBarInternal.showAssistDisclosure();
+ }
+ }
+ };
};