DO NOT MERGE - Merge RQ1A.201205.011

Bug: 172690556
Merged-In: I26bed08456197721d07f2fab563be0c54e43efd2
Change-Id: Ic1ac100efa50687ccfcbb87ee91a57703105afad
This commit is contained in:
Xin Li
2020-12-06 19:59:02 -08:00
14 changed files with 157 additions and 59 deletions

View File

@@ -554,6 +554,10 @@ status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8
return NO_ERROR;
}
if (!args[0].compare(String8("section"))) {
if (argCount == 1) {
fprintf(out, "Not enough arguments for section\n");
return NO_ERROR;
}
int id = atoi(args[1]);
int idx = 0;
while (SECTION_LIST[idx] != NULL) {

View File

@@ -105,7 +105,8 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd
public ActivityView(
@NonNull Context context, @NonNull AttributeSet attrs, int defStyle,
boolean singleTaskInstance, boolean usePublicVirtualDisplay) {
this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay, false);
this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay,
false /* disableSurfaceViewBackgroundLayer */);
}
/** @hide */
@@ -113,12 +114,22 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd
@NonNull Context context, @NonNull AttributeSet attrs, int defStyle,
boolean singleTaskInstance, boolean usePublicVirtualDisplay,
boolean disableSurfaceViewBackgroundLayer) {
this(context, attrs, defStyle, singleTaskInstance, usePublicVirtualDisplay,
disableSurfaceViewBackgroundLayer, false /* useTrustedDisplay */);
}
// TODO(b/162901735): Refactor ActivityView with Builder
/** @hide */
public ActivityView(
@NonNull Context context, @NonNull AttributeSet attrs, int defStyle,
boolean singleTaskInstance, boolean usePublicVirtualDisplay,
boolean disableSurfaceViewBackgroundLayer, boolean useTrustedDisplay) {
super(context, attrs, defStyle);
if (useTaskOrganizer()) {
mTaskEmbedder = new TaskOrganizerTaskEmbedder(context, this);
} else {
mTaskEmbedder = new VirtualDisplayTaskEmbedder(context, this, singleTaskInstance,
usePublicVirtualDisplay);
usePublicVirtualDisplay, useTrustedDisplay);
}
mSurfaceView = new SurfaceView(context, null, 0, 0, disableSurfaceViewBackgroundLayer);
// Since ActivityView#getAlpha has been overridden, we should use parent class's alpha

View File

@@ -16,11 +16,11 @@
package android.inputmethodservice;
import static android.graphics.Color.TRANSPARENT;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -69,6 +69,7 @@ import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsets.Side;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
@@ -1202,22 +1203,25 @@ public class InputMethodService extends AbstractInputMethodService {
Context.LAYOUT_INFLATER_SERVICE);
mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState,
WindowManager.LayoutParams.TYPE_INPUT_METHOD, Gravity.BOTTOM, false);
mWindow.getWindow().getAttributes().setFitInsetsTypes(navigationBars());
mWindow.getWindow().getAttributes().setFitInsetsTypes(statusBars() | navigationBars());
mWindow.getWindow().getAttributes().setFitInsetsSides(Side.all() & ~Side.BOTTOM);
mWindow.getWindow().getAttributes().setFitInsetsIgnoringVisibility(true);
// Our window will extend into the status bar area no matter the bar is visible or not.
// We don't want the ColorView to be visible when status bar is shown.
mWindow.getWindow().setStatusBarColor(TRANSPARENT);
// Automotive devices may request the navigation bar to be hidden when the IME shows up
// (controlled via config_automotiveHideNavBarForKeyboard) in order to maximize the visible
// screen real estate. When this happens, the IME window should animate from the bottom of
// the screen to reduce the jank that happens from the lack of synchronization between the
// bottom system window and the IME window.
// IME layout should always be inset by navigation bar, no matter its current visibility,
// unless automotive requests it. Automotive devices may request the navigation bar to be
// hidden when the IME shows up (controlled via config_automotiveHideNavBarForKeyboard)
// in order to maximize the visible screen real estate. When this happens, the IME window
// should animate from the bottom of the screen to reduce the jank that happens from the
// lack of synchronization between the bottom system window and the IME window.
if (mIsAutomotive && mAutomotiveHideNavBarForKeyboard) {
mWindow.getWindow().setDecorFitsSystemWindows(false);
}
mWindow.getWindow().getDecorView().setOnApplyWindowInsetsListener(
(v, insets) -> v.onApplyWindowInsets(
new WindowInsets.Builder(insets).setInsets(
navigationBars(),
insets.getInsetsIgnoringVisibility(navigationBars()))
.build()));
// For ColorView in DecorView to work, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS needs to be set
// by default (but IME developers can opt this out later if they want a new behavior).

View File

