Maybe decrypt user when quiet mode is disabled

When quiet mode is disabled for a user and that user is not currently
decrypted, we show a confirm credentials screen to trigger decryption
of that user. Only if that was successful, do we actually disable quiet
mode.

Bug: 27764124
Change-Id: Ib1f649194d89e225dad62c14f3ddba1fa3d79da2
This commit is contained in:
Benjamin Franz
2016-04-04 18:52:21 +01:00
parent bb9fb194f8
commit f02420c5e1
6 changed files with 75 additions and 5 deletions

View File

@@ -20,6 +20,7 @@ package android.os;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.content.pm.UserInfo;
import android.content.IntentSender;
import android.content.RestrictionEntry;
import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;
@@ -70,6 +71,7 @@ interface IUserManager {
boolean markGuestForDeletion(int userHandle);
void setQuietModeEnabled(int userHandle, boolean enableQuietMode);
boolean isQuietModeEnabled(int userHandle);
boolean trySetQuietModeDisabled(int userHandle, in IntentSender target);
void setSeedAccountData(int userHandle, in String accountName,
in String accountType, in PersistableBundle accountOptions, boolean persist);
String getSeedAccountName();

View File

@@ -29,6 +29,7 @@ import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -1690,6 +1691,23 @@ public class UserManager {
}
}
/**
* Tries disabling quiet mode for a given user. If the user is still locked, we unlock the user
* first by showing the confirm credentials screen and disable quiet mode upon successful
* unlocking. If the user is already unlocked, we call through to {@link #setQuietModeEnabled}
* directly.
*
* @return true if the quiet mode was disabled immediately
* @hide
*/
public boolean trySetQuietModeDisabled(@UserIdInt int userHandle, IntentSender target) {
try {
return mService.trySetQuietModeDisabled(userHandle, target);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
/**
* If the target user is a managed profile of the calling user or the caller
* is itself a managed profile, then this returns a badged copy of the given

View File

@@ -107,9 +107,8 @@ public class UnlaunchableAppActivity extends Activity
@Override
public void onClick(DialogInterface dialog, int which) {
if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE && which == DialogInterface.BUTTON_POSITIVE) {
UserManager.get(this).setQuietModeEnabled(mUserId, false);
if (mTarget != null) {
if (UserManager.get(this).trySetQuietModeDisabled(mUserId, mTarget)
&& mTarget != null) {
try {
startIntentSenderForResult(mTarget, -1, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {

View File

@@ -15,6 +15,7 @@
package com.android.systemui.statusbar.phone;
import android.app.ActivityManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -57,10 +58,18 @@ public class ManagedProfileController {
}
}
public void setWorkModeEnabled(boolean enabled) {
public void setWorkModeEnabled(boolean enableWorkMode) {
synchronized (mProfiles) {
for (UserInfo ui : mProfiles) {
mUserManager.setQuietModeEnabled(ui.id, !enabled);
if (enableWorkMode) {
if (!mUserManager.trySetQuietModeDisabled(ui.id, null)) {
StatusBarManager statusBarManager = (StatusBarManager) mContext
.getSystemService(android.app.Service.STATUS_BAR_SERVICE);
statusBarManager.collapsePanels();
}
} else {
mUserManager.setQuietModeEnabled(ui.id, true);
}
}
}
}

View File

@@ -702,6 +702,12 @@ public class LockSettingsService extends ILockSettings.Stub {
}
};
// Check if the user is currently in quiet mode and start it otherwise
if (mUserManager.isQuietModeEnabled(new UserHandle(userId))
&& mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
mUserManager.setQuietModeEnabled(userId, false);
}
try {
ActivityManagerNative.getDefault().unlockUser(userId, token, secret, listener);
} catch (RemoteException e) {

View File

@@ -17,6 +17,9 @@
package com.android.server.pm;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -27,10 +30,12 @@ import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.IStopUserCallback;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
@@ -692,6 +697,37 @@ public class UserManagerService extends IUserManager.Stub {
}
}
@Override
public boolean trySetQuietModeDisabled(int userHandle, IntentSender target) {
if (mContext.getSystemService(StorageManager.class).isUserKeyUnlocked(userHandle)
|| !mLockPatternUtils.isSecure(userHandle)
|| !mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
// if the user is already unlocked, no need to show a profile challenge
setQuietModeEnabled(userHandle, false);
return true;
}
long identity = Binder.clearCallingIdentity();
try {
// otherwise, we show a profile challenge to trigger decryption of the user
final KeyguardManager km = (KeyguardManager) mContext.getSystemService(
Context.KEYGUARD_SERVICE);
final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null,
userHandle);
if (unlockIntent == null) {
return false;
}
if (target != null) {
unlockIntent.putExtra(Intent.EXTRA_INTENT, target);
}
unlockIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
mContext.startActivity(unlockIntent);
} finally {
Binder.restoreCallingIdentity(identity);
}
return false;
}
@Override
public void setUserEnabled(int userId) {
checkManageUsersPermission("enable user");