diff options
Diffstat (limited to 'services')
35 files changed, 993 insertions, 391 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index be3fc47..7d4156f 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -67,6 +67,7 @@ import android.util.Pools.Pool; import android.util.Pools.SimplePool; import android.util.Slog; import android.util.SparseArray; +import android.view.AccessibilityManagerInternal; import android.view.Display; import android.view.IWindow; import android.view.InputDevice; @@ -91,6 +92,7 @@ import android.view.accessibility.IAccessibilityManagerClient; import com.android.internal.R; import com.android.internal.content.PackageMonitor; import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.widget.LockPatternUtils; import com.android.server.LocalServices; import org.xmlpull.v1.XmlPullParserException; @@ -202,6 +204,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final UserManager mUserManager; + private final LockPatternUtils mLockPatternUtils; + private int mCurrentUserId = UserHandle.USER_OWNER; //TODO: Remove this hack @@ -225,9 +229,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mSecurityPolicy = new SecurityPolicy(); mMainHandler = new MainHandler(mContext.getMainLooper()); + mLockPatternUtils = new LockPatternUtils(context); registerBroadcastReceivers(); new AccessibilityContentObserver(mMainHandler).register( context.getContentResolver()); + LocalServices.addService(AccessibilityManagerInternal.class, new LocalService()); } private UserState getUserStateLocked(int userId) { @@ -1294,6 +1300,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { updateTouchExplorationLocked(userState); updateEnhancedWebAccessibilityLocked(userState); updateDisplayColorAdjustmentSettingsLocked(userState); + updateEncryptionState(userState); scheduleUpdateInputFilter(userState); scheduleUpdateClientsIfNeededLocked(userState); } @@ -1570,6 +1577,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { DisplayAdjustmentUtils.applyAdjustments(mContext, userState.mUserId); } + private void updateEncryptionState(UserState userState) { + if (userState.mUserId != UserHandle.USER_OWNER) { + return; + } + if (hasRunningServicesLocked(userState) && LockPatternUtils.isDeviceEncrypted()) { + // If there are running accessibility services we do not have encryption as + // the user needs the accessibility layer to be running to authenticate. + mLockPatternUtils.clearEncryptionPassword(); + } + } + + private boolean hasRunningServicesLocked(UserState userState) { + return !userState.mBoundServices.isEmpty() || !userState.mBindingServices.isEmpty(); + } + private MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) { IBinder windowToken = mGlobalWindowTokens.get(windowId); if (windowToken == null) { @@ -1982,7 +2004,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } else { userState.mBindingServices.add(mComponentName); mService = userState.mUiAutomationServiceClient.asBinder(); - onServiceConnected(mComponentName, mService); + mMainHandler.post(new Runnable() { + @Override + public void run() { + // Simulate asynchronous connection since in onServiceConnected + // we may modify the state data in case of an error but bind is + // called while iterating over the data and bad things can happen. + onServiceConnected(mComponentName, mService); + } + }); userState.mUiAutomationService = this; } return false; @@ -2087,7 +2117,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return null; } @@ -2118,7 +2148,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return null; } @@ -2151,7 +2181,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return false; } @@ -2203,7 +2233,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return false; } @@ -2255,7 +2285,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return false; } @@ -2307,7 +2337,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return false; } @@ -2360,7 +2390,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return false; } @@ -2411,7 +2441,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return false; } @@ -2450,7 +2480,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return false; } @@ -2497,7 +2527,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { // performs the current profile parent resolution. final int resolvedUserId = mSecurityPolicy .resolveCallingUserIdEnforcingPermissionsLocked( - UserHandle.getCallingUserId()); + UserHandle.USER_CURRENT); if (resolvedUserId != mCurrentUserId) { return false; } @@ -3591,6 +3621,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (callingUserId == userId) { return resolveProfileParentLocked(userId); } + final int callingUserParentId = resolveProfileParentLocked(callingUserId); + if (callingUserParentId == mCurrentUserId && + (userId == UserHandle.USER_CURRENT + || userId == UserHandle.USER_CURRENT_OR_SELF)) { + return mCurrentUserId; + } if (!hasPermission(Manifest.permission.INTERACT_ACROSS_USERS) && !hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)) { throw new SecurityException("Call from user " + callingUserId + " as user " @@ -3883,4 +3919,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } } + + private final class LocalService extends AccessibilityManagerInternal { + @Override + public boolean isNonDefaultEncryptionPasswordAllowed() { + synchronized (mLock) { + UserState userState = getCurrentUserStateLocked(); + return !hasRunningServicesLocked(userState); + } + } + } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 0b1a627..a9cff22 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -137,6 +137,7 @@ import com.android.server.connectivity.Nat464Xlat; import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkMonitor; import com.android.server.connectivity.PacManager; +import com.android.server.connectivity.PermissionMonitor; import com.android.server.connectivity.Tethering; import com.android.server.connectivity.Vpn; import com.android.server.net.BaseNetworkObserver; @@ -225,6 +226,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { private Tethering mTethering; + private final PermissionMonitor mPermissionMonitor; + private KeyStore mKeyStore; @GuardedBy("mVpns") @@ -516,11 +519,13 @@ public class ConnectivityService extends IConnectivityManager.Stub { return; } - if (list.isEmpty() || isDefaultNetwork(nai)) { + list.add(nai); + + // Send a broadcast if this is the first network of its type or if it's the default. + if (list.size() == 1 || isDefaultNetwork(nai)) { maybeLogBroadcast(nai, true, type); sendLegacyNetworkBroadcast(nai, true, type); } - list.add(nai); } /** Removes the given network from the specified legacy type list. */ @@ -700,6 +705,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { mTethering = new Tethering(mContext, mNetd, statsService, mHandler.getLooper()); + mPermissionMonitor = new PermissionMonitor(mContext, mNetd); + //set up the listener for user state for creating user VPNs IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_STARTING); @@ -1482,6 +1489,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { } mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY)); + + mPermissionMonitor.startMonitoring(); } private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() { diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 7f24d07..b0535b3 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -63,6 +63,7 @@ import android.util.AttributeSet; import android.util.Slog; import android.util.Xml; +import android.view.AccessibilityManagerInternal; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IMediaContainerService; @@ -557,6 +558,8 @@ class MountService extends IMountService.Stub private final Handler mHandler; + private final AccessibilityManagerInternal mAccessibilityManagerInternal; + void waitForAsecScan() { waitForLatch(mAsecsScanned); } @@ -1454,6 +1457,9 @@ class MountService extends IMountService.Stub hthread.start(); mHandler = new MountServiceHandler(hthread.getLooper()); + mAccessibilityManagerInternal = LocalServices.getService( + AccessibilityManagerInternal.class); + // Watch for user changes final IntentFilter userFilter = new IntentFilter(); userFilter.addAction(Intent.ACTION_USER_ADDED); @@ -2254,8 +2260,15 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { + // The accessibility layer may veto having a non-default encryption + // password because if there are enabled accessibility services the + // user cannot authenticate as the latter need access to the data. + if (!TextUtils.isEmpty(password) + && !mAccessibilityManagerInternal.isNonDefaultEncryptionPasswordAllowed()) { + return getEncryptionState(); + } event = mConnector.execute("cryptfs", "changepw", CRYPTO_TYPES[type], - new SensitiveArg(toHex(password))); + new SensitiveArg(toHex(password))); return Integer.parseInt(event.getMessage()); } catch (NativeDaemonConnectorException e) { // Encryption failed @@ -2302,7 +2315,7 @@ class MountService extends IMountService.Stub * @return The type, one of the CRYPT_TYPE_XXX consts from StorageManager. */ @Override - public int getPasswordType() throws RemoteException { + public int getPasswordType() { waitForReady(); diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 822007a..020c951 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -16,7 +16,6 @@ package com.android.server; -import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CONNECTIVITY_INTERNAL; import static android.Manifest.permission.DUMP; import static android.Manifest.permission.SHUTDOWN; @@ -2059,20 +2058,26 @@ public class NetworkManagementService extends INetworkManagementService.Stub } @Override - public void setPermission(boolean internal, boolean changeNetState, int[] uids) { + public void setPermission(String permission, int[] uids) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - final Command cmd = new Command("network", "permission", "user", "set"); - if (internal) cmd.appendArg(CONNECTIVITY_INTERNAL); - if (changeNetState) cmd.appendArg(CHANGE_NETWORK_STATE); - for (int i=0; i<uids.length; i++) { - cmd.appendArg(uids[i]); - } - - try { - mConnector.execute(cmd); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + Object[] argv = new Object[4 + MAX_UID_RANGES_PER_COMMAND]; + argv[0] = "permission"; + argv[1] = "user"; + argv[2] = "set"; + argv[3] = permission; + int argc = 4; + // Avoid overly long commands by limiting number of UIDs per command. + for (int i = 0; i < uids.length; ++i) { + argv[argc++] = uids[i]; + if (i == uids.length - 1 || argc == argv.length) { + try { + mConnector.execute("network", Arrays.copyOf(argv, argc)); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + argc = 4; + } } } @@ -2080,15 +2085,22 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void clearPermission(int[] uids) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - final Command cmd = new Command("network", "permission", "user", "clear"); - for (int i=0; i<uids.length; i++) { - cmd.appendArg(uids[i]); - } - - try { - mConnector.execute(cmd); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND]; + argv[0] = "permission"; + argv[1] = "user"; + argv[2] = "clear"; + int argc = 3; + // Avoid overly long commands by limiting number of UIDs per command. + for (int i = 0; i < uids.length; ++i) { + argv[argc++] = uids[i]; + if (i == uids.length - 1 || argc == argv.length) { + try { + mConnector.execute("network", Arrays.copyOf(argv, argc)); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + argc = 3; + } } } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index b3337bb..e3e0228 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -212,11 +212,12 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { //defaultSubId comes before new defaultSubId update) we need to recall all //possible missed notify callback synchronized (mRecords) { - for (Record r : mRecords) { - if(r.subId == SubscriptionManager.DEFAULT_SUB_ID) { - checkPossibleMissNotify(r, newDefaultPhoneId); - } - } + for (Record r : mRecords) { + if(r.subId == SubscriptionManager.DEFAULT_SUB_ID) { + checkPossibleMissNotify(r, newDefaultPhoneId); + } + } + handleRemoveListLocked(); } mDefaultSubId = newDefaultSubId; mDefaultPhoneId = newDefaultPhoneId; @@ -1445,7 +1446,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callback.onServiceStateChanged( new ServiceState(mServiceState[phoneId])); } catch (RemoteException ex) { - remove(r.binder); + mRemoveList.add(r.binder); } } @@ -1472,7 +1473,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 : gsmSignalStrength)); } catch (RemoteException ex) { - remove(r.binder); + mRemoveList.add(r.binder); } } @@ -1484,7 +1485,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); } catch (RemoteException ex) { - remove(r.binder); + mRemoveList.add(r.binder); } } @@ -1497,7 +1498,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callback.onMessageWaitingIndicatorChanged( mMessageWaiting[phoneId]); } catch (RemoteException ex) { - remove(r.binder); + mRemoveList.add(r.binder); } } @@ -1510,7 +1511,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callback.onCallForwardingIndicatorChanged( mCallForwarding[phoneId]); } catch (RemoteException ex) { - remove(r.binder); + mRemoveList.add(r.binder); } } @@ -1535,7 +1536,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], mDataConnectionNetworkType[phoneId]); } catch (RemoteException ex) { - remove(r.binder); + mRemoveList.add(r.binder); } } } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 01e80b7..f430c56 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1468,6 +1468,7 @@ public final class ActiveServices { app.services.remove(r); r.app = null; scheduleServiceRestartLocked(r, false); + return; } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 12c98c1..4a10b73 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1192,7 +1192,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int SYSTEM_USER_START_MSG = 42; static final int SYSTEM_USER_CURRENT_MSG = 43; static final int ENTER_ANIMATION_COMPLETE_MSG = 44; - static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; + static final int FINISH_BOOTING_MSG = 45; static final int START_USER_SWITCH_MSG = 46; static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; @@ -1877,8 +1877,13 @@ public final class ActivityManagerService extends ActivityManagerNative } break; } - case ENABLE_SCREEN_AFTER_BOOT_MSG: { - enableScreenAfterBoot(); + case FINISH_BOOTING_MSG: { + if (msg.arg1 != 0) { + finishBooting(); + } + if (msg.arg2 != 0) { + enableScreenAfterBoot(); + } break; } case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { @@ -2025,7 +2030,7 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void onPackageModified(String packageName) { final int eventUserId = getChangingUserId(); - final PackageManager pm = mContext.getPackageManager(); + final IPackageManager pm = AppGlobals.getPackageManager(); final ArrayList<Pair<Intent, Integer>> recentTaskIntents = new ArrayList<Pair<Intent, Integer>>(); final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); @@ -2050,13 +2055,15 @@ public final class ActivityManagerService extends ActivityManagerNative continue; } try { - ActivityInfo info = pm.getActivityInfo(cn, eventUserId); - if (info != null && info.isEnabled()) { + ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); + if (info != null) { componentsKnownToExist.add(cn); } else { tasksToRemove.add(p.second); } - } catch (Exception e) {} + } catch (RemoteException e) { + Log.e(TAG, "Failed to query activity info for component: " + cn, e); + } } } // Prune all the tasks with removed components from the list of recent tasks @@ -4950,7 +4957,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } catch (InterruptedException e) { - Log.wtf(TAG, e); + Slog.wtf(TAG, e); } } @@ -4990,7 +4997,7 @@ public final class ActivityManagerService extends ActivityManagerNative observer.wait(200); // Wait for write-close, give up after 200msec } } catch (InterruptedException e) { - Log.wtf(TAG, e); + Slog.wtf(TAG, e); } } @@ -6258,8 +6265,9 @@ public final class ActivityManagerService extends ActivityManagerNative Binder.restoreCallingIdentity(origId); } - void postEnableScreenAfterBootLocked() { - mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); + void postFinishBooting(boolean finishBooting, boolean enableScreen) { + mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, + finishBooting? 1 : 0, enableScreen ? 1 : 0)); } void enableScreenAfterBoot() { @@ -6324,7 +6332,7 @@ public final class ActivityManagerService extends ActivityManagerNative startProcessLocked(procs.get(ip), "on-hold", null); } } - + if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { // Start looking for apps that are abusing wake locks. Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); @@ -6564,7 +6572,7 @@ public final class ActivityManagerService extends ActivityManagerNative throw new IllegalArgumentException("File descriptors passed in options"); } } - + synchronized(this) { int callingUid = Binder.getCallingUid(); int origUserId = userId; @@ -6594,7 +6602,7 @@ public final class ActivityManagerService extends ActivityManagerNative return getIntentSenderLocked(type, packageName, callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes, flags, options); - + } catch (RemoteException e) { throw new SecurityException(e); } @@ -6852,7 +6860,7 @@ public final class ActivityManagerService extends ActivityManagerNative "setProcessForeground()"); synchronized(this) { boolean changed = false; - + synchronized (mPidsSelfLocked) { ProcessRecord pr = mPidsSelfLocked.get(pid); if (pr == null && isForeground) { @@ -6888,13 +6896,13 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - + if (changed) { updateOomAdjLocked(); } } } - + // ========================================================= // PERMISSIONS // ========================================================= @@ -6956,7 +6964,7 @@ public final class ActivityManagerService extends ActivityManagerNative * permission is automatically denied. (Internally a null permission * string is used when calling {@link #checkComponentPermission} in cases * when only uid-based security is needed.) - * + * * This can be called with or without the global lock held. */ @Override @@ -7213,12 +7221,12 @@ public final class ActivityManagerService extends ActivityManagerNative if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking grant " + targetPkg + " permission to " + grantUri); } - + final IPackageManager pm = AppGlobals.getPackageManager(); // If this is not a content: uri, we can't do anything with it. if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { - if (DEBUG_URI_PERMISSION) Slog.v(TAG, + if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Can't grant URI permission for non-content URI: " + grantUri); return -1; } @@ -7346,7 +7354,7 @@ public final class ActivityManagerService extends ActivityManagerNative // to the uri, and the target doesn't. Let's now give this to // the target. - if (DEBUG_URI_PERMISSION) Slog.v(TAG, + if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); final String authority = grantUri.uri.getAuthority(); @@ -7548,7 +7556,7 @@ public final class ActivityManagerService extends ActivityManagerNative final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( perm.targetUid); if (perms != null) { - if (DEBUG_URI_PERMISSION) Slog.v(TAG, + if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Removing " + perm.targetUid + " permission to " + perm.uri); perms.remove(perm.uri); @@ -7909,9 +7917,9 @@ public final class ActivityManagerService extends ActivityManagerNative } catch (FileNotFoundException e) { // Missing grants is okay } catch (IOException e) { - Log.wtf(TAG, "Failed reading Uri grants", e); + Slog.wtf(TAG, "Failed reading Uri grants", e); } catch (XmlPullParserException e) { - Log.wtf(TAG, "Failed reading Uri grants", e); + Slog.wtf(TAG, "Failed reading Uri grants", e); } finally { IoUtils.closeQuietly(fis); } @@ -8117,7 +8125,7 @@ public final class ActivityManagerService extends ActivityManagerNative outInfo.foregroundAppThreshold = mProcessList.getMemLevel( ProcessList.FOREGROUND_APP_ADJ); } - + // ========================================================= // TASK MANAGEMENT // ========================================================= @@ -8519,7 +8527,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - + /** * TODO: Add mController hook */ @@ -8595,7 +8603,7 @@ public final class ActivityManagerService extends ActivityManagerNative /** * Moves an activity, and all of the other activities within the same task, to the bottom * of the history stack. The activity's order within the task is unchanged. - * + * * @param token A reference to the activity we wish to move * @param nonRoot If false then this only works if the activity is the root * of a task; if true it will work for any activity in a task. @@ -9016,7 +9024,7 @@ public final class ActivityManagerService extends ActivityManagerNative == PackageManager.PERMISSION_GRANTED) { return null; } - + PathPermission[] pps = cpi.pathPermissions; if (pps != null) { int i = pps.length; @@ -9349,6 +9357,7 @@ public final class ActivityManagerService extends ActivityManagerNative checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); final boolean firstClass = cpr == null; if (firstClass) { + final long ident = Binder.clearCallingIdentity(); try { checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); ApplicationInfo ai = @@ -9366,6 +9375,8 @@ public final class ActivityManagerService extends ActivityManagerNative cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); } catch (RemoteException ex) { // pm is in same process, this will never happen. + } finally { + Binder.restoreCallingIdentity(ident); } } @@ -9597,7 +9608,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - + public final void publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers) { if (providers == null) { @@ -10075,7 +10086,7 @@ public final class ActivityManagerService extends ActivityManagerNative return timedout; } - + public final void activitySlept(IBinder token) { if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); @@ -10150,7 +10161,7 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException("Requires permission " + android.Manifest.permission.STOP_APP_SWITCHES); } - + synchronized(this) { mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME; @@ -10160,14 +10171,14 @@ public final class ActivityManagerService extends ActivityManagerNative mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); } } - + public void resumeAppSwitches() { if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires permission " + android.Manifest.permission.STOP_APP_SWITCHES); } - + synchronized(this) { // Note that we don't execute any pending app switches... we will // let those wait until either the timeout, or the next start @@ -10175,7 +10186,7 @@ public final class ActivityManagerService extends ActivityManagerNative mAppSwitchesAllowedTime = 0; } } - + boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, int callingPid, int callingUid, String name) { if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { @@ -10203,7 +10214,7 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, name + " request from " + sourceUid + " stopped"); return false; } - + public void setDebugApp(String packageName, boolean waitForDebugger, boolean persistent) { enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, @@ -11177,7 +11188,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - + synchronized(this) { if (procsToKill != null) { for (int i=procsToKill.size()-1; i>=0; i--) { @@ -11186,20 +11197,20 @@ public final class ActivityManagerService extends ActivityManagerNative removeProcessLocked(proc, true, false, "system update done"); } } - + // Now that we have cleaned up any update processes, we // are ready to start launching real processes and know that // we won't trample on them any more. mProcessesReady = true; } - + Slog.i(TAG, "System now ready"); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis()); synchronized(this) { // Make sure we have no pre-ready processes sitting around. - + if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { ResolveInfo ri = mContext.getPackageManager() .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), @@ -11272,6 +11283,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Start up initial activity. mBooting = true; + startHomeActivityLocked(mCurrentUserId); try { if (AppGlobals.getPackageManager().hasSystemUidErrors()) { @@ -11333,12 +11345,12 @@ public final class ActivityManagerService extends ActivityManagerNative startAppProblemLocked(app); app.stopFreezingAllLocked(); } - + /** * Generate a process error record, suitable for attachment to a ProcessRecord. - * + * * @param app The ProcessRecord in which the error occurred. - * @param condition Crashing, Application Not Responding, etc. Values are defined in + * @param condition Crashing, Application Not Responding, etc. Values are defined in * ActivityManager.AppErrorStateInfo * @param activity The activity associated with the crash, if known. * @param shortMsg Short message describing the crash. @@ -11347,7 +11359,7 @@ public final class ActivityManagerService extends ActivityManagerNative * * @return Returns a fully-formed AppErrorStateInfo record. */ - private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, + private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, int condition, String activity, String shortMsg, String longMsg, String stackTrace) { ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); @@ -11700,17 +11712,10 @@ public final class ActivityManagerService extends ActivityManagerNative * @param crashInfo describing the context of the error * @return true if the process should exit immediately (WTF is fatal) */ - public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, + public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, final ApplicationErrorReport.CrashInfo crashInfo) { - final ProcessRecord r = findAppProcess(app, "WTF"); - final String processName = app == null ? "system_server" - : (r == null ? "unknown" : r.processName); - - EventLog.writeEvent(EventLogTags.AM_WTF, - UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), - processName, - r == null ? -1 : r.info.flags, - tag, crashInfo.exceptionMessage); + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); if (system) { // If this is coming from the system, we could very well have low-level @@ -11718,14 +11723,14 @@ public final class ActivityManagerService extends ActivityManagerNative // never want this to become fatal, so there is that too. mHandler.post(new Runnable() { @Override public void run() { - addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, - crashInfo); + handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); } }); return false; } - addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); + final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, + crashInfo); if (r != null && r.pid != Process.myPid() && Settings.Global.getInt(mContext.getContentResolver(), @@ -11737,6 +11742,20 @@ public final class ActivityManagerService extends ActivityManagerNative } } + ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, + final ApplicationErrorReport.CrashInfo crashInfo) { + final ProcessRecord r = findAppProcess(app, "WTF"); + final String processName = app == null ? "system_server" + : (r == null ? "unknown" : r.processName); + + EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, + processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); + + addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); + + return r; + } + /** * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) * @return the corresponding {@link ProcessRecord} object, or null if none could be found @@ -12104,14 +12123,14 @@ public final class ActivityManagerService extends ActivityManagerNative } else if (app.notResponding) { report = app.notRespondingReport; } - + if (report != null) { if (errList == null) { errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); } errList.add(report); } else { - Slog.w(TAG, "Missing app error report, app = " + app.processName + + Slog.w(TAG, "Missing app error report, app = " + app.processName + " crashing = " + app.crashing + " notResponding = " + app.notResponding); } @@ -12170,7 +12189,7 @@ public final class ActivityManagerService extends ActivityManagerNative } if ((app.thread != null) && (!app.crashing && !app.notResponding)) { // Generate process state info for running application - ActivityManager.RunningAppProcessInfo currApp = + ActivityManager.RunningAppProcessInfo currApp = new ActivityManager.RunningAppProcessInfo(app.processName, app.pid, app.getPackageList()); fillInProcMemInfo(app, currApp); @@ -12252,7 +12271,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean dumpAll = false; boolean dumpClient = false; String dumpPackage = null; - + int opti = 0; while (opti < args.length) { String opt = args[opti]; @@ -12505,7 +12524,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean printedAnything = false; - if (mRecentTasks.size() > 0) { + if (mRecentTasks != null && mRecentTasks.size() > 0) { boolean printedHeader = false; final int N = mRecentTasks.size(); @@ -12625,12 +12644,12 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - + if (mForegroundProcesses.size() > 0) { synchronized (mPidsSelfLocked) { boolean printed = false; for (int i=0; i<mForegroundProcesses.size(); i++) { - ProcessRecord r = mPidsSelfLocked.get( + ProcessRecord r = mPidsSelfLocked.get( mForegroundProcesses.valueAt(i).pid); if (dumpPackage != null && (r == null || !r.pkgList.containsKey(dumpPackage))) { @@ -12648,7 +12667,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - + if (mPersistentStartingProcesses.size() > 0) { if (needSep) pw.println(); needSep = true; @@ -12666,7 +12685,7 @@ public final class ActivityManagerService extends ActivityManagerNative dumpProcessList(pw, this, mRemovedProcesses, " ", "Removed Norm", "Removed PERS", dumpPackage); } - + if (mProcessesOnHold.size() > 0) { if (needSep) pw.println(); needSep = true; @@ -12677,7 +12696,7 @@ public final class ActivityManagerService extends ActivityManagerNative } needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); - + if (mProcessCrashTimes.getMap().size() > 0) { boolean printed = false; long now = SystemClock.uptimeMillis(); @@ -12904,10 +12923,12 @@ public final class ActivityManagerService extends ActivityManagerNative if (dumpAll) { pw.println(" Total persistent processes: " + numPers); pw.println(" mProcessesReady=" + mProcessesReady - + " mSystemReady=" + mSystemReady); - pw.println(" mBooting=" + mBooting + + " mSystemReady=" + mSystemReady + " mBooted=" + mBooted + " mFactoryTest=" + mFactoryTest); + pw.println(" mBooting=" + mBooting + + " mCallFinishBooting=" + mCallFinishBooting + + " mBootAnimationComplete=" + mBootAnimationComplete); pw.print(" mLastPowerCheckRealtime="); TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); pw.println(""); @@ -13047,7 +13068,7 @@ public final class ActivityManagerService extends ActivityManagerNative ArrayList<String> strings; ArrayList<Integer> objects; boolean all; - + ItemMatcher() { all = true; } @@ -13132,7 +13153,7 @@ public final class ActivityManagerService extends ActivityManagerNative protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) { ArrayList<ActivityRecord> activities; - + synchronized (this) { activities = mStackSupervisor.getDumpActivitiesLocked(name); } @@ -13255,7 +13276,7 @@ public final class ActivityManagerService extends ActivityManagerNative } needSep = true; - + if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { for (int user=0; user<mStickyBroadcasts.size(); user++) { if (needSep) { @@ -13290,7 +13311,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - + if (!onlyHistory && dumpAll) { pw.println(); for (BroadcastQueue queue : mBroadcastQueues) { @@ -13302,7 +13323,7 @@ public final class ActivityManagerService extends ActivityManagerNative needSep = true; printedAnything = true; } - + if (!printedAnything) { pw.println(" (nothing)"); } @@ -13638,7 +13659,7 @@ public final class ActivityManagerService extends ActivityManagerNative long realtime = SystemClock.elapsedRealtime(); pw.println("Applications Graphics Acceleration Info:"); pw.println("Uptime: " + uptime + " Realtime: " + realtime); - + for (int i = procs.size() - 1 ; i >= 0 ; i--) { ProcessRecord r = procs.get(i); if (r.thread != null) { @@ -13832,7 +13853,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean oomOnly = false; boolean isCompact = false; boolean localOnly = false; - + int opti = 0; while (opti < args.length) { String opt = args[opti]; @@ -13866,7 +13887,7 @@ public final class ActivityManagerService extends ActivityManagerNative pw.println("Unknown argument: " + opt + "; use -h for help"); } } - + final boolean isCheckinRequest = scanArgs(args, "--checkin"); long uptime = SystemClock.uptimeMillis(); long realtime = SystemClock.elapsedRealtime(); @@ -14551,7 +14572,7 @@ public final class ActivityManagerService extends ActivityManagerNative } return restart; } - + // ========================================================= // SERVICES // ========================================================= @@ -14633,7 +14654,7 @@ public final class ActivityManagerService extends ActivityManagerNative return mServices.peekServiceLocked(service, resolvedType); } } - + @Override public boolean stopServiceToken(ComponentName className, IBinder token, int startId) { @@ -14855,11 +14876,11 @@ public final class ActivityManagerService extends ActivityManagerNative mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); } } - + // ========================================================= // BACKUP AND RESTORE // ========================================================= - + // Cause the target app to be launched if necessary and its backup agent // instantiated. The backup agent will invoke backupAgentCreated() on the // activity manager to announce its creation. @@ -14922,7 +14943,7 @@ public final class ActivityManagerService extends ActivityManagerNative // mBackupAppName describe the app, so that when it binds back to the AM we // know that it's scheduled for a backup-agent operation. } - + return true; } @@ -15225,7 +15246,7 @@ public final class ActivityManagerService extends ActivityManagerNative mReceiverResolver.removeFilter(rl.get(i)); } } - + private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { ProcessRecord r = mLruProcesses.get(i); @@ -15631,10 +15652,10 @@ public final class ActivityManagerService extends ActivityManagerNative final boolean replacePending = (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; - + if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() + " replacePending=" + replacePending); - + int NR = registeredReceivers != null ? registeredReceivers.size() : 0; if (!ordered && NR > 0) { // If we are not serializing this broadcast, then send the @@ -15742,7 +15763,7 @@ public final class ActivityManagerService extends ActivityManagerNative int seq = r.intent.getIntExtra("seq", -1); Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); } - boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); + boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); if (!replaced) { queue.enqueueOrderedBroadcastLocked(r); queue.scheduleBroadcastsLocked(); @@ -15908,7 +15929,7 @@ public final class ActivityManagerService extends ActivityManagerNative Binder.restoreCallingIdentity(origId); } } - + // ========================================================= // INSTRUMENTATION // ========================================================= @@ -15978,17 +15999,17 @@ public final class ActivityManagerService extends ActivityManagerNative return true; } - + /** - * Report errors that occur while attempting to start Instrumentation. Always writes the + * Report errors that occur while attempting to start Instrumentation. Always writes the * error to the logs, but if somebody is watching, send the report there too. This enables * the "am" command to report errors with more information. - * + * * @param watcher The IInstrumentationWatcher. Null if there isn't one. * @param cn The component name of the instrumentation. * @param report The error report. */ - private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, + private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, ComponentName cn, String report) { Slog.w(TAG, report); try { @@ -16058,7 +16079,7 @@ public final class ActivityManagerService extends ActivityManagerNative // ========================================================= // CONFIGURATION // ========================================================= - + public ConfigurationInfo getDeviceConfigurationInfo() { ConfigurationInfo config = new ConfigurationInfo(); synchronized (this) { @@ -16148,11 +16169,11 @@ public final class ActivityManagerService extends ActivityManagerNative if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { Slog.i(TAG, "Updating configuration to: " + values); } - + EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); if (values.locale != null && !initLocale) { - saveLocaleLocked(values.locale, + saveLocaleLocked(values.locale, !values.locale.equals(mConfiguration.locale), values.userSetLocale); } @@ -16168,7 +16189,7 @@ public final class ActivityManagerService extends ActivityManagerNative //mUsageStatsService.noteStartConfig(newConfig); final Configuration configCopy = new Configuration(mConfiguration); - + // TODO: If our config changes, should we auto dismiss any currently // showing dialogs? mShowDialogs = shouldShowDialogs(newConfig); @@ -16267,7 +16288,7 @@ public final class ActivityManagerService extends ActivityManagerNative if(isDiff) { SystemProperties.set("user.language", l.getLanguage()); SystemProperties.set("user.region", l.getCountry()); - } + } if(isPersist) { SystemProperties.set("persist.sys.language", l.getLanguage()); @@ -16955,7 +16976,7 @@ public final class ActivityManagerService extends ActivityManagerNative } app.curRawAdj = adj; - + //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); if (adj > app.maxAdj) { @@ -17038,7 +17059,7 @@ public final class ActivityManagerService extends ActivityManagerNative // whatever. } } - + /** * Returns true if things are idle enough to perform GCs. */ @@ -17052,7 +17073,7 @@ public final class ActivityManagerService extends ActivityManagerNative return !processingBroadcasts && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); } - + /** * Perform GCs on all processes that are waiting for it, but only * if things are idle. @@ -17081,11 +17102,11 @@ public final class ActivityManagerService extends ActivityManagerNative } } } - + scheduleAppGcsLocked(); } } - + /** * If all looks good, perform GCs on all processes waiting for them. */ @@ -17103,12 +17124,12 @@ public final class ActivityManagerService extends ActivityManagerNative */ final void scheduleAppGcsLocked() { mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); - + if (mProcessesToGc.size() > 0) { // Schedule a GC for the time to the next process. ProcessRecord proc = mProcessesToGc.get(0); Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); - + long when = proc.lastRequestedGc + GC_MIN_INTERVAL; long now = SystemClock.uptimeMillis(); if (when < (now+GC_TIMEOUT)) { @@ -17117,7 +17138,7 @@ public final class ActivityManagerService extends ActivityManagerNative mHandler.sendMessageAtTime(msg, when); } } - + /** * Add a process to the array of processes waiting to be GCed. Keeps the * list in sorted order by the last GC time. The process can't already be @@ -17137,7 +17158,7 @@ public final class ActivityManagerService extends ActivityManagerNative mProcessesToGc.add(0, proc); } } - + /** * Set up to ask a process to GC itself. This will either do it * immediately, or put it on the list of processes to gc the next diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 0646cce..e1b8278 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1105,6 +1105,11 @@ final class ActivityStack { invalidateLastScreenshot(); } next.returningOptions = null; + + if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == next) { + // When resuming an activity, require it to call requestVisibleBehind() again. + mActivityContainer.mActivityDisplay.setVisibleBehindActivity(null); + } } private void setVisibile(ActivityRecord r, boolean visible) { @@ -1482,6 +1487,11 @@ final class ActivityStack { final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); + if (!mService.mBooting && !mService.mBooted) { + // Not ready yet! + return false; + } + ActivityRecord parent = mActivityContainer.mParentActivity; if ((parent != null && parent.state != ActivityState.RESUMED) || !mActivityContainer.isAttachedLocked()) { @@ -3291,6 +3301,11 @@ final class ActivityStack { if (hasVisibleBehindActivity() && !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) { final ActivityRecord r = getVisibleBehindActivity(); + if (r == topRunningActivityLocked(null)) { + // Don't release the top activity if it has requested to run behind the next + // activity. + return; + } if (DEBUG_STATES) Slog.d(TAG, "releaseBackgroundResources activtyDisplay=" + mActivityContainer.mActivityDisplay + " visibleBehind=" + r + " app=" + r.app + " thread=" + r.app.thread); @@ -3606,6 +3621,10 @@ final class ActivityStack { final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null; if (task == tr && tr.isOverHomeStack() || numTasks <= 1 && isOnHomeDisplay()) { + if (!mService.mBooting && !mService.mBooted) { + // Not ready yet! + return false; + } final int taskToReturnTo = tr.getTaskToReturnTo(); tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 83a8d45..bbfb62a 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -421,6 +421,11 @@ public final class ActivityStackSupervisor implements DisplayListener { } boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) { + if (!mService.mBooting && !mService.mBooted) { + // Not ready yet! + return false; + } + if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { mWindowManager.showRecentApps(); return false; @@ -2238,9 +2243,13 @@ public final class ActivityStackSupervisor implements DisplayListener { r.idle = true; //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); - if (!mService.mBooted && isFrontStack(r.task.stack)) { - mService.mBooted = true; - enableScreen = true; + if (isFrontStack(r.task.stack) || fromTimeout) { + booting = mService.mBooting; + mService.mBooting = false; + if (!mService.mBooted) { + mService.mBooted = true; + enableScreen = true; + } } } @@ -2268,9 +2277,6 @@ public final class ActivityStackSupervisor implements DisplayListener { mFinishingActivities.clear(); } - booting = mService.mBooting; - mService.mBooting = false; - if (mStartingUsers.size() > 0) { startingUsers = new ArrayList<UserStartedState>(mStartingUsers); mStartingUsers.clear(); @@ -2295,9 +2301,7 @@ public final class ActivityStackSupervisor implements DisplayListener { activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle"); } - if (booting) { - mService.finishBooting(); - } else { + if (!booting) { // Complete user switch if (startingUsers != null) { for (int i = 0; i < startingUsers.size(); i++) { @@ -2318,8 +2322,8 @@ public final class ActivityStackSupervisor implements DisplayListener { //dump(); //mWindowManager.dump(); - if (enableScreen) { - mService.postEnableScreenAfterBootLocked(); + if (booting || enableScreen) { + mService.postFinishBooting(booting, enableScreen); } if (activityRemoved) { @@ -2584,7 +2588,6 @@ public final class ActivityStackSupervisor implements DisplayListener { r.mLaunchTaskBehind); } } - resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); } void moveTaskToStack(int taskId, int stackId, boolean toTop) { diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 4e554eb..e01b983 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -901,7 +901,7 @@ public final class BroadcastQueue { Slog.w(TAG, "Exception when sending broadcast to " + r.curComponent, e); } catch (RuntimeException e) { - Log.wtf(TAG, "Failed sending broadcast to " + Slog.wtf(TAG, "Failed sending broadcast to " + r.curComponent + " with " + r.intent, e); // If some unexpected exception happened, just skip // this broadcast. At this point we are not in the call diff --git a/services/core/java/com/android/server/am/UriPermission.java b/services/core/java/com/android/server/am/UriPermission.java index 91daf77..650a837 100644 --- a/services/core/java/com/android/server/am/UriPermission.java +++ b/services/core/java/com/android/server/am/UriPermission.java @@ -257,7 +257,7 @@ final class UriPermission { */ void removeReadOwner(UriPermissionOwner owner) { if (!mReadOwners.remove(owner)) { - Log.wtf(TAG, "Unknown read owner " + owner + " in " + this); + Slog.wtf(TAG, "Unknown read owner " + owner + " in " + this); } if (mReadOwners.size() == 0) { mReadOwners = null; @@ -282,7 +282,7 @@ final class UriPermission { */ void removeWriteOwner(UriPermissionOwner owner) { if (!mWriteOwners.remove(owner)) { - Log.wtf(TAG, "Unknown write owner " + owner + " in " + this); + Slog.wtf(TAG, "Unknown write owner " + owner + " in " + this); } if (mWriteOwners.size() == 0) { mWriteOwners = null; diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java new file mode 100644 index 0000000..238402f --- /dev/null +++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.connectivity; + +import static android.Manifest.permission.CHANGE_NETWORK_STATE; +import static android.Manifest.permission.CONNECTIVITY_INTERNAL; +import static android.content.pm.ApplicationInfo.FLAG_SYSTEM; +import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; +import static android.content.pm.PackageManager.GET_PERMISSIONS; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.UserInfo; +import android.net.Uri; +import android.os.INetworkManagementService; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; +import android.text.TextUtils; +import android.util.Log; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Map; +import java.util.Set; + +/** + * A utility class to inform Netd of UID permisisons. + * Does a mass update at boot and then monitors for app install/remove. + * + * @hide + */ +public class PermissionMonitor { + private static final String TAG = "PermissionMonitor"; + private static final boolean DBG = true; + private static final boolean SYSTEM = true; + private static final boolean NETWORK = false; + + private final Context mContext; + private final PackageManager mPackageManager; + private final UserManager mUserManager; + private final INetworkManagementService mNetd; + private final BroadcastReceiver mIntentReceiver; + + // Values are User IDs. + private final Set<Integer> mUsers = new HashSet<Integer>(); + + // Keys are App IDs. Values are true for SYSTEM permission and false for NETWORK permission. + private final Map<Integer, Boolean> mApps = new HashMap<Integer, Boolean>(); + + public PermissionMonitor(Context context, INetworkManagementService netd) { + mContext = context; + mPackageManager = context.getPackageManager(); + mUserManager = UserManager.get(context); + mNetd = netd; + mIntentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); + int appUid = intent.getIntExtra(Intent.EXTRA_UID, -1); + Uri appData = intent.getData(); + String appName = appData != null ? appData.getSchemeSpecificPart() : null; + + if (Intent.ACTION_USER_ADDED.equals(action)) { + onUserAdded(user); + } else if (Intent.ACTION_USER_REMOVED.equals(action)) { + onUserRemoved(user); + } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { + onAppAdded(appName, appUid); + } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { + onAppRemoved(appUid); + } + } + }; + } + + // Intended to be called only once at startup, after the system is ready. Installs a broadcast + // receiver to monitor ongoing UID changes, so this shouldn't/needn't be called again. + public synchronized void startMonitoring() { + log("Monitoring"); + + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_USER_ADDED); + intentFilter.addAction(Intent.ACTION_USER_REMOVED); + mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, intentFilter, null, null); + + intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + intentFilter.addDataScheme("package"); + mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, intentFilter, null, null); + + List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS); + if (apps == null) { + loge("No apps"); + return; + } + + for (PackageInfo app : apps) { + int uid = app.applicationInfo != null ? app.applicationInfo.uid : -1; + if (uid < 0) { + continue; + } + + boolean isNetwork = hasNetworkPermission(app); + boolean isSystem = hasSystemPermission(app); + + if (isNetwork || isSystem) { + Boolean permission = mApps.get(uid); + // If multiple packages share a UID (cf: android:sharedUserId) and ask for different + // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is). + if (permission == null || permission == NETWORK) { + mApps.put(uid, isSystem); + } + } + } + + List<UserInfo> users = mUserManager.getUsers(true); // exclude dying users + if (users != null) { + for (UserInfo user : users) { + mUsers.add(user.id); + } + } + + log("Users: " + mUsers.size() + ", Apps: " + mApps.size()); + update(mUsers, mApps, true); + } + + private boolean hasPermission(PackageInfo app, String permission) { + if (app.requestedPermissions != null) { + for (String p : app.requestedPermissions) { + if (permission.equals(p)) { + return true; + } + } + } + return false; + } + + private boolean hasNetworkPermission(PackageInfo app) { + return hasPermission(app, CHANGE_NETWORK_STATE); + } + + private boolean hasSystemPermission(PackageInfo app) { + int flags = app.applicationInfo != null ? app.applicationInfo.flags : 0; + if ((flags & FLAG_SYSTEM) != 0 || (flags & FLAG_UPDATED_SYSTEM_APP) != 0) { + return true; + } + return hasPermission(app, CONNECTIVITY_INTERNAL); + } + + private int[] toIntArray(List<Integer> list) { + int[] array = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + array[i] = list.get(i); + } + return array; + } + + private void update(Set<Integer> users, Map<Integer, Boolean> apps, boolean add) { + List<Integer> network = new ArrayList<Integer>(); + List<Integer> system = new ArrayList<Integer>(); + for (Entry<Integer, Boolean> app : apps.entrySet()) { + List<Integer> list = app.getValue() ? system : network; + for (int user : users) { + list.add(UserHandle.getUid(user, app.getKey())); + } + } + try { + if (add) { + mNetd.setPermission(CHANGE_NETWORK_STATE, toIntArray(network)); + mNetd.setPermission(CONNECTIVITY_INTERNAL, toIntArray(system)); + } else { + mNetd.clearPermission(toIntArray(network)); + mNetd.clearPermission(toIntArray(system)); + } + } catch (RemoteException e) { + loge("Exception when updating permissions: " + e); + } + } + + private synchronized void onUserAdded(int user) { + if (user < 0) { + loge("Invalid user in onUserAdded: " + user); + return; + } + mUsers.add(user); + + Set<Integer> users = new HashSet<Integer>(); + users.add(user); + update(users, mApps, true); + } + + private synchronized void onUserRemoved(int user) { + if (user < 0) { + loge("Invalid user in onUserRemoved: " + user); + return; + } + mUsers.remove(user); + + Set<Integer> users = new HashSet<Integer>(); + users.add(user); + update(users, mApps, false); + } + + private synchronized void onAppAdded(String appName, int appUid) { + if (TextUtils.isEmpty(appName) || appUid < 0) { + loge("Invalid app in onAppAdded: " + appName + " | " + appUid); + return; + } + + try { + PackageInfo app = mPackageManager.getPackageInfo(appName, GET_PERMISSIONS); + boolean isNetwork = hasNetworkPermission(app); + boolean isSystem = hasSystemPermission(app); + if (isNetwork || isSystem) { + Boolean permission = mApps.get(appUid); + // If multiple packages share a UID (cf: android:sharedUserId) and ask for different + // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is). + if (permission == null || permission == NETWORK) { + mApps.put(appUid, isSystem); + + Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>(); + apps.put(appUid, isSystem); + update(mUsers, apps, true); + } + } + } catch (NameNotFoundException e) { + loge("NameNotFoundException in onAppAdded: " + e); + } + } + + private synchronized void onAppRemoved(int appUid) { + if (appUid < 0) { + loge("Invalid app in onAppRemoved: " + appUid); + return; + } + mApps.remove(appUid); + + Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>(); + apps.put(appUid, NETWORK); // doesn't matter which permission we pick here + update(mUsers, apps, false); + } + + private static void log(String s) { + if (DBG) { + Log.d(TAG, s); + } + } + + private static void loge(String s) { + Log.e(TAG, s); + } +} diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 9292d45..adc96f7 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -311,7 +311,9 @@ public class SyncManager { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Reconnection detected: clearing all backoffs"); } - mSyncStorageEngine.clearAllBackoffs(mSyncQueue); + synchronized (mSyncQueue) { + mSyncStorageEngine.clearAllBackoffsLocked(mSyncQueue); + } } sendCheckAlarmsMessage(); } diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java index 9499370..0d5f240 100644 --- a/services/core/java/com/android/server/content/SyncStorageEngine.java +++ b/services/core/java/com/android/server/content/SyncStorageEngine.java @@ -834,17 +834,16 @@ public class SyncStorageEngine extends Handler { return changed; } - public void clearAllBackoffs(SyncQueue syncQueue) { + public void clearAllBackoffsLocked(SyncQueue syncQueue) { boolean changed = false; synchronized (mAuthorities) { - synchronized (syncQueue) { // Clear backoff for all sync adapters. for (AccountInfo accountInfo : mAccounts.values()) { for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "clearAllBackoffs:" + Log.v(TAG, "clearAllBackoffsLocked:" + " authority:" + authorityInfo.target + " account:" + accountInfo.accountAndUser.account.name + " user:" + accountInfo.accountAndUser.userId @@ -868,7 +867,6 @@ public class SyncStorageEngine extends Handler { authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; } } - } syncQueue.clearBackoffs(); } } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 43c01cd..97748e8 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -448,7 +448,7 @@ public final class DisplayManagerService extends SystemService { mWifiDisplayAdapter.requestStopScanLocked(); } } else if (mWifiDisplayScanRequestCount < 0) { - Log.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " + Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " + mWifiDisplayScanRequestCount); mWifiDisplayScanRequestCount = 0; } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index e2a548a..e3a25c0 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -227,6 +227,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // turning off the screen. private boolean mPendingScreenOff; + // True if we have unfinished business and are holding a suspend blocker. + private boolean mUnfinishedBusiness; + // The elapsed real time when the screen on was blocked. private long mScreenOnBlockStartRealTime; @@ -633,22 +636,42 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAppliedLowPower = true; } - // Animate the screen brightness when the screen is on. - if (state != Display.STATE_OFF) { - animateScreenBrightness(brightness, slowChange - ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); - } - // Animate the screen state change unless already animating. animateScreenStateChange(state, performScreenOffTransition); - // Report whether the display is ready for use and all changes have been applied. - if (mustNotify - && mPendingScreenOnUnblocker == null + // Animate the screen brightness when the screen is on or dozing. + // Skip the animation when the screen is off or suspended. + final int actualState = mPowerState.getScreenState(); + if (actualState == Display.STATE_ON || actualState == Display.STATE_DOZE) { + animateScreenBrightness(brightness, + slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); + } else { + animateScreenBrightness(brightness, 0); + } + + // Determine whether the display is ready for use in the newly requested state. + // Note that we do not wait for the brightness ramp animation to complete before + // reporting the display is ready because we only need to ensure the screen is in the + // right power state even as it continues to converge on the desired brightness. + final boolean ready = mPendingScreenOnUnblocker == null && !mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted() - && !mScreenBrightnessRampAnimator.isAnimating() - && mPowerState.waitUntilClean(mCleanListener)) { + && mPowerState.waitUntilClean(mCleanListener); + final boolean finished = ready + && !mScreenBrightnessRampAnimator.isAnimating(); + + // Grab a wake lock if we have unfinished business. + if (!finished && !mUnfinishedBusiness) { + if (DEBUG) { + Slog.d(TAG, "Unfinished business..."); + } + mCallbacks.acquireSuspendBlocker(); + mUnfinishedBusiness = true; + } + + // Notify the power manager when ready. + if (ready && mustNotify) { + // Send state change. synchronized (mLock) { if (!mPendingRequestChangedLocked) { mDisplayReadyLocked = true; @@ -660,6 +683,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } sendOnStateChangedWithWakelock(); } + + // Release the wake lock when we have no unfinished business. + if (finished && mUnfinishedBusiness) { + if (DEBUG) { + Slog.d(TAG, "Finished business..."); + } + mUnfinishedBusiness = false; + mCallbacks.releaseSuspendBlocker(); + } } @Override @@ -723,6 +755,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void animateScreenBrightness(int target, int rate) { + if (DEBUG) { + Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate); + } if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { try { mBatteryStats.noteScreenBrightness(target); diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java index a7651e4..fc068af 100644 --- a/services/core/java/com/android/server/display/DisplayPowerState.java +++ b/services/core/java/com/android/server/display/DisplayPowerState.java @@ -80,6 +80,7 @@ final class DisplayPowerState { mBacklight = backlight; mColorFade = electronBeam; mPhotonicModulator = new PhotonicModulator(); + mPhotonicModulator.start(); // At boot time, we know that the screen is on and the electron beam // animation is not playing. We don't know the screen's brightness though, @@ -336,7 +337,7 @@ final class DisplayPowerState { /** * Updates the state of the screen and backlight asynchronously on a separate thread. */ - private final class PhotonicModulator { + private final class PhotonicModulator extends Thread { private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off private static final int INITIAL_BACKLIGHT = -1; // unknown @@ -361,7 +362,7 @@ final class DisplayPowerState { if (!mChangeInProgress) { mChangeInProgress = true; - AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask); + mLock.notifyAll(); } } return !mChangeInProgress; @@ -369,75 +370,78 @@ final class DisplayPowerState { } public void dump(PrintWriter pw) { - pw.println(); - pw.println("Photonic Modulator State:"); - pw.println(" mPendingState=" + Display.stateToString(mPendingState)); - pw.println(" mPendingBacklight=" + mPendingBacklight); - pw.println(" mActualState=" + Display.stateToString(mActualState)); - pw.println(" mActualBacklight=" + mActualBacklight); - pw.println(" mChangeInProgress=" + mChangeInProgress); + synchronized (mLock) { + pw.println(); + pw.println("Photonic Modulator State:"); + pw.println(" mPendingState=" + Display.stateToString(mPendingState)); + pw.println(" mPendingBacklight=" + mPendingBacklight); + pw.println(" mActualState=" + Display.stateToString(mActualState)); + pw.println(" mActualBacklight=" + mActualBacklight); + pw.println(" mChangeInProgress=" + mChangeInProgress); + } } - private final Runnable mTask = new Runnable() { - @Override - public void run() { - // Apply pending changes until done. - for (;;) { - final int state; - final boolean stateChanged; - final int backlight; - final boolean backlightChanged; - synchronized (mLock) { - state = mPendingState; - stateChanged = (state != mActualState); - backlight = mPendingBacklight; - backlightChanged = (backlight != mActualBacklight); - if (!stateChanged && !backlightChanged) { - mChangeInProgress = false; - break; - } - mActualState = state; - mActualBacklight = backlight; - } - - if (DEBUG) { - Slog.d(TAG, "Updating screen state: state=" - + Display.stateToString(state) + ", backlight=" + backlight); - } - boolean suspending = Display.isSuspendedState(state); - if (stateChanged && !suspending) { - requestDisplayState(state); - } - if (backlightChanged) { - setBrightness(backlight); - } - if (stateChanged && suspending) { - requestDisplayState(state); + @Override + public void run() { + for (;;) { + // Get pending change. + final int state; + final boolean stateChanged; + final int backlight; + final boolean backlightChanged; + synchronized (mLock) { + state = mPendingState; + stateChanged = (state != mActualState); + backlight = mPendingBacklight; + backlightChanged = (backlight != mActualBacklight); + if (!stateChanged && !backlightChanged) { + // All changed applied, notify outer class and wait for more. + mChangeInProgress = false; + postScreenUpdateThreadSafe(); + try { + mLock.wait(); + } catch (InterruptedException ex) { } + continue; } + mActualState = state; + mActualBacklight = backlight; } - // Let the outer class know that all changes have been applied. - postScreenUpdateThreadSafe(); + // Apply pending change. + if (DEBUG) { + Slog.d(TAG, "Updating screen state: state=" + + Display.stateToString(state) + ", backlight=" + backlight); + } + boolean suspending = Display.isSuspendedState(state); + if (stateChanged && !suspending) { + requestDisplayState(state); + } + if (backlightChanged) { + setBrightness(backlight); + } + if (stateChanged && suspending) { + requestDisplayState(state); + } } + } - private void requestDisplayState(int state) { - Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState(" - + Display.stateToString(state) + ")"); - try { - mBlanker.requestDisplayState(state); - } finally { - Trace.traceEnd(Trace.TRACE_TAG_POWER); - } + private void requestDisplayState(int state) { + Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState(" + + Display.stateToString(state) + ")"); + try { + mBlanker.requestDisplayState(state); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_POWER); } + } - private void setBrightness(int backlight) { - Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")"); - try { - mBacklight.setBrightness(backlight); - } finally { - Trace.traceEnd(Trace.TRACE_TAG_POWER); - } + private void setBrightness(int backlight) { + Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")"); + try { + mBacklight.setBrightness(backlight); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_POWER); } - }; + } } } diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index 3b23b6a..f514531 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -248,6 +248,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { mInfo.width = mWidth; mInfo.height = mHeight; mInfo.refreshRate = mRefreshRate; + mInfo.supportedRefreshRates = new float[] { mRefreshRate }; mInfo.densityDpi = mDensityDpi; mInfo.xDpi = mDensityDpi; mInfo.yDpi = mDensityDpi; diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java index ad1e857..d71269f 100644 --- a/services/core/java/com/android/server/display/RampAnimator.java +++ b/services/core/java/com/android/server/display/RampAnimator.java @@ -50,20 +50,32 @@ final class RampAnimator<T> { /** * Starts animating towards the specified value. * - * If this is the first time the property is being set, the value jumps - * directly to the target. + * If this is the first time the property is being set or if the rate is 0, + * the value jumps directly to the target. * * @param target The target value. - * @param rate The convergence rate, in units per second. + * @param rate The convergence rate in units per second, or 0 to set the value immediately. * @return True if the target differs from the previous target. */ public boolean animateTo(int target, int rate) { // Immediately jump to the target the first time. - if (mFirstTime) { - mFirstTime = false; - mProperty.setValue(mObject, target); - mCurrentValue = target; - return true; + if (mFirstTime || rate <= 0) { + if (mFirstTime || target != mCurrentValue) { + mFirstTime = false; + mRate = 0; + mTargetValue = target; + mCurrentValue = target; + mProperty.setValue(mObject, target); + if (mAnimating) { + mAnimating = false; + cancelAnimationCallback(); + } + if (mListener != null) { + mListener.onAnimationEnd(); + } + return true; + } + return false; } // Adjust the rate based on the closest target. @@ -88,7 +100,7 @@ final class RampAnimator<T> { mAnimating = true; mAnimatedValue = mCurrentValue; mLastFrameTimeNanos = System.nanoTime(); - postCallback(); + postAnimationCallback(); } return changed; @@ -108,11 +120,15 @@ final class RampAnimator<T> { mListener = listener; } - private void postCallback() { - mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mCallback, null); + private void postAnimationCallback() { + mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null); + } + + private void cancelAnimationCallback() { + mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null); } - private final Runnable mCallback = new Runnable() { + private final Runnable mAnimationCallback = new Runnable() { @Override // Choreographer callback public void run() { final long frameTimeNanos = mChoreographer.getFrameTimeNanos(); @@ -144,7 +160,7 @@ final class RampAnimator<T> { } if (mTargetValue != mCurrentValue) { - postCallback(); + postAnimationCallback(); } else { mAnimating = false; if (mListener != null) { diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index c2b4478..0232bad 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -257,6 +257,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter { mInfo.width = mWidth; mInfo.height = mHeight; mInfo.refreshRate = 60; + mInfo.supportedRefreshRates = new float[] { 60.0f }; mInfo.densityDpi = mDensityDpi; mInfo.xDpi = mDensityDpi; mInfo.yDpi = mDensityDpi; diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java index a17d731..6b010d9 100644 --- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java @@ -625,6 +625,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { mInfo.width = mWidth; mInfo.height = mHeight; mInfo.refreshRate = mRefreshRate; + mInfo.supportedRefreshRates = new float[] { mRefreshRate }; mInfo.presentationDeadlineNanos = 1000000000L / (int) mRefreshRate; // 1 frame mInfo.flags = mFlags; mInfo.type = Display.TYPE_WIFI; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java b/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java index 3bb89af..2eca42b 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java @@ -252,7 +252,7 @@ final class HdmiCecKeycode { new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_LEFT_DOWN), new KeycodeEntry(KeyEvent.KEYCODE_HOME, CEC_KEYCODE_ROOT_MENU), new KeycodeEntry(KeyEvent.KEYCODE_SETTINGS, CEC_KEYCODE_SETUP_MENU), - new KeycodeEntry(KeyEvent.KEYCODE_TV_CONTENTS_MENU, CEC_KEYCODE_CONTENTS_MENU), + new KeycodeEntry(KeyEvent.KEYCODE_TV_CONTENTS_MENU, CEC_KEYCODE_CONTENTS_MENU, false), // No Android keycode defined for CEC_KEYCODE_FAVORITE_MENU new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_FAVORITE_MENU), // Note that both BACK and ESCAPE are mapped to EXIT of CEC keycode. @@ -287,8 +287,8 @@ final class HdmiCecKeycode { // RESERVED // No Android keycode defined for CEC_KEYCODE_NEXT_FAVORITE new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_NEXT_FAVORITE), - new KeycodeEntry(KeyEvent.KEYCODE_CHANNEL_UP, CEC_KEYCODE_CHANNEL_UP, false), - new KeycodeEntry(KeyEvent.KEYCODE_CHANNEL_DOWN, CEC_KEYCODE_CHANNEL_DOWN, false), + new KeycodeEntry(KeyEvent.KEYCODE_CHANNEL_UP, CEC_KEYCODE_CHANNEL_UP), + new KeycodeEntry(KeyEvent.KEYCODE_CHANNEL_DOWN, CEC_KEYCODE_CHANNEL_DOWN), new KeycodeEntry(KeyEvent.KEYCODE_LAST_CHANNEL, CEC_KEYCODE_PREVIOUS_CHANNEL), // No Android keycode defined for CEC_KEYCODE_SOUND_SELECT new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SOUND_SELECT), @@ -355,31 +355,31 @@ final class HdmiCecKeycode { // The following deterministic key definitions do not need key mapping // since they are supposed to be generated programmatically only. // No Android keycode defined for CEC_KEYCODE_PLAY_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PLAY_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PLAY_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_PAUSE_PLAY_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_PLAY_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_PLAY_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_RECORD_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RECORD_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RECORD_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_PAUSE_RECORD_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_RECORD_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_PAUSE_RECORD_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_STOP_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_STOP_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_STOP_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_MUTE_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_MUTE_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_RESTORE_VOLUME_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_RESTORE_VOLUME_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_TUNE_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_TUNE_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_TUNE_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_SELECT_MEDIA_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_MEDIA_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_MEDIA_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_SELECT_AV_INPUT_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_AV_INPUT_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_AV_INPUT_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_SELECT_AUDIO_INPUT_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_AUDIO_INPUT_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_SELECT_AUDIO_INPUT_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_POWER_TOGGLE_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_TOGGLE_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_TOGGLE_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_POWER_OFF_FUNCTION - new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_OFF_FUNCTION), + new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_OFF_FUNCTION, false), // No Android keycode defined for CEC_KEYCODE_POWER_ON_FUNCTION new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_POWER_ON_FUNCTION, false), // RESERVED diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 5097927..a0ec1d5 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.content.pm.ParceledListSlice; import android.media.AudioManager; import android.media.AudioManagerInternal; +import android.media.AudioSystem; import android.media.MediaDescription; import android.media.MediaMetadata; import android.media.Rating; @@ -237,6 +238,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { */ public void adjustVolume(int direction, int flags, String packageName, int uid, boolean useSuggested) { + int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND; if (isPlaybackActive(false) || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) { flags &= ~AudioManager.FLAG_PLAY_SOUND; } @@ -248,8 +250,15 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) { int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); if (useSuggested) { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction, flags, - packageName, uid); + if (AudioSystem.isStreamActive(stream, 0)) { + mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction, + flags, packageName, uid); + } else { + flags |= previousFlagPlaySound; + mAudioManagerInternal.adjustSuggestedStreamVolumeForUid( + AudioManager.USE_DEFAULT_STREAM_TYPE, direction, flags, packageName, + uid); + } } else { mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, packageName, uid); @@ -615,7 +624,10 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } private PlaybackState getStateWithUpdatedPosition() { - PlaybackState state = mPlaybackState; + PlaybackState state; + synchronized (mLock) { + state = mPlaybackState; + } long duration = -1; if (mMetadata != null && mMetadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { duration = mMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION); @@ -674,7 +686,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void sendEvent(String event, Bundle data) { - mHandler.post(MessageHandler.MSG_SEND_EVENT, event, data); + mHandler.post(MessageHandler.MSG_SEND_EVENT, event, + data == null ? null : new Bundle(data)); } @Override @@ -712,7 +725,11 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void setMetadata(MediaMetadata metadata) { - mMetadata = metadata; + // Make a copy of the metadata as the underlying bundle may be + // modified on this thread. + synchronized (mLock) { + mMetadata = metadata == null ? null : new MediaMetadata.Builder(metadata).build(); + } mHandler.post(MessageHandler.MSG_UPDATE_METADATA); } @@ -723,14 +740,18 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { if (MediaSession.isActiveState(oldState) && newState == PlaybackState.STATE_PAUSED) { mLastActiveTime = SystemClock.elapsedRealtime(); } - mPlaybackState = state; + synchronized (mLock) { + mPlaybackState = state; + } mService.onSessionPlaystateChange(MediaSessionRecord.this, oldState, newState); mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE); } @Override public void setQueue(ParceledListSlice queue) { - mQueue = queue; + synchronized (mLock) { + mQueue = queue; + } mHandler.post(MessageHandler.MSG_UPDATE_QUEUE); } @@ -742,7 +763,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void setExtras(Bundle extras) { - mExtras = extras; + synchronized (mLock) { + mExtras = extras == null ? null : new Bundle(extras); + } mHandler.post(MessageHandler.MSG_UPDATE_EXTRAS); } @@ -1118,7 +1141,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public MediaMetadata getMetadata() { - return mMetadata; + synchronized (mLock) { + return mMetadata; + } } @Override @@ -1128,7 +1153,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public ParceledListSlice getQueue() { - return mQueue; + synchronized (mLock) { + return mQueue; + } } @Override @@ -1138,7 +1165,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public Bundle getExtras() { - return mExtras; + synchronized (mLock) { + return mExtras; + } } @Override diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 557a44e..e6007bf 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -150,48 +150,50 @@ public class ZenModeHelper { } public boolean shouldIntercept(NotificationRecord record) { - if (mZenMode != Global.ZEN_MODE_OFF) { - if (isSystem(record)) { - return false; - } - if (isAlarm(record)) { - if (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) { - ZenLog.traceIntercepted(record, "alarm"); - return true; + if (isSystem(record)) { + return false; + } + switch (mZenMode) { + case Global.ZEN_MODE_NO_INTERRUPTIONS: + // #notevenalarms + ZenLog.traceIntercepted(record, "none"); + return true; + case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: + if (isAlarm(record)) { + // Alarms are always priority + return false; } - return false; - } - // allow user-prioritized packages through in priority mode - if (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { + // allow user-prioritized packages through in priority mode if (record.getPackagePriority() == Notification.PRIORITY_MAX) { ZenLog.traceNotIntercepted(record, "priorityApp"); return false; } - } - if (isCall(record)) { - if (!mConfig.allowCalls) { - ZenLog.traceIntercepted(record, "!allowCalls"); - return true; + if (isCall(record)) { + if (!mConfig.allowCalls) { + ZenLog.traceIntercepted(record, "!allowCalls"); + return true; + } + return shouldInterceptAudience(record); } - return shouldInterceptAudience(record); - } - if (isMessage(record)) { - if (!mConfig.allowMessages) { - ZenLog.traceIntercepted(record, "!allowMessages"); - return true; + if (isMessage(record)) { + if (!mConfig.allowMessages) { + ZenLog.traceIntercepted(record, "!allowMessages"); + return true; + } + return shouldInterceptAudience(record); } - return shouldInterceptAudience(record); - } - if (isEvent(record)) { - if (!mConfig.allowEvents) { - ZenLog.traceIntercepted(record, "!allowEvents"); - return true; + if (isEvent(record)) { + if (!mConfig.allowEvents) { + ZenLog.traceIntercepted(record, "!allowEvents"); + return true; + } + return false; } - } - ZenLog.traceIntercepted(record, "!allowed"); - return true; + ZenLog.traceIntercepted(record, "!priority"); + return true; + default: + return false; } - return false; } private boolean shouldInterceptAudience(NotificationRecord record) { diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index dcc4f8d..d787919 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -254,7 +254,7 @@ public class LauncherAppsService extends SystemService { try { IPackageManager pm = AppGlobals.getPackageManager(); ActivityInfo info = pm.getActivityInfo(component, 0, user.getIdentifier()); - return info != null && info.isEnabled(); + return info != null; } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index c106546..d5858a5 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -325,9 +325,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } catch (FileNotFoundException e) { // Missing sessions are okay, probably first boot } catch (IOException e) { - Log.wtf(TAG, "Failed reading install sessions", e); + Slog.wtf(TAG, "Failed reading install sessions", e); } catch (XmlPullParserException e) { - Log.wtf(TAG, "Failed reading install sessions", e); + Slog.wtf(TAG, "Failed reading install sessions", e); } finally { IoUtils.closeQuietly(fis); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 2718439..851cf17 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4729,6 +4729,18 @@ public class PackageManagerService extends IPackageManager.Stub { return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]); } + /** + * Returns deduplicated list of supported instructions for dex code. + */ + public static String[] getAllDexCodeInstructionSets() { + String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length]; + for (int i = 0; i < supportedInstructionSets.length; i++) { + String abi = Build.SUPPORTED_ABIS[i]; + supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi); + } + return getDexCodeInstructionSets(supportedInstructionSets); + } + @Override public void forceDexOpt(String packageName) { enforceSystemOrRoot("forceDexOpt"); diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 4e33ca8..9473495 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1178,12 +1178,14 @@ final class Settings { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading stopped packages: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", + e); } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", + e); } } @@ -1272,7 +1274,8 @@ final class Settings { // might have been corrupted. if (!backupFile.exists()) { if (!userPackagesStateFile.renameTo(backupFile)) { - Log.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, " + Slog.wtf(PackageManagerService.TAG, + "Unable to backup user packages state file, " + "current changes will be lost at reboot"); return; } @@ -1379,7 +1382,7 @@ final class Settings { // Done, all is good! return; } catch(java.io.IOException e) { - Log.wtf(PackageManagerService.TAG, + Slog.wtf(PackageManagerService.TAG, "Unable to write package manager user packages state, " + " current changes will be lost at reboot", e); } @@ -1485,12 +1488,14 @@ final class Settings { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading stopped packages: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", + e); } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", + e); } } @@ -1507,7 +1512,8 @@ final class Settings { // might have been corrupted. if (!mBackupSettingsFilename.exists()) { if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) { - Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, " + Slog.wtf(PackageManagerService.TAG, + "Unable to backup package manager settings, " + " current changes will be lost at reboot"); return; } @@ -1698,7 +1704,7 @@ final class Settings { str.close(); journal.commit(); } catch (Exception e) { - Log.wtf(TAG, "Failed to write packages.list", e); + Slog.wtf(TAG, "Failed to write packages.list", e); IoUtils.closeQuietly(str); journal.rollback(); } @@ -1707,16 +1713,16 @@ final class Settings { return; } catch(XmlPullParserException e) { - Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " + Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " + "current changes will be lost at reboot", e); } catch(java.io.IOException e) { - Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " + Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " + "current changes will be lost at reboot", e); } // Clean up partially written files if (mSettingsFilename.exists()) { if (!mSettingsFilename.delete()) { - Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + mSettingsFilename); } } @@ -1984,7 +1990,7 @@ final class Settings { mReadMessages.append("No start tag found in settings file\n"); PackageManagerService.reportSettingsProblem(Log.WARN, "No start tag found in package manager settings"); - Log.wtf(PackageManagerService.TAG, + Slog.wtf(PackageManagerService.TAG, "No start tag found in package manager settings"); return false; } @@ -2097,12 +2103,12 @@ final class Settings { } catch (XmlPullParserException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); } final int N = mPendingPackages.size(); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 4f41bee..52807c0 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -142,10 +142,12 @@ public final class PowerManagerService extends SystemService // Summarizes the user activity state. private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0; private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1; + private static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2; // Default timeout in milliseconds. This is only used until the settings // provider populates the actual default value (R.integer.def_screen_off_timeout). private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000; + private static final int DEFAULT_SLEEP_TIMEOUT = -1; // Power hints defined in hardware/libhardware/include/hardware/power.h. private static final int POWER_HINT_INTERACTION = 2; @@ -214,7 +216,6 @@ public final class PowerManagerService extends SystemService private long mLastInteractivePowerHintTime; // A bitfield that summarizes the effect of the user activity timer. - // A zero value indicates that the user activity timer has expired. private int mUserActivitySummary; // The desired display power state. The actual state may lag behind the @@ -340,6 +341,9 @@ public final class PowerManagerService extends SystemService // The screen off timeout setting value in milliseconds. private int mScreenOffTimeoutSetting; + // The sleep timeout setting value in milliseconds. + private int mSleepTimeoutSetting; + // The maximum allowable screen off timeout according to the device // administration policy. Overrides other settings. private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE; @@ -543,6 +547,9 @@ public final class PowerManagerService extends SystemService resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_OFF_TIMEOUT), false, mSettingsObserver, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.Secure.getUriFor( + Settings.Secure.SLEEP_TIMEOUT), + false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.STAY_ON_WHILE_PLUGGED_IN), false, mSettingsObserver, UserHandle.USER_ALL); @@ -624,6 +631,9 @@ public final class PowerManagerService extends SystemService mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT, UserHandle.USER_CURRENT); + mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver, + Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT, + UserHandle.USER_CURRENT); mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC); @@ -1431,7 +1441,8 @@ public final class PowerManagerService extends SystemService if (mWakefulness == WAKEFULNESS_AWAKE || mWakefulness == WAKEFULNESS_DREAMING || mWakefulness == WAKEFULNESS_DOZING) { - final int screenOffTimeout = getScreenOffTimeoutLocked(); + final int sleepTimeout = getSleepTimeoutLocked(); + final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout); final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout); mUserActivitySummary = 0; @@ -1439,11 +1450,11 @@ public final class PowerManagerService extends SystemService nextTimeout = mLastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < nextTimeout) { - mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT; + mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; } else { nextTimeout = mLastUserActivityTime + screenOffTimeout; if (now < nextTimeout) { - mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM; + mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM; } } } @@ -1458,7 +1469,22 @@ public final class PowerManagerService extends SystemService } } } - if (mUserActivitySummary != 0) { + if (mUserActivitySummary == 0) { + if (sleepTimeout >= 0) { + final long anyUserActivity = Math.max(mLastUserActivityTime, + mLastUserActivityTimeNoChangeLights); + if (anyUserActivity >= mLastWakeTime) { + nextTimeout = anyUserActivity + sleepTimeout; + if (now < nextTimeout) { + mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM; + } + } + } else { + mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM; + nextTimeout = -1; + } + } + if (mUserActivitySummary != 0 && nextTimeout >= 0) { Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, nextTimeout); @@ -1495,7 +1521,15 @@ public final class PowerManagerService extends SystemService } } - private int getScreenOffTimeoutLocked() { + private int getSleepTimeoutLocked() { + int timeout = mSleepTimeoutSetting; + if (timeout <= 0) { + return -1; + } + return Math.max(timeout, mMinimumScreenOffTimeoutConfig); + } + + private int getScreenOffTimeoutLocked(int sleepTimeout) { int timeout = mScreenOffTimeoutSetting; if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) { timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin); @@ -1503,6 +1537,9 @@ public final class PowerManagerService extends SystemService if (mUserActivityTimeoutOverrideFromWindowManager >= 0) { timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager); } + if (sleepTimeout >= 0) { + timeout = Math.min(timeout, sleepTimeout); + } return Math.max(timeout, mMinimumScreenOffTimeoutConfig); } @@ -1619,8 +1656,7 @@ public final class PowerManagerService extends SystemService mSandmanScheduled = false; wakefulness = mWakefulness; if (mSandmanSummoned && mDisplayReady) { - startDreaming = ((wakefulness == WAKEFULNESS_DREAMING && canDreamLocked()) - || wakefulness == WAKEFULNESS_DOZING); + startDreaming = canDreamLocked() || canDozeLocked(); mSandmanSummoned = false; } else { startDreaming = false; @@ -1708,13 +1744,14 @@ public final class PowerManagerService extends SystemService /** * Returns true if the device is allowed to dream in its current state. - * This function is not called when dozing. */ private boolean canDreamLocked() { if (mWakefulness != WAKEFULNESS_DREAMING || !mDreamsSupportedConfig || !mDreamsEnabledSetting || !mDisplayPowerRequest.isBrightOrDim() + || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT + | USER_ACTIVITY_SCREEN_DIM | USER_ACTIVITY_SCREEN_DREAM)) == 0 || !mBootCompleted) { return false; } @@ -1737,6 +1774,13 @@ public final class PowerManagerService extends SystemService } /** + * Returns true if the device is allowed to doze in its current state. + */ + private boolean canDozeLocked() { + return mWakefulness == WAKEFULNESS_DOZING; + } + + /** * Updates the display power state asynchronously. * When the update is finished, mDisplayReady will be set to true. The display * controller posts a message to tell us when the actual display power state @@ -2126,7 +2170,7 @@ public final class PowerManagerService extends SystemService t.start(); t.join(); } catch (InterruptedException e) { - Log.wtf(TAG, e); + Slog.wtf(TAG, e); } } @@ -2343,6 +2387,7 @@ public final class PowerManagerService extends SystemService pw.println(" mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig); pw.println(" mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig); pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting); + pw.println(" mSleepTimeoutSetting=" + mSleepTimeoutSetting); pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin=" + mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced=" + isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")"); @@ -2367,9 +2412,11 @@ public final class PowerManagerService extends SystemService pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum); pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault); - final int screenOffTimeout = getScreenOffTimeoutLocked(); + final int sleepTimeout = getSleepTimeoutLocked(); + final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout); final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout); pw.println(); + pw.println("Sleep timeout: " + sleepTimeout + " ms"); pw.println("Screen off timeout: " + screenOffTimeout + " ms"); pw.println("Screen dim duration: " + screenDimDuration + " ms"); diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java index 468a344..111c09b 100644 --- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java +++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java @@ -18,6 +18,7 @@ package com.android.server.storage; import com.android.server.EventLogTags; import com.android.server.SystemService; +import com.android.server.pm.PackageManagerService; import android.app.Notification; import android.app.NotificationManager; @@ -51,6 +52,8 @@ import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; +import dalvik.system.VMRuntime; + /** * This class implements a service to monitor the amount of disk * storage space on the device. If the free storage on device is less @@ -89,6 +92,7 @@ public class DeviceStorageMonitorService extends SystemService { private long mLastReportedFreeMemTime; boolean mLowMemFlag=false; private boolean mMemFullFlag=false; + private final boolean mIsBootImageOnDisk; private final ContentResolver mResolver; private final long mTotalMemory; // on /data private final StatFs mDataFileStats; @@ -285,6 +289,10 @@ public class DeviceStorageMonitorService extends SystemService { mLowMemFlag = false; } } + if (!mLowMemFlag && !mIsBootImageOnDisk) { + Slog.i(TAG, "No boot image on disk due to lack of space. Sending notification"); + sendNotification(); + } if (mFreeMem < mMemFullThreshold) { if (!mMemFullFlag) { sendFullNotification(); @@ -314,6 +322,7 @@ public class DeviceStorageMonitorService extends SystemService { super(context); mLastReportedFreeMemTime = 0; mResolver = context.getContentResolver(); + mIsBootImageOnDisk = isBootImageOnDisk(); //create StatFs object mDataFileStats = new StatFs(DATA_PATH.getAbsolutePath()); mSystemFileStats = new StatFs(SYSTEM_PATH.getAbsolutePath()); @@ -331,6 +340,15 @@ public class DeviceStorageMonitorService extends SystemService { mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); } + private static boolean isBootImageOnDisk() { + for (String instructionSet : PackageManagerService.getAllDexCodeInstructionSets()) { + if (!VMRuntime.isBootClassPathOnDisk(instructionSet)) { + return false; + } + } + return true; + } + /** * Initializes the disk space threshold value and posts an empty message to * kickstart the process. @@ -364,7 +382,7 @@ public class DeviceStorageMonitorService extends SystemService { @Override public boolean isMemoryLow() { - return mLowMemFlag; + return mLowMemFlag || !mIsBootImageOnDisk; } @Override @@ -409,6 +427,7 @@ public class DeviceStorageMonitorService extends SystemService { pw.print(" mLowMemFlag="); pw.print(mLowMemFlag); pw.print(" mMemFullFlag="); pw.println(mMemFullFlag); + pw.print(" mIsBootImageOnDisk="); pw.print(mIsBootImageOnDisk); pw.print(" mClearSucceeded="); pw.print(mClearSucceeded); pw.print(" mClearingCache="); pw.println(mClearingCache); @@ -445,19 +464,25 @@ public class DeviceStorageMonitorService extends SystemService { Context.NOTIFICATION_SERVICE); CharSequence title = context.getText( com.android.internal.R.string.low_internal_storage_view_title); - CharSequence details = context.getText( - com.android.internal.R.string.low_internal_storage_view_text); + CharSequence details = context.getText(mIsBootImageOnDisk + ? com.android.internal.R.string.low_internal_storage_view_text + : com.android.internal.R.string.low_internal_storage_view_text_no_boot); PendingIntent intent = PendingIntent.getActivityAsUser(context, 0, lowMemIntent, 0, null, UserHandle.CURRENT); - Notification notification = new Notification(); - notification.icon = com.android.internal.R.drawable.stat_notify_disk_full; - notification.tickerText = title; + Notification notification = new Notification.Builder(context) + .setSmallIcon(com.android.internal.R.drawable.stat_notify_disk_full) + .setTicker(title) + .setColor(context.getResources().getColor( + com.android.internal.R.color.system_notification_accent_color)) + .setContentTitle(title) + .setContentText(details) + .setContentIntent(intent) + .setStyle(new Notification.BigTextStyle() + .bigText(details)) + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setCategory(Notification.CATEGORY_SYSTEM) + .build(); notification.flags |= Notification.FLAG_NO_CLEAR; - notification.color = context.getResources().getColor( - com.android.internal.R.color.system_notification_accent_color); - notification.setLatestEventInfo(context, title, details, intent); - notification.visibility = Notification.VISIBILITY_PUBLIC; - notification.category = Notification.CATEGORY_SYSTEM; mNotificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification, UserHandle.ALL); context.sendStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL); diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index da5cfda..69d3191 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -632,7 +632,7 @@ public class WindowAnimator { mService.mWatermark.drawIfNeeded(); } } catch (RuntimeException e) { - Log.wtf(TAG, "Unhandled exception in Window Manager", e); + Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 999649b..467b9a4 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2712,9 +2712,10 @@ public class WindowManagerService extends IWindowManager.Stub if (atoken != null) { if (atoken.startingWindow == win) { - if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win); - atoken.startingWindow = null; - } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) { + if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Notify removed startingWindow " + win); + scheduleRemoveStartingWindowLocked(atoken); + } else + if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) { // If this is the last window and we had requested a starting // transition window, well there is no point now. if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow"); @@ -2722,7 +2723,7 @@ public class WindowManagerService extends IWindowManager.Stub } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) { // If this is the last window except for a starting transition // window, we need to get rid of the starting transition. - scheduleRemoveStartingWindow(atoken); + scheduleRemoveStartingWindowLocked(atoken); } } @@ -4329,7 +4330,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { AppWindowToken wtoken = mTokenMap.get(token).appWindowToken; if (wtoken.startingWindow != null) { - scheduleRemoveStartingWindow(wtoken); + scheduleRemoveStartingWindowLocked(wtoken); } } } @@ -4791,14 +4792,19 @@ public class WindowManagerService extends IWindowManager.Stub if (!delayed && wtoken != null) { wtoken.updateReportedVisibilityLocked(); } + + // Will only remove if startingToken non null. + scheduleRemoveStartingWindowLocked(startingToken); } Binder.restoreCallingIdentity(origId); - // Will only remove if startingToken non null. - scheduleRemoveStartingWindow(startingToken); } - void scheduleRemoveStartingWindow(AppWindowToken wtoken) { + void scheduleRemoveStartingWindowLocked(AppWindowToken wtoken) { + if (mH.hasMessages(H.REMOVE_STARTING, wtoken)) { + // Already scheduled. + return; + } if (wtoken != null && wtoken.startingWindow != null) { if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) + ": Schedule remove starting " + wtoken + (wtoken != null ? @@ -8646,7 +8652,7 @@ public class WindowManagerService extends IWindowManager.Stub } } } catch (RuntimeException e) { - Log.wtf(TAG, "Unhandled exception while force removing for memory", e); + Slog.wtf(TAG, "Unhandled exception while force removing for memory", e); } try { @@ -8671,7 +8677,7 @@ public class WindowManagerService extends IWindowManager.Stub } } catch (RuntimeException e) { mInLayout = false; - Log.wtf(TAG, "Unhandled exception while laying out windows", e); + Slog.wtf(TAG, "Unhandled exception while laying out windows", e); } Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); @@ -9093,6 +9099,11 @@ public class WindowManagerService extends IWindowManager.Stub // gotten drawn. wtoken.allDrawn = true; wtoken.deferClearAllDrawn = false; + // Ensure that apps that are mid-starting are also scheduled to have their + // starting windows removed after the animation is complete + if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) { + scheduleRemoveStartingWindowLocked(wtoken); + } if (animLp != null) { int layer = -1; @@ -9751,7 +9762,7 @@ public class WindowManagerService extends IWindowManager.Stub mDisplayManagerInternal.performTraversalInTransactionFromWindowManager(); } catch (RuntimeException e) { - Log.wtf(TAG, "Unhandled exception in Window Manager", e); + Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, @@ -10236,7 +10247,7 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.mSurfaceShown = false; winAnimator.mSurfaceControl = null; winAnimator.mWin.mHasSurface = false; - scheduleRemoveStartingWindow(winAnimator.mWin.mAppToken); + scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken); } try { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 5b007d4..0c727f3 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -515,6 +515,7 @@ class WindowStateAnimator { static class SurfaceTrace extends SurfaceControl { private final static String SURFACE_TAG = "SurfaceTrace"; + private final static boolean logSurfaceTrace = DEBUG_SURFACE_TRACE; final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>(); private float mSurfaceTraceAlpha = 0; @@ -534,7 +535,7 @@ class WindowStateAnimator { super(s, name, w, h, format, flags); mName = name != null ? name : "Not named"; mSize.set(w, h); - Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by " + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by " + Debug.getCallers(3)); synchronized (sSurfaces) { sSurfaces.add(0, this); @@ -544,8 +545,8 @@ class WindowStateAnimator { @Override public void setAlpha(float alpha) { if (mSurfaceTraceAlpha != alpha) { - Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this + ". Called by " - + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this + + ". Called by " + Debug.getCallers(3)); mSurfaceTraceAlpha = alpha; } super.setAlpha(alpha); @@ -554,8 +555,8 @@ class WindowStateAnimator { @Override public void setLayer(int zorder) { if (zorder != mLayer) { - Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this + ". Called by " - + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this + + ". Called by " + Debug.getCallers(3)); mLayer = zorder; } super.setLayer(zorder); @@ -576,8 +577,8 @@ class WindowStateAnimator { @Override public void setPosition(float x, float y) { if (x != mPosition.x || y != mPosition.y) { - Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:" + this - + ". Called by " + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:" + + this + ". Called by " + Debug.getCallers(3)); mPosition.set(x, y); } super.setPosition(x, y); @@ -586,8 +587,8 @@ class WindowStateAnimator { @Override public void setSize(int w, int h) { if (w != mSize.x || h != mSize.y) { - Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:" + this + ". Called by " - + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:" + + this + ". Called by " + Debug.getCallers(3)); mSize.set(w, h); } super.setSize(w, h); @@ -597,8 +598,9 @@ class WindowStateAnimator { public void setWindowCrop(Rect crop) { if (crop != null) { if (!crop.equals(mWindowCrop)) { - Slog.v(SURFACE_TAG, "setWindowCrop(" + crop.toShortString() + "): OLD:" + this - + ". Called by " + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setWindowCrop(" + + crop.toShortString() + "): OLD:" + this + ". Called by " + + Debug.getCallers(3)); mWindowCrop.set(crop); } } @@ -608,8 +610,8 @@ class WindowStateAnimator { @Override public void setLayerStack(int layerStack) { if (layerStack != mLayerStack) { - Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:" + this - + ". Called by " + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:" + + this + ". Called by " + Debug.getCallers(3)); mLayerStack = layerStack; } super.setLayerStack(layerStack); @@ -618,8 +620,8 @@ class WindowStateAnimator { @Override public void setOpaque(boolean isOpaque) { if (isOpaque != mIsOpaque) { - Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:" + this - + ". Called by " + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:" + + this + ". Called by " + Debug.getCallers(3)); mIsOpaque = isOpaque; } super.setOpaque(isOpaque); @@ -628,8 +630,9 @@ class WindowStateAnimator { @Override public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) { - Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + - "): OLD:" + this + ". Called by " + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + "," + + dsdy + "," + dtdy + "): OLD:" + this + ". Called by " + + Debug.getCallers(3)); mDsdx = dsdx; mDtdx = dtdx; mDsdy = dsdy; @@ -641,7 +644,8 @@ class WindowStateAnimator { @Override public void hide() { if (mShown) { - Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " + + Debug.getCallers(3)); mShown = false; } super.hide(); @@ -650,7 +654,8 @@ class WindowStateAnimator { @Override public void show() { if (!mShown) { - Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by " + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by " + + Debug.getCallers(3)); mShown = true; } super.show(); @@ -659,7 +664,8 @@ class WindowStateAnimator { @Override public void destroy() { super.destroy(); - Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " + Debug.getCallers(3)); + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " + + Debug.getCallers(3)); synchronized (sSurfaces) { sSurfaces.remove(this); } @@ -668,7 +674,7 @@ class WindowStateAnimator { @Override public void release() { super.release(); - Slog.v(SURFACE_TAG, "release: " + this + ". Called by " + if (logSurfaceTrace) Slog.v(SURFACE_TAG, "release: " + this + ". Called by " + Debug.getCallers(3)); synchronized (sSurfaces) { sSurfaces.remove(this); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index f339dba..92ad1ad 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -272,7 +272,7 @@ public final class SystemServer { private void reportWtf(String msg, Throwable e) { Slog.w(TAG, "***********************************************"); - Log.wtf(TAG, "BOOT FAILURE " + msg, e); + Slog.wtf(TAG, "BOOT FAILURE " + msg, e); } private void performPendingShutdown() { diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java index 972c929..cfa4436 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java +++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java @@ -382,6 +382,10 @@ class UsageStatsDatabase { File[] files = dir.listFiles(); if (files != null) { for (File f : files) { + String path = f.getPath(); + if (path.endsWith(".bak")) { + f = new File(path.substring(0, path.length() - 4)); + } long beginTime = Long.parseLong(f.getName()); if (beginTime < expiryTime) { new AtomicFile(f).delete(); |