@@ -218,8 +218,15 @@ public abstract class DocumentsProvider extends ContentProvider {
}
/** {@hide} */
private void enforceTree(Uri documentUri) {
if (isTreeUri(documentUri)) {
private void enforceTreeForExtraUris(Bundle extras) {
enforceTree(extras.getParcelable(DocumentsContract.EXTRA_URI));
enforceTree(extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI));
enforceTree(extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI));
}
/** {@hide} */
private void enforceTree(@Nullable Uri documentUri) {
if (documentUri != null && isTreeUri(documentUri)) {
final String parent = getTreeDocumentId(documentUri);
final String child = getDocumentId(documentUri);
if (Objects.equals(parent, child)) {
@@ -232,6 +239,10 @@ public abstract class DocumentsProvider extends ContentProvider {
}
}
private Uri validateIncomingNullableUri(@Nullable Uri uri) {
return uri == null ? null : validateIncomingUri(uri);
}
/**
* Create a new document and return its newly generated
* {@link Document#COLUMN_DOCUMENT_ID}. You must allocate a new
@@ -1076,11 +1087,21 @@ public abstract class DocumentsProvider extends ContentProvider {
final Context context = getContext();
final Bundle out = new Bundle();
// If the URI is a tree URI performs some validation.
enforceTreeForExtraUris(extras);
final Uri extraUri = validateIncomingNullableUri(
extras.getParcelable(DocumentsContract.EXTRA_URI));
final Uri extraTargetUri = validateIncomingNullableUri(
extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI));
final Uri extraParentUri = validateIncomingNullableUri(
extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI));
if (METHOD_EJECT_ROOT.equals(method)) {
// Given that certain system apps can hold MOUNT_UNMOUNT permission, but only apps
// signed with platform signature can hold MANAGE_DOCUMENTS, we are going to check for
// MANAGE_DOCUMENTS or associated URI permission here instead
final Uri rootUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
final Uri rootUri = extraUri;
enforceWritePermissionInner(rootUri, getCallingPackage(), getCallingAttributionTag(),
null);
@@ -1090,7 +1111,7 @@ public abstract class DocumentsProvider extends ContentProvider {
return out;
}
final Uri documentUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
final Uri documentUri = extraUri;
final String authority = documentUri.getAuthority();
final String documentId = DocumentsContract.getDocumentId(documentUri);
@@ -1099,14 +1120,11 @@ public abstract class DocumentsProvider extends ContentProvider {
"Requested authority " + authority + " doesn't match provider " + mAuthority);
}
// If the URI is a tree URI performs some validation.
enforceTree(documentUri);
if (METHOD_IS_CHILD_DOCUMENT.equals(method)) {
enforceReadPermissionInner(documentUri, getCallingPackage(),
getCallingAttributionTag(), null);
final Uri childUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
final Uri childUri = extraTargetUri;
final String childAuthority = childUri.getAuthority();
final String childId = DocumentsContract.getDocumentId(childUri);
@@ -1173,7 +1191,7 @@ public abstract class DocumentsProvider extends ContentProvider {
revokeDocumentPermission(documentId);
} else if (METHOD_COPY_DOCUMENT.equals(method)) {
final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
final Uri targetUri = extraTargetUri;
final String targetId = DocumentsContract.getDocumentId(targetUri);
enforceReadPermissionInner(documentUri, getCallingPackage(),
@@ -1197,9 +1215,9 @@ public abstract class DocumentsProvider extends ContentProvider {
}
} else if (METHOD_MOVE_DOCUMENT.equals(method)) {
final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
final Uri parentSourceUri = extraParentUri;
final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
final Uri targetUri = extraTargetUri;
final String targetId = DocumentsContract.getDocumentId(targetUri);
enforceWritePermissionInner(documentUri, getCallingPackage(),
@@ -1225,7 +1243,7 @@ public abstract class DocumentsProvider extends ContentProvider {
}
} else if (METHOD_REMOVE_DOCUMENT.equals(method)) {
final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
final Uri parentSourceUri = extraParentUri;
final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
enforceReadPermissionInner(parentSourceUri, getCallingPackage(),

View File

@@ -19,6 +19,7 @@ package android.window;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
import static android.view.Display.INVALID_DISPLAY;
import android.app.ActivityManager;
@@ -63,6 +64,7 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
private int mDisplayDensityDpi;
private final boolean mSingleTaskInstance;
private final boolean mUsePublicVirtualDisplay;
private final boolean mUseTrustedDisplay;
private VirtualDisplay mVirtualDisplay;
private Insets mForwardedInsets;
private DisplayMetrics mTmpDisplayMetrics;
@@ -77,10 +79,12 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
* only applicable if virtual displays are used
*/
public VirtualDisplayTaskEmbedder(Context context, VirtualDisplayTaskEmbedder.Host host,
boolean singleTaskInstance, boolean usePublicVirtualDisplay) {
boolean singleTaskInstance, boolean usePublicVirtualDisplay,
boolean useTrustedDisplay) {
super(context, host);
mSingleTaskInstance = singleTaskInstance;
mUsePublicVirtualDisplay = usePublicVirtualDisplay;
mUseTrustedDisplay = useTrustedDisplay;
}
/**
@@ -103,6 +107,9 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
if (mUsePublicVirtualDisplay) {
virtualDisplayFlags |= VIRTUAL_DISPLAY_FLAG_PUBLIC;
}
if (mUseTrustedDisplay) {
virtualDisplayFlags |= VIRTUAL_DISPLAY_FLAG_TRUSTED;
}
mVirtualDisplay = displayManager.createVirtualDisplay(
DISPLAY_NAME + "@" + System.identityHashCode(this), mHost.getWidth(),

View File

@@ -144,7 +144,7 @@
<protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.device.action.UUID" />
<protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" />
<protected-broadcast android:name="android.bluetooth.action.ALIAS_CHANGED" />
<protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" />
<protected-broadcast android:name="android.bluetooth.device.action.FOUND" />
<protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" />
<protected-broadcast android:name="android.bluetooth.device.action.ACL_CONNECTED" />

View File

@@ -129,6 +129,7 @@
<!-- virtual display test permissions -->
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
<!-- color extraction test permissions -->
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />

View File

@@ -247,6 +247,25 @@ public class VirtualDisplayTest extends AndroidTestCase {
assertDisplayUnregistered(display);
}
/**
* Ensures that an application can create a trusted virtual display with the permission
* {@code ADD_TRUSTED_DISPLAY}.
*/
public void testTrustedVirtualDisplay() throws Exception {
VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
WIDTH, HEIGHT, DENSITY, mSurface,
DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED);
assertNotNull("virtual display must not be null", virtualDisplay);
Display display = virtualDisplay.getDisplay();
try {
assertDisplayRegistered(display, Display.FLAG_PRIVATE | Display.FLAG_TRUSTED);
} finally {
virtualDisplay.release();
}
assertDisplayUnregistered(display);
}
private void assertDisplayRegistered(Display display, int flags) {
assertNotNull("display object must not be null", display);
assertTrue("display must be valid", display.isValid());

View File

@@ -21,6 +21,7 @@ cc_library_shared {
shared_libs: [
"libdrmframework",
"libdrmframeworkcommon",
"liblog",
"libutils",
"libandroid_runtime",

View File

@@ -301,7 +301,7 @@ public class BubbleExpandedView extends LinearLayout {
mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */,
true /* singleTaskInstance */, false /* usePublicVirtualDisplay*/,
true /* disableSurfaceViewBackgroundLayer */);
true /* disableSurfaceViewBackgroundLayer */, true /* useTrustedDisplay */);
// Set ActivityView's alpha value as zero, since there is no view content to be shown.
setContentVisibility(false);

View File

@@ -315,11 +315,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
private List<Map<Pair<Integer, ApnSetting>, PreciseDataConnectionState>>
mPreciseDataConnectionStates;
static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK =
PhoneStateListener.LISTEN_REGISTRATION_FAILURE
| PhoneStateListener.LISTEN_BARRING_INFO;
static final int ENFORCE_FINE_LOCATION_PERMISSION_MASK =
// Starting in Q, almost all cellular location requires FINE location enforcement.
// Prior to Q, cellular was available with COARSE location enforcement. Bits in this
// list will be checked for COARSE on apps targeting P or earlier and FINE on Q or later.
static final int ENFORCE_LOCATION_PERMISSION_MASK =
PhoneStateListener.LISTEN_CELL_LOCATION
| PhoneStateListener.LISTEN_CELL_INFO
| PhoneStateListener.LISTEN_REGISTRATION_FAILURE
@@ -376,7 +375,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
+ " newDefaultPhoneId=" + newDefaultPhoneId);
}
//Due to possible risk condition,(notify call back using the new
//Due to possible race condition,(notify call back using the new
//defaultSubId comes before new defaultSubId update) we need to recall all
//possible missed notify callback
synchronized (mRecords) {
@@ -909,7 +908,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
try {
if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]);
if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
&& checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
// null will be translated to empty CellLocation object in client.
r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
}
@@ -964,7 +964,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
try {
if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
+ mCellInfo.get(phoneId));
if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
&& checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
}
} catch (RemoteException ex) {
@@ -1518,7 +1519,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
for (Record r : mRecords) {
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) &&
idMatch(r.subId, subId, phoneId) &&
checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
(checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
&& checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
try {
if (DBG_LOC) {
log("notifyCellInfoForSubscriber: mCellInfo=" + cellInfo
@@ -1797,7 +1799,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
for (Record r : mRecords) {
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) &&
idMatch(r.subId, subId, phoneId) &&
checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
(checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
&& checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
try {
if (DBG_LOC) {
log("notifyCellLocation: cellIdentity=" + cellIdentity
@@ -2542,19 +2545,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
.setCallingPid(Binder.getCallingPid())
.setCallingUid(Binder.getCallingUid());
boolean shouldCheckLocationPermissions = false;
if ((events & ENFORCE_COARSE_LOCATION_PERMISSION_MASK) != 0) {
locationQueryBuilder.setMinSdkVersionForCoarse(0);
shouldCheckLocationPermissions = true;
}
if ((events & ENFORCE_FINE_LOCATION_PERMISSION_MASK) != 0) {
if ((events & ENFORCE_LOCATION_PERMISSION_MASK) != 0) {
// Everything that requires fine location started in Q. So far...
locationQueryBuilder.setMinSdkVersionForFine(Build.VERSION_CODES.Q);
shouldCheckLocationPermissions = true;
}
// If we're enforcing fine starting in Q, we also want to enforce coarse even for
// older SDK versions.
locationQueryBuilder.setMinSdkVersionForCoarse(0);
if (shouldCheckLocationPermissions) {
LocationAccessPolicy.LocationPermissionResult result =
LocationAccessPolicy.checkLocationPermission(
mContext, locationQueryBuilder.build());
@@ -2721,8 +2718,16 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
try {
if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" +
mServiceState[phoneId]);
r.callback.onServiceStateChanged(
new ServiceState(mServiceState[phoneId]));
ServiceState ss = new ServiceState(mServiceState[phoneId]);
if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
r.callback.onServiceStateChanged(ss);
} else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) {
r.callback.onServiceStateChanged(
ss.createLocationInfoSanitizedCopy(false));
} else {
r.callback.onServiceStateChanged(
ss.createLocationInfoSanitizedCopy(true));
}
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
@@ -2767,7 +2772,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = "
+ mCellInfo.get(phoneId));
}
if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
&& checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
}
} catch (RemoteException ex) {
@@ -2833,7 +2839,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = "
+ mCellIdentity[phoneId]);
}
if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
&& checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
// null will be translated to empty CellLocation object in client.
r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
}

View File

@@ -86,6 +86,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.IntArray;
import android.util.Pair;
import android.util.Slog;
@@ -2191,10 +2192,16 @@ public final class DisplayManagerService extends SystemService {
}
}
if (callingUid == Process.SYSTEM_UID
|| checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
flags |= VIRTUAL_DISPLAY_FLAG_TRUSTED;
} else {
if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
EventLog.writeEvent(0x534e4554, "162627132", callingUid,
"Attempt to create a trusted display without holding permission!");
throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
+ "create a trusted virtual display.");
}
}
if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
}

