diff options
Diffstat (limited to 'services')
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); } |