summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/backup/java/com/android/server/backup/Trampoline.java17
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java32
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java432
-rw-r--r--services/core/java/com/android/server/IntentResolver.java97
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java2
-rw-r--r--services/core/java/com/android/server/PersistentDataBlockService.java215
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java288
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java191
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityStack.java11
-rw-r--r--services/core/java/com/android/server/am/ProcessStatsService.java53
-rw-r--r--services/core/java/com/android/server/am/TaskPersister.java6
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java63
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java2
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiLogger.java5
-rw-r--r--services/core/java/com/android/server/location/GpsLocationProvider.java15
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java9
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java15
-rw-r--r--services/core/java/com/android/server/net/IpConfigStore.java6
-rw-r--r--services/core/java/com/android/server/net/NetworkIdentitySet.java13
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsCollection.java99
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsRecorder.java51
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java36
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java11
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java65
-rw-r--r--services/core/java/com/android/server/pm/Settings.java45
-rw-r--r--services/core/java/com/android/server/power/Notifier.java132
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java94
-rw-r--r--services/core/java/com/android/server/trust/TrustAgentWrapper.java29
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java147
-rw-r--r--services/core/java/com/android/server/tv/TvInputHardwareManager.java107
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java16
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java13
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java47
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java6
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java9
36 files changed, 1496 insertions, 885 deletions
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 5d2187f..8bd7132 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -94,7 +94,7 @@ public class Trampoline extends IBackupManager.Stub {
if (userHandle == UserHandle.USER_OWNER) {
synchronized (this) {
- if (makeActive != (mService != null)) {
+ if (makeActive != isBackupServiceActive(userHandle)) {
Slog.i(TAG, "Making backup "
+ (makeActive ? "" : "in") + "active in user " + userHandle);
if (makeActive) {
@@ -113,6 +113,21 @@ public class Trampoline extends IBackupManager.Stub {
}
}
+ /**
+ * Querying activity state of backup service. Calling this method before initialize yields
+ * undefined result.
+ * @param userHandle The user in which the activity state of backup service is queried.
+ * @return true if the service is active.
+ */
+ public boolean isBackupServiceActive(final int userHandle) {
+ if (userHandle == UserHandle.USER_OWNER) {
+ synchronized (this) {
+ return mService != null;
+ }
+ }
+ return false;
+ }
+
// IBackupManager binder API
@Override
public void dataChanged(String packageName) throws RemoteException {
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 8b524dd..831af85 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -75,6 +75,12 @@ class AlarmManagerService extends SystemService {
// warning message. The time duration is in milliseconds.
private static final long LATE_ALARM_THRESHOLD = 10 * 1000;
+ // Minimum futurity of a new alarm
+ private static final long MIN_FUTURITY = 5 * 1000; // 5 seconds, in millis
+
+ // Minimum alarm recurrence interval
+ private static final long MIN_INTERVAL = 60 * 1000; // one minute, in millis
+
private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP;
private static final int RTC_MASK = 1 << RTC;
private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP;
@@ -696,6 +702,15 @@ class AlarmManagerService extends SystemService {
windowLength = AlarmManager.INTERVAL_HOUR;
}
+ // Sanity check the recurrence interval. This will catch people who supply
+ // seconds when the API expects milliseconds.
+ if (interval > 0 && interval < MIN_INTERVAL) {
+ Slog.w(TAG, "Suspiciously short interval " + interval
+ + " millis; expanding to " + (int)(MIN_INTERVAL/1000)
+ + " seconds");
+ interval = MIN_INTERVAL;
+ }
+
if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
throw new IllegalArgumentException("Invalid alarm type " + type);
}
@@ -709,7 +724,11 @@ class AlarmManagerService extends SystemService {
}
final long nowElapsed = SystemClock.elapsedRealtime();
- final long triggerElapsed = convertToElapsed(triggerAtTime, type);
+ final long nominalTrigger = convertToElapsed(triggerAtTime, type);
+ // Try to prevent spamming by making sure we aren't firing alarms in the immediate future
+ final long minTrigger = nowElapsed + MIN_FUTURITY;
+ final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger;
+
final long maxElapsed;
if (windowLength == AlarmManager.WINDOW_EXACT) {
maxElapsed = triggerElapsed;
@@ -1105,7 +1124,7 @@ class AlarmManagerService extends SystemService {
if (DEBUG_ALARM_CLOCK) {
Log.v(TAG, "Found AlarmClockInfo at " +
- formatNextAlarm(getContext(), a.alarmClock) +
+ formatNextAlarm(getContext(), a.alarmClock, userId) +
" for user " + userId);
}
@@ -1143,7 +1162,7 @@ class AlarmManagerService extends SystemService {
if (alarmClock != null) {
if (DEBUG_ALARM_CLOCK) {
Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): " +
- formatNextAlarm(getContext(), alarmClock));
+ formatNextAlarm(getContext(), alarmClock, userId));
}
mNextAlarmClockForUser.put(userId, alarmClock);
} else {
@@ -1185,7 +1204,7 @@ class AlarmManagerService extends SystemService {
AlarmManager.AlarmClockInfo alarmClock = pendingUsers.valueAt(i);
Settings.System.putStringForUser(getContext().getContentResolver(),
Settings.System.NEXT_ALARM_FORMATTED,
- formatNextAlarm(getContext(), alarmClock),
+ formatNextAlarm(getContext(), alarmClock, userId),
userId);
getContext().sendBroadcastAsUser(NEXT_ALARM_CLOCK_CHANGED_INTENT,
@@ -1196,8 +1215,9 @@ class AlarmManagerService extends SystemService {
/**
* Formats an alarm like platform/packages/apps/DeskClock used to.
*/
- private static String formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info) {
- String skeleton = DateFormat.is24HourFormat(context) ? "EHm" : "Ehma";
+ private static String formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info,
+ int userId) {
+ String skeleton = DateFormat.is24HourFormat(context, userId) ? "EHm" : "Ehma";
String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
return (info == null) ? "" :
DateFormat.format(pattern, info.getTriggerTime()).toString();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 6d161a2..c935cbf 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -65,7 +65,6 @@ import android.net.INetworkStatsService;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.LinkProperties.CompareResult;
-import android.net.LinkQualityInfo;
import android.net.MobileDataStateTracker;
import android.net.Network;
import android.net.NetworkAgent;
@@ -256,7 +255,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
private Context mContext;
private int mNetworkPreference;
- private int mActiveDefaultNetwork = TYPE_NONE;
// 0 is full bad, 100 is full good
private int mDefaultInetConditionPublished = 0;
@@ -819,20 +817,85 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- /**
- * Check if UID should be blocked from using the network represented by the given networkType.
- * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type.
- */
- private boolean isNetworkBlocked(int networkType, int uid) {
- return isNetworkWithLinkPropertiesBlocked(getLinkPropertiesForType(networkType), uid);
+ private NetworkState getFilteredNetworkState(int networkType, int uid) {
+ NetworkInfo info = null;
+ LinkProperties lp = null;
+ NetworkCapabilities nc = null;
+ Network network = null;
+
+ if (mLegacyTypeTracker.isTypeSupported(networkType)) {
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ if (nai != null) {
+ synchronized (nai) {
+ info = new NetworkInfo(nai.networkInfo);
+ lp = new LinkProperties(nai.linkProperties);
+ nc = new NetworkCapabilities(nai.networkCapabilities);
+ network = new Network(nai.network);
+ }
+ info.setType(networkType);
+ } else {
+ info = new NetworkInfo(networkType, 0, getNetworkTypeName(networkType), "");
+ info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
+ info.setIsAvailable(true);
+ lp = new LinkProperties();
+ nc = new NetworkCapabilities();
+ network = null;
+ }
+ info = getFilteredNetworkInfo(info, lp, uid);
+ }
+
+ return new NetworkState(info, lp, nc, network);
}
- /**
- * Check if UID should be blocked from using the network represented by the given
- * NetworkAgentInfo.
- */
- private boolean isNetworkBlocked(NetworkAgentInfo nai, int uid) {
- return isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid);
+ private NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
+ if (network == null) {
+ return null;
+ }
+ synchronized (mNetworkForNetId) {
+ return mNetworkForNetId.get(network.netId);
+ }
+ };
+
+ private NetworkState getUnfilteredActiveNetworkState(int uid) {
+ NetworkInfo info = null;
+ LinkProperties lp = null;
+ NetworkCapabilities nc = null;
+ Network network = null;
+
+ NetworkAgentInfo nai = mNetworkForRequestId.get(mDefaultRequest.requestId);
+
+ if (!mLockdownEnabled) {
+ int user = UserHandle.getUserId(uid);
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(user);
+ if (vpn != null && vpn.appliesToUid(uid)) {
+ // getUnderlyingNetworks() returns:
+ // null => the VPN didn't specify anything, so we use the default.
+ // empty array => the VPN explicitly said "no default network".
+ // non-empty array => the VPN specified one or more default networks; we use the
+ // first one.
+ Network[] networks = vpn.getUnderlyingNetworks();
+ if (networks != null) {
+ if (networks.length > 0) {
+ nai = getNetworkAgentInfoForNetwork(networks[0]);
+ } else {
+ nai = null;
+ }
+ }
+ }
+ }
+ }
+
+ if (nai != null) {
+ synchronized (nai) {
+ info = new NetworkInfo(nai.networkInfo);
+ lp = new LinkProperties(nai.linkProperties);
+ nc = new NetworkCapabilities(nai.networkCapabilities);
+ network = new Network(nai.network);
+ }
+ }
+
+ return new NetworkState(info, lp, nc, network);
}
/**
@@ -859,40 +922,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
/**
* Return a filtered {@link NetworkInfo}, potentially marked
* {@link DetailedState#BLOCKED} based on
- * {@link #isNetworkBlocked}.
- * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type.
- */
- private NetworkInfo getFilteredNetworkInfo(int networkType, int uid) {
- NetworkInfo info = getNetworkInfoForType(networkType);
- return getFilteredNetworkInfo(info, networkType, uid);
- }
-
- /*
- * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type.
+ * {@link #isNetworkWithLinkPropertiesBlocked}.
*/
- private NetworkInfo getFilteredNetworkInfo(NetworkInfo info, int networkType, int uid) {
- if (isNetworkBlocked(networkType, uid)) {
- // network is blocked; clone and override state
- info = new NetworkInfo(info);
- info.setDetailedState(DetailedState.BLOCKED, null, null);
- if (VDBG) log("returning Blocked NetworkInfo");
- }
- if (mLockdownTracker != null) {
- info = mLockdownTracker.augmentNetworkInfo(info);
- if (VDBG) log("returning Locked NetworkInfo");
- }
- return info;
- }
-
- private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid) {
- NetworkInfo info = nai.networkInfo;
- if (isNetworkBlocked(nai, uid)) {
+ private NetworkInfo getFilteredNetworkInfo(NetworkInfo info, LinkProperties lp, int uid) {
+ if (info != null && isNetworkWithLinkPropertiesBlocked(lp, uid)) {
// network is blocked; clone and override state
info = new NetworkInfo(info);
info.setDetailedState(DetailedState.BLOCKED, null, null);
if (DBG) log("returning Blocked NetworkInfo");
}
- if (mLockdownTracker != null) {
+ if (info != null && mLockdownTracker != null) {
info = mLockdownTracker.augmentNetworkInfo(info);
if (DBG) log("returning Locked NetworkInfo");
}
@@ -910,7 +949,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
public NetworkInfo getActiveNetworkInfo() {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
- return getNetworkInfo(mActiveDefaultNetwork, uid);
+ NetworkState state = getUnfilteredActiveNetworkState(uid);
+ return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
}
/**
@@ -945,8 +985,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
NetworkInfo provNi = getProvisioningNetworkInfo();
if (provNi == null) {
- final int uid = Binder.getCallingUid();
- provNi = getNetworkInfo(mActiveDefaultNetwork, uid);
+ provNi = getActiveNetworkInfo();
}
if (DBG) log("getProvisioningOrActiveNetworkInfo: X provNi=" + provNi);
return provNi;
@@ -954,62 +993,50 @@ public class ConnectivityService extends IConnectivityManager.Stub
public NetworkInfo getActiveNetworkInfoUnfiltered() {
enforceAccessPermission();
- if (isNetworkTypeValid(mActiveDefaultNetwork)) {
- return getNetworkInfoForType(mActiveDefaultNetwork);
- }
- return null;
+ final int uid = Binder.getCallingUid();
+ NetworkState state = getUnfilteredActiveNetworkState(uid);
+ return state.networkInfo;
}
@Override
public NetworkInfo getActiveNetworkInfoForUid(int uid) {
enforceConnectivityInternalPermission();
- return getNetworkInfo(mActiveDefaultNetwork, uid);
+ NetworkState state = getUnfilteredActiveNetworkState(uid);
+ return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
}
@Override
public NetworkInfo getNetworkInfo(int networkType) {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
- return getNetworkInfo(networkType, uid);
- }
-
- private NetworkInfo getNetworkInfo(int networkType, int uid) {
- NetworkInfo info = null;
- if (isNetworkTypeValid(networkType)) {
- if (getNetworkInfoForType(networkType) != null) {
- info = getFilteredNetworkInfo(networkType, uid);
- }
- }
- return info;
+ NetworkState state = getFilteredNetworkState(networkType, uid);
+ return state.networkInfo;
}
@Override
public NetworkInfo getNetworkInfoForNetwork(Network network) {
enforceAccessPermission();
- if (network == null) return null;
-
final int uid = Binder.getCallingUid();
- NetworkAgentInfo nai = null;
- synchronized (mNetworkForNetId) {
- nai = mNetworkForNetId.get(network.netId);
- }
- if (nai == null) return null;
- synchronized (nai) {
- if (nai.networkInfo == null) return null;
-
- return getFilteredNetworkInfo(nai, uid);
+ NetworkInfo info = null;
+ NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ if (nai != null) {
+ synchronized (nai) {
+ info = new NetworkInfo(nai.networkInfo);
+ info = getFilteredNetworkInfo(info, nai.linkProperties, uid);
+ }
}
+ return info;
}
@Override
public NetworkInfo[] getAllNetworkInfo() {
enforceAccessPermission();
- final int uid = Binder.getCallingUid();
final ArrayList<NetworkInfo> result = Lists.newArrayList();
for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
networkType++) {
- if (getNetworkInfoForType(networkType) != null) {
- result.add(getFilteredNetworkInfo(networkType, uid));
+ NetworkInfo info = getNetworkInfo(networkType);
+ if (info != null) {
+ result.add(info);
}
}
return result.toArray(new NetworkInfo[result.size()]);
@@ -1019,11 +1046,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
public Network getNetworkForType(int networkType) {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
- if (isNetworkBlocked(networkType, uid)) {
- return null;
+ NetworkState state = getFilteredNetworkState(networkType, uid);
+ if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid)) {
+ return state.network;
}
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- return (nai == null) ? null : nai.network;
+ return null;
}
@Override
@@ -1041,7 +1068,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public boolean isNetworkSupported(int networkType) {
enforceAccessPermission();
- return (isNetworkTypeValid(networkType) && (getNetworkInfoForType(networkType) != null));
+ return mLegacyTypeTracker.isTypeSupported(networkType);
}
/**
@@ -1054,14 +1081,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
@Override
public LinkProperties getActiveLinkProperties() {
- return getLinkPropertiesForType(mActiveDefaultNetwork);
+ enforceAccessPermission();
+ final int uid = Binder.getCallingUid();
+ NetworkState state = getUnfilteredActiveNetworkState(uid);
+ return state.linkProperties;
}
@Override
public LinkProperties getLinkPropertiesForType(int networkType) {
enforceAccessPermission();
- if (isNetworkTypeValid(networkType)) {
- return getLinkPropertiesForTypeInternal(networkType);
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ if (nai != null) {
+ synchronized (nai) {
+ return new LinkProperties(nai.linkProperties);
+ }
}
return null;
}
@@ -1070,11 +1103,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public LinkProperties getLinkProperties(Network network) {
enforceAccessPermission();
- NetworkAgentInfo nai = null;
- synchronized (mNetworkForNetId) {
- nai = mNetworkForNetId.get(network.netId);
- }
-
+ NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
synchronized (nai) {
return new LinkProperties(nai.linkProperties);
@@ -1086,10 +1115,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public NetworkCapabilities getNetworkCapabilities(Network network) {
enforceAccessPermission();
- NetworkAgentInfo nai = null;
- synchronized (mNetworkForNetId) {
- nai = mNetworkForNetId.get(network.netId);
- }
+ NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
synchronized (nai) {
return new NetworkCapabilities(nai.networkCapabilities);
@@ -1105,36 +1131,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
final ArrayList<NetworkState> result = Lists.newArrayList();
for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
networkType++) {
- if (getNetworkInfoForType(networkType) != null) {
- final NetworkInfo info = getFilteredNetworkInfo(networkType, uid);
- final LinkProperties lp = getLinkPropertiesForTypeInternal(networkType);
- final NetworkCapabilities netcap = getNetworkCapabilitiesForType(networkType);
- result.add(new NetworkState(info, lp, netcap));
+ NetworkState state = getFilteredNetworkState(networkType, uid);
+ if (state.networkInfo != null) {
+ result.add(state);
}
}
return result.toArray(new NetworkState[result.size()]);
}
- private NetworkState getNetworkStateUnchecked(int networkType) {
- if (isNetworkTypeValid(networkType)) {
- NetworkInfo info = getNetworkInfoForType(networkType);
- if (info != null) {
- return new NetworkState(info,
- getLinkPropertiesForTypeInternal(networkType),
- getNetworkCapabilitiesForType(networkType));
- }
- }
- return null;
- }
-
@Override
public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
enforceAccessPermission();
-
+ final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
- final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
- if (state != null) {
+ final NetworkState state = getUnfilteredActiveNetworkState(uid);
+ if (state.networkInfo != null) {
try {
return mPolicyManager.getNetworkQuotaInfo(state);
} catch (RemoteException e) {
@@ -1149,17 +1161,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public boolean isActiveNetworkMetered() {
enforceAccessPermission();
+ final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
- return isNetworkMeteredUnchecked(mActiveDefaultNetwork);
+ return isActiveNetworkMeteredUnchecked(uid);
} finally {
Binder.restoreCallingIdentity(token);
}
}
- private boolean isNetworkMeteredUnchecked(int networkType) {
- final NetworkState state = getNetworkStateUnchecked(networkType);
- if (state != null) {
+ private boolean isActiveNetworkMeteredUnchecked(int uid) {
+ final NetworkState state = getUnfilteredActiveNetworkState(uid);
+ if (state.networkInfo != null) {
try {
return mPolicyManager.isNetworkMetered(state);
} catch (RemoteException e) {
@@ -1330,16 +1343,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
// kick off connectivity change broadcast for active network, since
// global background policy change is radical.
- final int networkType = mActiveDefaultNetwork;
- if (isNetworkTypeValid(networkType)) {
- final NetworkStateTracker tracker = mNetTrackers[networkType];
- if (tracker != null) {
- final NetworkInfo info = tracker.getNetworkInfo();
- if (info != null && info.isConnected()) {
- sendConnectedBroadcast(info);
- }
- }
- }
+ // TODO: Dead code; remove.
+ //
+ // final int networkType = mActiveDefaultNetwork;
+ // if (isNetworkTypeValid(networkType)) {
+ // final NetworkStateTracker tracker = mNetTrackers[networkType];
+ // if (tracker != null) {
+ // final NetworkInfo info = tracker.getNetworkInfo();
+ // if (info != null && info.isConnected()) {
+ // sendConnectedBroadcast(info);
+ // }
+ // }
+ // }
}
};
@@ -1766,16 +1781,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
pw.println();
pw.decreaseIndent();
- pw.print("mActiveDefaultNetwork: " + mActiveDefaultNetwork);
- if (mActiveDefaultNetwork != TYPE_NONE) {
- NetworkInfo activeNetworkInfo = getActiveNetworkInfo();
- if (activeNetworkInfo != null) {
- pw.print(" " + activeNetworkInfo.getState() +
- "/" + activeNetworkInfo.getDetailedState());
- }
- }
- pw.println();
-
pw.println("mLegacyTypeTracker:");
pw.increaseIndent();
mLegacyTypeTracker.dump(pw);
@@ -1804,10 +1809,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) {
if (nai.network == null) return false;
- final NetworkAgentInfo officialNai;
- synchronized (mNetworkForNetId) {
- officialNai = mNetworkForNetId.get(nai.network.netId);
- }
+ final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network);
if (officialNai != null && officialNai.equals(nai)) return true;
if (officialNai != null || VDBG) {
loge(msg + " - isLiveNetworkAgent found mismatched netId: " + officialNai +
@@ -2003,7 +2005,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
* to the link that may have incorrectly setup by the lower
* levels.
*/
- LinkProperties lp = getLinkPropertiesForTypeInternal(info.getType());
+ LinkProperties lp = getLinkPropertiesForType(info.getType());
if (DBG) {
log("EVENT_STATE_CHANGED: connected to provisioning network, lp=" + lp);
}
@@ -2145,7 +2147,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
removeDataActivityTracking(nai);
- mActiveDefaultNetwork = ConnectivityManager.TYPE_NONE;
notifyLockdownVpn(nai);
requestNetworkTransitionWakelock(nai.name());
}
@@ -2556,10 +2557,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (network == null) return;
final int uid = Binder.getCallingUid();
- NetworkAgentInfo nai = null;
- synchronized (mNetworkForNetId) {
- nai = mNetworkForNetId.get(network.netId);
- }
+ NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai == null) return;
if (DBG) log("reportBadNetwork(" + nai.name() + ") by " + uid);
synchronized (nai) {
@@ -2567,7 +2565,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// which isn't meant to work on uncreated networks.
if (!nai.created) return;
- if (isNetworkBlocked(nai, uid)) return;
+ if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid)) return;
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid);
}
@@ -2598,7 +2596,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
String exclList = "";
String pacFileUrl = "";
if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) ||
- (proxyProperties.getPacFileUrl() != null))) {
+ !Uri.EMPTY.equals(proxyProperties.getPacFileUrl()))) {
if (!proxyProperties.isValid()) {
if (DBG)
log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
@@ -2608,7 +2606,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
host = mGlobalProxy.getHost();
port = mGlobalProxy.getPort();
exclList = mGlobalProxy.getExclusionListAsString();
- if (proxyProperties.getPacFileUrl() != null) {
+ if (!Uri.EMPTY.equals(proxyProperties.getPacFileUrl())) {
pacFileUrl = proxyProperties.getPacFileUrl().toString();
}
} else {
@@ -2670,7 +2668,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void handleApplyDefaultProxy(ProxyInfo proxy) {
if (proxy != null && TextUtils.isEmpty(proxy.getHost())
- && (proxy.getPacFileUrl() == null)) {
+ && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
proxy = null;
}
synchronized (mProxyLock) {
@@ -2686,7 +2684,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// global (to get the correct local port), and send a broadcast.
// TODO: Switch PacManager to have its own message to send back rather than
// reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
- if ((mGlobalProxy != null) && (proxy != null) && (proxy.getPacFileUrl() != null)
+ if ((mGlobalProxy != null) && (proxy != null)
+ && (!Uri.EMPTY.equals(proxy.getPacFileUrl()))
&& proxy.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
mGlobalProxy = proxy;
sendProxyBroadcast(mGlobalProxy);
@@ -2769,42 +2768,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
Slog.e(TAG, s);
}
- int convertFeatureToNetworkType(int networkType, String feature) {
- int usedNetworkType = networkType;
-
- if(networkType == ConnectivityManager.TYPE_MOBILE) {
- if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
- TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_FOTA;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_IMS;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_CBS;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_EMERGENCY)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_EMERGENCY;
- } else {
- Slog.e(TAG, "Can't match any mobile netTracker!");
- }
- } else if (networkType == ConnectivityManager.TYPE_WIFI) {
- if (TextUtils.equals(feature, "p2p")) {
- usedNetworkType = ConnectivityManager.TYPE_WIFI_P2P;
- } else {
- Slog.e(TAG, "Can't match any wifi netTracker!");
- }
- } else {
- Slog.e(TAG, "Unexpected network type");
- }
- return usedNetworkType;
- }
-
private static <T> T checkNotNull(T value, String message) {
if (value == null) {
throw new NullPointerException(message);
@@ -3290,43 +3253,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
};
- @Override
- public LinkQualityInfo getLinkQualityInfo(int networkType) {
- enforceAccessPermission();
- if (isNetworkTypeValid(networkType) && mNetTrackers[networkType] != null) {
- return mNetTrackers[networkType].getLinkQualityInfo();
- } else {
- return null;
- }
- }
-
- @Override
- public LinkQualityInfo getActiveLinkQualityInfo() {
- enforceAccessPermission();
- if (isNetworkTypeValid(mActiveDefaultNetwork) &&
- mNetTrackers[mActiveDefaultNetwork] != null) {
- return mNetTrackers[mActiveDefaultNetwork].getLinkQualityInfo();
- } else {
- return null;
- }
- }
-
- @Override
- public LinkQualityInfo[] getAllLinkQualityInfo() {
- enforceAccessPermission();
- final ArrayList<LinkQualityInfo> result = Lists.newArrayList();
- for (NetworkStateTracker tracker : mNetTrackers) {
- if (tracker != null) {
- LinkQualityInfo li = tracker.getLinkQualityInfo();
- if (li != null) {
- result.add(li);
- }
- }
- }
-
- return result.toArray(new LinkQualityInfo[result.size()]);
- }
-
/* Infrastructure for network sampling */
private void handleNetworkSamplingTimeout() {
@@ -3842,9 +3768,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
int notificationType) {
if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE) {
Intent intent = new Intent();
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST_NETWORK, nri.request);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST_NETWORK_REQUEST,
- networkAgent.network);
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nri.request);
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, networkAgent.network);
sendIntent(nri.mPendingIntent, intent);
}
// else not handled
@@ -3934,7 +3859,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void makeDefault(NetworkAgentInfo newNetwork) {
if (DBG) log("Switching to new default network: " + newNetwork);
- mActiveDefaultNetwork = newNetwork.networkInfo.getType();
setupDataActivityTracking(newNetwork);
try {
mNetd.setDefaultNetId(newNetwork.network.netId);
@@ -3976,7 +3900,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// another higher scoring network by another call to rematchNetworkAndRequests()
// and this other call also lingered newNetwork.
private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, boolean nascent) {
- if (!newNetwork.created) loge("ERROR: uncreated network being rematched.");
+ if (!newNetwork.created) return;
if (nascent && !newNetwork.validated) loge("ERROR: nascent network not validated.");
boolean keep = newNetwork.isVPN();
boolean isNewDefault = false;
@@ -4039,7 +3963,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (mDefaultRequest.requestId == nri.request.requestId) {
isNewDefault = true;
// TODO: Remove following line. It's redundant with makeDefault call.
- mActiveDefaultNetwork = newNetwork.networkInfo.getType();
if (newNetwork.linkProperties != null) {
updateTcpBufferSizes(newNetwork);
setDefaultDnsSystemProperties(
@@ -4275,7 +4198,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final int oldScore = nai.getCurrentScore();
nai.setCurrentScore(score);
- if (nai.created) rematchAllNetworksAndRequests(nai, oldScore);
+ rematchAllNetworksAndRequests(nai, oldScore);
sendUpdatedScoreToFactories(nai);
}
@@ -4374,44 +4297,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
return "UNKNOWN";
}
- private LinkProperties getLinkPropertiesForTypeInternal(int networkType) {
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai != null) {
- synchronized (nai) {
- return new LinkProperties(nai.linkProperties);
- }
- }
- return new LinkProperties();
- }
-
- private NetworkInfo getNetworkInfoForType(int networkType) {
- if (!mLegacyTypeTracker.isTypeSupported(networkType))
- return null;
-
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai != null) {
- NetworkInfo result = new NetworkInfo(nai.networkInfo);
- result.setType(networkType);
- return result;
- } else {
- NetworkInfo result = new NetworkInfo(
- networkType, 0, ConnectivityManager.getNetworkTypeName(networkType), "");
- result.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
- result.setIsAvailable(true);
- return result;
- }
- }
-
- private NetworkCapabilities getNetworkCapabilitiesForType(int networkType) {
- NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- if (nai != null) {
- synchronized (nai) {
- return new NetworkCapabilities(nai.networkCapabilities);
- }
- }
- return new NetworkCapabilities();
- }
-
@Override
public boolean addVpnAddress(String address, int prefixLength) {
throwIfLockdownEnabled();
@@ -4429,4 +4314,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
return mVpns.get(user).removeAddress(address, prefixLength);
}
}
+
+ @Override
+ public boolean setUnderlyingNetworksForVpn(Network[] networks) {
+ throwIfLockdownEnabled();
+ int user = UserHandle.getUserId(Binder.getCallingUid());
+ synchronized (mVpns) {
+ return mVpns.get(user).setUnderlyingNetworks(networks);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index 387eabc..cea1ebe 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -23,7 +23,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import android.net.Uri;
@@ -31,6 +30,7 @@ import android.util.FastImmutableArraySet;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
+import android.util.MutableInt;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.LogPrinter;
@@ -213,36 +213,65 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
}
boolean dumpMap(PrintWriter out, String titlePrefix, String title,
- String prefix, Map<String, F[]> map, String packageName,
- boolean printFilter) {
- String eprefix = prefix + " ";
- String fprefix = prefix + " ";
+ String prefix, ArrayMap<String, F[]> map, String packageName,
+ boolean printFilter, boolean collapseDuplicates) {
+ final String eprefix = prefix + " ";
+ final String fprefix = prefix + " ";
+ final ArrayMap<Object, MutableInt> found = new ArrayMap<>();
boolean printedSomething = false;
Printer printer = null;
- for (Map.Entry<String, F[]> e : map.entrySet()) {
- F[] a = e.getValue();
+ for (int mapi=0; mapi<map.size(); mapi++) {
+ F[] a = map.valueAt(mapi);
final int N = a.length;
boolean printedHeader = false;
F filter;
- for (int i=0; i<N && (filter=a[i]) != null; i++) {
- if (packageName != null && !isPackageForFilter(packageName, filter)) {
- continue;
- }
- if (title != null) {
- out.print(titlePrefix); out.println(title);
- title = null;
+ if (collapseDuplicates) {
+ found.clear();
+ for (int i=0; i<N && (filter=a[i]) != null; i++) {
+ if (packageName != null && !isPackageForFilter(packageName, filter)) {
+ continue;
+ }
+ Object label = filterToLabel(filter);
+ int index = found.indexOfKey(label);
+ if (index < 0) {
+ found.put(label, new MutableInt(1));
+ } else {
+ found.valueAt(index).value++;
+ }
}
- if (!printedHeader) {
- out.print(eprefix); out.print(e.getKey()); out.println(":");
- printedHeader = true;
+ for (int i=0; i<found.size(); i++) {
+ if (title != null) {
+ out.print(titlePrefix); out.println(title);
+ title = null;
+ }
+ if (!printedHeader) {
+ out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":");
+ printedHeader = true;
+ }
+ printedSomething = true;
+ dumpFilterLabel(out, fprefix, found.keyAt(i), found.valueAt(i).value);
}
- printedSomething = true;
- dumpFilter(out, fprefix, filter);
- if (printFilter) {
- if (printer == null) {
- printer = new PrintWriterPrinter(out);
+ } else {
+ for (int i=0; i<N && (filter=a[i]) != null; i++) {
+ if (packageName != null && !isPackageForFilter(packageName, filter)) {
+ continue;
+ }
+ if (title != null) {
+ out.print(titlePrefix); out.println(title);
+ title = null;
+ }
+ if (!printedHeader) {
+ out.print(eprefix); out.print(map.keyAt(mapi)); out.println(":");
+ printedHeader = true;
+ }
+ printedSomething = true;
+ dumpFilter(out, fprefix, filter);
+ if (printFilter) {
+ if (printer == null) {
+ printer = new PrintWriterPrinter(out);
+ }
+ filter.dump(printer, fprefix + " ");
}
- filter.dump(printer, fprefix + " ");
}
}
}
@@ -250,32 +279,32 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
}
public boolean dump(PrintWriter out, String title, String prefix, String packageName,
- boolean printFilter) {
+ boolean printFilter, boolean collapseDuplicates) {
String innerPrefix = prefix + " ";
String sepPrefix = "\n" + prefix;
String curPrefix = title + "\n" + prefix;
if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix,
- mTypeToFilter, packageName, printFilter)) {
+ mTypeToFilter, packageName, printFilter, collapseDuplicates)) {
curPrefix = sepPrefix;
}
if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix,
- mBaseTypeToFilter, packageName, printFilter)) {
+ mBaseTypeToFilter, packageName, printFilter, collapseDuplicates)) {
curPrefix = sepPrefix;
}
if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix,
- mWildTypeToFilter, packageName, printFilter)) {
+ mWildTypeToFilter, packageName, printFilter, collapseDuplicates)) {
curPrefix = sepPrefix;
}
if (dumpMap(out, curPrefix, "Schemes:", innerPrefix,
- mSchemeToFilter, packageName, printFilter)) {
+ mSchemeToFilter, packageName, printFilter, collapseDuplicates)) {
curPrefix = sepPrefix;
}
if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix,
- mActionToFilter, packageName, printFilter)) {
+ mActionToFilter, packageName, printFilter, collapseDuplicates)) {
curPrefix = sepPrefix;
}
if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix,
- mTypedActionToFilter, packageName, printFilter)) {
+ mTypedActionToFilter, packageName, printFilter, collapseDuplicates)) {
curPrefix = sepPrefix;
}
return curPrefix == sepPrefix;
@@ -479,6 +508,14 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
out.print(prefix); out.println(filter);
}
+ protected Object filterToLabel(F filter) {
+ return "IntentFilter";
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ out.print(prefix); out.print(label); out.print(": "); out.println(count);
+ }
+
private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) {
F[] array = map.get(name);
if (array == null) {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 0f033d7..5fe0d1c 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -239,7 +239,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mDaemonHandler = new Handler(FgThread.get().getLooper());
- mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUB_ID,
+ mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
mDaemonHandler.getLooper()) {
@Override
public void onDataConnectionRealTimeInfoChanged(
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index de90aa2..17edb53 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -41,6 +41,9 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
/**
* Service for reading and writing blocks to a persistent partition.
@@ -63,22 +66,16 @@ public class PersistentDataBlockService extends SystemService {
private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
private static final int HEADER_SIZE = 8;
// Magic number to mark block device as adhering to the format consumed by this service
- private static final int PARTITION_TYPE_MARKER = 0x1990;
+ private static final int PARTITION_TYPE_MARKER = 0x19901873;
// Limit to 100k as blocks larger than this might cause strain on Binder.
- // TODO(anmorales): Consider splitting up too-large blocks in PersistentDataBlockManager
private static final int MAX_DATA_BLOCK_SIZE = 1024 * 100;
+ public static final int DIGEST_SIZE_BYTES = 32;
private final Context mContext;
private final String mDataBlockFile;
private final Object mLock = new Object();
private int mAllowedUid = -1;
- /*
- * Separate lock for OEM unlock related operations as they can happen in parallel with regular
- * block operations.
- */
- private final Object mOemLock = new Object();
-
private long mBlockDeviceSize;
public PersistentDataBlockService(Context context) {
@@ -89,7 +86,6 @@ public class PersistentDataBlockService extends SystemService {
mAllowedUid = getAllowedUid(UserHandle.USER_OWNER);
}
-
private int getAllowedUid(int userHandle) {
String allowedPackage = mContext.getResources()
.getString(R.string.config_persistentDataPackageName);
@@ -106,6 +102,7 @@ public class PersistentDataBlockService extends SystemService {
@Override
public void onStart() {
+ enforceChecksumValidity();
publishBinderService(Context.PERSISTENT_DATA_BLOCK_SERVICE, mService);
}
@@ -128,6 +125,9 @@ public class PersistentDataBlockService extends SystemService {
}
private int getTotalDataSizeLocked(DataInputStream inputStream) throws IOException {
+ // skip over checksum
+ inputStream.skipBytes(DIGEST_SIZE_BYTES);
+
int totalDataSize;
int blockId = inputStream.readInt();
if (blockId == PARTITION_TYPE_MARKER) {
@@ -148,6 +148,143 @@ public class PersistentDataBlockService extends SystemService {
return mBlockDeviceSize;
}
+ private boolean enforceChecksumValidity() {
+ byte[] storedDigest = new byte[DIGEST_SIZE_BYTES];
+
+ synchronized (mLock) {
+ byte[] digest = computeDigestLocked(storedDigest);
+ if (digest == null || !Arrays.equals(storedDigest, digest)) {
+ Slog.i(TAG, "Formatting FRP partition...");
+ formatPartitionLocked();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean computeAndWriteDigestLocked() {
+ byte[] digest = computeDigestLocked(null);
+ if (digest != null) {
+ DataOutputStream outputStream;
+ try {
+ outputStream = new DataOutputStream(
+ new FileOutputStream(new File(mDataBlockFile)));
+ } catch (FileNotFoundException e) {
+ Slog.e(TAG, "partition not available?", e);
+ return false;
+ }
+
+ try {
+ outputStream.write(digest, 0, DIGEST_SIZE_BYTES);
+ outputStream.flush();
+ } catch (IOException e) {
+ Slog.e(TAG, "failed to write block checksum", e);
+ return false;
+ } finally {
+ IoUtils.closeQuietly(outputStream);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private byte[] computeDigestLocked(byte[] storedDigest) {
+ DataInputStream inputStream;
+ try {
+ inputStream = new DataInputStream(new FileInputStream(new File(mDataBlockFile)));
+ } catch (FileNotFoundException e) {
+ Slog.e(TAG, "partition not available?", e);
+ return null;
+ }
+
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("SHA-256");
+ } catch (NoSuchAlgorithmException e) {
+ // won't ever happen -- every implementation is required to support SHA-256
+ Slog.e(TAG, "SHA-256 not supported?", e);
+ IoUtils.closeQuietly(inputStream);
+ return null;
+ }
+
+ try {
+ if (storedDigest != null && storedDigest.length == DIGEST_SIZE_BYTES) {
+ inputStream.read(storedDigest);
+ } else {
+ inputStream.skipBytes(DIGEST_SIZE_BYTES);
+ }
+
+ int read;
+ byte[] data = new byte[1024];
+ md.update(data, 0, DIGEST_SIZE_BYTES); // include 0 checksum in digest
+ while ((read = inputStream.read(data)) != -1) {
+ md.update(data, 0, read);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "failed to read partition", e);
+ return null;
+ } finally {
+ IoUtils.closeQuietly(inputStream);
+ }
+
+ return md.digest();
+ }
+
+ private void formatPartitionLocked() {
+ DataOutputStream outputStream;
+ try {
+ outputStream = new DataOutputStream(new FileOutputStream(new File(mDataBlockFile)));
+ } catch (FileNotFoundException e) {
+ Slog.e(TAG, "partition not available?", e);
+ return;
+ }
+
+ byte[] data = new byte[DIGEST_SIZE_BYTES];
+ try {
+ outputStream.write(data, 0, DIGEST_SIZE_BYTES);
+ outputStream.writeInt(PARTITION_TYPE_MARKER);
+ outputStream.writeInt(0); // data size
+ outputStream.flush();
+ } catch (IOException e) {
+ Slog.e(TAG, "failed to format block", e);
+ return;
+ } finally {
+ IoUtils.closeQuietly(outputStream);
+ }
+
+ doSetOemUnlockEnabledLocked(false);
+ computeAndWriteDigestLocked();
+ }
+
+ private void doSetOemUnlockEnabledLocked(boolean enabled) {
+ FileOutputStream outputStream;
+ try {
+ outputStream = new FileOutputStream(new File(mDataBlockFile));
+ } catch (FileNotFoundException e) {
+ Slog.e(TAG, "partition not available", e);
+ return;
+ }
+
+ try {
+ FileChannel channel = outputStream.getChannel();
+
+ channel.position(getBlockDeviceSize() - 1);
+
+ ByteBuffer data = ByteBuffer.allocate(1);
+ data.put(enabled ? (byte) 1 : (byte) 0);
+ data.flip();
+ channel.write(data);
+ outputStream.flush();
+ } catch (IOException e) {
+ Slog.e(TAG, "unable to access persistent partition", e);
+ return;
+ } finally {
+ IoUtils.closeQuietly(outputStream);
+ }
+ }
+
private native long nativeGetBlockDeviceSize(String path);
private native int nativeWipe(String path);
@@ -176,19 +313,23 @@ public class PersistentDataBlockService extends SystemService {
headerAndData.putInt(data.length);
headerAndData.put(data);
- try {
- synchronized (mLock) {
- outputStream.write(headerAndData.array());
- return data.length;
- }
- } catch (IOException e) {
- Slog.e(TAG, "failed writing to the persistent data block", e);
- return -1;
- } finally {
+ synchronized (mLock) {
try {
- outputStream.close();
+ byte[] checksum = new byte[DIGEST_SIZE_BYTES];
+ outputStream.write(checksum, 0, DIGEST_SIZE_BYTES);
+ outputStream.write(headerAndData.array());
+ outputStream.flush();
} catch (IOException e) {
- Slog.e(TAG, "failed closing output stream", e);
+ Slog.e(TAG, "failed writing to the persistent data block", e);
+ return -1;
+ } finally {
+ IoUtils.closeQuietly(outputStream);
+ }
+
+ if (computeAndWriteDigestLocked()) {
+ return data.length;
+ } else {
+ return -1;
}
}
}
@@ -196,6 +337,9 @@ public class PersistentDataBlockService extends SystemService {
@Override
public byte[] read() {
enforceUid(Binder.getCallingUid());
+ if (!enforceChecksumValidity()) {
+ return new byte[0];
+ }
DataInputStream inputStream;
try {
@@ -256,30 +400,10 @@ public class PersistentDataBlockService extends SystemService {
}
enforceOemUnlockPermission();
enforceIsOwner();
- FileOutputStream outputStream;
- try {
- outputStream = new FileOutputStream(new File(mDataBlockFile));
- } catch (FileNotFoundException e) {
- Slog.e(TAG, "parition not available", e);
- return;
- }
-
- try {
- FileChannel channel = outputStream.getChannel();
- channel.position(getBlockDeviceSize() - 1);
-
- ByteBuffer data = ByteBuffer.allocate(1);
- data.put(enabled ? (byte) 1 : (byte) 0);
- data.flip();
-
- synchronized (mOemLock) {
- channel.write(data);
- }
- } catch (IOException e) {
- Slog.e(TAG, "unable to access persistent partition", e);
- } finally {
- IoUtils.closeQuietly(outputStream);
+ synchronized (mLock) {
+ doSetOemUnlockEnabledLocked(enabled);
+ computeAndWriteDigestLocked();
}
}
@@ -295,8 +419,8 @@ public class PersistentDataBlockService extends SystemService {
}
try {
- inputStream.skip(getBlockDeviceSize() - 1);
- synchronized (mOemLock) {
+ synchronized (mLock) {
+ inputStream.skip(getBlockDeviceSize() - 1);
return inputStream.readByte() != 0;
}
} catch (IOException e) {
@@ -336,6 +460,5 @@ public class PersistentDataBlockService extends SystemService {
long actualSize = getBlockDeviceSize() - HEADER_SIZE - 1;
return actualSize <= MAX_DATA_BLOCK_SIZE ? actualSize : MAX_DATA_BLOCK_SIZE;
}
-
};
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 2ed021a..34da901 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -34,8 +34,6 @@ import android.os.UserHandle;
import android.telephony.CellLocation;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.Rlog;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionListener;
import android.telephony.TelephonyManager;
import android.telephony.SubscriptionManager;
import android.telephony.PhoneStateListener;
@@ -43,7 +41,6 @@ import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.CellInfo;
import android.telephony.VoLteServiceState;
-import android.telephony.TelephonyManager;
import android.telephony.DisconnectCause;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
@@ -52,13 +49,12 @@ import android.text.TextUtils;
import android.text.format.Time;
import java.util.ArrayList;
-import java.util.Calendar;
import java.util.List;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.ISubscriptionListener;
+import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.DefaultPhoneNotifier;
@@ -93,28 +89,29 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
IBinder binder;
IPhoneStateListener callback;
- ISubscriptionListener subscriptionListenerCallback;
+ IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
int callerUid;
int events;
- int subId = SubscriptionManager.INVALID_SUB_ID;
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- int phoneId = SubscriptionManager.INVALID_PHONE_ID;
+ int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
boolean matchPhoneStateListenerEvent(int events) {
return (callback != null) && ((events & this.events) != 0);
}
- boolean matchSubscriptionListenerEvent(int events) {
- return (subscriptionListenerCallback != null) && ((events & this.events) != 0);
+ boolean matchOnSubscriptionsChangedListener() {
+ return (onSubscriptionsChangedListenerCallback != null);
}
@Override
public String toString() {
return "{pkgForDebug=" + pkgForDebug + " binder=" + binder + " callback=" + callback
- + " subscriptionListenererCallback=" + subscriptionListenerCallback
+ + " onSubscriptionsChangedListenererCallback="
+ + onSubscriptionsChangedListenerCallback
+ " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
+ " events=" + Integer.toHexString(events) + "}";
}
@@ -128,6 +125,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private final IBatteryStats mBatteryStats;
+ private boolean hasNotifySubscriptionInfoChangedOccurred = false;
+
private int mNumPhones;
private int[] mCallState;
@@ -168,9 +167,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private VoLteServiceState mVoLteServiceState = new VoLteServiceState();
- private int mDefaultSubId = SubscriptionManager.INVALID_SUB_ID;
+ private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_ID;
+ private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo();
@@ -227,7 +226,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
//possible missed notify callback
synchronized (mRecords) {
for (Record r : mRecords) {
- if(r.subId == SubscriptionManager.DEFAULT_SUB_ID) {
+ if(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
checkPossibleMissNotify(r, newDefaultPhoneId);
}
}
@@ -339,90 +338,89 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
@Override
- public void registerSubscriptionListener(String pkgForDebug, ISubscriptionListener callback,
- int events) {
+ public void registerOnSubscriptionsChangedListener(String pkgForDebug,
+ IOnSubscriptionsChangedListener callback) {
int callerUid = UserHandle.getCallingUserId();
int myUid = UserHandle.myUserId();
if (VDBG) {
- log("listen sl: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
- + " myUid=" + myUid + " callerUid=" + callerUid + " callback=" + callback
+ log("listen oscl: E pkg=" + pkgForDebug + " myUid=" + myUid
+ + " callerUid=" + callerUid + " callback=" + callback
+ " callback.asBinder=" + callback.asBinder());
}
- if (events != 0) {
- /* Checks permission and throws Security exception */
- checkSubscriptionListenerPermission(events);
- Record r = null;
+ /* Checks permission and throws Security exception */
+ checkOnSubscriptionsChangedListenerPermission();
+ Record r = null;
- synchronized (mRecords) {
- // register
- find_and_add: {
- IBinder b = callback.asBinder();
- final int N = mRecords.size();
- for (int i = 0; i < N; i++) {
- r = mRecords.get(i);
- if (b == r.binder) {
- break find_and_add;
- }
+ synchronized (mRecords) {
+ // register
+ find_and_add: {
+ IBinder b = callback.asBinder();
+ final int N = mRecords.size();
+ for (int i = 0; i < N; i++) {
+ r = mRecords.get(i);
+ if (b == r.binder) {
+ break find_and_add;
}
- r = new Record();
- r.binder = b;
- mRecords.add(r);
- if (DBG) log("listen sl: add new record");
- }
-
- r.subscriptionListenerCallback = callback;
- r.pkgForDebug = pkgForDebug;
- r.callerUid = callerUid;
- r.events = events;
- if (DBG) {
- log("listen sl: Register r=" + r);
}
+ r = new Record();
+ r.binder = b;
+ mRecords.add(r);
+ if (DBG) log("listen oscl: add new record");
}
- // Always notify when a listen is established.
- if (r.matchSubscriptionListenerEvent(
- SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) {
+ r.onSubscriptionsChangedListenerCallback = callback;
+ r.pkgForDebug = pkgForDebug;
+ r.callerUid = callerUid;
+ r.events = 0;
+ if (DBG) {
+ log("listen oscl: Register r=" + r);
+ }
+ // Always notify when registration occurs if there has been a notification.
+ if (hasNotifySubscriptionInfoChangedOccurred) {
try {
- if (VDBG) log("listen sl: send to r=" + r);
- r.subscriptionListenerCallback.onSubscriptionInfoChanged();
- if (VDBG) log("listen sl: sent to r=" + r);
+ if (VDBG) log("listen oscl: send to r=" + r);
+ r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
+ if (VDBG) log("listen oscl: sent to r=" + r);
} catch (RemoteException e) {
- if (VDBG) log("listen sl: remote exception sending to r=" + r + " e=" + e);
+ if (VDBG) log("listen oscl: remote exception sending to r=" + r + " e=" + e);
remove(r.binder);
}
+ } else {
+ log("listen oscl: hasNotifySubscriptionInfoChangedOccurred==false no callback");
}
- } else {
- if (DBG) log("listen sl: Unregister as event is LISTEN_NONE");
- unregisterSubscriptionListener(pkgForDebug, callback);
}
}
@Override
- public void unregisterSubscriptionListener(String pkgForDebug, ISubscriptionListener callback) {
- if (DBG) log("listen sl: Unregister as event is LISTEN_NONE");
+ public void unregisterOnSubscriptionsChangedListener(String pkgForDebug,
+ IOnSubscriptionsChangedListener callback) {
+ if (DBG) log("listen oscl: Unregister");
remove(callback.asBinder());
}
- private void checkSubscriptionListenerPermission(int events) {
- if ((events & SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED) != 0) {
- mContext.enforceCallingOrSelfPermission(
- SubscriptionListener.PERMISSION_LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED, null);
- }
+ private void checkOnSubscriptionsChangedListenerPermission() {
+ mContext.enforceCallingOrSelfPermission(
+ SubscriptionManager.OnSubscriptionsChangedListener
+ .PERMISSION_ON_SUBSCRIPTIONS_CHANGED, null);
}
@Override
public void notifySubscriptionInfoChanged() {
if (VDBG) log("notifySubscriptionInfoChanged:");
synchronized (mRecords) {
+ if (!hasNotifySubscriptionInfoChangedOccurred) {
+ log("notifySubscriptionInfoChanged: first invocation mRecords.size="
+ + mRecords.size());
+ }
+ hasNotifySubscriptionInfoChangedOccurred = true;
mRemoveList.clear();
for (Record r : mRecords) {
- if (r.matchSubscriptionListenerEvent(
- SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) {
+ if (r.matchOnSubscriptionsChangedListener()) {
try {
- if (VDBG) log("notifySubscriptionInfoChanged: send to r=" + r);
- r.subscriptionListenerCallback.onSubscriptionInfoChanged();
- if (VDBG) log("notifySubscriptionInfoChanged: sent to r=" + r);
+ if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r);
+ r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
+ if (VDBG) log("notifySubscriptionInfoChanged: done osc to r=" + r);
} catch (RemoteException ex) {
if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r);
mRemoveList.add(r.binder);
@@ -436,8 +434,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
@Override
public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
boolean notifyNow) {
- listenForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, pkgForDebug, callback, events,
- notifyNow);
+ listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback,
+ events, notifyNow);
}
@Override
@@ -483,7 +481,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
// Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
// force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
if (!SubscriptionManager.isValidSubId(subId)) {
- r.subId = SubscriptionManager.DEFAULT_SUB_ID;
+ r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
} else {//APP specify subID
r.subId = subId;
}
@@ -642,7 +640,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
- (r.subId == SubscriptionManager.DEFAULT_SUB_ID)) {
+ (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
r.callback.onCallStateChanged(state, incomingNumber);
} catch (RemoteException ex) {
@@ -652,7 +650,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
handleRemoveListLocked();
}
- broadcastCallStateChanged(state, incomingNumber, SubscriptionManager.DEFAULT_SUB_ID);
+ broadcastCallStateChanged(state, incomingNumber,
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
}
public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) {
@@ -671,7 +670,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
(r.subId == subId) &&
- (r.subId != SubscriptionManager.DEFAULT_SUB_ID)) {
+ (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
r.callback.onCallStateChanged(state, incomingNumber);
} catch (RemoteException ex) {
@@ -728,7 +727,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
public void notifySignalStrength(SignalStrength signalStrength) {
- notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, signalStrength);
+ notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ signalStrength);
}
public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) {
@@ -789,7 +789,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
public void notifyCellInfo(List<CellInfo> cellInfo) {
- notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellInfo);
+ notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo);
}
public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) {
@@ -877,7 +877,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
public void notifyCallForwardingChanged(boolean cfi) {
- notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cfi);
+ notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi);
}
public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) {
@@ -909,7 +909,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
public void notifyDataActivity(int state) {
- notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state);
+ notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state);
}
public void notifyDataActivityForSubscriber(int subId, int state) {
@@ -918,13 +918,15 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- mDataActivity[phoneId] = state;
- for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) {
- try {
- r.callback.onDataActivity(state);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
+ if (validatePhoneId(phoneId)) {
+ mDataActivity[phoneId] = state;
+ for (Record r : mRecords) {
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) {
+ try {
+ r.callback.onDataActivity(state);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
}
@@ -935,7 +937,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
String reason, String apn, String apnType, LinkProperties linkProperties,
NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
- notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state,
+ notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state,
isDataConnectivityPossible,reason, apn, apnType, linkProperties,
networkCapabilities, networkType, roaming);
}
@@ -956,67 +958,69 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- boolean modified = false;
- if (state == TelephonyManager.DATA_CONNECTED) {
- if (!mConnectedApns.contains(apnType)) {
- mConnectedApns.add(apnType);
- if (mDataConnectionState[phoneId] != state) {
- mDataConnectionState[phoneId] = state;
- modified = true;
+ if (validatePhoneId(phoneId)) {
+ boolean modified = false;
+ if (state == TelephonyManager.DATA_CONNECTED) {
+ if (!mConnectedApns.contains(apnType)) {
+ mConnectedApns.add(apnType);
+ if (mDataConnectionState[phoneId] != state) {
+ mDataConnectionState[phoneId] = state;
+ modified = true;
+ }
}
- }
- } else {
- if (mConnectedApns.remove(apnType)) {
- if (mConnectedApns.isEmpty()) {
- mDataConnectionState[phoneId] = state;
- modified = true;
- } else {
- // leave mDataConnectionState as is and
- // send out the new status for the APN in question.
+ } else {
+ if (mConnectedApns.remove(apnType)) {
+ if (mConnectedApns.isEmpty()) {
+ mDataConnectionState[phoneId] = state;
+ modified = true;
+ } else {
+ // leave mDataConnectionState as is and
+ // send out the new status for the APN in question.
+ }
}
}
- }
- mDataConnectionPossible[phoneId] = isDataConnectivityPossible;
- mDataConnectionReason[phoneId] = reason;
- mDataConnectionLinkProperties[phoneId] = linkProperties;
- mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities;
- if (mDataConnectionNetworkType[phoneId] != networkType) {
- mDataConnectionNetworkType[phoneId] = networkType;
- // need to tell registered listeners about the new network type
- modified = true;
- }
- if (modified) {
- if (DBG) {
- log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId]
- + ", " + mDataConnectionNetworkType[phoneId] + ")");
+ mDataConnectionPossible[phoneId] = isDataConnectivityPossible;
+ mDataConnectionReason[phoneId] = reason;
+ mDataConnectionLinkProperties[phoneId] = linkProperties;
+ mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities;
+ if (mDataConnectionNetworkType[phoneId] != networkType) {
+ mDataConnectionNetworkType[phoneId] = networkType;
+ // need to tell registered listeners about the new network type
+ modified = true;
}
+ if (modified) {
+ if (DBG) {
+ log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId]
+ + ", " + mDataConnectionNetworkType[phoneId] + ")");
+ }
+ for (Record r : mRecords) {
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) &&
+ idMatch(r.subId, subId, phoneId)) {
+ try {
+ log("Notify data connection state changed on sub: " +
+ subId);
+ r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
+ mDataConnectionNetworkType[phoneId]);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
+ apnType, apn, reason, linkProperties, "");
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) &&
- idMatch(r.subId, subId, phoneId)) {
+ PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
try {
- log("Notify data connection state changed on sub: " +
- subId);
- r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
- mDataConnectionNetworkType[phoneId]);
+ r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
}
}
- handleRemoveListLocked();
- }
- mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
- apnType, apn, reason, linkProperties, "");
- for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
- try {
- r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
- }
- }
}
handleRemoveListLocked();
}
@@ -1027,7 +1031,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
public void notifyDataConnectionFailed(String reason, String apnType) {
- notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID,
+ notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
reason, apnType);
}
@@ -1062,7 +1066,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
public void notifyCellLocation(Bundle cellLocation) {
- notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellLocation);
+ notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation);
}
public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) {
@@ -1226,7 +1230,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
if ((r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) &&
((r.subId == subId) ||
- (r.subId == SubscriptionManager.DEFAULT_SUB_ID))) {
+ (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID))) {
try {
r.callback.onOemHookRawEvent(rawData);
} catch (RemoteException ex) {
@@ -1399,14 +1403,17 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
- String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) {
+ String apnType, String apn, String reason, LinkProperties linkProperties,
+ String failCause) {
Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
intent.putExtra(PhoneConstants.STATE_KEY, state);
intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
- if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
+ if (linkProperties != null) {
+ intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties);
+ }
if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
@@ -1506,7 +1513,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
@Override
public String toString() {
- return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId " + mPhoneId + " mState " + mState;
+ return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId "
+ + mPhoneId + " mState " + mState;
}
}
@@ -1550,7 +1558,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
boolean idMatch(int rSubId, int subId, int phoneId) {
- if(rSubId == SubscriptionManager.DEFAULT_SUB_ID) {
+ if(rSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
if(subId < 0) {
// Invalid case, we need compare phoneId with default one.
return (mDefaultPhoneId == phoneId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 772192a..7e17043 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -173,6 +173,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
+import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -795,7 +796,11 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public int hashCode() {
- return toString().hashCode();
+ int hashCode = 1;
+ hashCode = 31 * hashCode + sourceUserId;
+ hashCode = 31 * hashCode + uri.hashCode();
+ hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
+ return hashCode;
}
@Override
@@ -834,10 +839,12 @@ public final class ActivityManagerService extends ActivityManagerNative
* indirect content-provider access.
*/
private class Identity {
- public int pid;
- public int uid;
+ public final IBinder token;
+ public final int pid;
+ public final int uid;
- Identity(int _pid, int _uid) {
+ Identity(IBinder _token, int _pid, int _uid) {
+ token = _token;
pid = _pid;
uid = _uid;
}
@@ -952,9 +959,9 @@ public final class ActivityManagerService extends ActivityManagerNative
private boolean mRunningVoice = false;
/**
- * State of external calls telling us if the device is asleep.
+ * State of external calls telling us if the device is awake or asleep.
*/
- private boolean mWentToSleep = false;
+ private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
static final int LOCK_SCREEN_HIDDEN = 0;
static final int LOCK_SCREEN_LEAVING = 1;
@@ -2271,15 +2278,19 @@ public final class ActivityManagerService extends ActivityManagerNative
* process when the bindApplication() IPC is sent to the process. They're
* lazily setup to make sure the services are running when they're asked for.
*/
- private HashMap<String, IBinder> getCommonServicesLocked() {
+ private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
if (mAppBindArgs == null) {
- mAppBindArgs = new HashMap<String, IBinder>();
+ mAppBindArgs = new HashMap<>();
- // Setup the application init args
- mAppBindArgs.put("package", ServiceManager.getService("package"));
- mAppBindArgs.put("window", ServiceManager.getService("window"));
- mAppBindArgs.put(Context.ALARM_SERVICE,
- ServiceManager.getService(Context.ALARM_SERVICE));
+ // Isolated processes won't get this optimization, so that we don't
+ // violate the rules about which services they have access to.
+ if (!isolated) {
+ // Setup the application init args
+ mAppBindArgs.put("package", ServiceManager.getService("package"));
+ mAppBindArgs.put("window", ServiceManager.getService("window"));
+ mAppBindArgs.put(Context.ALARM_SERVICE,
+ ServiceManager.getService(Context.ALARM_SERVICE));
+ }
}
return mAppBindArgs;
}
@@ -5650,7 +5661,7 @@ public final class ActivityManagerService extends ActivityManagerNative
didSomething = true;
it.remove();
pir.canceled = true;
- if (pir.key.activity != null) {
+ if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
pir.key.activity.pendingResults.remove(pir.ref);
}
}
@@ -5902,7 +5913,8 @@ public final class ActivityManagerService extends ActivityManagerNative
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
- new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
+ new Configuration(mConfiguration), app.compat,
+ getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
@@ -6050,6 +6062,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mWindowManager.keyguardWaitingForActivityDrawn();
if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
mLockScreenShown = LOCK_SCREEN_LEAVING;
+ updateSleepIfNeededLocked();
}
}
} finally {
@@ -6256,7 +6269,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
- stack.backgroundResourcesReleased(token);
+ stack.backgroundResourcesReleased();
}
}
} finally {
@@ -6722,21 +6735,9 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
int checkComponentPermission(String permission, int pid, int uid,
int owningUid, boolean exported) {
- // We might be performing an operation on behalf of an indirect binder
- // invocation, e.g. via {@link #openContentUri}. Check and adjust the
- // client identity accordingly before proceeding.
- Identity tlsIdentity = sCallerIdentity.get();
- if (tlsIdentity != null) {
- Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
- + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
- uid = tlsIdentity.uid;
- pid = tlsIdentity.pid;
- }
-
if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
}
-
return ActivityManager.checkComponentPermission(permission, uid,
owningUid, exported);
}
@@ -6758,6 +6759,26 @@ public final class ActivityManagerService extends ActivityManagerNative
return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
}
+ @Override
+ public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
+ if (permission == null) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+
+ // We might be performing an operation on behalf of an indirect binder
+ // invocation, e.g. via {@link #openContentUri}. Check and adjust the
+ // client identity accordingly before proceeding.
+ Identity tlsIdentity = sCallerIdentity.get();
+ if (tlsIdentity != null && tlsIdentity.token == callerToken) {
+ Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
+ + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
+ uid = tlsIdentity.uid;
+ pid = tlsIdentity.pid;
+ }
+
+ return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
+ }
+
/**
* Binder IPC calls go through the public entry point.
* This can be called with or without the global lock held.
@@ -6963,13 +6984,13 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
@Override
public int checkUriPermission(Uri uri, int pid, int uid,
- final int modeFlags, int userId) {
+ final int modeFlags, int userId, IBinder callerToken) {
enforceNotIsolatedCaller("checkUriPermission");
// Another redirected-binder-call permissions check as in
- // {@link checkComponentPermission}.
+ // {@link checkPermissionWithToken}.
Identity tlsIdentity = sCallerIdentity.get();
- if (tlsIdentity != null) {
+ if (tlsIdentity != null && tlsIdentity.token == callerToken) {
uid = tlsIdentity.uid;
pid = tlsIdentity.pid;
}
@@ -9876,10 +9897,11 @@ public final class ActivityManagerService extends ActivityManagerNative
// we do the check against the caller's permissions even though it looks
// to the content provider like the Activity Manager itself is making
// the request.
+ Binder token = new Binder();
sCallerIdentity.set(new Identity(
- Binder.getCallingPid(), Binder.getCallingUid()));
+ token, Binder.getCallingPid(), Binder.getCallingUid()));
try {
- pfd = cph.provider.openFile(null, uri, "r", null);
+ pfd = cph.provider.openFile(null, uri, "r", null, token);
} catch (FileNotFoundException e) {
// do nothing; pfd will be returned null
} finally {
@@ -9905,32 +9927,55 @@ public final class ActivityManagerService extends ActivityManagerNative
return mSleeping;
}
- void goingToSleep() {
+ void onWakefulnessChanged(int wakefulness) {
synchronized(this) {
- mWentToSleep = true;
- goToSleepIfNeededLocked();
+ mWakefulness = wakefulness;
+ updateSleepIfNeededLocked();
}
}
void finishRunningVoiceLocked() {
if (mRunningVoice) {
mRunningVoice = false;
- goToSleepIfNeededLocked();
+ updateSleepIfNeededLocked();
}
}
- void goToSleepIfNeededLocked() {
- if (mWentToSleep && !mRunningVoice) {
- if (!mSleeping) {
- mSleeping = true;
- mStackSupervisor.goingToSleepLocked();
+ void updateSleepIfNeededLocked() {
+ if (mSleeping && !shouldSleepLocked()) {
+ mSleeping = false;
+ mStackSupervisor.comeOutOfSleepIfNeededLocked();
+ } else if (!mSleeping && shouldSleepLocked()) {
+ mSleeping = true;
+ mStackSupervisor.goingToSleepLocked();
- // Initialize the wake times of all processes.
- checkExcessivePowerUsageLocked(false);
- mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
- Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
- mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
- }
+ // Initialize the wake times of all processes.
+ checkExcessivePowerUsageLocked(false);
+ mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
+ Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
+ mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
+ }
+ }
+
+ private boolean shouldSleepLocked() {
+ // Resume applications while running a voice interactor.
+ if (mRunningVoice) {
+ return false;
+ }
+
+ switch (mWakefulness) {
+ case PowerManagerInternal.WAKEFULNESS_AWAKE:
+ case PowerManagerInternal.WAKEFULNESS_DREAMING:
+ // If we're interactive but applications are already paused then defer
+ // resuming them until the lock screen is hidden.
+ return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
+ case PowerManagerInternal.WAKEFULNESS_DOZING:
+ // If we're dozing then pause applications whenever the lock screen is shown.
+ return mLockScreenShown != LOCK_SCREEN_HIDDEN;
+ case PowerManagerInternal.WAKEFULNESS_ASLEEP:
+ default:
+ // If we're asleep then pause applications unconditionally.
+ return true;
}
}
@@ -9996,31 +10041,16 @@ public final class ActivityManagerService extends ActivityManagerNative
}
void logLockScreen(String msg) {
- if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
- " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
- mWentToSleep + " mSleeping=" + mSleeping);
- }
-
- void comeOutOfSleepIfNeededLocked() {
- if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
- if (mSleeping) {
- mSleeping = false;
- mStackSupervisor.comeOutOfSleepIfNeededLocked();
- }
- }
- }
-
- void wakingUp() {
- synchronized(this) {
- mWentToSleep = false;
- comeOutOfSleepIfNeededLocked();
- }
+ if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
+ + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
+ + PowerManagerInternal.wakefulnessToString(mWakefulness)
+ + " mSleeping=" + mSleeping);
}
void startRunningVoiceLocked() {
if (!mRunningVoice) {
mRunningVoice = true;
- comeOutOfSleepIfNeededLocked();
+ updateSleepIfNeededLocked();
}
}
@@ -10040,7 +10070,7 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
- comeOutOfSleepIfNeededLocked();
+ updateSleepIfNeededLocked();
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -12810,13 +12840,11 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
if (dumpPackage == null) {
- if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
- pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
- + " mLockScreenShown " + lockScreenShownToString());
- }
- if (mShuttingDown || mRunningVoice) {
- pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
- }
+ pw.println(" mWakefulness="
+ + PowerManagerInternal.wakefulnessToString(mWakefulness));
+ pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
+ + lockScreenShownToString());
+ pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
}
if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
|| mOrigWaitForDebugger) {
@@ -13204,7 +13232,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mReceiverResolver.dump(pw, needSep ?
"\n Receiver Resolver Table:" : " Receiver Resolver Table:",
- " ", dumpPackage, false)) {
+ " ", dumpPackage, false, false)) {
needSep = true;
printedAnything = true;
}
@@ -19184,13 +19212,8 @@ public final class ActivityManagerService extends ActivityManagerNative
private final class LocalService extends ActivityManagerInternal {
@Override
- public void goingToSleep() {
- ActivityManagerService.this.goingToSleep();
- }
-
- @Override
- public void wakingUp() {
- ActivityManagerService.this.wakingUp();
+ public void onWakefulnessChanged(int wakefulness) {
+ ActivityManagerService.this.onWakefulnessChanged(wakefulness);
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 3a1fafe..ea694ad 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -700,6 +700,10 @@ final class ActivityStack {
activities.get(activityNdx).setSleeping(false);
}
}
+ if (mPausingActivity != null) {
+ Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause");
+ activityPausedLocked(mPausingActivity.appToken, true);
+ }
}
/**
@@ -1477,7 +1481,7 @@ final class ActivityStack {
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
- mService.comeOutOfSleepIfNeededLocked();
+ mService.updateSleepIfNeededLocked();
}
result = resumeTopActivityInnerLocked(prev, options);
} finally {
@@ -3317,17 +3321,18 @@ final class ActivityStack {
mHandler.sendEmptyMessageDelayed(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG, 500);
} else {
Slog.e(TAG, "releaseBackgroundResources: activity " + r + " no longer running");
- backgroundResourcesReleased(r.appToken);
+ backgroundResourcesReleased();
}
}
}
- final void backgroundResourcesReleased(IBinder token) {
+ final void backgroundResourcesReleased() {
mHandler.removeMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG);
final ActivityRecord r = getVisibleBehindActivity();
if (r != null) {
mStackSupervisor.mStoppingActivities.add(r);
setVisibleBehindActivity(null);
+ mStackSupervisor.scheduleIdleTimeoutLocked(null);
}
mStackSupervisor.resumeTopActivitiesLocked();
}
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index bffb541..d05910b 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -582,9 +582,10 @@ public final class ProcessStatsService extends IProcessStats.Stub {
pw.println("Process stats (procstats) dump options:");
pw.println(" [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
pw.println(" [--details] [--full-details] [--current] [--hours N] [--last N]");
- pw.println(" [--active] [--commit] [--reset] [--clear] [--write] [-h] [<package.name>]");
+ pw.println(" [--max N] --active] [--commit] [--reset] [--clear] [--write] [-h]");
+ pw.println(" [<package.name>]");
pw.println(" --checkin: perform a checkin: print and delete old committed states.");
- pw.println(" --c: print only state in checkin format.");
+ pw.println(" -c: print only state in checkin format.");
pw.println(" --csv: output data suitable for putting in a spreadsheet.");
pw.println(" --csv-screen: on, off.");
pw.println(" --csv-mem: norm, mod, low, crit.");
@@ -595,6 +596,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
pw.println(" --current: only dump current state.");
pw.println(" --hours: aggregate over about N last hours.");
pw.println(" --last: only show the last committed stats at index N (starting at 1).");
+ pw.println(" --max: for -a, max num of historical batches to print.");
pw.println(" --active: only show currently active processes/services.");
pw.println(" --commit: commit current stats to disk and reset to start new stats.");
pw.println(" --reset: reset current stats, without committing.");
@@ -636,6 +638,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
boolean dumpAll = false;
int aggregateHours = 0;
int lastIndex = 0;
+ int maxNum = 2;
boolean activeOnly = false;
String reqPackage = null;
boolean csvSepScreenStats = false;
@@ -734,6 +737,20 @@ public final class ProcessStatsService extends IProcessStats.Stub {
dumpHelp(pw);
return;
}
+ } else if ("--max".equals(arg)) {
+ i++;
+ if (i >= args.length) {
+ pw.println("Error: argument required for --max");
+ dumpHelp(pw);
+ return;
+ }
+ try {
+ maxNum = Integer.parseInt(args[i]);
+ } catch (NumberFormatException e) {
+ pw.println("Error: --max argument not an int -- " + args[i]);
+ dumpHelp(pw);
+ return;
+ }
} else if ("--active".equals(arg)) {
activeOnly = true;
currentOnly = true;
@@ -892,7 +909,11 @@ public final class ProcessStatsService extends IProcessStats.Stub {
try {
ArrayList<String> files = getCommittedFiles(0, false, !isCheckin);
if (files != null) {
- for (int i=0; i<files.size(); i++) {
+ int start = isCheckin ? 0 : (files.size() - maxNum);
+ if (start < 0) {
+ start = 0;
+ }
+ for (int i=start; i<files.size(); i++) {
if (DEBUG) Slog.d(TAG, "Retrieving state: " + files.get(i));
try {
AtomicFile file = new AtomicFile(new File(files.get(i)));
@@ -947,19 +968,6 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
if (!isCheckin) {
- if (!currentOnly) {
- if (sepNeeded) {
- pw.println();
- }
- pw.println("AGGREGATED OVER LAST 24 HOURS:");
- dumpAggregatedStats(pw, 24, now, reqPackage, isCompact,
- dumpDetails, dumpFullDetails, dumpAll, activeOnly);
- pw.println();
- pw.println("AGGREGATED OVER LAST 3 HOURS:");
- dumpAggregatedStats(pw, 3, now, reqPackage, isCompact,
- dumpDetails, dumpFullDetails, dumpAll, activeOnly);
- sepNeeded = true;
- }
synchronized (mAm) {
if (isCompact) {
mProcessStats.dumpCheckinLocked(pw, reqPackage);
@@ -977,8 +985,21 @@ public final class ProcessStatsService extends IProcessStats.Stub {
} else {
mProcessStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
}
+ sepNeeded = true;
}
}
+ if (!currentOnly) {
+ if (sepNeeded) {
+ pw.println();
+ }
+ pw.println("AGGREGATED OVER LAST 24 HOURS:");
+ dumpAggregatedStats(pw, 24, now, reqPackage, isCompact,
+ dumpDetails, dumpFullDetails, dumpAll, activeOnly);
+ pw.println();
+ pw.println("AGGREGATED OVER LAST 3 HOURS:");
+ dumpAggregatedStats(pw, 3, now, reqPackage, isCompact,
+ dumpDetails, dumpFullDetails, dumpAll, activeOnly);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index b331c84..9311f25 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -63,6 +63,12 @@ public class TaskPersister {
private static final String IMAGES_DIRNAME = "recent_images";
static final String IMAGE_EXTENSION = ".png";
+ // Directory where restored historical task XML/PNG files are placed. This directory
+ // contains subdirs named after TASKS_DIRNAME and IMAGES_DIRNAME mirroring the
+ // ancestral device's dataset. This needs to match the RECENTS_TASK_RESTORE_DIR
+ // value in RecentsBackupHelper.
+ private static final String RESTORED_TASKS = "restored_" + TASKS_DIRNAME;
+
private static final String TAG_TASK = "task";
static File sImagesDir;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 03c05ec..6da186f 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -46,6 +46,7 @@ import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
+import android.net.Network;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
@@ -580,7 +581,13 @@ public class Vpn {
}
private boolean isRunningLocked() {
- return mVpnUsers != null;
+ return mNetworkAgent != null && mInterface != null;
+ }
+
+ // Returns true if the VPN has been established and the calling UID is its owner. Used to check
+ // that a call to mutate VPN state is admissible.
+ private boolean isCallerEstablishedOwnerLocked() {
+ return isRunningLocked() && Binder.getCallingUid() == mOwnerUID;
}
// Note: Return type guarantees results are deduped and sorted, which callers require.
@@ -595,7 +602,7 @@ public class Vpn {
// Note: This function adds to mVpnUsers but does not publish list to NetworkAgent.
private void addVpnUserLocked(int userHandle) {
- if (!isRunningLocked()) {
+ if (mVpnUsers == null) {
throw new IllegalStateException("VPN is not active");
}
@@ -647,7 +654,7 @@ public class Vpn {
}
private void removeVpnUserLocked(int userHandle) {
- if (!isRunningLocked()) {
+ if (mVpnUsers == null) {
throw new IllegalStateException("VPN is not active");
}
final List<UidRange> ranges = uidRangesForUser(userHandle);
@@ -767,27 +774,61 @@ public class Vpn {
}
public synchronized boolean addAddress(String address, int prefixLength) {
- if (Binder.getCallingUid() != mOwnerUID || mInterface == null || mNetworkAgent == null) {
+ if (!isCallerEstablishedOwnerLocked()) {
return false;
}
boolean success = jniAddAddress(mInterface, address, prefixLength);
- if (mNetworkAgent != null) {
- mNetworkAgent.sendLinkProperties(makeLinkProperties());
- }
+ mNetworkAgent.sendLinkProperties(makeLinkProperties());
return success;
}
public synchronized boolean removeAddress(String address, int prefixLength) {
- if (Binder.getCallingUid() != mOwnerUID || mInterface == null || mNetworkAgent == null) {
+ if (!isCallerEstablishedOwnerLocked()) {
return false;
}
boolean success = jniDelAddress(mInterface, address, prefixLength);
- if (mNetworkAgent != null) {
- mNetworkAgent.sendLinkProperties(makeLinkProperties());
- }
+ mNetworkAgent.sendLinkProperties(makeLinkProperties());
return success;
}
+ public synchronized boolean setUnderlyingNetworks(Network[] networks) {
+ if (!isCallerEstablishedOwnerLocked()) {
+ return false;
+ }
+ if (networks == null) {
+ mConfig.underlyingNetworks = null;
+ } else {
+ mConfig.underlyingNetworks = new Network[networks.length];
+ for (int i = 0; i < networks.length; ++i) {
+ if (networks[i] == null) {
+ mConfig.underlyingNetworks[i] = null;
+ } else {
+ mConfig.underlyingNetworks[i] = new Network(networks[i].netId);
+ }
+ }
+ }
+ return true;
+ }
+
+ public synchronized Network[] getUnderlyingNetworks() {
+ if (!isRunningLocked()) {
+ return null;
+ }
+ return mConfig.underlyingNetworks;
+ }
+
+ public synchronized boolean appliesToUid(int uid) {
+ if (!isRunningLocked()) {
+ return false;
+ }
+ for (UidRange uidRange : mVpnUsers) {
+ if (uidRange.start <= uid && uid <= uidRange.stop) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private native int jniCreate(int mtu);
private native String jniGetName(int tun);
private native int jniSetAddresses(String interfaze, String addresses);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 0cdb4d5..ec38124 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -798,7 +798,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
boolean isSystemAudioActivated() {
- if (getAvrDeviceInfo() == null) {
+ if (!hasSystemAudioDevice()) {
return false;
}
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiLogger.java b/services/core/java/com/android/server/hdmi/HdmiLogger.java
index 2562ffc..7f6971f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiLogger.java
+++ b/services/core/java/com/android/server/hdmi/HdmiLogger.java
@@ -17,6 +17,7 @@
package com.android.server.hdmi;
import android.annotation.Nullable;
+import android.os.Build;
import android.os.SystemClock;
import android.util.Pair;
import android.util.Slog;
@@ -41,7 +42,7 @@ final class HdmiLogger {
// Logging duration for same error message.
private static final long ERROR_LOG_DURATTION_MILLIS = 20 * 1000; // 20s
- private static final boolean DEBUG = false;
+ private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
private static final ThreadLocal<HdmiLogger> sLogger = new ThreadLocal<>();
@@ -82,7 +83,7 @@ final class HdmiLogger {
}
private void debugInternal(String logMessage) {
- if (!DEBUG) {
+ if (IS_USER_BUILD) {
return;
}
Slog.d(TAG, logMessage);
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 8c3c102..c960c07 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -73,8 +73,8 @@ import android.provider.Telephony.Carriers;
import android.provider.Telephony.Sms.Intents;
import android.telephony.SmsMessage;
import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionListener;
import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
@@ -462,9 +462,10 @@ public class GpsLocationProvider implements LocationProviderInterface {
}
};
- private final SubscriptionListener mSubscriptionListener = new SubscriptionListener() {
+ private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
+ new OnSubscriptionsChangedListener() {
@Override
- public void onSubscriptionInfoChanged() {
+ public void onSubscriptionsChanged() {
subscriptionOrSimChanged(mContext);
}
};
@@ -640,14 +641,14 @@ public class GpsLocationProvider implements LocationProviderInterface {
mSuplEsEnabled);
// TODO: When this object "finishes" we should unregister by invoking
- // SubscriptionManager.unregister(mContext, mSubscriptionListener);
+ // SubscriptionManager.getInstance(mContext).unregister(mOnSubscriptionsChangedListener);
// This is not strictly necessary because it will be unregistered if the
// notification fails but it is good form.
// Register for SubscriptionInfo list changes which is guaranteed
- // to invoke onSubscriptionInfoChanged the first time.
- SubscriptionManager.register(mContext, mSubscriptionListener,
- SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
+ // to invoke onSubscriptionsChanged the first time.
+ SubscriptionManager.from(mContext)
+ .registerOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
// construct handler, listen for events
mHandler = new ProviderHandler(looper);
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 921b68b..9440697 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -90,6 +90,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
private final SessionStub mSession;
private final SessionCb mSessionCb;
private final MediaSessionService mService;
+ private final boolean mUseMasterVolume;
private final Object mLock = new Object();
private final ArrayList<ISessionControllerCallback> mControllerCallbacks =
@@ -139,6 +140,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
mAudioManager = (AudioManager) service.getContext().getSystemService(Context.AUDIO_SERVICE);
mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+ mUseMasterVolume = service.getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_useMasterVolume);
}
/**
@@ -248,6 +251,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
direction = -1;
}
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
+ if (mUseMasterVolume) {
+ // If this device only uses master volume and playback is local
+ // just adjust the master volume and return.
+ mAudioManagerInternal.adjustMasterVolumeForUid(direction, flags, packageName, uid);
+ return;
+ }
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
if (useSuggested) {
if (AudioSystem.isStreamActive(stream, 0)) {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index ba18f48..053c988 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -86,6 +86,7 @@ public class MediaSessionService extends SystemService implements Monitor {
private final Object mLock = new Object();
private final MessageHandler mHandler = new MessageHandler();
private final PowerManager.WakeLock mMediaEventWakeLock;
+ private final boolean mUseMasterVolume;
private KeyguardManager mKeyguardManager;
private IAudioService mAudioService;
@@ -104,6 +105,8 @@ public class MediaSessionService extends SystemService implements Monitor {
mPriorityStack = new MediaSessionStack();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
+ mUseMasterVolume = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_useMasterVolume);
}
@Override
@@ -424,7 +427,7 @@ public class MediaSessionService extends SystemService implements Monitor {
private int findIndexOfSessionsListenerLocked(IActiveSessionsListener listener) {
for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
- if (mSessionsListeners.get(i).mListener == listener) {
+ if (mSessionsListeners.get(i).mListener.asBinder() == listener.asBinder()) {
return i;
}
}
@@ -761,6 +764,7 @@ public class MediaSessionService extends SystemService implements Monitor {
pw.println();
synchronized (mLock) {
+ pw.println(mSessionsListeners.size() + " sessions listeners.");
int count = mAllSessions.size();
pw.println(count + " Sessions:");
for (int i = 0; i < count; i++) {
@@ -819,8 +823,13 @@ public class MediaSessionService extends SystemService implements Monitor {
return;
}
try {
- mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream, flags,
- getContext().getOpPackageName());
+ if (mUseMasterVolume) {
+ mAudioService.adjustMasterVolume(direction, flags,
+ getContext().getOpPackageName());
+ } else {
+ mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream, flags,
+ getContext().getOpPackageName());
+ }
} catch (RemoteException e) {
Log.e(TAG, "Error adjusting default volume.", e);
}
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index 857b9e9..b5a450d 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -122,8 +122,10 @@ public class IpConfigStore {
out.writeUTF(proxyProperties.getHost());
out.writeUTF(PROXY_PORT_KEY);
out.writeInt(proxyProperties.getPort());
- out.writeUTF(EXCLUSION_LIST_KEY);
- out.writeUTF(exclusionList);
+ if (exclusionList != null) {
+ out.writeUTF(EXCLUSION_LIST_KEY);
+ out.writeUTF(exclusionList);
+ }
written = true;
break;
case PAC:
diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java
index 397f9f4..f230bb3 100644
--- a/services/core/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java
@@ -29,7 +29,8 @@ import java.util.HashSet;
*
* @hide
*/
-public class NetworkIdentitySet extends HashSet<NetworkIdentity> {
+public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
+ Comparable<NetworkIdentitySet> {
private static final int VERSION_INIT = 1;
private static final int VERSION_ADD_ROAMING = 2;
private static final int VERSION_ADD_NETWORK_ID = 3;
@@ -92,4 +93,14 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> {
return null;
}
}
+
+ @Override
+ public int compareTo(NetworkIdentitySet another) {
+ if (isEmpty()) return -1;
+ if (another.isEmpty()) return 1;
+
+ final NetworkIdentity ident = iterator().next();
+ final NetworkIdentity anotherIdent = another.iterator().next();
+ return ident.compareTo(anotherIdent);
+ }
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 475482f..3ac20f7 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -22,15 +22,20 @@ import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.TrafficStats.UID_REMOVED;
+import static android.text.format.DateUtils.SECOND_IN_MILLIS;
+import static android.text.format.DateUtils.WEEK_IN_MILLIS;
+import android.net.ConnectivityManager;
import android.net.NetworkIdentity;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
-import android.text.format.DateUtils;
+import android.util.ArrayMap;
import android.util.AtomicFile;
+import libcore.io.IoUtils;
+
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
@@ -44,15 +49,13 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.PrintWriter;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Map;
import java.util.Objects;
-import libcore.io.IoUtils;
-
/**
* Collection of {@link NetworkStatsHistory}, stored based on combined key of
* {@link NetworkIdentitySet}, UID, set, and tag. Knows how to persist itself.
@@ -70,7 +73,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {
private static final int VERSION_UNIFIED_INIT = 16;
- private HashMap<Key, NetworkStatsHistory> mStats = Maps.newHashMap();
+ private ArrayMap<Key, NetworkStatsHistory> mStats = new ArrayMap<>();
private final long mBucketDuration;
@@ -145,12 +148,13 @@ public class NetworkStatsCollection implements FileRotator.Reader {
NetworkTemplate template, int uid, int set, int tag, int fields, long start, long end) {
final NetworkStatsHistory combined = new NetworkStatsHistory(
mBucketDuration, estimateBuckets(), fields);
- for (Map.Entry<Key, NetworkStatsHistory> entry : mStats.entrySet()) {
- final Key key = entry.getKey();
+ for (int i = 0; i < mStats.size(); i++) {
+ final Key key = mStats.keyAt(i);
final boolean setMatches = set == SET_ALL || key.set == set;
if (key.uid == uid && setMatches && key.tag == tag
&& templateMatches(template, key.ident)) {
- combined.recordHistory(entry.getValue(), start, end);
+ final NetworkStatsHistory value = mStats.valueAt(i);
+ combined.recordHistory(value, start, end);
}
}
return combined;
@@ -170,11 +174,11 @@ public class NetworkStatsCollection implements FileRotator.Reader {
// shortcut when we know stats will be empty
if (start == end) return stats;
- for (Map.Entry<Key, NetworkStatsHistory> mapEntry : mStats.entrySet()) {
- final Key key = mapEntry.getKey();
+ for (int i = 0; i < mStats.size(); i++) {
+ final Key key = mStats.keyAt(i);
if (templateMatches(template, key.ident)) {
- final NetworkStatsHistory history = mapEntry.getValue();
- historyEntry = history.getValues(start, end, now, historyEntry);
+ final NetworkStatsHistory value = mStats.valueAt(i);
+ historyEntry = value.getValues(start, end, now, historyEntry);
entry.iface = IFACE_ALL;
entry.uid = key.uid;
@@ -225,8 +229,10 @@ public class NetworkStatsCollection implements FileRotator.Reader {
* into this collection.
*/
public void recordCollection(NetworkStatsCollection another) {
- for (Map.Entry<Key, NetworkStatsHistory> entry : another.mStats.entrySet()) {
- recordHistory(entry.getKey(), entry.getValue());
+ for (int i = 0; i < another.mStats.size(); i++) {
+ final Key key = another.mStats.keyAt(i);
+ final NetworkStatsHistory value = another.mStats.valueAt(i);
+ recordHistory(key, value);
}
}
@@ -460,7 +466,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {
}
private int estimateBuckets() {
- return (int) (Math.min(mEndMillis - mStartMillis, DateUtils.WEEK_IN_MILLIS * 5)
+ return (int) (Math.min(mEndMillis - mStartMillis, WEEK_IN_MILLIS * 5)
/ mBucketDuration);
}
@@ -482,6 +488,54 @@ public class NetworkStatsCollection implements FileRotator.Reader {
}
}
+ public void dumpCheckin(PrintWriter pw, long start, long end) {
+ dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateMobileWildcard(), "cell");
+ dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateWifiWildcard(), "wifi");
+ dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateEthernet(), "eth");
+ dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateBluetooth(), "bt");
+ }
+
+ /**
+ * Dump all contained stats that match requested parameters, but group
+ * together all matching {@link NetworkTemplate} under a single prefix.
+ */
+ private void dumpCheckin(PrintWriter pw, long start, long end, NetworkTemplate groupTemplate,
+ String groupPrefix) {
+ final ArrayMap<Key, NetworkStatsHistory> grouped = new ArrayMap<>();
+
+ // Walk through all history, grouping by matching network templates
+ for (int i = 0; i < mStats.size(); i++) {
+ final Key key = mStats.keyAt(i);
+ final NetworkStatsHistory value = mStats.valueAt(i);
+
+ if (!templateMatches(groupTemplate, key.ident)) continue;
+
+ final Key groupKey = new Key(null, key.uid, key.set, key.tag);
+ NetworkStatsHistory groupHistory = grouped.get(groupKey);
+ if (groupHistory == null) {
+ groupHistory = new NetworkStatsHistory(value.getBucketDuration());
+ grouped.put(groupKey, groupHistory);
+ }
+ groupHistory.recordHistory(value, start, end);
+ }
+
+ for (int i = 0; i < grouped.size(); i++) {
+ final Key key = grouped.keyAt(i);
+ final NetworkStatsHistory value = grouped.valueAt(i);
+
+ if (value.size() == 0) continue;
+
+ pw.print("c,");
+ pw.print(groupPrefix); pw.print(',');
+ pw.print(key.uid); pw.print(',');
+ pw.print(NetworkStats.setToCheckinString(key.set)); pw.print(',');
+ pw.print(key.tag);
+ pw.println();
+
+ value.dumpCheckin(pw);
+ }
+ }
+
/**
* Test if given {@link NetworkTemplate} matches any {@link NetworkIdentity}
* in the given {@link NetworkIdentitySet}.
@@ -528,7 +582,20 @@ public class NetworkStatsCollection implements FileRotator.Reader {
@Override
public int compareTo(Key another) {
- return Integer.compare(uid, another.uid);
+ int res = 0;
+ if (ident != null && another.ident != null) {
+ res = ident.compareTo(another.ident);
+ }
+ if (res == 0) {
+ res = Integer.compare(uid, another.uid);
+ }
+ if (res == 0) {
+ res = Integer.compare(set, another.set);
+ }
+ if (res == 0) {
+ res = Integer.compare(tag, another.tag);
+ }
+ return res;
}
}
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index cea084b..d5d7667 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -41,6 +41,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashSet;
@@ -124,23 +125,36 @@ public class NetworkStatsRecorder {
* as reference is valid.
*/
public NetworkStatsCollection getOrLoadCompleteLocked() {
- NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
- if (complete == null) {
- if (LOGD) Slog.d(TAG, "getOrLoadCompleteLocked() reading from disk for " + mCookie);
- try {
- complete = new NetworkStatsCollection(mBucketDuration);
- mRotator.readMatching(complete, Long.MIN_VALUE, Long.MAX_VALUE);
- complete.recordCollection(mPending);
- mComplete = new WeakReference<NetworkStatsCollection>(complete);
- } catch (IOException e) {
- Log.wtf(TAG, "problem completely reading network stats", e);
- recoverFromWtf();
- } catch (OutOfMemoryError e) {
- Log.wtf(TAG, "problem completely reading network stats", e);
- recoverFromWtf();
- }
+ NetworkStatsCollection res = mComplete != null ? mComplete.get() : null;
+ if (res == null) {
+ res = loadLocked(Long.MIN_VALUE, Long.MAX_VALUE);
+ mComplete = new WeakReference<NetworkStatsCollection>(res);
}
- return complete;
+ return res;
+ }
+
+ public NetworkStatsCollection getOrLoadPartialLocked(long start, long end) {
+ NetworkStatsCollection res = mComplete != null ? mComplete.get() : null;
+ if (res == null) {
+ res = loadLocked(start, end);
+ }
+ return res;
+ }
+
+ private NetworkStatsCollection loadLocked(long start, long end) {
+ if (LOGD) Slog.d(TAG, "loadLocked() reading from disk for " + mCookie);
+ final NetworkStatsCollection res = new NetworkStatsCollection(mBucketDuration);
+ try {
+ mRotator.readMatching(res, start, end);
+ res.recordCollection(mPending);
+ } catch (IOException e) {
+ Log.wtf(TAG, "problem completely reading network stats", e);
+ recoverFromWtf();
+ } catch (OutOfMemoryError e) {
+ Log.wtf(TAG, "problem completely reading network stats", e);
+ recoverFromWtf();
+ }
+ return res;
}
/**
@@ -384,6 +398,11 @@ public class NetworkStatsRecorder {
}
}
+ public void dumpCheckin(PrintWriter pw, long start, long end) {
+ // Only load and dump stats from the requested window
+ getOrLoadPartialLocked(start, end).dumpCheckin(pw, start, end);
+ }
+
/**
* Recover from {@link FileRotator} failure by dumping state to
* {@link DropBoxManager} and deleting contents.
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 150ad34..61f9a26 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -104,6 +104,7 @@ import android.provider.Settings;
import android.provider.Settings.Global;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
+import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
@@ -1094,12 +1095,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
@Override
- protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+ long duration = DateUtils.DAY_IN_MILLIS;
final HashSet<String> argSet = new HashSet<String>();
for (String arg : args) {
argSet.add(arg);
+
+ if (arg.startsWith("--duration=")) {
+ try {
+ duration = Long.parseLong(arg.substring(11));
+ } catch (NumberFormatException ignored) {
+ }
+ }
}
// usage: dumpsys netstats --full --uid --tag --poll --checkin
@@ -1109,7 +1118,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
- final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
+ final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
synchronized (mStatsLock) {
if (poll) {
@@ -1119,13 +1128,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
if (checkin) {
- // list current stats files to verify rotation
- pw.println("Current files:");
- pw.increaseIndent();
- for (String file : mBaseDir.list()) {
- pw.println(file);
+ final long end = System.currentTimeMillis();
+ final long start = end - duration;
+
+ pw.print("v1,");
+ pw.print(start / SECOND_IN_MILLIS); pw.print(',');
+ pw.print(end / SECOND_IN_MILLIS); pw.println();
+
+ pw.println("xt");
+ mXtRecorder.dumpCheckin(rawWriter, start, end);
+
+ if (includeUid) {
+ pw.println("uid");
+ mUidRecorder.dumpCheckin(rawWriter, start, end);
+ }
+ if (includeTag) {
+ pw.println("tag");
+ mUidTagRecorder.dumpCheckin(rawWriter, start, end);
}
- pw.decreaseIndent();
return;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 42a8551..6958ff8 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1931,12 +1931,7 @@ public class NotificationManagerService extends SystemService {
if (hasValidSound) {
boolean looping =
(notification.flags & Notification.FLAG_INSISTENT) != 0;
- AudioAttributes audioAttributes;
- if (notification.audioAttributes != null) {
- audioAttributes = notification.audioAttributes;
- } else {
- audioAttributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
- }
+ AudioAttributes audioAttributes = audioAttributesForNotification(notification);
mSoundNotification = record;
// do not play notifications if stream volume is 0 (typically because
// ringer mode is silent) or if there is a user of exclusive audio focus
@@ -2030,7 +2025,9 @@ public class NotificationManagerService extends SystemService {
}
private static AudioAttributes audioAttributesForNotification(Notification n) {
- if (n.audioAttributes != null) {
+ if (n.audioAttributes != null
+ && !Notification.AUDIO_ATTRIBUTES_DEFAULT.equals(n.audioAttributes)) {
+ // the audio attributes are set and different from the default, use them
return n.audioAttributes;
} else if (n.audioStreamType >= 0 && n.audioStreamType < AudioSystem.getNumStreamTypes()) {
// the stream type is valid, use it
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 195a886..b891d0c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7379,6 +7379,23 @@ public class PackageManagerService extends IPackageManager.Stub {
out.println(Integer.toHexString(System.identityHashCode(filter)));
}
+ @Override
+ protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
+ return filter.activity;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ PackageParser.Activity activity = (PackageParser.Activity)label;
+ out.print(prefix); out.print(
+ Integer.toHexString(System.identityHashCode(activity)));
+ out.print(' ');
+ activity.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" ("); out.print(count); out.print(" filters)");
+ }
+ out.println();
+ }
+
// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
// final Iterator<ResolveInfo> i = resolveInfoList.iterator();
// final List<ResolveInfo> retList = Lists.newArrayList();
@@ -7578,6 +7595,23 @@ public class PackageManagerService extends IPackageManager.Stub {
out.println(Integer.toHexString(System.identityHashCode(filter)));
}
+ @Override
+ protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
+ return filter.service;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ PackageParser.Service service = (PackageParser.Service)label;
+ out.print(prefix); out.print(
+ Integer.toHexString(System.identityHashCode(service)));
+ out.print(' ');
+ service.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" ("); out.print(count); out.print(" filters)");
+ }
+ out.println();
+ }
+
// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
// final Iterator<ResolveInfo> i = resolveInfoList.iterator();
// final List<ResolveInfo> retList = Lists.newArrayList();
@@ -7785,6 +7819,23 @@ public class PackageManagerService extends IPackageManager.Stub {
out.println(Integer.toHexString(System.identityHashCode(filter)));
}
+ @Override
+ protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
+ return filter.provider;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ PackageParser.Provider provider = (PackageParser.Provider)label;
+ out.print(prefix); out.print(
+ Integer.toHexString(System.identityHashCode(provider)));
+ out.print(' ');
+ provider.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" ("); out.print(count); out.print(" filters)");
+ }
+ out.println();
+ }
+
private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
= new ArrayMap<ComponentName, PackageParser.Provider>();
private int mFlags;
@@ -12555,22 +12606,22 @@ public class PackageManagerService extends IPackageManager.Stub {
if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
: "Activity Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
: "Receiver Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
: "Service Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
: "Provider Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
}
@@ -12583,7 +12634,7 @@ public class PackageManagerService extends IPackageManager.Stub {
dumpState.getTitlePrinted()
? "\nPreferred Activities User " + user + ":"
: "Preferred Activities User " + user + ":", " ",
- packageName, true)) {
+ packageName, true, false)) {
dumpState.setTitlePrinted(true);
}
}
@@ -12676,8 +12727,8 @@ public class PackageManagerService extends IPackageManager.Stub {
mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
}
- if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
- mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
+ if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
+ mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index f0506a6..393ebd6 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3608,31 +3608,36 @@ final class Settings {
}
}
- void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
+ void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState,
+ boolean checkin) {
boolean printedSomething = false;
for (SharedUserSetting su : mSharedUsers.values()) {
if (packageName != null && su != dumpState.getSharedUser()) {
continue;
}
- if (!printedSomething) {
- if (dumpState.onTitlePrinted())
- pw.println();
- pw.println("Shared users:");
- printedSomething = true;
- }
- pw.print(" SharedUser [");
- pw.print(su.name);
- pw.print("] (");
- pw.print(Integer.toHexString(System.identityHashCode(su)));
- pw.println("):");
- pw.print(" userId=");
- pw.print(su.userId);
- pw.print(" gids=");
- pw.println(PackageManagerService.arrayToString(su.gids));
- pw.println(" grantedPermissions:");
- for (String s : su.grantedPermissions) {
- pw.print(" ");
- pw.println(s);
+ if (!checkin) {
+ if (!printedSomething) {
+ if (dumpState.onTitlePrinted())
+ pw.println();
+ pw.println("Shared users:");
+ printedSomething = true;
+ }
+ pw.print(" SharedUser [");
+ pw.print(su.name);
+ pw.print("] (");
+ pw.print(Integer.toHexString(System.identityHashCode(su)));
+ pw.println("):");
+ pw.print(" userId=");
+ pw.print(su.userId);
+ pw.print(" gids=");
+ pw.println(PackageManagerService.arrayToString(su.gids));
+ pw.println(" grantedPermissions:");
+ for (String s : su.grantedPermissions) {
+ pw.print(" ");
+ pw.println(s);
+ }
+ } else {
+ pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
}
}
}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 94a628d..1349926 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -38,6 +38,7 @@ import android.os.Handler;
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.SystemClock;
@@ -70,9 +71,9 @@ final class Notifier {
private static final boolean DEBUG = false;
- private static final int POWER_STATE_UNKNOWN = 0;
- private static final int POWER_STATE_AWAKE = 1;
- private static final int POWER_STATE_ASLEEP = 2;
+ private static final int INTERACTIVE_STATE_UNKNOWN = 0;
+ private static final int INTERACTIVE_STATE_AWAKE = 1;
+ private static final int INTERACTIVE_STATE_ASLEEP = 2;
private static final int MSG_USER_ACTIVITY = 1;
private static final int MSG_BROADCAST = 2;
@@ -92,17 +93,17 @@ final class Notifier {
private final Intent mScreenOnIntent;
private final Intent mScreenOffIntent;
- // The current power state.
- private int mActualPowerState;
- private int mLastGoToSleepReason;
+ // The current interactive state.
+ private int mActualInteractiveState;
+ private int mLastReason;
// True if there is a pending transition that needs to be reported.
private boolean mPendingWakeUpBroadcast;
private boolean mPendingGoToSleepBroadcast;
- // The currently broadcasted power state. This reflects what other parts of the
+ // The currently broadcasted interactive state. This reflects what other parts of the
// system have observed.
- private int mBroadcastedPowerState;
+ private int mBroadcastedInteractiveState;
private boolean mBroadcastInProgress;
private long mBroadcastStartTime;
@@ -236,62 +237,83 @@ final class Notifier {
}
/**
- * Notifies that the device is changing interactive state.
+ * Notifies that the device is changing wakefulness.
*/
- public void onInteractiveStateChangeStarted(boolean interactive, final int reason) {
+ public void onWakefulnessChangeStarted(int wakefulness, int reason) {
if (DEBUG) {
- Slog.d(TAG, "onInteractiveChangeStarted: interactive=" + interactive
+ Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
+ ", reason=" + reason);
}
+ // We handle interactive state changes once they start so that the system can
+ // set everything up or the user to begin interacting with applications.
+ final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
+ if (interactive) {
+ handleWakefulnessChange(wakefulness, interactive, reason);
+ } else {
+ mLastReason = reason;
+ }
+
+ // Start input as soon as we start waking up or going to sleep.
+ mInputManagerInternal.setInteractive(interactive);
+ }
+
+ /**
+ * Notifies that the device has finished changing wakefulness.
+ */
+ public void onWakefulnessChangeFinished(int wakefulness) {
+ if (DEBUG) {
+ Slog.d(TAG, "onWakefulnessChangeFinished: wakefulness=" + wakefulness);
+ }
+
+ // Handle interactive state changes once they are finished so that the system can
+ // finish pending transitions (such as turning the screen off) before causing
+ // applications to change state visibly.
+ final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
+ if (!interactive) {
+ handleWakefulnessChange(wakefulness, interactive, mLastReason);
+ }
+ }
+
+ private void handleWakefulnessChange(final int wakefulness, boolean interactive,
+ final int reason) {
+ // Tell the activity manager about changes in wakefulness, not just interactivity.
+ // It needs more granularity than other components.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mActivityManagerInternal.onWakefulnessChanged(wakefulness);
+ }
+ });
+
+ // Handle changes in the overall interactive state.
+ boolean interactiveChanged = false;
synchronized (mLock) {
+ // Broadcast interactive state changes.
if (interactive) {
// Waking up...
- if (mActualPowerState != POWER_STATE_AWAKE) {
- mActualPowerState = POWER_STATE_AWAKE;
+ interactiveChanged = (mActualInteractiveState != INTERACTIVE_STATE_AWAKE);
+ if (interactiveChanged) {
+ mActualInteractiveState = INTERACTIVE_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
mHandler.post(new Runnable() {
@Override
public void run() {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
mPolicy.wakingUp();
- mActivityManagerInternal.wakingUp();
}
});
updatePendingBroadcastLocked();
}
} else {
// Going to sleep...
- mLastGoToSleepReason = reason;
- }
- }
-
- mInputManagerInternal.setInteractive(interactive);
-
- if (interactive) {
- try {
- mBatteryStats.noteInteractive(true);
- } catch (RemoteException ex) { }
- }
- }
-
- /**
- * Notifies that the device has finished changing interactive state.
- */
- public void onInteractiveStateChangeFinished(boolean interactive) {
- if (DEBUG) {
- Slog.d(TAG, "onInteractiveChangeFinished");
- }
-
- synchronized (mLock) {
- if (!interactive) {
- // Finished going to sleep...
// This is a good time to make transitions that we don't want the user to see,
// such as bringing the key guard to focus. There's no guarantee for this,
// however because the user could turn the device on again at any time.
// Some things may need to be protected by other mechanisms that defer screen on.
- if (mActualPowerState != POWER_STATE_ASLEEP) {
- mActualPowerState = POWER_STATE_ASLEEP;
+ interactiveChanged = (mActualInteractiveState != INTERACTIVE_STATE_ASLEEP);
+ if (interactiveChanged) {
+ mActualInteractiveState = INTERACTIVE_STATE_ASLEEP;
mPendingGoToSleepBroadcast = true;
if (mUserActivityPending) {
mUserActivityPending = false;
@@ -301,7 +323,7 @@ final class Notifier {
@Override
public void run() {
int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER;
- switch (mLastGoToSleepReason) {
+ switch (reason) {
case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
break;
@@ -311,7 +333,6 @@ final class Notifier {
}
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
mPolicy.goingToSleep(why);
- mActivityManagerInternal.goingToSleep();
}
});
updatePendingBroadcastLocked();
@@ -319,9 +340,10 @@ final class Notifier {
}
}
- if (!interactive) {
+ // Notify battery stats.
+ if (interactiveChanged) {
try {
- mBatteryStats.noteInteractive(false);
+ mBatteryStats.noteInteractive(interactive);
} catch (RemoteException ex) { }
}
}
@@ -366,9 +388,9 @@ final class Notifier {
private void updatePendingBroadcastLocked() {
if (!mBroadcastInProgress
- && mActualPowerState != POWER_STATE_UNKNOWN
+ && mActualInteractiveState != INTERACTIVE_STATE_UNKNOWN
&& (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
- || mActualPowerState != mBroadcastedPowerState)) {
+ || mActualInteractiveState != mBroadcastedInteractiveState)) {
mBroadcastInProgress = true;
mSuspendBlocker.acquire();
Message msg = mHandler.obtainMessage(MSG_BROADCAST);
@@ -396,16 +418,16 @@ final class Notifier {
private void sendNextBroadcast() {
final int powerState;
synchronized (mLock) {
- if (mBroadcastedPowerState == POWER_STATE_UNKNOWN) {
+ if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
// Broadcasted power state is unknown. Send wake up.
mPendingWakeUpBroadcast = false;
- mBroadcastedPowerState = POWER_STATE_AWAKE;
- } else if (mBroadcastedPowerState == POWER_STATE_AWAKE) {
+ mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
+ } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
// Broadcasted power state is awake. Send asleep if needed.
if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
- || mActualPowerState == POWER_STATE_ASLEEP) {
+ || mActualInteractiveState == INTERACTIVE_STATE_ASLEEP) {
mPendingGoToSleepBroadcast = false;
- mBroadcastedPowerState = POWER_STATE_ASLEEP;
+ mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
} else {
finishPendingBroadcastLocked();
return;
@@ -413,9 +435,9 @@ final class Notifier {
} else {
// Broadcasted power state is asleep. Send awake if needed.
if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
- || mActualPowerState == POWER_STATE_AWAKE) {
+ || mActualInteractiveState == INTERACTIVE_STATE_AWAKE) {
mPendingWakeUpBroadcast = false;
- mBroadcastedPowerState = POWER_STATE_AWAKE;
+ mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
} else {
finishPendingBroadcastLocked();
return;
@@ -423,12 +445,12 @@ final class Notifier {
}
mBroadcastStartTime = SystemClock.uptimeMillis();
- powerState = mBroadcastedPowerState;
+ powerState = mBroadcastedInteractiveState;
}
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
- if (powerState == POWER_STATE_AWAKE) {
+ if (powerState == INTERACTIVE_STATE_AWAKE) {
sendWakeUpBroadcast();
} else {
sendGoToSleepBroadcast();
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 4d8b98f..4d1ab4c 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -61,7 +61,6 @@ import android.os.WorkSource;
import android.provider.Settings;
import android.service.dreams.DreamManagerInternal;
import android.util.EventLog;
-import android.util.Log;
import android.util.Slog;
import android.util.TimeUtils;
import android.view.Display;
@@ -73,6 +72,11 @@ import java.util.ArrayList;
import libcore.util.Objects;
+import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
+import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
+import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
+import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
+
/**
* The power manager service is responsible for coordinating power management
* functions on the device.
@@ -116,24 +120,6 @@ public final class PowerManagerService extends SystemService
// Dirty bit: brightness boost changed
private static final int DIRTY_SCREEN_BRIGHTNESS_BOOST = 1 << 11;
- // Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
- // The screen should be off or in the process of being turned off by the display controller.
- // The device typically passes through the dozing state first.
- private static final int WAKEFULNESS_ASLEEP = 0;
- // Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
- // When the user activity timeout expires, the device may start dreaming or go to sleep.
- private static final int WAKEFULNESS_AWAKE = 1;
- // Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
- // which ends the dream. The device goes to sleep when goToSleep() is called, when
- // the dream ends or when unplugged.
- // User activity may brighten the screen but does not end the dream.
- private static final int WAKEFULNESS_DREAMING = 2;
- // Wakefulness: The device is dozing. It is almost asleep but is allowing a special
- // low-power "doze" dream to run which keeps the display on but lets the application
- // processor be suspended. It can be awoken by a call to wakeUp() which ends the dream.
- // The device fully goes to sleep if the dream cannot be started or ends on its own.
- private static final int WAKEFULNESS_DOZING = 3;
-
// Summarizes the state of all active wakelocks.
private static final int WAKE_LOCK_CPU = 1 << 0;
private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
@@ -187,6 +173,7 @@ public final class PowerManagerService extends SystemService
// Indicates whether the device is awake or asleep or somewhere in between.
// This is distinct from the screen power state, which is managed separately.
private int mWakefulness;
+ private boolean mWakefulnessChanging;
// True if the sandman has just been summoned for the first time since entering the
// dreaming or dozing state. Indicates whether a new dream should begin.
@@ -205,10 +192,6 @@ public final class PowerManagerService extends SystemService
// A bitfield that summarizes the state of all active wakelocks.
private int mWakeLockSummary;
- // True if the device is in an interactive state.
- private boolean mInteractive;
- private boolean mInteractiveChanging;
-
// If true, instructs the display controller to wait for the proximity sensor to
// go negative before turning the screen on.
private boolean mRequestWaitForNegativeProximity;
@@ -467,7 +450,6 @@ public final class PowerManagerService extends SystemService
mHalInteractiveModeEnabled = true;
mWakefulness = WAKEFULNESS_AWAKE;
- mInteractive = true;
nativeInit();
nativeSetAutoSuspend(false);
@@ -1047,9 +1029,7 @@ public final class PowerManagerService extends SystemService
}
mLastWakeTime = eventTime;
- mDirty |= DIRTY_WAKEFULNESS;
- mWakefulness = WAKEFULNESS_AWAKE;
- setInteractiveStateLocked(true, 0);
+ setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
userActivityNoUpdateLocked(
eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
@@ -1109,10 +1089,8 @@ public final class PowerManagerService extends SystemService
}
mLastSleepTime = eventTime;
- mDirty |= DIRTY_WAKEFULNESS;
- mWakefulness = WAKEFULNESS_DOZING;
mSandmanSummoned = true;
- setInteractiveStateLocked(false, reason);
+ setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
// Report the number of wake locks that will be cleared by going to sleep.
int numWakeLocksCleared = 0;
@@ -1161,10 +1139,8 @@ public final class PowerManagerService extends SystemService
try {
Slog.i(TAG, "Nap time (uid " + uid +")...");
- mDirty |= DIRTY_WAKEFULNESS;
- mWakefulness = WAKEFULNESS_DREAMING;
mSandmanSummoned = true;
- setInteractiveStateLocked(true, 0);
+ setWakefulnessLocked(WAKEFULNESS_DREAMING, 0);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -1187,29 +1163,28 @@ public final class PowerManagerService extends SystemService
try {
Slog.i(TAG, "Sleeping (uid " + uid +")...");
- mDirty |= DIRTY_WAKEFULNESS;
- mWakefulness = WAKEFULNESS_ASLEEP;
- setInteractiveStateLocked(false, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+ setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
return true;
}
- private void setInteractiveStateLocked(boolean interactive, int reason) {
- if (mInteractive != interactive) {
- finishInteractiveStateChangeLocked();
+ private void setWakefulnessLocked(int wakefulness, int reason) {
+ if (mWakefulness != wakefulness) {
+ finishWakefulnessChangeLocked();
- mInteractive = interactive;
- mInteractiveChanging = true;
- mNotifier.onInteractiveStateChangeStarted(interactive, reason);
+ mWakefulness = wakefulness;
+ mWakefulnessChanging = true;
+ mDirty |= DIRTY_WAKEFULNESS;
+ mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
}
}
- private void finishInteractiveStateChangeLocked() {
- if (mInteractiveChanging) {
- mNotifier.onInteractiveStateChangeFinished(mInteractive);
- mInteractiveChanging = false;
+ private void finishWakefulnessChangeLocked() {
+ if (mWakefulnessChanging) {
+ mNotifier.onWakefulnessChangeFinished(mWakefulness);
+ mWakefulnessChanging = false;
}
}
@@ -1261,7 +1236,7 @@ public final class PowerManagerService extends SystemService
// Phase 4: Send notifications, if needed.
if (mDisplayReady) {
- finishInteractiveStateChangeLocked();
+ finishWakefulnessChangeLocked();
}
// Phase 5: Update suspend blocker.
@@ -1450,7 +1425,7 @@ public final class PowerManagerService extends SystemService
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
- + wakefulnessToString(mWakefulness)
+ + PowerManagerInternal.wakefulnessToString(mWakefulness)
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
}
}
@@ -1527,7 +1502,7 @@ public final class PowerManagerService extends SystemService
if (DEBUG_SPEW) {
Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
- + wakefulnessToString(mWakefulness)
+ + PowerManagerInternal.wakefulnessToString(mWakefulness)
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+ ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
}
@@ -2150,7 +2125,7 @@ public final class PowerManagerService extends SystemService
private boolean isInteractiveInternal() {
synchronized (mLock) {
- return mInteractive;
+ return PowerManagerInternal.isInteractive(mWakefulness);
}
}
@@ -2428,8 +2403,8 @@ public final class PowerManagerService extends SystemService
synchronized (mLock) {
pw.println("Power Manager State:");
pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
- pw.println(" mWakefulness=" + wakefulnessToString(mWakefulness));
- pw.println(" mInteractive=" + mInteractive);
+ pw.println(" mWakefulness=" + PowerManagerInternal.wakefulnessToString(mWakefulness));
+ pw.println(" mWakefulnessChanging=" + mWakefulnessChanging);
pw.println(" mIsPowered=" + mIsPowered);
pw.println(" mPlugType=" + mPlugType);
pw.println(" mBatteryLevel=" + mBatteryLevel);
@@ -2564,21 +2539,6 @@ public final class PowerManagerService extends SystemService
return suspendBlocker;
}
- private static String wakefulnessToString(int wakefulness) {
- switch (wakefulness) {
- case WAKEFULNESS_ASLEEP:
- return "Asleep";
- case WAKEFULNESS_AWAKE:
- return "Awake";
- case WAKEFULNESS_DREAMING:
- return "Dreaming";
- case WAKEFULNESS_DOZING:
- return "Dozing";
- default:
- return Integer.toString(wakefulness);
- }
- }
-
private static WorkSource copyWorkSource(WorkSource workSource) {
return workSource != null ? new WorkSource(workSource) : null;
}
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 4906bd1..57b204d 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -232,6 +232,12 @@ public class TrustAgentWrapper {
mTrustManagerService.mArchive.logAgentConnected(mUserId, name);
setCallback(mCallback);
updateDevicePolicyFeatures();
+
+ if (mTrustManagerService.isDeviceLockedInner(mUserId)) {
+ onDeviceLocked();
+ } else {
+ onDeviceUnlocked();
+ }
}
@Override
@@ -287,6 +293,7 @@ public class TrustAgentWrapper {
onError(e);
}
}
+
/**
* @see android.service.trust.TrustAgentService#onUnlockAttempt(boolean)
*/
@@ -298,6 +305,28 @@ public class TrustAgentWrapper {
}
}
+ /**
+ * @see android.service.trust.TrustAgentService#onDeviceLocked()
+ */
+ public void onDeviceLocked() {
+ try {
+ if (mTrustAgentService != null) mTrustAgentService.onDeviceLocked();
+ } catch (RemoteException e) {
+ onError(e);
+ }
+ }
+
+ /**
+ * @see android.service.trust.TrustAgentService#onDeviceUnlocked()
+ */
+ public void onDeviceUnlocked() {
+ try {
+ if (mTrustAgentService != null) mTrustAgentService.onDeviceUnlocked();
+ } catch (RemoteException e) {
+ onError(e);
+ }
+ }
+
private void setCallback(ITrustAgentServiceCallback callback) {
try {
if (mTrustAgentService != null) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 2388c85..cd1c9a5 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -26,7 +26,6 @@ import org.xmlpull.v1.XmlPullParserException;
import android.Manifest;
import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
import android.app.trust.ITrustListener;
import android.app.trust.ITrustManager;
@@ -61,6 +60,8 @@ import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.util.Xml;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -96,6 +97,10 @@ public class TrustManagerService extends SystemService {
private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5;
+ private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
+ private static final int MSG_START_USER = 7;
+ private static final int MSG_CLEANUP_USER = 8;
+ private static final int MSG_SWITCH_USER = 9;
private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
@@ -110,7 +115,11 @@ public class TrustManagerService extends SystemService {
@GuardedBy("mUserIsTrusted")
private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
+ @GuardedBy("mDeviceLockedForUser")
+ private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
+
private boolean mTrustAgentsCanRun = false;
+ private int mCurrentUser = UserHandle.USER_OWNER;
public TrustManagerService(Context context) {
super(context);
@@ -177,10 +186,15 @@ public class TrustManagerService extends SystemService {
public void updateTrust(int userId, boolean initiatedByUser) {
dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
boolean trusted = aggregateIsTrusted(userId);
+ boolean changed;
synchronized (mUserIsTrusted) {
+ changed = mUserIsTrusted.get(userId) != trusted;
mUserIsTrusted.put(userId, trusted);
}
dispatchOnTrustChanged(trusted, userId, initiatedByUser);
+ if (changed) {
+ refreshDeviceLockedForUser(userId);
+ }
}
void refreshAgentList(int userId) {
@@ -212,8 +226,7 @@ public class TrustManagerService extends SystemService {
|| userInfo.guestToRemove) continue;
if (!userInfo.supportsSwitchTo()) continue;
if (!mActivityManager.isUserRunning(userInfo.id)) continue;
- if (lockPatternUtils.getKeyguardStoredPasswordQuality(userInfo.id)
- == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue;
+ if (!lockPatternUtils.isSecure(userInfo.id)) continue;
if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue;
DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
@@ -273,6 +286,73 @@ public class TrustManagerService extends SystemService {
}
}
+ boolean isDeviceLockedInner(int userId) {
+ synchronized (mDeviceLockedForUser) {
+ return mDeviceLockedForUser.get(userId, true);
+ }
+ }
+
+ private void refreshDeviceLockedForUser(int userId) {
+ if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
+ Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
+ + " must be USER_ALL or a specific user.", new Throwable("here"));
+ userId = UserHandle.USER_ALL;
+ }
+
+ List<UserInfo> userInfos;
+ if (userId == UserHandle.USER_ALL) {
+ userInfos = mUserManager.getUsers(true /* excludeDying */);
+ } else {
+ userInfos = new ArrayList<>();
+ userInfos.add(mUserManager.getUserInfo(userId));
+ }
+
+ IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+
+ for (int i = 0; i < userInfos.size(); i++) {
+ UserInfo info = userInfos.get(i);
+
+ if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
+ || !info.supportsSwitchTo()) {
+ continue;
+ }
+
+ int id = info.id;
+ boolean secure = mLockPatternUtils.isSecure(id);
+ boolean trusted = aggregateIsTrusted(id);
+ boolean showingKeyguard = true;
+ if (mCurrentUser == id) {
+ try {
+ showingKeyguard = wm.isKeyguardLocked();
+ } catch (RemoteException e) {
+ }
+ }
+ boolean deviceLocked = secure && showingKeyguard && !trusted;
+
+ boolean changed;
+ synchronized (mDeviceLockedForUser) {
+ changed = isDeviceLockedInner(id) != deviceLocked;
+ mDeviceLockedForUser.put(id, deviceLocked);
+ }
+ if (changed) {
+ dispatchDeviceLocked(id, deviceLocked);
+ }
+ }
+ }
+
+ private void dispatchDeviceLocked(int userId, boolean isLocked) {
+ for (int i = 0; i < mActiveAgents.size(); i++) {
+ AgentInfo agent = mActiveAgents.valueAt(i);
+ if (agent.userId == userId) {
+ if (isLocked) {
+ agent.agent.onDeviceLocked();
+ } else{
+ agent.agent.onDeviceUnlocked();
+ }
+ }
+ }
+ }
+
void updateDevicePolicyFeatures() {
for (int i = 0; i < mActiveAgents.size(); i++) {
AgentInfo info = mActiveAgents.valueAt(i);
@@ -540,12 +620,17 @@ public class TrustManagerService extends SystemService {
@Override
public void onStartUser(int userId) {
- refreshAgentList(userId);
+ mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
}
@Override
public void onCleanupUser(int userId) {
- refreshAgentList(userId);
+ mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
+ }
+
+ @Override
+ public void onSwitchUser(int userId) {
+ mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
}
// Plumbing
@@ -578,6 +663,14 @@ public class TrustManagerService extends SystemService {
}
@Override
+ public void reportKeyguardShowingChanged() throws RemoteException {
+ enforceReportPermission();
+ // coalesce refresh messages.
+ mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
+ mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
+ }
+
+ @Override
public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
enforceListenerPermission();
mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
@@ -590,13 +683,12 @@ public class TrustManagerService extends SystemService {
}
@Override
- public boolean isTrusted(int userId) throws RemoteException {
+ public boolean isDeviceLocked(int userId) throws RemoteException {
userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
- false /* allowAll */, true /* requireFull */, "isTrusted", null);
+ false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
userId = resolveProfileParent(userId);
- synchronized (mUserIsTrusted) {
- return mUserIsTrusted.get(userId);
- }
+
+ return isDeviceLockedInner(userId);
}
private void enforceReportPermission() {
@@ -621,19 +713,13 @@ public class TrustManagerService extends SystemService {
fout.println("disabled because the third-party apps can't run yet.");
return;
}
- final UserInfo currentUser;
final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
- try {
- currentUser = ActivityManagerNative.getDefault().getCurrentUser();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
mHandler.runWithScissors(new Runnable() {
@Override
public void run() {
fout.println("Trust manager state:");
for (UserInfo user : userInfos) {
- dumpUser(fout, user, user.id == currentUser.id);
+ dumpUser(fout, user, user.id == mCurrentUser);
}
}
}, 1500);
@@ -642,11 +728,17 @@ public class TrustManagerService extends SystemService {
private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
fout.printf(" User \"%s\" (id=%d, flags=%#x)",
user.name, user.id, user.flags);
+ if (!user.supportsSwitchTo()) {
+ fout.println("(managed profile)");
+ fout.println(" disabled because switching to this user is not possible.");
+ return;
+ }
if (isCurrent) {
fout.print(" (current)");
}
fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
+ fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
fout.println();
fout.println(" Enabled agents:");
boolean duplicateSimpleNames = false;
@@ -711,10 +803,23 @@ public class TrustManagerService extends SystemService {
break;
case MSG_ENABLED_AGENTS_CHANGED:
refreshAgentList(UserHandle.USER_ALL);
+ // This is also called when the security mode of a user changes.
+ refreshDeviceLockedForUser(UserHandle.USER_ALL);
break;
case MSG_REQUIRE_CREDENTIAL_ENTRY:
requireCredentialEntry(msg.arg1);
break;
+ case MSG_KEYGUARD_SHOWING_CHANGED:
+ refreshDeviceLockedForUser(mCurrentUser);
+ break;
+ case MSG_START_USER:
+ case MSG_CLEANUP_USER:
+ refreshAgentList(msg.arg1);
+ break;
+ case MSG_SWITCH_USER:
+ mCurrentUser = msg.arg1;
+ refreshDeviceLockedForUser(UserHandle.USER_ALL);
+ break;
}
}
};
@@ -756,8 +861,14 @@ public class TrustManagerService extends SystemService {
int userId = getUserId(intent);
if (userId > 0) {
mUserHasAuthenticatedSinceBoot.delete(userId);
- mUserIsTrusted.delete(userId);
+ synchronized (mUserIsTrusted) {
+ mUserIsTrusted.delete(userId);
+ }
+ synchronized (mDeviceLockedForUser) {
+ mDeviceLockedForUser.delete(userId);
+ }
refreshAgentList(userId);
+ refreshDeviceLockedForUser(userId);
}
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 85659cf..716487c 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -299,6 +299,13 @@ class TvInputHardwareManager implements TvInputHal.Callback {
return -1;
}
+ private static boolean intArrayContains(int[] array, int value) {
+ for (int element : array) {
+ if (element == value) return true;
+ }
+ return false;
+ }
+
public void addHdmiTvInput(int id, TvInputInfo info) {
if (info.getType() != TvInputInfo.TYPE_HDMI) {
throw new IllegalArgumentException("info (" + info + ") has non-HDMI type.");
@@ -673,28 +680,35 @@ class TvInputHardwareManager implements TvInputHal.Callback {
if (mReleased) {
throw new IllegalStateException("Device already released.");
}
- if (surface != null && config == null) {
- return false;
- }
- if (surface == null && mActiveConfig == null) {
- return false;
- }
- int result = TvInputHal.ERROR_UNKNOWN;
+ int result = TvInputHal.SUCCESS;
if (surface == null) {
- result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig);
- mActiveConfig = null;
+ // The value of config is ignored when surface == null.
+ if (mActiveConfig != null) {
+ result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig);
+ mActiveConfig = null;
+ } else {
+ // We already have no active stream.
+ return true;
+ }
} else {
- if (!config.equals(mActiveConfig)) {
+ // It's impossible to set a non-null surface with a null config.
+ if (config == null) {
+ return false;
+ }
+ // Remove stream only if we have an existing active configuration.
+ if (mActiveConfig != null && !config.equals(mActiveConfig)) {
result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig);
if (result != TvInputHal.SUCCESS) {
mActiveConfig = null;
- return false;
}
}
- result = mHal.addOrUpdateStream(mInfo.getDeviceId(), surface, config);
+ // Proceed only if all previous operations succeeded.
if (result == TvInputHal.SUCCESS) {
- mActiveConfig = config;
+ result = mHal.addOrUpdateStream(mInfo.getDeviceId(), surface, config);
+ if (result == TvInputHal.SUCCESS) {
+ mActiveConfig = config;
+ }
}
}
updateAudioConfigLocked();
@@ -755,20 +769,64 @@ class TvInputHardwareManager implements TvInputHal.Callback {
AudioPortConfig sinkConfig = mAudioSink.activeConfig();
AudioPatch[] audioPatchArray = new AudioPatch[] { mAudioPatch };
boolean shouldRecreateAudioPatch = sourceUpdated || sinkUpdated;
+
+ int sinkSamplingRate = mDesiredSamplingRate;
+ int sinkChannelMask = mDesiredChannelMask;
+ int sinkFormat = mDesiredFormat;
+ // If sinkConfig != null and values are set to default, fill in the sinkConfig values.
+ if (sinkConfig != null) {
+ if (sinkSamplingRate == 0) {
+ sinkSamplingRate = sinkConfig.samplingRate();
+ }
+ if (sinkChannelMask == AudioFormat.CHANNEL_OUT_DEFAULT) {
+ sinkChannelMask = sinkConfig.channelMask();
+ }
+ if (sinkFormat == AudioFormat.ENCODING_DEFAULT) {
+ sinkChannelMask = sinkConfig.format();
+ }
+ }
+
if (sinkConfig == null
- || (mDesiredSamplingRate != 0
- && sinkConfig.samplingRate() != mDesiredSamplingRate)
- || (mDesiredChannelMask != AudioFormat.CHANNEL_OUT_DEFAULT
- && sinkConfig.channelMask() != mDesiredChannelMask)
- || (mDesiredFormat != AudioFormat.ENCODING_DEFAULT
- && sinkConfig.format() != mDesiredFormat)) {
- sinkConfig = mAudioSink.buildConfig(mDesiredSamplingRate, mDesiredChannelMask,
- mDesiredFormat, null);
+ || sinkConfig.samplingRate() != sinkSamplingRate
+ || sinkConfig.channelMask() != sinkChannelMask
+ || sinkConfig.format() != sinkFormat) {
+ // Check for compatibility and reset to default if necessary.
+ if (!intArrayContains(mAudioSink.samplingRates(), sinkSamplingRate)
+ && mAudioSink.samplingRates().length > 0) {
+ sinkSamplingRate = mAudioSink.samplingRates()[0];
+ }
+ if (!intArrayContains(mAudioSink.channelMasks(), sinkChannelMask)) {
+ sinkChannelMask = AudioFormat.CHANNEL_OUT_DEFAULT;
+ }
+ if (!intArrayContains(mAudioSink.formats(), sinkFormat)) {
+ sinkFormat = AudioFormat.ENCODING_DEFAULT;
+ }
+ sinkConfig = mAudioSink.buildConfig(sinkSamplingRate, sinkChannelMask,
+ sinkFormat, null);
shouldRecreateAudioPatch = true;
}
if (sourceConfig == null || sourceGainConfig != null) {
- sourceConfig = mAudioSource.buildConfig(sinkConfig.samplingRate(),
- sinkConfig.channelMask(), sinkConfig.format(), sourceGainConfig);
+ int sourceSamplingRate = 0;
+ if (intArrayContains(mAudioSource.samplingRates(), sinkConfig.samplingRate())) {
+ sourceSamplingRate = sinkConfig.samplingRate();
+ } else if (mAudioSource.samplingRates().length > 0) {
+ // Use any sampling rate and hope audio patch can handle resampling...
+ sourceSamplingRate = mAudioSource.samplingRates()[0];
+ }
+ int sourceChannelMask = AudioFormat.CHANNEL_IN_DEFAULT;
+ for (int inChannelMask : mAudioSource.channelMasks()) {
+ if (AudioFormat.channelCountFromOutChannelMask(sinkConfig.channelMask())
+ == AudioFormat.channelCountFromInChannelMask(inChannelMask)) {
+ sourceChannelMask = inChannelMask;
+ break;
+ }
+ }
+ int sourceFormat = AudioFormat.ENCODING_DEFAULT;
+ if (intArrayContains(mAudioSource.formats(), sinkConfig.format())) {
+ sourceFormat = sinkConfig.format();
+ }
+ sourceConfig = mAudioSource.buildConfig(sourceSamplingRate, sourceChannelMask,
+ sourceFormat, sourceGainConfig);
shouldRecreateAudioPatch = true;
}
if (shouldRecreateAudioPatch) {
@@ -778,6 +836,9 @@ class TvInputHardwareManager implements TvInputHal.Callback {
new AudioPortConfig[] { sourceConfig },
new AudioPortConfig[] { sinkConfig });
mAudioPatch = audioPatchArray[0];
+ if (sourceGainConfig != null) {
+ mAudioManager.setAudioPortGain(mAudioSource, sourceGainConfig);
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 7e6da8b..0cbf03a 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -992,12 +992,6 @@ final class AccessibilityController {
continue;
}
- // If the window is an accessibility overlay - ignore.
- if (windowState.mAttrs.type ==
- WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
- continue;
- }
-
// Compute the bounds in the screen.
final Rect boundsInScreen = mTempRect;
computeWindowBoundsInScreen(windowState, boundsInScreen);
@@ -1018,8 +1012,14 @@ final class AccessibilityController {
}
}
- unaccountedSpace.op(boundsInScreen, unaccountedSpace,
- Region.Op.REVERSE_DIFFERENCE);
+ // Account for the space this window takes if the window
+ // is not an accessibility overlay which does not change
+ // the reported windows.
+ if (windowState.mAttrs.type !=
+ WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
+ unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+ Region.Op.REVERSE_DIFFERENCE);
+ }
// We figured out what is touchable for the entire screen - done.
if (unaccountedSpace.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 1086eb2..f859fd2 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -254,15 +254,18 @@ class AppWindowToken extends WindowToken {
@Override
void removeAllWindows() {
- int winNdx;
- while ((winNdx = allAppWindows.size()) > 0) {
- WindowState win = allAppWindows.get(winNdx - 1);
+ for (int winNdx = allAppWindows.size() - 1; winNdx >= 0;
+ // removeWindowLocked at bottom of loop may remove multiple entries from
+ // allAppWindows if the window to be removed has child windows. It also may
+ // not remove any windows from allAppWindows at all if win is exiting and
+ // currently animating away. This ensures that winNdx is monotonically decreasing
+ // and never beyond allAppWindows bounds.
+ winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) {
+ WindowState win = allAppWindows.get(winNdx);
if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) {
Slog.w(WindowManagerService.TAG, "removeAllWindows: removing win=" + win);
}
- // {@link WindowManagerService.removeWindowLocked} may remove multiple entries from
- // {@link #allAppWindows} if the window to be removed has child windows.
win.mService.removeWindowLocked(win.mSession, win);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9e51849..6331dfe 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -34,6 +34,7 @@ import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IDevicePolicyManager;
+import android.app.backup.IBackupManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -76,6 +77,7 @@ import android.security.Credentials;
import android.security.IKeyChainService;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
+import android.text.TextUtils;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
@@ -2520,6 +2522,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @Override
public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) {
if (!mHasFeature) {
return 0;
@@ -2532,6 +2535,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @Override
+ public int getProfileWithMinimumFailedPasswordsForWipe(int userHandle) {
+ if (!mHasFeature) {
+ return UserHandle.USER_NULL;
+ }
+ enforceCrossUserPermission(userHandle);
+ synchronized (this) {
+ ActiveAdmin admin = getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
+ return admin != null ? admin.getUserHandle().getIdentifier() : UserHandle.USER_NULL;
+ }
+ }
+
/**
* Returns the admin with the strictest policy on maximum failed passwords for this user and all
* profiles that are visible from this user. If the policy for the primary and any other profile
@@ -2561,13 +2576,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return strictestAdmin;
}
- public boolean resetPassword(String password, int flags, int userHandle) {
+ public boolean resetPassword(String passwordOrNull, int flags, int userHandle) {
if (!mHasFeature) {
return false;
}
enforceCrossUserPermission(userHandle);
enforceNotManagedProfile(userHandle, "reset the password");
+ String password = passwordOrNull != null ? passwordOrNull : "";
+
int quality;
synchronized (this) {
// This api can only be called by an active device admin,
@@ -2671,7 +2688,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
long ident = Binder.clearCallingIdentity();
try {
LockPatternUtils utils = new LockPatternUtils(mContext);
- utils.saveLockPassword(password, quality, false, userHandle);
+ if (!TextUtils.isEmpty(password)) {
+ utils.saveLockPassword(password, quality, false, userHandle);
+ } else {
+ utils.clearLock(false, userHandle);
+ }
boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
if (requireEntry) {
utils.requireCredentialEntry(UserHandle.USER_ALL);
@@ -3652,6 +3673,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
"Trying to set device owner but device owner is already set.");
}
+ // Shutting down backup manager service permanently.
+ long ident = Binder.clearCallingIdentity();
+ try {
+ IBackupManager ibm = IBackupManager.Stub.asInterface(
+ ServiceManager.getService(Context.BACKUP_SERVICE));
+ ibm.setBackupServiceActive(UserHandle.USER_OWNER, false);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Failed deactivating backup service.", e);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
if (mDeviceOwner == null) {
// Device owner is not set and does not exist, set it.
mDeviceOwner = DeviceOwner.createWithDeviceOwner(packageName, ownerName);
@@ -3923,7 +3956,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final int n = policy.mAdminList.size();
for (int i = 0; i < n; i++) {
ActiveAdmin admin = policy.mAdminList.get(i);
- if (profileOwner.equals(admin.info)) {
+ if (profileOwner.equals(admin.info.getComponent())) {
return admin;
}
}
@@ -5040,13 +5073,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean isUninstallBlocked(ComponentName who, String packageName) {
+ // This function should return true if and only if the package is blocked by
+ // setUninstallBlocked(). It should still return false for other cases of blocks, such as
+ // when the package is a system app, or when it is an active device admin.
final int userId = UserHandle.getCallingUserId();
synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
+ if (who != null) {
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
}
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
long id = Binder.clearCallingIdentity();
try {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 8392672..b74716f 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -838,7 +838,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null, null, TEST_SSID);
+ return new NetworkState(info, prop, null, null, null, TEST_SSID);
}
private void expectCurrentTime() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index c115339..f9a03fc 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -1006,7 +1006,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null, null, TEST_SSID);
+ return new NetworkState(info, prop, null, null, null, TEST_SSID);
}
private static NetworkState buildMobile3gState(String subscriberId) {
@@ -1015,7 +1015,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null, subscriberId, null);
+ return new NetworkState(info, prop, null, null, subscriberId, null);
}
private static NetworkState buildMobile4gState(String iface) {
@@ -1023,7 +1023,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(iface);
- return new NetworkState(info, prop, null);
+ return new NetworkState(info, prop, null, null);
}
private NetworkStats buildEmptyStats() {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index c63eb18..23ba3b6 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -209,8 +209,13 @@ public class UsbDeviceManager {
mUseUsbNotification = !massStorageSupported;
// make sure the ADB_ENABLED setting value matches the current state
- Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
-
+ try {
+ Settings.Global.putInt(mContentResolver,
+ Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
+ } catch (SecurityException e) {
+ // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed.
+ Slog.d(TAG, "ADB_ENABLED is restricted.");
+ }
mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
}