View File

@@ -113,6 +113,7 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.LockPatternUtils;
@@ -2629,6 +2630,10 @@ public class LockSettingsService extends ILockSettings.Stub {
protected AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
LockscreenCredential credential, int userId) {
Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
Preconditions.checkState(
getSyntheticPasswordHandleLocked(userId) == SyntheticPasswordManager.DEFAULT_HANDLE,
"Cannot reinitialize SP");
final AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(
getGateKeeperService(), credentialHash, credential, userId);
if (auth == null) {
@@ -2689,7 +2694,7 @@ public class LockSettingsService extends ILockSettings.Stub {
@VisibleForTesting
protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) {
return true;
return getSyntheticPasswordHandleLocked(userId) == SyntheticPasswordManager.DEFAULT_HANDLE;
}
private VerifyCredentialResponse spBasedDoVerifyCredential(LockscreenCredential userCredential,

View File

@@ -519,10 +519,24 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
LockscreenCredential password = newPassword("password");
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
assertTrue(mService.setLockCredential(password, password, PRIMARY_USER_ID));
assertNoOrphanedFilesLeft(PRIMARY_USER_ID);
}
@Test
public void testAddingEscrowToken_NoOrphanedFilesLeft() throws Exception {
final byte[] token = "some-high-entropy-secure-token".getBytes();
for (int i = 0; i < 16; i++) {
long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
mLocalService.removeEscrowToken(handle, PRIMARY_USER_ID);
}
assertNoOrphanedFilesLeft(PRIMARY_USER_ID);
}
private void assertNoOrphanedFilesLeft(int userId) {
String handleString = String.format("%016x",
mService.getSyntheticPasswordHandleLocked(PRIMARY_USER_ID));
File directory = mStorage.getSyntheticPasswordDirectoryForUser(PRIMARY_USER_ID);
mService.getSyntheticPasswordHandleLocked(userId));
File directory = mStorage.getSyntheticPasswordDirectoryForUser(userId);
for (File file : directory.listFiles()) {
String[] parts = file.getName().split("\\.");
if (!parts[0].equals(handleString) && !parts[0].equals("0000000000000000")) {