diff options
Diffstat (limited to 'services/core/java')
19 files changed, 315 insertions, 386 deletions
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index e9419ad..b04cc19 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -1535,7 +1535,7 @@ class AlarmManagerService extends SystemService { for (int i=0; i<triggerList.size(); i++) { Alarm alarm = triggerList.get(i); try { - if (localLOGV) Slog.v(TAG, "sending alarm " + alarm); + Slog.v(TAG, "sending alarm " + alarm); alarm.operation.send(getContext(), 0, mBackgroundIntent.putExtra( Intent.EXTRA_ALARM_COUNT, alarm.count), diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 5845ad0..2885b83 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -180,6 +180,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UpdateLock; import android.os.UserHandle; +import android.os.UserManager; import android.provider.Settings; import android.text.format.DateUtils; import android.text.format.Time; @@ -1077,13 +1078,16 @@ public final class ActivityManagerService extends ActivityManagerNative /** * Runtime CPU use collection thread. This object's lock is used to - * protect all related state. + * perform synchronization with the thread (notifying it to run). */ final Thread mProcessCpuThread; /** - * Used to collect process stats when showing not responding dialog. - * Protected by mProcessCpuThread. + * Used to collect per-process CPU use for ANRs, battery stats, etc. + * Must acquire this object's lock when accessing it. + * NOTE: this lock will be held while doing long operations (trawling + * through all processes in /proc), so it should never be acquired by + * any critical paths such as when holding the main activity manager lock. */ final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( MONITOR_THREAD_CPU_USAGE); @@ -1597,7 +1601,7 @@ public final class ActivityManagerService extends ActivityManagerNative infoMap.put(mi.pid, mi); } updateCpuStatsNow(); - synchronized (mProcessCpuThread) { + synchronized (mProcessCpuTracker) { final int N = mProcessCpuTracker.countStats(); for (int i=0; i<N; i++) { ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); @@ -1896,7 +1900,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (memInfo != null) { updateCpuStatsNow(); long nativeTotalPss = 0; - synchronized (mProcessCpuThread) { + synchronized (mProcessCpuTracker) { final int N = mProcessCpuTracker.countStats(); for (int j=0; j<N; j++) { ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); @@ -1914,7 +1918,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } memInfo.readMemInfo(); - synchronized (this) { + synchronized (ActivityManagerService.this) { if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " + (SystemClock.uptimeMillis()-start) + "ms"); mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), @@ -2185,7 +2189,7 @@ public final class ActivityManagerService extends ActivityManagerNative return; } - synchronized (mActivityManagerService.mProcessCpuThread) { + synchronized (mActivityManagerService.mProcessCpuTracker) { pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( SystemClock.uptimeMillis())); @@ -2381,7 +2385,7 @@ public final class ActivityManagerService extends ActivityManagerNative } void updateCpuStatsNow() { - synchronized (mProcessCpuThread) { + synchronized (mProcessCpuTracker) { mProcessCpuMutexFree.set(false); final long now = SystemClock.uptimeMillis(); boolean haveNewCpuStats = false; @@ -3366,6 +3370,16 @@ public final class ActivityManagerService extends ActivityManagerNative } } + void enforceShellRestriction(String restriction, int userHandle) { + if (Binder.getCallingUid() == Process.SHELL_UID) { + if (userHandle < 0 + || mUserManager.hasUserRestriction(restriction, userHandle)) { + throw new SecurityException("Shell does not have permission to access user " + + userHandle); + } + } + } + @Override public int getFrontActivityScreenCompatMode() { enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); @@ -5076,7 +5090,7 @@ public final class ActivityManagerService extends ActivityManagerNative String cpuInfo = null; if (MONITOR_CPU_USAGE) { updateCpuStatsNow(); - synchronized (mProcessCpuThread) { + synchronized (mProcessCpuTracker) { cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); } info.append(processCpuTracker.printCurrentLoad()); @@ -7468,12 +7482,33 @@ public final class ActivityManagerService extends ActivityManagerNative // Does the caller have this permission on the URI? if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { - // Right now, if you are not the original owner of the permission, - // you are not allowed to revoke it. - //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { - throw new SecurityException("Uid " + callingUid - + " does not have permission to uri " + grantUri); - //} + // Have they don't have direct access to the URI, then revoke any URI + // permissions that have been granted to them. + final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); + if (perms != null) { + boolean persistChanged = false; + for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { + final UriPermission perm = it.next(); + if (perm.uri.sourceUserId == grantUri.sourceUserId + && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { + if (DEBUG_URI_PERMISSION) + Slog.v(TAG, + "Revoking " + perm.targetUid + " permission to " + perm.uri); + persistChanged |= perm.revokeModes( + modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + if (perm.modeFlags == 0) { + it.remove(); + } + } + } + if (perms.isEmpty()) { + mGrantedUriPermissions.remove(callingUid); + } + if (persistChanged) { + schedulePersistUriGrants(); + } + } + return; } boolean persistChanged = false; @@ -9687,14 +9722,9 @@ public final class ActivityManagerService extends ActivityManagerNative long ident = 0; boolean clearedIdentity = false; userId = unsafeConvertIncomingUser(userId); - if (UserHandle.getUserId(callingUid) != userId) { - if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, - callingUid, -1, true) == PackageManager.PERMISSION_GRANTED - || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, - callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { - clearedIdentity = true; - ident = Binder.clearCallingIdentity(); - } + if (canClearIdentity(callingPid, callingUid, userId)) { + clearedIdentity = true; + ident = Binder.clearCallingIdentity(); } ContentProviderHolder holder = null; try { @@ -9722,6 +9752,19 @@ public final class ActivityManagerService extends ActivityManagerNative return null; } + private boolean canClearIdentity(int callingPid, int callingUid, int userId) { + if (UserHandle.getUserId(callingUid) == userId) { + return true; + } + if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, + callingUid, -1, true) == PackageManager.PERMISSION_GRANTED + || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, + callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { + return true; + } + return false; + } + // ========================================================= // GLOBAL MANAGEMENT // ========================================================= @@ -13722,7 +13765,7 @@ public final class ActivityManagerService extends ActivityManagerNative findPid = Integer.parseInt(args[opti]); } catch (NumberFormatException e) { } - synchronized (mProcessCpuThread) { + synchronized (mProcessCpuTracker) { final int N = mProcessCpuTracker.countStats(); for (int i=0; i<N; i++) { ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); @@ -13884,7 +13927,7 @@ public final class ActivityManagerService extends ActivityManagerNative // If we are showing aggregations, also look for native processes to // include so that our aggregations are more accurate. updateCpuStatsNow(); - synchronized (mProcessCpuThread) { + synchronized (mProcessCpuTracker) { final int N = mProcessCpuTracker.countStats(); for (int i=0; i<N; i++) { ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); @@ -14570,6 +14613,14 @@ public final class ActivityManagerService extends ActivityManagerNative throw new IllegalArgumentException( "Call does not support special user #" + targetUserId); } + // Check shell permission + if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { + if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, + targetUserId)) { + throw new SecurityException("Shell does not have permission to access user " + + targetUserId + "\n " + Debug.getCallers(3)); + } + } return targetUserId; } @@ -14594,13 +14645,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } else if ("system".equals(componentProcessName)) { result = true; - } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) - && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { - // Phone app is allowed to export singleuser providers. - result = true; - } else { - // App with pre-defined UID, check if it's a persistent app - result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; + } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { + // Phone app and persistent apps are allowed to export singleuser providers. + result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) + || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; } if (DEBUG_MU) { Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo @@ -14628,6 +14676,7 @@ public final class ActivityManagerService extends ActivityManagerNative Intent service, String resolvedType, IServiceConnection connection, int flags, int userId) { enforceNotIsolatedCaller("bindService"); + // Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); @@ -15062,12 +15111,18 @@ public final class ActivityManagerService extends ActivityManagerNative } private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, - int[] users) { + int callingUid, int[] users) { List<ResolveInfo> receivers = null; try { HashSet<ComponentName> singleUserReceivers = null; boolean scannedFirstReceivers = false; for (int user : users) { + // Skip users that have Shell restrictions + if (callingUid == Process.SHELL_UID + && getUserManagerLocked().hasUserRestriction( + UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { + continue; + } List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); if (user != 0 && newReceivers != null) { @@ -15156,7 +15211,6 @@ public final class ActivityManagerService extends ActivityManagerNative // Make sure that the user who is receiving this broadcast is started. // If not, we will just skip it. - if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { if (callingUid != Process.SYSTEM_UID || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { @@ -15421,11 +15475,30 @@ public final class ActivityManagerService extends ActivityManagerNative // Need to resolve the intent to interested receivers... if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { - receivers = collectReceiverComponents(intent, resolvedType, users); + receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); } if (intent.getComponent() == null) { - registeredReceivers = mReceiverResolver.queryIntent(intent, - resolvedType, false, userId); + if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { + // Query one target user at a time, excluding shell-restricted users + UserManagerService ums = getUserManagerLocked(); + for (int i = 0; i < users.length; i++) { + if (ums.hasUserRestriction( + UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { + continue; + } + List<BroadcastFilter> registeredReceiversForUser = + mReceiverResolver.queryIntent(intent, + resolvedType, false, users[i]); + if (registeredReceivers == null) { + registeredReceivers = registeredReceiversForUser; + } else if (registeredReceiversForUser != null) { + registeredReceivers.addAll(registeredReceiversForUser); + } + } + } else { + registeredReceivers = mReceiverResolver.queryIntent(intent, + resolvedType, false, userId); + } } final boolean replacePending = @@ -15587,7 +15660,7 @@ public final class ActivityManagerService extends ActivityManagerNative enforceNotIsolatedCaller("broadcastIntent"); synchronized(this) { intent = verifyBroadcastLocked(intent); - + final ProcessRecord callerApp = getRecordForAppLocked(caller); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); @@ -17995,6 +18068,7 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public boolean switchUser(final int userId) { + enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); String userName; synchronized (this) { UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); @@ -18436,6 +18510,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (userId <= 0) { throw new IllegalArgumentException("Can't stop primary user " + userId); } + enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); synchronized (this) { return stopUserLocked(userId, callback); } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index bcf3b17..d71f94e 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1042,11 +1042,8 @@ final class ActivityStack { if (prev.app != null && prev.cpuTimeAtResume > 0 && mService.mBatteryStatsService.isOnBattery()) { - long diff; - synchronized (mService.mProcessCpuThread) { - diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid) - - prev.cpuTimeAtResume; - } + long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid) + - prev.cpuTimeAtResume; if (diff > 0) { BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics(); synchronized (bsi) { @@ -1097,9 +1094,7 @@ final class ActivityStack { // TODO: To be more accurate, the mark should be before the onCreate, // not after the onResume. But for subsequent starts, onResume is fine. if (next.app != null) { - synchronized (mService.mProcessCpuThread) { - next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid); - } + next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid); } else { next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process } diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java index 3cc406b..b21af48 100644 --- a/services/core/java/com/android/server/am/TaskPersister.java +++ b/services/core/java/com/android/server/am/TaskPersister.java @@ -347,6 +347,10 @@ public class TaskPersister { private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) { if (DEBUG) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds=" + persistentTaskIds + " files=" + files); + if (files == null) { + Slog.e(TAG, "File error accessing recents directory (too many files open?)."); + return; + } for (int fileNdx = 0; fileNdx < files.length; ++fileNdx) { File file = files[fileNdx]; String filename = file.getName(); diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index f6399a3..a6a9a89 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -69,7 +69,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter { try { if (projection != null) { - projection.addCallback(new MediaProjectionCallback(appToken)); + projection.registerCallback(new MediaProjectionCallback(appToken)); } appToken.linkToDeath(device, 0); } catch (RemoteException ex) { diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java index 344c57b..d0447bc 100644 --- a/services/core/java/com/android/server/job/JobServiceContext.java +++ b/services/core/java/com/android/server/job/JobServiceContext.java @@ -153,7 +153,8 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne } mRunningJob = job; - mParams = new JobParameters(job.getJobId(), job.getExtras(), this); + mParams = new JobParameters(this, job.getJobId(), job.getExtras(), + !job.isConstraintsSatisfied()); mExecutionStartTimeElapsed = SystemClock.elapsedRealtime(); mVerb = VERB_BINDING; diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java index f562721..e3c55b6 100644 --- a/services/core/java/com/android/server/job/controllers/JobStatus.java +++ b/services/core/java/com/android/server/job/controllers/JobStatus.java @@ -195,16 +195,23 @@ public class JobStatus { } /** - * @return Whether or not this job is ready to run, based on its requirements. + * @return Whether or not this job is ready to run, based on its requirements. This is true if + * the constraints are satisfied <strong>or</strong> the deadline on the job has expired. */ public synchronized boolean isReady() { + return isConstraintsSatisfied() + || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get()); + } + + /** + * @return Whether the constraints set on this job are satisfied. + */ + public synchronized boolean isConstraintsSatisfied() { return (!hasChargingConstraint() || chargingConstraintSatisfied.get()) && (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get()) && (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get()) && (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get()) - && (!hasIdleConstraint() || idleConstraintSatisfied.get()) - // Also ready if the deadline has expired - special case. - || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get()); + && (!hasIdleConstraint() || idleConstraintSatisfied.get()); } public boolean matches(int uid, int jobId) { diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java index 8ec9b25..8a1f3ad 100644 --- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java @@ -389,7 +389,7 @@ public final class MediaProjectionManagerService extends SystemService throw new IllegalStateException( "Cannot start already started MediaProjection"); } - addCallback(callback); + registerCallback(callback); try { mToken = callback.asBinder(); mDeathEater = new IBinder.DeathRecipient() { @@ -424,7 +424,7 @@ public final class MediaProjectionManagerService extends SystemService } @Override - public void addCallback(IMediaProjectionCallback callback) { + public void registerCallback(IMediaProjectionCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback must not be null"); } @@ -432,7 +432,7 @@ public final class MediaProjectionManagerService extends SystemService } @Override - public void removeCallback(IMediaProjectionCallback callback) { + public void unregisterCallback(IMediaProjectionCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback must not be null"); } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 9e5fa41..cf19416 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -433,14 +433,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // listen for configured wifi networks to be removed final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION); - mContext.registerReceiver( - mWifiConfigReceiver, wifiConfigFilter, CONNECTIVITY_INTERNAL, mHandler); + mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler); // listen for wifi state changes to catch metered hint final IntentFilter wifiStateFilter = new IntentFilter( WifiManager.NETWORK_STATE_CHANGED_ACTION); - mContext.registerReceiver( - mWifiStateReceiver, wifiStateFilter, CONNECTIVITY_INTERNAL, mHandler); + mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler); } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index f995dee..b5aa4d8 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -318,7 +318,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // watch for tethering changes final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED); - mContext.registerReceiver(mTetherReceiver, tetherFilter, CONNECTIVITY_INTERNAL, mHandler); + mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler); // listen for periodic polling events final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL); diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 496c136..ed678d2 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -446,7 +446,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private int createSessionInternal(SessionParams params, String installerPackageName, int userId) throws IOException { final int callingUid = Binder.getCallingUid(); - mPm.enforceCrossUserPermission(callingUid, userId, true, "createSession"); + mPm.enforceCrossUserPermission(callingUid, userId, true, false, "createSession"); if (mPm.isUserRestricted(UserHandle.getUserId(callingUid), UserManager.DISALLOW_INSTALL_APPS)) { @@ -654,7 +654,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { @Override public List<SessionInfo> getAllSessions(int userId) { - mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "getAllSessions"); + mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getAllSessions"); final List<SessionInfo> result = new ArrayList<>(); synchronized (mSessions) { @@ -670,7 +670,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { @Override public List<SessionInfo> getMySessions(String installerPackageName, int userId) { - mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "getMySessions"); + mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getMySessions"); mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName); final List<SessionInfo> result = new ArrayList<>(); @@ -688,7 +688,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { @Override public void uninstall(String packageName, int flags, IntentSender statusReceiver, int userId) { - mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstall"); + mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "uninstall"); final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext, statusReceiver, packageName); @@ -717,7 +717,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { @Override public void registerCallback(IPackageInstallerCallback callback, int userId) { - mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "registerCallback"); + mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "registerCallback"); mCallbacks.register(callback, userId); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index d821fc1..3e5d514 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -138,6 +138,7 @@ import android.os.Bundle; import android.os.Environment; import android.os.Environment.UserEnvironment; import android.os.storage.StorageManager; +import android.os.Debug; import android.os.FileUtils; import android.os.Handler; import android.os.IBinder; @@ -1845,7 +1846,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public boolean isPackageAvailable(String packageName, int userId) { if (!sUserManager.exists(userId)) return false; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); if (p != null) { @@ -1864,7 +1865,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public PackageInfo getPackageInfo(String packageName, int flags, int userId) { if (!sUserManager.exists(userId)) return null; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); // reader synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); @@ -1909,7 +1910,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public int getPackageUid(String packageName, int userId) { if (!sUserManager.exists(userId)) return -1; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); // reader synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); @@ -2059,7 +2060,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { if (!sUserManager.exists(userId)) return null; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); // writer synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); @@ -2150,7 +2151,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); synchronized (mPackages) { PackageParser.Activity a = mActivities.mActivities.get(component); @@ -2189,7 +2190,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); synchronized (mPackages) { PackageParser.Activity a = mReceivers.mActivities.get(component); if (DEBUG_PACKAGE_INFO) Log.v( @@ -2207,7 +2208,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); synchronized (mPackages) { PackageParser.Service s = mServices.mServices.get(component); if (DEBUG_PACKAGE_INFO) Log.v( @@ -2225,7 +2226,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); synchronized (mPackages) { PackageParser.Provider p = mProviders.mProviders.get(component); if (DEBUG_PACKAGE_INFO) Log.v( @@ -2329,13 +2330,17 @@ public class PackageManagerService extends IPackageManager.Stub { /** * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. + * @param checkShell TODO(yamasani): * @param message the message to log on security exception */ void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, - String message) { + boolean checkShell, String message) { if (userId < 0) { throw new IllegalArgumentException("Invalid userId " + userId); } + if (checkShell) { + enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); + } if (userId == UserHandle.getUserId(callingUid)) return; if (callingUid != Process.SYSTEM_UID && callingUid != 0) { if (requireFullPermission) { @@ -2353,6 +2358,19 @@ public class PackageManagerService extends IPackageManager.Stub { } } + void enforceShellRestriction(String restriction, int callingUid, int userHandle) { + if (callingUid == Process.SHELL_UID) { + if (userHandle >= 0 + && sUserManager.hasUserRestriction(restriction, userHandle)) { + throw new SecurityException("Shell does not have permission to access user " + + userHandle); + } else if (userHandle < 0) { + Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" + + Debug.getCallers(3)); + } + } + } + private BasePermission findPermissionTreeLP(String permName) { for(BasePermission bp : mSettings.mPermissionTrees.values()) { if (permName.startsWith(bp.name) && @@ -2876,7 +2894,7 @@ public class PackageManagerService extends IPackageManager.Stub { public ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return null; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); return chooseBestActivity(intent, resolvedType, flags, query, userId); } @@ -3183,24 +3201,6 @@ public class PackageManagerService extends IPackageManager.Stub { if (matches.get(i).getTargetUserId() == targetUserId) return true; } } - ArrayList<String> packageNames = null; - SparseArray<ArrayList<String>> fromSource = - mSettings.mCrossProfilePackageInfo.get(sourceUserId); - if (fromSource != null) { - packageNames = fromSource.get(targetUserId); - if (packageNames != null) { - // We need the package name, so we try to resolve with the loosest flags possible - List<ResolveInfo> resolveInfos = mActivities.queryIntent(intent, resolvedType, - PackageManager.GET_UNINSTALLED_PACKAGES, targetUserId); - int count = resolveInfos.size(); - for (int i = 0; i < count; i++) { - ResolveInfo resolveInfo = resolveInfos.get(i); - if (packageNames.contains(resolveInfo.activityInfo.packageName)) { - return true; - } - } - } - } return false; } @@ -3217,7 +3217,7 @@ public class PackageManagerService extends IPackageManager.Stub { public List<ResolveInfo> queryIntentActivities(Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { @@ -3241,20 +3241,10 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { final String pkgName = intent.getPackage(); if (pkgName == null) { - ResolveInfo resolveInfo = null; - - // Check if the intent needs to be forwarded to another user for this package - ArrayList<ResolveInfo> crossProfileResult = - queryIntentActivitiesCrossProfilePackage( - intent, resolvedType, flags, userId); - if (!crossProfileResult.isEmpty()) { - // Skip the current profile - return crossProfileResult; - } List<CrossProfileIntentFilter> matchingFilters = getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); // Check for results that need to skip the current profile. - resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, + ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, resolvedType, flags, userId); if (resolveInfo != null) { List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); @@ -3276,13 +3266,6 @@ public class PackageManagerService extends IPackageManager.Stub { } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { - ArrayList<ResolveInfo> crossProfileResult = - queryIntentActivitiesCrossProfilePackage( - intent, resolvedType, flags, userId, pkg, pkgName); - if (!crossProfileResult.isEmpty()) { - // Skip the current profile - return crossProfileResult; - } return mActivities.queryIntentForPackage(intent, resolvedType, flags, pkg.activities, userId); } @@ -3311,56 +3294,6 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } - private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage( - Intent intent, String resolvedType, int flags, int userId) { - ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>(); - SparseArray<ArrayList<String>> sourceForwardingInfo = - mSettings.mCrossProfilePackageInfo.get(userId); - if (sourceForwardingInfo != null) { - int NI = sourceForwardingInfo.size(); - for (int i = 0; i < NI; i++) { - int targetUserId = sourceForwardingInfo.keyAt(i); - ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i); - List<ResolveInfo> resolveInfos = mActivities.queryIntent( - intent, resolvedType, flags, targetUserId); - int NJ = resolveInfos.size(); - for (int j = 0; j < NJ; j++) { - ResolveInfo resolveInfo = resolveInfos.get(j); - if (packageNames.contains(resolveInfo.activityInfo.packageName)) { - matchingResolveInfos.add(createForwardingResolveInfo( - resolveInfo.filter, userId, targetUserId)); - } - } - } - } - return matchingResolveInfos; - } - - private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage( - Intent intent, String resolvedType, int flags, int userId, PackageParser.Package pkg, - String packageName) { - ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>(); - SparseArray<ArrayList<String>> sourceForwardingInfo = - mSettings.mCrossProfilePackageInfo.get(userId); - if (sourceForwardingInfo != null) { - int NI = sourceForwardingInfo.size(); - for (int i = 0; i < NI; i++) { - int targetUserId = sourceForwardingInfo.keyAt(i); - if (sourceForwardingInfo.valueAt(i).contains(packageName)) { - List<ResolveInfo> resolveInfos = mActivities.queryIntentForPackage( - intent, resolvedType, flags, pkg.activities, targetUserId); - int NJ = resolveInfos.size(); - for (int j = 0; j < NJ; j++) { - ResolveInfo resolveInfo = resolveInfos.get(j); - matchingResolveInfos.add(createForwardingResolveInfo( - resolveInfo.filter, userId, targetUserId)); - } - } - } - } - return matchingResolveInfos; - } - // Return matching ResolveInfo if any for skip current profile intent filters. private ResolveInfo queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, @@ -3431,7 +3364,7 @@ public class PackageManagerService extends IPackageManager.Stub { String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); enforceCrossUserPermission(Binder.getCallingUid(), userId, false, - "query intent activity options"); + false, "query intent activity options"); final String resultsAction = intent.getAction(); List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags @@ -3727,7 +3660,7 @@ public class PackageManagerService extends IPackageManager.Stub { public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); // writer synchronized (mPackages) { @@ -7745,7 +7678,7 @@ public class PackageManagerService extends IPackageManager.Stub { final File originFile = new File(originPath); final int uid = Binder.getCallingUid(); - if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) { + if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { try { if (observer != null) { observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); @@ -7833,11 +7766,8 @@ public class PackageManagerService extends IPackageManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); PackageSetting pkgSetting; final int uid = Binder.getCallingUid(); - if (UserHandle.getUserId(uid) != userId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, - "setApplicationHiddenSetting for user " + userId); - } + enforceCrossUserPermission(uid, userId, true, true, + "setApplicationHiddenSetting for user " + userId); if (hidden && isPackageDeviceAdmin(packageName, userId)) { Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); @@ -7896,7 +7826,7 @@ public class PackageManagerService extends IPackageManager.Stub { public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); enforceCrossUserPermission(Binder.getCallingUid(), userId, true, - "getApplicationHidden for user " + userId); + false, "getApplicationHidden for user " + userId); PackageSetting pkgSetting; long callingId = Binder.clearCallingIdentity(); try { @@ -7922,7 +7852,8 @@ public class PackageManagerService extends IPackageManager.Stub { null); PackageSetting pkgSetting; final int uid = Binder.getCallingUid(); - enforceCrossUserPermission(uid, userId, true, "installExistingPackage for user " + userId); + enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " + + userId); if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { return PackageManager.INSTALL_FAILED_USER_RESTRICTED; } @@ -11046,7 +10977,7 @@ public class PackageManagerService extends IPackageManager.Stub { final IPackageDataObserver observer, final int userId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CLEAR_APP_USER_DATA, null); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); // Queue up an async operation since the package deletion may take a little while. mHandler.post(new Runnable() { public void run() { @@ -11346,7 +11277,7 @@ public class PackageManagerService extends IPackageManager.Stub { String opname) { // writer int callingUid = Binder.getCallingUid(); - enforceCrossUserPermission(callingUid, userId, true, "add preferred activity"); + enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); if (filter.countActions() == 0) { Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); return; @@ -11391,7 +11322,7 @@ public class PackageManagerService extends IPackageManager.Stub { } final int callingUid = Binder.getCallingUid(); - enforceCrossUserPermission(callingUid, userId, true, "replace preferred activity"); + enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); synchronized (mPackages) { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS) @@ -11532,6 +11463,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public void resetPreferredActivities(int userId) { + /* TODO: Actually use userId. Why is it being passed in? */ mContext.enforceCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); // writer @@ -11646,6 +11578,7 @@ public class PackageManagerService extends IPackageManager.Stub { android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); int callingUid = Binder.getCallingUid(); enforceOwnerRights(ownerPackage, ownerUserId, callingUid); + enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); if (intentFilter.countActions() == 0) { Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); return; @@ -11659,30 +11592,13 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - public void addCrossProfileIntentsForPackage(String packageName, - int sourceUserId, int targetUserId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - mSettings.addCrossProfilePackage(packageName, sourceUserId, targetUserId); - mSettings.writePackageRestrictionsLPr(sourceUserId); - } - - @Override - public void removeCrossProfileIntentsForPackage(String packageName, - int sourceUserId, int targetUserId) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - mSettings.removeCrossProfilePackage(packageName, sourceUserId, targetUserId); - mSettings.writePackageRestrictionsLPr(sourceUserId); - } - - @Override public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, int ownerUserId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); int callingUid = Binder.getCallingUid(); enforceOwnerRights(ownerPackage, ownerUserId, callingUid); + enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); int callingUserId = UserHandle.getUserId(callingUid); synchronized (mPackages) { CrossProfileIntentResolver resolver = @@ -11777,7 +11693,7 @@ public class PackageManagerService extends IPackageManager.Stub { final int uid = Binder.getCallingUid(); final int permission = mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); - enforceCrossUserPermission(uid, userId, false, "set enabled"); + enforceCrossUserPermission(uid, userId, false, true, "set enabled"); final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); boolean sendNow = false; boolean isApp = (className == null); @@ -11911,7 +11827,7 @@ public class PackageManagerService extends IPackageManager.Stub { final int permission = mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); - enforceCrossUserPermission(uid, userId, true, "stop package"); + enforceCrossUserPermission(uid, userId, true, true, "stop package"); // writer synchronized (mPackages) { if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, @@ -11933,7 +11849,7 @@ public class PackageManagerService extends IPackageManager.Stub { public int getApplicationEnabledSetting(String packageName, int userId) { if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; int uid = Binder.getCallingUid(); - enforceCrossUserPermission(uid, userId, false, "get enabled"); + enforceCrossUserPermission(uid, userId, false, false, "get enabled"); // reader synchronized (mPackages) { return mSettings.getApplicationEnabledSettingLPr(packageName, userId); @@ -11944,7 +11860,7 @@ public class PackageManagerService extends IPackageManager.Stub { public int getComponentEnabledSetting(ComponentName componentName, int userId) { if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; int uid = Binder.getCallingUid(); - enforceCrossUserPermission(uid, userId, false, "get component enabled"); + enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); // reader synchronized (mPackages) { return mSettings.getComponentEnabledSettingLPr(componentName, userId); diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index c1caeac..0dadee7 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -138,10 +138,6 @@ final class Settings { "persistent-preferred-activities"; static final String TAG_CROSS_PROFILE_INTENT_FILTERS = "crossProfile-intent-filters"; - private static final String TAG_CROSS_PROFILE_PACKAGE_INFO = "cross-profile-package-info"; - private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID = "target-user-id"; - private static final String CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME = "package-name"; - private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME = "value"; private static final String ATTR_NAME = "name"; private static final String ATTR_USER = "user"; @@ -249,23 +245,15 @@ final class Settings { */ private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>(); - private final Context mContext; - private final File mSystemDir; public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages); - // A mapping of (sourceUserId, targetUserId, packageNames) for forwarding the intents of a - // package. - final SparseArray<SparseArray<ArrayList<String>>> - mCrossProfilePackageInfo = new SparseArray<SparseArray<ArrayList<String>>>(); - Settings(Context context) { this(context, Environment.getDataDirectory()); } Settings(Context context, File dataDir) { - mContext = context; mSystemDir = new File(dataDir, "system"); mSystemDir.mkdirs(); FileUtils.setPermissions(mSystemDir.toString(), @@ -282,47 +270,6 @@ final class Settings { mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); } - public void addCrossProfilePackage( - String packageName, int sourceUserId, int targetUserId) { - synchronized(mCrossProfilePackageInfo) { - SparseArray<ArrayList<String>> sourceForwardingInfo = - mCrossProfilePackageInfo.get(sourceUserId); - if (sourceForwardingInfo == null) { - sourceForwardingInfo = new SparseArray<ArrayList<String>>(); - mCrossProfilePackageInfo.put(sourceUserId, sourceForwardingInfo); - } - ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId); - if (packageNames == null) { - packageNames = new ArrayList<String>(); - sourceForwardingInfo.put(targetUserId, packageNames); - } - if (!packageNames.contains(packageName)) { - packageNames.add(packageName); - } - } - } - - public void removeCrossProfilePackage( - String packageName, int sourceUserId, int targetUserId) { - synchronized(mCrossProfilePackageInfo) { - SparseArray<ArrayList<String>> sourceForwardingInfo = - mCrossProfilePackageInfo.get(sourceUserId); - if (sourceForwardingInfo == null) { - return; - } - ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId); - if (packageNames != null && packageNames.contains(packageName)) { - packageNames.remove(packageName); - if (packageNames.isEmpty()) { - sourceForwardingInfo.remove(targetUserId); - if (sourceForwardingInfo.size() == 0) { - mCrossProfilePackageInfo.remove(sourceUserId); - } - } - } - } - } - PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbi, String secondaryCpuAbi, @@ -517,6 +464,7 @@ final class Settings { int vc, int pkgFlags, UserHandle installUser, boolean add, boolean allowInstall) { PackageSetting p = mPackages.get(name); + UserManagerService userManager = UserManagerService.getInstance(); if (p != null) { p.primaryCpuAbiString = primaryCpuAbiString; p.secondaryCpuAbiString = secondaryCpuAbiString; @@ -594,6 +542,7 @@ final class Settings { Slog.i(PackageManagerService.TAG, "Stopping package " + name, e); } List<UserInfo> users = getAllUsers(); + final int installUserId = installUser != null ? installUser.getIdentifier() : 0; if (users != null && allowInstall) { for (UserInfo user : users) { // By default we consider this app to be installed @@ -603,8 +552,9 @@ final class Settings { // asked to install for all users, or this is the // user we are installing for. final boolean installed = installUser == null - || installUser.getIdentifier() == UserHandle.USER_ALL - || installUser.getIdentifier() == user.id; + || (installUserId == UserHandle.USER_ALL + && !isAdbInstallDisallowed(userManager, user.id)) + || installUserId == user.id; p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT, installed, true, // stopped, @@ -670,7 +620,8 @@ final class Settings { List<UserInfo> users = getAllUsers(); if (users != null) { for (UserInfo user : users) { - if (installUser.getIdentifier() == UserHandle.USER_ALL + if ((installUser.getIdentifier() == UserHandle.USER_ALL + && !isAdbInstallDisallowed(userManager, user.id)) || installUser.getIdentifier() == user.id) { boolean installed = p.getInstalled(user.id); if (!installed) { @@ -685,6 +636,11 @@ final class Settings { return p; } + boolean isAdbInstallDisallowed(UserManagerService userManager, int userId) { + return userManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, + userId); + } + void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) { p.pkg = pkg; // pkg.mSetEnabled = p.getEnabled(userId); @@ -1068,68 +1024,6 @@ final class Settings { } } - private void readCrossProfilePackageInfoLPw(XmlPullParser parser, int userId) - throws XmlPullParserException, IOException { - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - String tagName = parser.getName(); - if (tagName.equals(TAG_ITEM)) { - String targetUserIdString = parser.getAttributeValue(null, - CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID); - if (targetUserIdString == null) { - String msg = "Missing element under " + TAG +": " - + CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID + " at " + - parser.getPositionDescription(); - PackageManagerService.reportSettingsProblem(Log.WARN, msg); - continue; - } - int targetUserId = Integer.parseInt(targetUserIdString); - readCrossProfilePackageInfoForTargetLPw(parser, userId, targetUserId); - } else { - String msg = "Unknown element under " + TAG_CROSS_PROFILE_PACKAGE_INFO + ": " + - parser.getName(); - PackageManagerService.reportSettingsProblem(Log.WARN, msg); - XmlUtils.skipCurrentTag(parser); - } - } - } - - private void readCrossProfilePackageInfoForTargetLPw( - XmlPullParser parser, int sourceUserId, int targetUserId) - throws XmlPullParserException, IOException { - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - String tagName = parser.getName(); - if (tagName.equals(CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME)) { - String packageName = parser.getAttributeValue( - null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME); - if (packageName == null) { - String msg = "Missing element under " + TAG +": " - + CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME + " at " + - parser.getPositionDescription(); - PackageManagerService.reportSettingsProblem(Log.WARN, msg); - continue; - } - addCrossProfilePackage(packageName, sourceUserId, targetUserId); - } else { - String msg = "Unknown element under " + TAG_ITEM + ": " + - parser.getName(); - PackageManagerService.reportSettingsProblem(Log.WARN, msg); - XmlUtils.skipCurrentTag(parser); - } - } - } - void readPackageRestrictionsLPr(int userId) { if (DEBUG_MU) { Log.i(TAG, "Reading package restrictions for user=" + userId); @@ -1271,8 +1165,6 @@ final class Settings { readPersistentPreferredActivitiesLPw(parser, userId); } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) { readCrossProfileIntentFiltersLPw(parser, userId); - } else if (tagName.equals(TAG_CROSS_PROFILE_PACKAGE_INFO)){ - readCrossProfilePackageInfoLPw(parser, userId); } else { Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " + parser.getName()); @@ -1364,32 +1256,6 @@ final class Settings { serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS); } - void writeCrossProfilePackageInfoLPr(XmlSerializer serializer, int userId) - throws IllegalArgumentException, IllegalStateException, IOException { - SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(userId); - if (sourceForwardingInfo == null) { - return; - } - serializer.startTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO); - int NI = sourceForwardingInfo.size(); - for (int i = 0; i < NI; i++) { - int targetUserId = sourceForwardingInfo.keyAt(i); - ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i); - serializer.startTag(null, TAG_ITEM); - serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID, - Integer.toString(targetUserId)); - int NJ = packageNames.size(); - for (int j = 0; j < NJ; j++) { - serializer.startTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME); - serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME, - packageNames.get(j)); - serializer.endTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME); - } - serializer.endTag(null, TAG_ITEM); - } - serializer.endTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO); - } - void writePackageRestrictionsLPr(int userId) { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); @@ -1494,8 +1360,6 @@ final class Settings { writeCrossProfileIntentFiltersLPr(serializer, userId); - writeCrossProfilePackageInfoLPr(serializer, userId); - serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); serializer.endDocument(); @@ -3180,7 +3044,6 @@ final class Settings { file = getUserPackagesStateBackupFile(userId); file.delete(); removeCrossProfileIntentFiltersLPw(userId); - removeCrossProfilePackagesLPw(userId); } void removeCrossProfileIntentFiltersLPw(int userId) { @@ -3211,27 +3074,6 @@ final class Settings { } } - public void removeCrossProfilePackagesLPw(int userId) { - synchronized(mCrossProfilePackageInfo) { - // userId is the source user - if (mCrossProfilePackageInfo.get(userId) != null) { - mCrossProfilePackageInfo.remove(userId); - writePackageRestrictionsLPr(userId); - } - // userId is the target user - int count = mCrossProfilePackageInfo.size(); - for (int i = 0; i < count; i++) { - int sourceUserId = mCrossProfilePackageInfo.keyAt(i); - SparseArray<ArrayList<String>> sourceForwardingInfo = - mCrossProfilePackageInfo.valueAt(i); - if (sourceForwardingInfo.get(userId) != null) { - sourceForwardingInfo.remove(userId); - writePackageRestrictionsLPr(sourceUserId); - } - } - } - } - // This should be called (at least) whenever an application is removed private void setFirstAvailableUid(int uid) { if (uid > mFirstAvailableUid) { diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index d032d29..26e0db3 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -33,6 +33,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Binder; import android.os.Bundle; +import android.os.Debug; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; @@ -480,6 +481,14 @@ public class UserManagerService extends IUserManager.Stub { } @Override + public boolean hasUserRestriction(String restrictionKey, int userId) { + synchronized (mPackagesLock) { + Bundle restrictions = mUserRestrictions.get(userId); + return restrictions != null ? restrictions.getBoolean(restrictionKey) : false; + } + } + + @Override public Bundle getUserRestrictions(int userId) { // checkManageUsersPermission("getUserRestrictions"); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 7808800..0a4b3bc 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -814,7 +814,7 @@ public final class PowerManagerService extends com.android.server.SystemService + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags)); } - if ((flags & PowerManager.WAIT_FOR_DISTANT_PROXIMITY) != 0) { + if ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) { mRequestWaitForNegativeProximity = true; } diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 3380f71..adae84f 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -85,6 +85,7 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -139,7 +140,7 @@ public final class TvInputManagerService extends SystemService { registerBroadcastReceivers(); } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { synchronized (mLock) { - buildTvInputListLocked(mCurrentUserId); + buildTvInputListLocked(mCurrentUserId, null); buildTvContentRatingSystemListLocked(mCurrentUserId); } } @@ -148,19 +149,64 @@ public final class TvInputManagerService extends SystemService { private void registerBroadcastReceivers() { PackageMonitor monitor = new PackageMonitor() { + private void buildTvInputList(String[] packages) { + synchronized (mLock) { + buildTvInputListLocked(getChangingUserId(), packages); + buildTvContentRatingSystemListLocked(getChangingUserId()); + } + } + + @Override + public void onPackageUpdateFinished(String packageName, int uid) { + if (DEBUG) Slog.d(TAG, "onPackageUpdateFinished(packageName=" + packageName + ")"); + // This callback is invoked when the TV input is reinstalled. + // In this case, isReplacing() always returns true. + buildTvInputList(new String[] { packageName }); + } + + @Override + public void onPackagesAvailable(String[] packages) { + if (DEBUG) { + Slog.d(TAG, "onPackagesAvailable(packages=" + Arrays.toString(packages) + ")"); + } + // This callback is invoked when the media on which some packages exist become + // available. + if (isReplacing()) { + buildTvInputList(packages); + } + } + + @Override + public void onPackagesUnavailable(String[] packages) { + // This callback is invoked when the media on which some packages exist become + // unavailable. + if (DEBUG) { + Slog.d(TAG, "onPackagesUnavailable(packages=" + Arrays.toString(packages) + + ")"); + } + if (isReplacing()) { + buildTvInputList(packages); + } + } + @Override public void onSomePackagesChanged() { + // TODO: Use finer-grained methods(e.g. onPackageAdded, onPackageRemoved) to manage + // the TV inputs. if (DEBUG) Slog.d(TAG, "onSomePackagesChanged()"); - synchronized (mLock) { - buildTvInputListLocked(mCurrentUserId); - buildTvContentRatingSystemListLocked(mCurrentUserId); + if (isReplacing()) { + if (DEBUG) Slog.d(TAG, "Skipped building TV input list due to replacing"); + // When the package is updated, buildTvInputListLocked is called in other + // methods instead. + return; } + buildTvInputList(null); } @Override public void onPackageRemoved(String packageName, int uid) { synchronized (mLock) { - UserState userState = getUserStateLocked(mCurrentUserId); + UserState userState = getUserStateLocked(getChangingUserId()); if (!userState.packageSet.contains(packageName)) { // Not a TV input package. return; @@ -218,13 +264,11 @@ public final class TvInputManagerService extends SystemService { component.getPackageName()) == PackageManager.PERMISSION_GRANTED; } - private void buildTvInputListLocked(int userId) { + private void buildTvInputListLocked(int userId, String[] updatedPackages) { UserState userState = getUserStateLocked(userId); userState.packageSet.clear(); - if (DEBUG) { - Slog.d(TAG, "buildTvInputList"); - } + if (DEBUG) Slog.d(TAG, "buildTvInputList"); PackageManager pm = mContext.getPackageManager(); List<ResolveInfo> services = pm.queryIntentServices( new Intent(TvInputService.SERVICE_INTERFACE), @@ -278,6 +322,15 @@ public final class TvInputManagerService extends SystemService { for (String inputId : inputMap.keySet()) { if (!userState.inputMap.containsKey(inputId)) { notifyInputAddedLocked(userState, inputId); + } else if (updatedPackages != null) { + // Notify the package updates + TvInputState inputState = inputMap.get(inputId); + for (String updatedPackage : updatedPackages) { + if (inputState.info.getComponent().getPackageName().equals(updatedPackage)) { + notifyInputUpdatedLocked(userState, inputId); + break; + } + } } } @@ -337,7 +390,7 @@ public final class TvInputManagerService extends SystemService { userState = new UserState(mContext, userId); } mUserStates.put(userId, userState); - buildTvInputListLocked(userId); + buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); } } @@ -649,6 +702,19 @@ public final class TvInputManagerService extends SystemService { } } + private void notifyInputUpdatedLocked(UserState userState, String inputId) { + if (DEBUG) { + Slog.d(TAG, "notifyInputUpdatedLocked(inputId=" + inputId + ")"); + } + for (ITvInputManagerCallback callback : userState.callbackSet) { + try { + callback.onInputUpdated(inputId); + } catch (RemoteException e) { + Slog.e(TAG, "failed to report updated input to callback", e); + } + } + } + private void notifyInputStateChangedLocked(UserState userState, String inputId, int state, ITvInputManagerCallback targetCallback) { if (DEBUG) { @@ -1813,7 +1879,7 @@ public final class TvInputManagerService extends SystemService { private void addTvInputLocked(TvInputInfo inputInfo) { ServiceState serviceState = getServiceStateLocked(mComponent, mUserId); serviceState.inputList.add(inputInfo); - buildTvInputListLocked(mUserId); + buildTvInputListLocked(mUserId, null); } @Override @@ -1851,7 +1917,7 @@ public final class TvInputManagerService extends SystemService { } } if (removed) { - buildTvInputListLocked(mUserId); + buildTvInputListLocked(mUserId, null); mTvInputHardwareManager.removeTvInput(inputId); } else { Slog.e(TAG, "failed to remove input " + inputId); diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index e1ade63..a8245e7 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -843,7 +843,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } File file = new File(dir, WALLPAPER); ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, - MODE_CREATE|MODE_READ_WRITE); + MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE); if (!SELinux.restorecon(file)) { return null; } diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 81cd602..05fc424 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -252,6 +252,10 @@ public class WindowAnimator { final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() && (imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0; + final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw(); + final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ? + null : winShowWhenLocked.mAppToken; + for (int i = windows.size() - 1; i >= 0; i--) { WindowState win = windows.get(i); WindowStateAnimator winAnimator = win.mWinAnimator; @@ -316,8 +320,8 @@ public class WindowAnimator { + " hidden=" + win.mRootToken.hidden + " anim=" + win.mWinAnimator.mAnimation); } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) { - final boolean hideWhenLocked = (flags & FLAG_SHOW_WHEN_LOCKED) == 0 && - !(win.mIsImWindow && showImeOverKeyguard); + final boolean hideWhenLocked = !((win.mIsImWindow && showImeOverKeyguard) || + (appShowWhenLocked != null && appShowWhenLocked == win.mAppToken)); final boolean changed; if (((mForceHiding == KEYGUARD_ANIMATING_IN) && (!winAnimator.isAnimating() || hideWhenLocked)) @@ -568,6 +572,15 @@ public class WindowAnimator { mBulkUpdateParams |= SET_UPDATE_ROTATION; screenRotationAnimation.kill(); displayAnimator.mScreenRotationAnimation = null; + + //TODO (multidisplay): Accessibility supported only for the default display. + if (mService.mAccessibilityController != null + && displayId == Display.DEFAULT_DISPLAY) { + // We just finished rotation animation which means we did not + // anounce the rotation and waited for it to end, announce now. + mService.mAccessibilityController.onRotationChangedLocked( + mService.getDefaultDisplayContentLocked(), mService.mRotation); + } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 54af851..b7e56cb 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6442,9 +6442,12 @@ public class WindowManagerService extends IWindowManager.Stub } //TODO (multidisplay): Magnification is supported only for the default display. - if (mAccessibilityController != null + // Announce rotation only if we will not animate as we already have the + // windows in final state. Otherwise, we make this call at the rotation end. + if (screenRotationAnimation == null && mAccessibilityController != null && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) { - mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation); + mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(), + rotation); } return true; |