frameworks/base
Revision | 970b19105d2c34fb8b92e5baf5decfd5c5bda7a6 (tree) |
---|---|
Time | 2020-05-06 11:35:57 |
Author | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge tag 'android-9.0.0_r56' into pie-x86
Android 9.0.0 release 56
@@ -1050,8 +1050,11 @@ public final class AssetManager implements AutoCloseable { | ||
1050 | 1050 | } |
1051 | 1051 | } |
1052 | 1052 | |
1053 | - if (mObject != 0) { | |
1054 | - nativeDestroy(mObject); | |
1053 | + synchronized (this) { | |
1054 | + if (mObject != 0) { | |
1055 | + nativeDestroy(mObject); | |
1056 | + mObject = 0; | |
1057 | + } | |
1055 | 1058 | } |
1056 | 1059 | } |
1057 | 1060 |
@@ -3116,6 +3116,11 @@ | ||
3116 | 3116 | <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" |
3117 | 3117 | android:protectionLevel="signature|privileged" /> |
3118 | 3118 | |
3119 | + <!-- Allows an application to manage the companion devices. | |
3120 | + @hide --> | |
3121 | + <permission android:name="android.permission.MANAGE_COMPANION_DEVICES" | |
3122 | + android:protectionLevel="signature" /> | |
3123 | + | |
3119 | 3124 | <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features. |
3120 | 3125 | <p>Not for use by third-party applications. |
3121 | 3126 | @hide |
@@ -691,6 +691,17 @@ public class KeyStore { | ||
691 | 691 | return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword); |
692 | 692 | } |
693 | 693 | |
694 | + /** | |
695 | + * Notify keystore about the latest user locked state. This is to support keyguard-bound key. | |
696 | + */ | |
697 | + public void onUserLockedStateChanged(int userHandle, boolean locked) { | |
698 | + try { | |
699 | + mBinder.onKeyguardVisibilityChanged(locked, userHandle); | |
700 | + } catch (RemoteException e) { | |
701 | + Log.w(TAG, "Failed to update user locked state " + userHandle, e); | |
702 | + } | |
703 | + } | |
704 | + | |
694 | 705 | public int attestKey( |
695 | 706 | String alias, KeymasterArguments params, KeymasterCertificateChain outChain) { |
696 | 707 | try { |
@@ -629,6 +629,11 @@ public class CompanionDeviceManagerService extends SystemService implements Bind | ||
629 | 629 | + "associate USER_ID PACKAGE MAC_ADDRESS\n" |
630 | 630 | + "disassociate USER_ID PACKAGE MAC_ADDRESS"; |
631 | 631 | |
632 | + ShellCmd() { | |
633 | + getContext().enforceCallingOrSelfPermission( | |
634 | + android.Manifest.permission.MANAGE_COMPANION_DEVICES, "ShellCmd"); | |
635 | + } | |
636 | + | |
632 | 637 | @Override |
633 | 638 | public int onCommand(String cmd) { |
634 | 639 | switch (cmd) { |
@@ -7582,7 +7582,7 @@ public class ActivityManagerService extends IActivityManager.Stub | ||
7582 | 7582 | } |
7583 | 7583 | |
7584 | 7584 | @GuardedBy("this") |
7585 | - private final boolean attachApplicationLocked(IApplicationThread thread, | |
7585 | + private boolean attachApplicationLocked(@NonNull IApplicationThread thread, | |
7586 | 7586 | int pid, int callingUid, long startSeq) { |
7587 | 7587 | |
7588 | 7588 | // Find the application record that is being attached... either via |
@@ -7963,6 +7963,9 @@ public class ActivityManagerService extends IActivityManager.Stub | ||
7963 | 7963 | |
7964 | 7964 | @Override |
7965 | 7965 | public final void attachApplication(IApplicationThread thread, long startSeq) { |
7966 | + if (thread == null) { | |
7967 | + throw new SecurityException("Invalid application interface"); | |
7968 | + } | |
7966 | 7969 | synchronized (this) { |
7967 | 7970 | int callingPid = Binder.getCallingPid(); |
7968 | 7971 | final int callingUid = Binder.getCallingUid(); |
@@ -3934,6 +3934,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai | ||
3934 | 3934 | |
3935 | 3935 | final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, |
3936 | 3936 | Intent resultData) { |
3937 | + if (srec.app == null || srec.app.thread == null) { | |
3938 | + // Nothing to do if the caller is not attached, because this method should be called | |
3939 | + // from an alive activity. | |
3940 | + return false; | |
3941 | + } | |
3937 | 3942 | final TaskRecord task = srec.getTask(); |
3938 | 3943 | final ArrayList<ActivityRecord> activities = task.mActivities; |
3939 | 3944 | final int start = activities.indexOf(srec); |
@@ -3985,14 +3990,14 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai | ||
3985 | 3990 | } |
3986 | 3991 | |
3987 | 3992 | if (parent != null && foundParentInTask) { |
3993 | + final int callingUid = srec.info.applicationInfo.uid; | |
3988 | 3994 | final int parentLaunchMode = parent.info.launchMode; |
3989 | 3995 | final int destIntentFlags = destIntent.getFlags(); |
3990 | 3996 | if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || |
3991 | 3997 | parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || |
3992 | 3998 | parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || |
3993 | 3999 | (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { |
3994 | - parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent, | |
3995 | - srec.packageName); | |
4000 | + parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName); | |
3996 | 4001 | } else { |
3997 | 4002 | try { |
3998 | 4003 | ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( |
@@ -4005,10 +4010,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai | ||
4005 | 4010 | .setActivityInfo(aInfo) |
4006 | 4011 | .setResultTo(parent.appToken) |
4007 | 4012 | .setCallingPid(-1) |
4008 | - .setCallingUid(parent.launchedFromUid) | |
4009 | - .setCallingPackage(parent.launchedFromPackage) | |
4013 | + .setCallingUid(callingUid) | |
4014 | + .setCallingPackage(srec.packageName) | |
4010 | 4015 | .setRealCallingPid(-1) |
4011 | - .setRealCallingUid(parent.launchedFromUid) | |
4016 | + .setRealCallingUid(callingUid) | |
4012 | 4017 | .setComponentSpecified(true) |
4013 | 4018 | .execute(); |
4014 | 4019 | foundParentInTask = res == ActivityManager.START_SUCCESS; |
@@ -328,6 +328,9 @@ public class ActivityStartController { | ||
328 | 328 | } else { |
329 | 329 | callingPid = callingUid = -1; |
330 | 330 | } |
331 | + boolean forceNewTask = false; | |
332 | + final int filterCallingUid = ActivityStarter.computeResolveFilterUid( | |
333 | + callingUid, realCallingUid, UserHandle.USER_NULL); | |
331 | 334 | final long origId = Binder.clearCallingIdentity(); |
332 | 335 | try { |
333 | 336 | synchronized (mService) { |
@@ -347,11 +350,13 @@ public class ActivityStartController { | ||
347 | 350 | |
348 | 351 | // Don't modify the client's object! |
349 | 352 | intent = new Intent(intent); |
353 | + if (forceNewTask) { | |
354 | + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
355 | + } | |
350 | 356 | |
351 | 357 | // Collect information about the target of the Intent. |
352 | 358 | ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, |
353 | - null, userId, ActivityStarter.computeResolveFilterUid( | |
354 | - callingUid, realCallingUid, UserHandle.USER_NULL)); | |
359 | + null, userId, filterCallingUid); | |
355 | 360 | // TODO: New, check if this is correct |
356 | 361 | aInfo = mService.getActivityInfoForUser(aInfo, userId); |
357 | 362 |
@@ -390,7 +395,17 @@ public class ActivityStartController { | ||
390 | 395 | return res; |
391 | 396 | } |
392 | 397 | |
393 | - resultTo = outActivity[0] != null ? outActivity[0].appToken : null; | |
398 | + final ActivityRecord started = outActivity[0]; | |
399 | + if (started != null && started.getUid() == filterCallingUid) { | |
400 | + // Only the started activity which has the same uid as the source caller can | |
401 | + // be the caller of next activity. | |
402 | + resultTo = started.appToken; | |
403 | + forceNewTask = false; | |
404 | + } else { | |
405 | + // Different apps not adjacent to the caller are forced to be new task. | |
406 | + resultTo = null; | |
407 | + forceNewTask = true; | |
408 | + } | |
394 | 409 | } |
395 | 410 | } |
396 | 411 | } finally { |
@@ -6991,6 +6991,7 @@ public class NotificationManagerService extends SystemService { | ||
6991 | 6991 | |
6992 | 6992 | @VisibleForTesting |
6993 | 6993 | protected void simulatePackageSuspendBroadcast(boolean suspend, String pkg) { |
6994 | + checkCallerIsSystemOrShell(); | |
6994 | 6995 | // only use for testing: mimic receive broadcast that package is (un)suspended |
6995 | 6996 | // but does not actually (un)suspend the package |
6996 | 6997 | final Bundle extras = new Bundle(); |
@@ -17656,41 +17656,55 @@ public class PackageManagerService extends IPackageManager.Stub | ||
17656 | 17656 | int count = 0; |
17657 | 17657 | final String packageName = pkg.packageName; |
17658 | 17658 | |
17659 | + boolean handlesWebUris = false; | |
17660 | + final boolean alreadyVerified; | |
17659 | 17661 | synchronized (mPackages) { |
17660 | 17662 | // If this is a new install and we see that we've already run verification for this |
17661 | 17663 | // package, we have nothing to do: it means the state was restored from backup. |
17662 | - if (!replacing) { | |
17663 | - IntentFilterVerificationInfo ivi = | |
17664 | - mSettings.getIntentFilterVerificationLPr(packageName); | |
17665 | - if (ivi != null) { | |
17666 | - if (DEBUG_DOMAIN_VERIFICATION) { | |
17667 | - Slog.i(TAG, "Package " + packageName+ " already verified: status=" | |
17668 | - + ivi.getStatusString()); | |
17669 | - } | |
17670 | - return; | |
17664 | + final IntentFilterVerificationInfo ivi = | |
17665 | + mSettings.getIntentFilterVerificationLPr(packageName); | |
17666 | + alreadyVerified = (ivi != null); | |
17667 | + if (!replacing && alreadyVerified) { | |
17668 | + if (DEBUG_DOMAIN_VERIFICATION) { | |
17669 | + Slog.i(TAG, "Package " + packageName + " already verified: status=" | |
17670 | + + ivi.getStatusString()); | |
17671 | 17671 | } |
17672 | + return; | |
17672 | 17673 | } |
17673 | 17674 | |
17674 | - // If any filters need to be verified, then all need to be. | |
17675 | + // If any filters need to be verified, then all need to be. In addition, we need to | |
17676 | + // know whether an updating app has any web navigation intent filters, to re- | |
17677 | + // examine handling policy even if not re-verifying. | |
17675 | 17678 | boolean needToVerify = false; |
17676 | 17679 | for (PackageParser.Activity a : pkg.activities) { |
17677 | 17680 | for (ActivityIntentInfo filter : a.intents) { |
17681 | + if (filter.handlesWebUris(true)) { | |
17682 | + handlesWebUris = true; | |
17683 | + } | |
17678 | 17684 | if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { |
17679 | 17685 | if (DEBUG_DOMAIN_VERIFICATION) { |
17680 | 17686 | Slog.d(TAG, |
17681 | 17687 | "Intent filter needs verification, so processing all filters"); |
17682 | 17688 | } |
17683 | 17689 | needToVerify = true; |
17690 | + // It's safe to break out here because filter.needsVerification() | |
17691 | + // can only be true if filter.handlesWebUris(true) returns true, so | |
17692 | + // we've already noted that. | |
17684 | 17693 | break; |
17685 | 17694 | } |
17686 | 17695 | } |
17687 | 17696 | } |
17688 | 17697 | |
17698 | + // Note whether this app publishes any web navigation handling support at all, | |
17699 | + // and whether there are any web-nav filters that fit the profile for running | |
17700 | + // a verification pass now. | |
17689 | 17701 | if (needToVerify) { |
17690 | 17702 | final int verificationId = mIntentFilterVerificationToken++; |
17691 | 17703 | for (PackageParser.Activity a : pkg.activities) { |
17692 | 17704 | for (ActivityIntentInfo filter : a.intents) { |
17693 | - if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { | |
17705 | + // Run verification against hosts mentioned in any web-nav intent filter, | |
17706 | + // even if the filter matches non-web schemes as well | |
17707 | + if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { | |
17694 | 17708 | if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, |
17695 | 17709 | "Verification needed for IntentFilter:" + filter.toString()); |
17696 | 17710 | mIntentFilterVerifier.addOneIntentFilterVerification( |
@@ -17703,13 +17717,23 @@ public class PackageManagerService extends IPackageManager.Stub | ||
17703 | 17717 | } |
17704 | 17718 | |
17705 | 17719 | if (count > 0) { |
17720 | + // count > 0 means that we're running a full verification pass | |
17706 | 17721 | if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count |
17707 | 17722 | + " IntentFilter verification" + (count > 1 ? "s" : "") |
17708 | 17723 | + " for userId:" + userId); |
17709 | 17724 | mIntentFilterVerifier.startVerifications(userId); |
17725 | + } else if (alreadyVerified && handlesWebUris) { | |
17726 | + // App used autoVerify in the past, no longer does, but still handles web | |
17727 | + // navigation starts. | |
17728 | + if (DEBUG_DOMAIN_VERIFICATION) { | |
17729 | + Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); | |
17730 | + } | |
17731 | + synchronized (mPackages) { | |
17732 | + clearIntentFilterVerificationsLPw(packageName, userId); | |
17733 | + } | |
17710 | 17734 | } else { |
17711 | 17735 | if (DEBUG_DOMAIN_VERIFICATION) { |
17712 | - Slog.d(TAG, "No filters or not all autoVerify for " + packageName); | |
17736 | + Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); | |
17713 | 17737 | } |
17714 | 17738 | } |
17715 | 17739 | } |
@@ -20619,7 +20643,29 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); | ||
20619 | 20643 | |
20620 | 20644 | @Override |
20621 | 20645 | public String getSystemTextClassifierPackageName() { |
20622 | - return mContext.getString(R.string.config_defaultTextClassifierPackage); | |
20646 | + return ensureSystemPackageName(mContext.getString( | |
20647 | + R.string.config_defaultTextClassifierPackage)); | |
20648 | + } | |
20649 | + | |
20650 | + @Nullable | |
20651 | + private String ensureSystemPackageName(@Nullable String packageName) { | |
20652 | + if (packageName == null) { | |
20653 | + return null; | |
20654 | + } | |
20655 | + long token = Binder.clearCallingIdentity(); | |
20656 | + try { | |
20657 | + if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { | |
20658 | + PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM); | |
20659 | + if (packageInfo != null) { | |
20660 | + EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid, | |
20661 | + ""); | |
20662 | + } | |
20663 | + return null; | |
20664 | + } | |
20665 | + } finally { | |
20666 | + Binder.restoreCallingIdentity(token); | |
20667 | + } | |
20668 | + return packageName; | |
20623 | 20669 | } |
20624 | 20670 | |
20625 | 20671 | @Override |
@@ -1319,6 +1319,7 @@ public final class Settings { | ||
1319 | 1319 | return false; |
1320 | 1320 | } |
1321 | 1321 | ps.clearDomainVerificationStatusForUser(userId); |
1322 | + ps.setIntentFilterVerificationInfo(null); | |
1322 | 1323 | return true; |
1323 | 1324 | } |
1324 | 1325 |
@@ -19,8 +19,6 @@ package com.android.server.policy.keyguard; | ||
19 | 19 | import android.app.ActivityManager; |
20 | 20 | import android.content.Context; |
21 | 21 | import android.os.RemoteException; |
22 | -import android.os.ServiceManager; | |
23 | -import android.security.IKeystoreService; | |
24 | 22 | import android.util.Slog; |
25 | 23 | |
26 | 24 | import com.android.internal.policy.IKeyguardService; |
@@ -53,16 +51,11 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { | ||
53 | 51 | private final LockPatternUtils mLockPatternUtils; |
54 | 52 | private final StateCallback mCallback; |
55 | 53 | |
56 | - IKeystoreService mKeystoreService; | |
57 | - | |
58 | 54 | public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) { |
59 | 55 | mLockPatternUtils = new LockPatternUtils(context); |
60 | 56 | mCurrentUserId = ActivityManager.getCurrentUser(); |
61 | 57 | mCallback = callback; |
62 | 58 | |
63 | - mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager | |
64 | - .getService("android.security.keystore")); | |
65 | - | |
66 | 59 | try { |
67 | 60 | service.addStateMonitorCallback(this); |
68 | 61 | } catch (RemoteException e) { |
@@ -95,11 +88,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { | ||
95 | 88 | mIsShowing = showing; |
96 | 89 | |
97 | 90 | mCallback.onShowingChanged(); |
98 | - try { | |
99 | - mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId); | |
100 | - } catch (RemoteException e) { | |
101 | - Slog.e(TAG, "Error informing keystore of screen lock", e); | |
102 | - } | |
103 | 91 | } |
104 | 92 | |
105 | 93 | @Override // Binder interface |
@@ -111,10 +99,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { | ||
111 | 99 | mCurrentUserId = userId; |
112 | 100 | } |
113 | 101 | |
114 | - private synchronized int getCurrentUser() { | |
115 | - return mCurrentUserId; | |
116 | - } | |
117 | - | |
118 | 102 | @Override // Binder interface |
119 | 103 | public void onInputRestrictedStateChanged(boolean inputRestricted) { |
120 | 104 | mInputRestricted = inputRestricted; |
@@ -48,6 +48,7 @@ import android.os.UserHandle; | ||
48 | 48 | import android.os.UserManager; |
49 | 49 | import android.os.storage.StorageManager; |
50 | 50 | import android.provider.Settings; |
51 | +import android.security.KeyStore; | |
51 | 52 | import android.service.trust.TrustAgentService; |
52 | 53 | import android.text.TextUtils; |
53 | 54 | import android.util.ArraySet; |
@@ -123,6 +124,33 @@ public class TrustManagerService extends SystemService { | ||
123 | 124 | @GuardedBy("mUserIsTrusted") |
124 | 125 | private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); |
125 | 126 | |
127 | + /** | |
128 | + * Stores the locked state for users on the device. There are three different type of users | |
129 | + * which are handled slightly differently: | |
130 | + * <ul> | |
131 | + * <li> Users with real keyguard | |
132 | + * These are users who can be switched to ({@link UserInfo#supportsSwitchToByUser()}). Their | |
133 | + * locked state is derived by a combination of user secure state, keyguard state, trust agent | |
134 | + * decision and biometric authentication result. These are updated via | |
135 | + * {@link #refreshDeviceLockedForUser(int)} and result stored in {@link #mDeviceLockedForUser}. | |
136 | + * <li> Managed profiles with unified challenge | |
137 | + * Managed profile with unified challenge always shares the same locked state as their parent, | |
138 | + * so their locked state is not recorded in {@link #mDeviceLockedForUser}. Instead, | |
139 | + * {@link ITrustManager#isDeviceLocked(int)} always resolves their parent user handle and | |
140 | + * queries its locked state instead. | |
141 | + * <li> Managed profiles with separate challenge | |
142 | + * Locked state for profile with separate challenge is determined by other parts of the | |
143 | + * framework (mostly PowerManager) and pushed to TrustManagerService via | |
144 | + * {@link ITrustManager#setDeviceLockedForUser(int, boolean)}. Although in a corner case when | |
145 | + * the profile has a separate but empty challenge, setting its {@link #mDeviceLockedForUser} to | |
146 | + * {@code false} is actually done by {@link #refreshDeviceLockedForUser(int)}. | |
147 | + * </ul> | |
148 | + * TODO: Rename {@link ITrustManager#setDeviceLockedForUser(int, boolean)} to | |
149 | + * {@code setDeviceLockedForProfile} to better reflect its purpose. Unifying | |
150 | + * {@code setDeviceLockedForProfile} and {@link #setDeviceLockedForUser} would also be nice. | |
151 | + * At the moment they both update {@link #mDeviceLockedForUser} but have slightly different | |
152 | + * side-effects: one notifies trust agents while the other sends out a broadcast. | |
153 | + */ | |
126 | 154 | @GuardedBy("mDeviceLockedForUser") |
127 | 155 | private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray(); |
128 | 156 |
@@ -412,6 +440,10 @@ public class TrustManagerService extends SystemService { | ||
412 | 440 | } |
413 | 441 | } |
414 | 442 | |
443 | + /** | |
444 | + * Update the user's locked state. Only applicable to users with a real keyguard | |
445 | + * ({@link UserInfo#supportsSwitchToByUser}) and unsecured managed profiles. | |
446 | + */ | |
415 | 447 | private void refreshDeviceLockedForUser(int userId) { |
416 | 448 | if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) { |
417 | 449 | Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle," |
@@ -465,6 +497,15 @@ public class TrustManagerService extends SystemService { | ||
465 | 497 | } |
466 | 498 | if (changed) { |
467 | 499 | dispatchDeviceLocked(userId, locked); |
500 | + | |
501 | + KeyStore.getInstance().onUserLockedStateChanged(userId, locked); | |
502 | + // Also update the user's profiles who have unified challenge, since they | |
503 | + // share the same unlocked state (see {@link #isDeviceLocked(int)}) | |
504 | + for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) { | |
505 | + if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) { | |
506 | + KeyStore.getInstance().onUserLockedStateChanged(profileHandle, locked); | |
507 | + } | |
508 | + } | |
468 | 509 | } |
469 | 510 | } |
470 | 511 |
@@ -987,6 +1028,10 @@ public class TrustManagerService extends SystemService { | ||
987 | 1028 | return "0x" + Integer.toHexString(i); |
988 | 1029 | } |
989 | 1030 | |
1031 | + /** | |
1032 | + * Changes the lock status for the given user. This is only applicable to managed profiles, | |
1033 | + * other users should be handled by Keyguard. | |
1034 | + */ | |
990 | 1035 | @Override |
991 | 1036 | public void setDeviceLockedForUser(int userId, boolean locked) { |
992 | 1037 | enforceReportPermission(); |
@@ -996,6 +1041,9 @@ public class TrustManagerService extends SystemService { | ||
996 | 1041 | synchronized (mDeviceLockedForUser) { |
997 | 1042 | mDeviceLockedForUser.put(userId, locked); |
998 | 1043 | } |
1044 | + | |
1045 | + KeyStore.getInstance().onUserLockedStateChanged(userId, locked); | |
1046 | + | |
999 | 1047 | if (locked) { |
1000 | 1048 | try { |
1001 | 1049 | ActivityManager.getService().notifyLockedProfile(userId); |
@@ -606,6 +606,19 @@ public class ActivityStackTests extends ActivityTestsBase { | ||
606 | 606 | assertTrue(listener.changed); |
607 | 607 | } |
608 | 608 | |
609 | + @Test | |
610 | + public void testNavigateUpTo() { | |
611 | + final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); | |
612 | + final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask) | |
613 | + .setUid(firstActivity.getUid() + 1).build(); | |
614 | + secondActivity.app.thread = null; | |
615 | + // This should do nothing from a non-attached caller (app.thread == null). | |
616 | + assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */, | |
617 | + firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */)); | |
618 | + assertFalse(secondActivity.finishing); | |
619 | + assertFalse(firstActivity.finishing); | |
620 | + } | |
621 | + | |
609 | 622 | private void verifyShouldSleepActivities(boolean focusedStack, |
610 | 623 | boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { |
611 | 624 | mSupervisor.mFocusedStack = focusedStack ? mStack : null; |
@@ -192,6 +192,8 @@ public class ActivityTestsBase { | ||
192 | 192 | aInfo.applicationInfo = new ApplicationInfo(); |
193 | 193 | aInfo.applicationInfo.packageName = mComponent.getPackageName(); |
194 | 194 | aInfo.applicationInfo.uid = mUid; |
195 | + aInfo.packageName = mComponent.getPackageName(); | |
196 | + aInfo.name = mComponent.getClassName(); | |
195 | 197 | aInfo.flags |= mActivityFlags; |
196 | 198 | |
197 | 199 | final ActivityRecord activity = new ActivityRecord(mService, null /* caller */, |