Merge "Support FBE for managed profiles." into nyc-dev

am: 716a9e1892

* commit '716a9e189297beba9e2205a335614e1750b9fdd4':
  Support FBE for managed profiles.
This commit is contained in:
Kenny Guy
2016-02-12 15:07:08 +00:00
committed by android-build-merger
12 changed files with 160 additions and 22 deletions

View File

@@ -8512,6 +8512,7 @@ package android.content {
field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED";
field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
field public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";

View File

@@ -8818,6 +8818,7 @@ package android.content {
field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED";
field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
field public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";

View File

@@ -8517,6 +8517,7 @@ package android.content {
field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED";
field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
field public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";

View File

@@ -3027,6 +3027,17 @@ public class Intent implements Parcelable, Cloneable {
public static final String ACTION_MANAGED_PROFILE_REMOVED =
"android.intent.action.MANAGED_PROFILE_REMOVED";
/**
* Broadcast sent to the primary user when the credential-encrypted private storage for
* an associated managed profile is unlocked. Carries an extra {@link #EXTRA_USER} that
* specifies the UserHandle of the profile that was unlocked. Only applications (for example
* Launchers) that need to display merged content across both primary and managed profiles
* need to worry about this broadcast. This is only sent to registered receivers,
* not manifest receivers.
*/
public static final String ACTION_MANAGED_PROFILE_UNLOCKED =
"android.intent.action.MANAGED_PROFILE_UNLOCKED";
/**
* Broadcast sent to the primary user when an associated managed profile's availability has
* changed. This includes when the user toggles the profile's quiet mode. Carries an extra

View File

@@ -4210,6 +4210,11 @@
<!-- Notification detail shown when user profile is credential encrypted and requires the user to unlock before some features are usable [CHAR LIMIT=30] -->
<string name="user_encrypted_detail">User data locked</string>
<!-- Notification detail shown when work profile is credential encrypted and requires the user to unlock before some features are usable [CHAR LIMIT=30] -->
<string name="profile_encrypted_detail">Work profile locked</string>
<!-- Notification message shown when work profile is credential encrypted and requires the user to unlock before some features are usable [CHAR LIMIT=30] -->
<string name="profile_encrypted_message">Tap to unlock work profile</string>
<!-- Title of notification shown after a MTP device is connected to Android. -->
<string name="usb_mtp_launch_notification_title">Connected to <xliff:g id="product_name">%1$s</xliff:g></string>
<!-- Description of notification shown after a MTP device is connected to Android. -->

View File

@@ -2522,6 +2522,8 @@
<java-symbol type="string" name="user_encrypted_title" />
<java-symbol type="string" name="user_encrypted_message" />
<java-symbol type="string" name="user_encrypted_detail" />
<java-symbol type="string" name="profile_encrypted_detail" />
<java-symbol type="string" name="profile_encrypted_message" />
<java-symbol type="drawable" name="ic_user_secure" />
<java-symbol type="string" name="usb_mtp_launch_notification_title" />

View File

@@ -17,6 +17,7 @@
package com.android.server;
import android.app.ActivityManagerNative;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -34,6 +35,7 @@ import android.content.pm.UserInfo;
import android.content.res.Resources;
import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.Context.USER_SERVICE;
import static android.Manifest.permission.READ_CONTACTS;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
@@ -124,7 +126,7 @@ public class LockSettingsService extends ILockSettings.Stub {
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mLockSettingsService.maybeShowEncryptionNotification(UserHandle.ALL);
mLockSettingsService.maybeShowEncryptionNotifications();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
// TODO
}
@@ -176,22 +178,48 @@ public class LockSettingsService extends ILockSettings.Stub {
* If the account is credential-encrypted, show notification requesting the user to unlock
* the device.
*/
private void maybeShowEncryptionNotification(UserHandle userHandle) {
if (UserHandle.ALL.equals(userHandle)) {
final List<UserInfo> users = mUserManager.getUsers();
for (int i = 0; i < users.size(); i++) {
UserHandle user = users.get(i).getUserHandle();
if (!mUserManager.isUserUnlocked(user)) {
showEncryptionNotification(user);
private void maybeShowEncryptionNotifications() {
final List<UserInfo> users = mUserManager.getUsers();
for (int i = 0; i < users.size(); i++) {
UserInfo user = users.get(i);
UserHandle userHandle = user.getUserHandle();
if (!mUserManager.isUserUnlocked(userHandle)) {
if (!user.isManagedProfile()) {
showEncryptionNotification(userHandle);
} else {
UserInfo parent = mUserManager.getProfileParent(user.id);
if (parent != null && mUserManager.isUserUnlocked(parent.getUserHandle())) {
// Only show notifications for managed profiles once their parent
// user is unlocked.
showEncryptionNotificationForProfile(userHandle);
}
}
}
} else if (!mUserManager.isUserUnlocked(userHandle)){
showEncryptionNotification(userHandle);
}
}
private void showEncryptionNotificationForProfile(UserHandle user) {
Resources r = mContext.getResources();
CharSequence title = r.getText(
com.android.internal.R.string.user_encrypted_title);
CharSequence message = r.getText(
com.android.internal.R.string.profile_encrypted_message);
CharSequence detail = r.getText(
com.android.internal.R.string.profile_encrypted_detail);
final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null, user.getIdentifier());
if (unlockIntent == null) {
return;
}
unlockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
showEncryptionNotification(user, title, message, detail, intent);
}
private void showEncryptionNotification(UserHandle user) {
if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
Resources r = mContext.getResources();
CharSequence title = r.getText(
com.android.internal.R.string.user_encrypted_title);
@@ -203,6 +231,12 @@ public class LockSettingsService extends ILockSettings.Stub {
PendingIntent intent = PendingIntent.getBroadcast(mContext, 0, ACTION_NULL,
PendingIntent.FLAG_UPDATE_CURRENT);
showEncryptionNotification(user, title, message, detail, intent);
}
private void showEncryptionNotification(UserHandle user, CharSequence title, CharSequence message,
CharSequence detail, PendingIntent intent) {
if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
Notification notification = new Notification.Builder(mContext)
.setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
.setWhen(0)
@@ -230,8 +264,21 @@ public class LockSettingsService extends ILockSettings.Stub {
hideEncryptionNotification(new UserHandle(userId));
}
public void onUnlockUser(int userHandle) {
hideEncryptionNotification(new UserHandle(userHandle));
public void onUnlockUser(int userId) {
hideEncryptionNotification(new UserHandle(userId));
// Now we have unlocked the parent user we should show notifications
// about any profiles that exist.
List<UserInfo> profiles = mUserManager.getProfiles(userId);
for (int i = 0; i < profiles.size(); i++) {
UserInfo profile = profiles.get(i);
if (profile.isManagedProfile()) {
UserHandle userHandle = profile.getUserHandle();
if (!mUserManager.isUserUnlocked(userHandle)) {
showEncryptionNotificationForProfile(userHandle);
}
}
}
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

View File

@@ -1046,10 +1046,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
return resolveIntent(intent, resolvedType, userId, 0);
}
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
try {
return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| ActivityManagerService.STOCK_PM_FLAGS, userId);
PackageManager.MATCH_DEFAULT_ONLY | flags
| ActivityManagerService.STOCK_PM_FLAGS, userId);
} catch (RemoteException e) {
}
return null;

View File

@@ -1,3 +1,19 @@
/*
* Copyright (C) 2016 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.am;
import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;

View File

@@ -1,3 +1,19 @@
/*
* Copyright (C) 2016 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.am;
import static android.app.Activity.RESULT_CANCELED;
@@ -74,7 +90,9 @@ import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
@@ -84,6 +102,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.voice.IVoiceInteractionSession;
import android.util.EventLog;
import android.util.Slog;
@@ -582,6 +601,22 @@ class ActivityStarter {
intent = new Intent(intent);
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
if (rInfo == null) {
UserInfo userInfo = mSupervisor.getUserInfo(userId);
if (userInfo != null && userInfo.isManagedProfile()) {
// Special case for managed profiles, if attempting to launch non-cryto aware
// app in a locked managed profile from an unlocked parent allow it to resolve
// as user will be sent via confirm credentials to unlock the profile.
UserManager userManager = UserManager.get(mService.mContext);
UserInfo parent = userManager.getProfileParent(userId);
if (parent != null
&& userManager.isUserUnlocked(parent.getUserHandle())
&& !userManager.isUserUnlocked(userInfo.getUserHandle())) {
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE);
}
}
}
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

View File

@@ -297,6 +297,22 @@ final class UserController {
null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
userId);
if (getUserInfo(userId).isManagedProfile()) {
UserInfo parent = getUserManager().getProfileParent(userId);
if (parent != null) {
final Intent profileUnlockedIntent = new Intent(
Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
unlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
unlockedIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
mService.broadcastIntentLocked(null, null, profileUnlockedIntent,
null, null, 0, null, null, null, AppOpsManager.OP_NONE,
null, false, false, MY_PID, SYSTEM_UID,
parent.id);
}
}
final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT

View File

@@ -201,8 +201,7 @@ public class LauncherAppsService extends SystemService {
long ident = Binder.clearCallingIdentity();
try {
List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
user.getIdentifier());
PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
return new ParceledListSlice<>(apps);
} finally {
Binder.restoreCallingIdentity(ident);
@@ -220,7 +219,7 @@ public class LauncherAppsService extends SystemService {
long ident = Binder.clearCallingIdentity();
try {
ResolveInfo app = mPm.resolveActivityAsUser(intent,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
return app;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -239,7 +238,7 @@ public class LauncherAppsService extends SystemService {
try {
IPackageManager pm = AppGlobals.getPackageManager();
PackageInfo info = pm.getPackageInfo(packageName,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
return info != null && info.applicationInfo.enabled;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -277,7 +276,7 @@ public class LauncherAppsService extends SystemService {
try {
IPackageManager pm = AppGlobals.getPackageManager();
ActivityInfo info = pm.getActivityInfo(component,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
return info != null;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -303,7 +302,7 @@ public class LauncherAppsService extends SystemService {
try {
IPackageManager pm = AppGlobals.getPackageManager();
ActivityInfo info = pm.getActivityInfo(component,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
if (!info.exported) {
throw new SecurityException("Cannot launch non-exported components "
+ component);
@@ -313,7 +312,7 @@ public class LauncherAppsService extends SystemService {
// as calling startActivityAsUser ignores the category and just
// resolves based on the component if present.
List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
final int size = apps.size();
for (int i = 0; i < size; ++i) {
ActivityInfo activityInfo = apps.get(i).activityInfo;