diff options
Diffstat (limited to 'services/core/java/com')
21 files changed, 470 insertions, 515 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/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 3062a92..75090db 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -4746,6 +4746,11 @@ public class ConnectivityService extends IConnectivityManager.Stub { private void updateNetworkScore(NetworkAgentInfo nai, int score) { if (DBG) log("updateNetworkScore for " + nai.name() + " to " + score); + if (score < 0) { + loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score + + "). Bumping score to min of 0"); + score = 0; + } nai.currentScore = score; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a9a4732..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; @@ -888,6 +889,8 @@ public final class ActivityManagerService extends ActivityManagerNative boolean mProcessesReady = false; boolean mSystemReady = false; boolean mBooting = false; + boolean mCallFinishBooting = false; + boolean mBootAnimationComplete = false; boolean mWaitingUpdate = false; boolean mDidUpdate = false; boolean mOnBattery = false; @@ -1075,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); @@ -1595,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); @@ -1894,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); @@ -1912,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(), @@ -2183,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())); @@ -2379,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; @@ -3364,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"); @@ -5074,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()); @@ -6195,6 +6211,14 @@ public final class ActivityManagerService extends ActivityManagerNative } final void finishBooting() { + synchronized (this) { + if (!mBootAnimationComplete) { + mCallFinishBooting = true; + return; + } + mCallFinishBooting = false; + } + // Register receivers to handle package update events mPackageMonitor.register(mContext, Looper.getMainLooper(), false); @@ -6253,6 +6277,18 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override + public void bootAnimationComplete() { + final boolean callFinishBooting; + synchronized (this) { + callFinishBooting = mCallFinishBooting; + mBootAnimationComplete = true; + } + if (callFinishBooting) { + finishBooting(); + } + } + final void ensureBootCompleted() { boolean booting; boolean enableScreen; @@ -7446,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; @@ -9665,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 { @@ -9700,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 // ========================================================= @@ -13700,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); @@ -13862,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); @@ -14548,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; } @@ -14572,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 @@ -14606,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"); @@ -15040,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) { @@ -15134,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) { @@ -15399,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 = @@ -15565,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(); @@ -17973,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); @@ -18414,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/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index f6beb9a..9292d45 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -16,6 +16,7 @@ package com.android.server.content; +import android.Manifest; import android.accounts.Account; import android.accounts.AccountAndUser; import android.accounts.AccountManager; @@ -478,7 +479,7 @@ public class SyncManager { mContext.registerReceiverAsUser(mAccountsUpdatedReceiver, UserHandle.ALL, new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION), - null, null); + Manifest.permission.ACCOUNT_MANAGER, null); } // Pick a random second in a day to seed all periodic syncs 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 5f97a00..0a4b3bc 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -91,8 +91,6 @@ public final class PowerManagerService extends com.android.server.SystemService private static final int MSG_SANDMAN = 2; // Message: Sent when the screen on blocker is released. private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3; - // Message: Sent to poll whether the boot animation has terminated. - private static final int MSG_CHECK_IF_BOOT_ANIMATION_FINISHED = 4; // Dirty bit: mWakeLocks changed private static final int DIRTY_WAKE_LOCKS = 1 << 0; @@ -154,12 +152,6 @@ public final class PowerManagerService extends com.android.server.SystemService // provider populates the actual default value (R.integer.def_screen_off_timeout). private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000; - // The name of the boot animation service in init.rc. - private static final String BOOT_ANIMATION_SERVICE = "bootanim"; - - // Poll interval in milliseconds for watching boot animation finished. - private static final int BOOT_ANIMATION_POLL_INTERVAL = 200; - // Power hints defined in hardware/libhardware/include/hardware/power.h. private static final int POWER_HINT_INTERACTION = 2; private static final int POWER_HINT_LOW_POWER = 5; @@ -478,14 +470,15 @@ public final class PowerManagerService extends com.android.server.SystemService @Override public void onBootPhase(int phase) { - if (phase == PHASE_BOOT_COMPLETED) { - // This is our early signal that the system thinks it has finished booting. - // However, the boot animation may still be running for a few more seconds - // since it is ultimately in charge of when it terminates. - // Defer transitioning into the boot completed state until the animation exits. - // We do this so that the screen does not start to dim prematurely before - // the user has actually had a chance to interact with the device. - startWatchingForBootAnimationFinished(); + synchronized (mLock) { + if (phase == PHASE_BOOT_COMPLETED) { + final long now = SystemClock.uptimeMillis(); + mBootCompleted = true; + mDirty |= DIRTY_BOOT_COMPLETED; + userActivityNoUpdateLocked( + now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); + updatePowerStateLocked(); + } } } @@ -821,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; } @@ -2076,38 +2069,6 @@ public final class PowerManagerService extends com.android.server.SystemService updatePowerStateLocked(); } - private void startWatchingForBootAnimationFinished() { - mHandler.sendEmptyMessage(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED); - } - - private void checkIfBootAnimationFinished() { - if (DEBUG) { - Slog.d(TAG, "Check if boot animation finished..."); - } - - if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) { - mHandler.sendEmptyMessageDelayed(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED, - BOOT_ANIMATION_POLL_INTERVAL); - return; - } - - synchronized (mLock) { - if (!mBootCompleted) { - Slog.i(TAG, "Boot animation finished."); - handleBootCompletedLocked(); - } - } - } - - private void handleBootCompletedLocked() { - final long now = SystemClock.uptimeMillis(); - mBootCompleted = true; - mDirty |= DIRTY_BOOT_COMPLETED; - userActivityNoUpdateLocked( - now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); - updatePowerStateLocked(); - } - private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm, final String reason, boolean wait) { if (mHandler == null || !mSystemReady) { @@ -2528,9 +2489,6 @@ public final class PowerManagerService extends com.android.server.SystemService case MSG_SCREEN_ON_BLOCKER_RELEASED: handleScreenOnBlockerReleased(); break; - case MSG_CHECK_IF_BOOT_ANIMATION_FINISHED: - checkIfBootAnimationFinished(); - break; } } } 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 92f57f5..05fc424 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -572,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 10ab6b5..b7e56cb 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.*; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import android.app.AppOpsManager; import android.os.Build; +import android.os.SystemService; import android.util.ArraySet; import android.util.TimeUtils; import android.view.IWindowId; @@ -272,6 +273,12 @@ public class WindowManagerService extends IWindowManager.Stub // Default input dispatching timeout in nanoseconds. static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L; + // Poll interval in milliseconds for watching boot animation finished. + private static final int BOOT_ANIMATION_POLL_INTERVAL = 200; + + // The name of the boot animation service in init.rc. + private static final String BOOT_ANIMATION_SERVICE = "bootanim"; + /** Minimum value for attachStack and resizeStack weight value */ public static final float STACK_WEIGHT_MIN = 0.2f; @@ -458,6 +465,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean mSystemBooted = false; boolean mForceDisplayEnabled = false; boolean mShowingBootMessages = false; + boolean mBootAnimationStopped = false; String mLastANRState; @@ -5607,17 +5615,70 @@ public class WindowManagerService extends IWindowManager.Stub performEnableScreen(); } + private boolean checkWaitingForWindowsLocked() { + + boolean haveBootMsg = false; + boolean haveApp = false; + // if the wallpaper service is disabled on the device, we're never going to have + // wallpaper, don't bother waiting for it + boolean haveWallpaper = false; + boolean wallpaperEnabled = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_enableWallpaperService) + && !mOnlyCore; + boolean haveKeyguard = true; + // TODO(multidisplay): Expand to all displays? + final WindowList windows = getDefaultWindowListLocked(); + final int N = windows.size(); + for (int i=0; i<N; i++) { + WindowState w = windows.get(i); + if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) { + return true; + } + if (w.isDrawnLw()) { + if (w.mAttrs.type == TYPE_BOOT_PROGRESS) { + haveBootMsg = true; + } else if (w.mAttrs.type == TYPE_APPLICATION) { + haveApp = true; + } else if (w.mAttrs.type == TYPE_WALLPAPER) { + haveWallpaper = true; + } else if (w.mAttrs.type == TYPE_STATUS_BAR) { + haveKeyguard = mPolicy.isKeyguardDrawnLw(); + } + } + } + + if (DEBUG_SCREEN_ON || DEBUG_BOOT) { + Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages + + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp + + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled + + " haveKeyguard=" + haveKeyguard); + } + + // If we are turning on the screen to show the boot message, + // don't do it until the boot message is actually displayed. + if (!mSystemBooted && !haveBootMsg) { + return true; + } + + // If we are turning on the screen after the boot is completed + // normally, don't do so until we have the application and + // wallpaper. + if (mSystemBooted && ((!haveApp && !haveKeyguard) || + (wallpaperEnabled && !haveWallpaper))) { + return true; + } + + return false; + } + public void performEnableScreen() { synchronized(mWindowMap) { - if (DEBUG_BOOT) { - RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); - Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled - + " mForceDisplayEnabled=" + mForceDisplayEnabled - + " mShowingBootMessages=" + mShowingBootMessages - + " mSystemBooted=" + mSystemBooted - + " mOnlyCore=" + mOnlyCore, here); - } + if (DEBUG_BOOT) Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled + + " mForceDisplayEnabled=" + mForceDisplayEnabled + + " mShowingBootMessages=" + mShowingBootMessages + + " mSystemBooted=" + mSystemBooted + + " mOnlyCore=" + mOnlyCore, + new RuntimeException("here").fillInStackTrace()); if (mDisplayEnabled) { return; } @@ -5625,94 +5686,64 @@ public class WindowManagerService extends IWindowManager.Stub return; } - if (!mForceDisplayEnabled) { - // Don't enable the screen until all existing windows - // have been drawn. - boolean haveBootMsg = false; - boolean haveApp = false; - // if the wallpaper service is disabled on the device, we're never going to have - // wallpaper, don't bother waiting for it - boolean haveWallpaper = false; - boolean wallpaperEnabled = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_enableWallpaperService) - && !mOnlyCore; - boolean haveKeyguard = true; - // TODO(multidisplay): Expand to all displays? - final WindowList windows = getDefaultWindowListLocked(); - final int N = windows.size(); - for (int i=0; i<N; i++) { - WindowState w = windows.get(i); - if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) { - return; - } - if (w.isDrawnLw()) { - if (w.mAttrs.type == TYPE_BOOT_PROGRESS) { - haveBootMsg = true; - } else if (w.mAttrs.type == TYPE_APPLICATION) { - haveApp = true; - } else if (w.mAttrs.type == TYPE_WALLPAPER) { - haveWallpaper = true; - } else if (w.mAttrs.type == TYPE_STATUS_BAR) { - haveKeyguard = mPolicy.isKeyguardDrawnLw(); - } - } - } - - if (DEBUG_SCREEN_ON || DEBUG_BOOT) { - Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages - + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp - + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled - + " haveKeyguard=" + haveKeyguard); - } + // Don't enable the screen until all existing windows have been drawn. + if (!mForceDisplayEnabled && checkWaitingForWindowsLocked()) { + return; + } - // If we are turning on the screen to show the boot message, - // don't do it until the boot message is actually displayed. - if (!mSystemBooted && !haveBootMsg) { - return; + if (!mBootAnimationStopped) { + // Do this one time. + try { + IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger"); + if (surfaceFlinger != null) { + //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!"); + Parcel data = Parcel.obtain(); + data.writeInterfaceToken("android.ui.ISurfaceComposer"); + surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED + data, null, 0); + data.recycle(); + } + } catch (RemoteException ex) { + Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!"); } + mBootAnimationStopped = true; + } - // If we are turning on the screen after the boot is completed - // normally, don't do so until we have the application and - // wallpaper. - if (mSystemBooted && ((!haveApp && !haveKeyguard) || - (wallpaperEnabled && !haveWallpaper))) { - return; - } + if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) { + if (DEBUG_BOOT) Slog.i(TAG, "performEnableScreen: Waiting for anim complete"); + return; } mDisplayEnabled = true; if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!"); - if (false) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new FastPrintWriter(sw, false, 1024); - this.dump(null, pw, null); - pw.flush(); - Slog.i(TAG, sw.toString()); - } - try { - IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger"); - if (surfaceFlinger != null) { - //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!"); - Parcel data = Parcel.obtain(); - data.writeInterfaceToken("android.ui.ISurfaceComposer"); - surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED - data, null, 0); - data.recycle(); - } - } catch (RemoteException ex) { - Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!"); - } // Enable input dispatch. mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled); } + try { + mActivityManager.bootAnimationComplete(); + } catch (RemoteException e) { + } + mPolicy.enableScreenAfterBoot(); // Make sure the last requested orientation has been applied. updateRotationUnchecked(false, false); } + private boolean checkBootAnimationCompleteLocked() { + if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) { + mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED); + mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED, + BOOT_ANIMATION_POLL_INTERVAL); + if (DEBUG_BOOT) Slog.i(TAG, "checkBootAnimationComplete: Waiting for anim complete"); + return false; + } + if (DEBUG_BOOT) Slog.i(TAG, "checkBootAnimationComplete: Animation complete!"); + return true; + } + public void showBootMessage(final CharSequence msg, final boolean always) { boolean first = false; synchronized(mWindowMap) { @@ -6411,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; @@ -7457,6 +7491,8 @@ public class WindowManagerService extends IWindowManager.Stub public static final int SHOW_CIRCULAR_DISPLAY_MASK = 35; public static final int SHOW_EMULATOR_DISPLAY_OVERLAY = 36; + public static final int CHECK_IF_BOOT_ANIMATION_FINISHED = 37; + @Override public void handleMessage(Message msg) { if (DEBUG_WINDOW_TRACE) { @@ -7941,6 +7977,17 @@ public class WindowManagerService extends IWindowManager.Stub } } break; + case CHECK_IF_BOOT_ANIMATION_FINISHED: { + final boolean bootAnimationComplete; + synchronized (mWindowMap) { + if (DEBUG_BOOT) Slog.i(TAG, "CHECK_IF_BOOT_ANIMATION_FINISHED:"); + bootAnimationComplete = checkBootAnimationCompleteLocked(); + } + if (bootAnimationComplete) { + performEnableScreen(); + } + } + break; } if (DEBUG_WINDOW_TRACE) { Slog.v(TAG, "handleMessage: exit"); |