Move CredentialProviderInfo for test/settings (framework)
This is a precusor CL to adding a subtitle for settings to use so we need to move CPI where it can be used by settings, atest and CTS. Test: ondevice & atest & cts Bug: 253157366 Change-Id: I2ffb1f89caf3f2c5bbf7d4dd693ad9a1bbc93fbb
This commit is contained in:
@@ -1072,6 +1072,40 @@ package android.content.rollback {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
package android.credentials {
|
||||||
|
|
||||||
|
public final class CredentialManager {
|
||||||
|
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.QUERY_ALL_PACKAGES, "android.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS"}) public java.util.List<android.credentials.CredentialProviderInfo> getCredentialProviderServicesForTesting(int);
|
||||||
|
method public static boolean isServiceEnabled(@NonNull android.content.Context);
|
||||||
|
field public static final int PROVIDER_FILTER_ALL_PROVIDERS = 0; // 0x0
|
||||||
|
field public static final int PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY = 1; // 0x1
|
||||||
|
field public static final int PROVIDER_FILTER_USER_PROVIDERS_ONLY = 2; // 0x2
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class CredentialProviderInfo implements android.os.Parcelable {
|
||||||
|
method public int describeContents();
|
||||||
|
method @NonNull public java.util.List<java.lang.String> getCapabilities();
|
||||||
|
method @NonNull public android.content.ComponentName getComponentName();
|
||||||
|
method @Nullable public CharSequence getLabel(@NonNull android.content.Context);
|
||||||
|
method @Nullable public android.graphics.drawable.Drawable getServiceIcon(@NonNull android.content.Context);
|
||||||
|
method @NonNull public android.content.pm.ServiceInfo getServiceInfo();
|
||||||
|
method @NonNull public boolean hasCapability(@NonNull String);
|
||||||
|
method public boolean isEnabled();
|
||||||
|
method public boolean isSystemProvider();
|
||||||
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
|
field @NonNull public static final android.os.Parcelable.Creator<android.credentials.CredentialProviderInfo> CREATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class CredentialProviderInfo.Builder {
|
||||||
|
ctor public CredentialProviderInfo.Builder(@NonNull android.content.pm.ServiceInfo);
|
||||||
|
method @NonNull public android.credentials.CredentialProviderInfo.Builder addCapabilities(@NonNull java.util.List<java.lang.String>);
|
||||||
|
method @NonNull public android.credentials.CredentialProviderInfo build();
|
||||||
|
method @NonNull public android.credentials.CredentialProviderInfo.Builder setEnabled(boolean);
|
||||||
|
method @NonNull public android.credentials.CredentialProviderInfo.Builder setSystemProvider(boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
package android.credentials.ui {
|
package android.credentials.ui {
|
||||||
|
|
||||||
public final class AuthenticationEntry implements android.os.Parcelable {
|
public final class AuthenticationEntry implements android.os.Parcelable {
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
import android.annotation.SystemService;
|
import android.annotation.SystemService;
|
||||||
|
import android.annotation.TestApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
import android.content.pm.ServiceInfo;
|
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.ICancellationSignal;
|
import android.os.ICancellationSignal;
|
||||||
import android.os.OutcomeReceiver;
|
import android.os.OutcomeReceiver;
|
||||||
@@ -75,21 +75,21 @@ public final class CredentialManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int PROVIDER_FILTER_ALL_PROVIDERS = 0;
|
@TestApi public static final int PROVIDER_FILTER_ALL_PROVIDERS = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns system credential providers only.
|
* Returns system credential providers only.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY = 1;
|
@TestApi public static final int PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns user credential providers only.
|
* Returns user credential providers only.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int PROVIDER_FILTER_USER_PROVIDERS_ONLY = 2;
|
@TestApi public static final int PROVIDER_FILTER_USER_PROVIDERS_ONLY = 2;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ICredentialManager mService;
|
private final ICredentialManager mService;
|
||||||
@@ -262,44 +262,6 @@ public final class CredentialManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of all user configurable credential providers registered on the system. This API
|
|
||||||
* is intended for browsers and settings apps.
|
|
||||||
*
|
|
||||||
* @param cancellationSignal an optional signal that allows for cancelling this call
|
|
||||||
* @param executor the callback will take place on this {@link Executor}
|
|
||||||
* @param callback the callback invoked when the request succeeds or fails
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
|
|
||||||
public void listEnabledProviders(
|
|
||||||
@Nullable CancellationSignal cancellationSignal,
|
|
||||||
@CallbackExecutor @NonNull Executor executor,
|
|
||||||
@NonNull
|
|
||||||
OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException>
|
|
||||||
callback) {
|
|
||||||
requireNonNull(executor, "executor must not be null");
|
|
||||||
requireNonNull(callback, "callback must not be null");
|
|
||||||
|
|
||||||
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
|
|
||||||
Log.w(TAG, "listEnabledProviders already canceled");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ICancellationSignal cancelRemote = null;
|
|
||||||
try {
|
|
||||||
cancelRemote =
|
|
||||||
mService.listEnabledProviders(
|
|
||||||
new ListEnabledProvidersTransport(executor, callback));
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cancellationSignal != null && cancelRemote != null) {
|
|
||||||
cancellationSignal.setRemote(cancelRemote);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a list of all user configurable credential providers registered on the system. This API
|
* Sets a list of all user configurable credential providers registered on the system. This API
|
||||||
* is intended for settings apps.
|
* is intended for settings apps.
|
||||||
@@ -348,36 +310,43 @@ public final class CredentialManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of ServiceInfo for all discovered credential providers on this device.
|
* Returns the list of CredentialProviderInfo for all discovered credential providers on this
|
||||||
|
* device but will include test system providers as well.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
@RequiresPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS)
|
@TestApi
|
||||||
public List<ServiceInfo> getCredentialProviderServicesForTesting(
|
@RequiresPermission(
|
||||||
@ProviderFilter int providerFilter) {
|
anyOf = {
|
||||||
|
android.Manifest.permission.QUERY_ALL_PACKAGES,
|
||||||
|
android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS
|
||||||
|
})
|
||||||
|
public List<CredentialProviderInfo> getCredentialProviderServicesForTesting(
|
||||||
|
@ProviderFilter int providerFilter) {
|
||||||
try {
|
try {
|
||||||
return mService.getCredentialProviderServices(
|
return mService.getCredentialProviderServicesForTesting(providerFilter);
|
||||||
mContext.getUserId(),
|
|
||||||
/* disableSystemAppVerificationForTests= */ true,
|
|
||||||
providerFilter);
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of ServiceInfo for all discovered credential providers on this device.
|
* Returns the list of CredentialProviderInfo for all discovered credential providers on this
|
||||||
|
* device.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
@RequiresPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS)
|
@RequiresPermission(
|
||||||
public List<ServiceInfo> getCredentialProviderServices(
|
anyOf = {
|
||||||
|
android.Manifest.permission.QUERY_ALL_PACKAGES,
|
||||||
|
android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS
|
||||||
|
})
|
||||||
|
public List<CredentialProviderInfo> getCredentialProviderServices(
|
||||||
int userId, @ProviderFilter int providerFilter) {
|
int userId, @ProviderFilter int providerFilter) {
|
||||||
try {
|
try {
|
||||||
return mService.getCredentialProviderServices(
|
return mService.getCredentialProviderServices(userId, providerFilter);
|
||||||
userId, /* disableSystemAppVerificationForTests= */ false, providerFilter);
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
@@ -388,7 +357,9 @@ public final class CredentialManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static boolean isServiceEnabled(Context context) {
|
@TestApi
|
||||||
|
public static boolean isServiceEnabled(@NonNull Context context) {
|
||||||
|
requireNonNull(context, "context must not be null");
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -578,33 +549,6 @@ public final class CredentialManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ListEnabledProvidersTransport extends IListEnabledProvidersCallback.Stub {
|
|
||||||
// TODO: listen for cancellation to release callback.
|
|
||||||
|
|
||||||
private final Executor mExecutor;
|
|
||||||
private final OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException>
|
|
||||||
mCallback;
|
|
||||||
|
|
||||||
private ListEnabledProvidersTransport(
|
|
||||||
Executor executor,
|
|
||||||
OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException>
|
|
||||||
callback) {
|
|
||||||
mExecutor = executor;
|
|
||||||
mCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResponse(ListEnabledProvidersResponse response) {
|
|
||||||
mExecutor.execute(() -> mCallback.onResult(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(String errorType, String message) {
|
|
||||||
mExecutor.execute(
|
|
||||||
() -> mCallback.onError(new ListEnabledProvidersException(errorType, message)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SetEnabledProvidersTransport extends ISetEnabledProvidersCallback.Stub {
|
private static class SetEnabledProvidersTransport extends ISetEnabledProvidersCallback.Stub {
|
||||||
// TODO: listen for cancellation to release callback.
|
// TODO: listen for cancellation to release callback.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2022 The Android Open Source Project
|
* Copyright 2023 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,14 +16,4 @@
|
|||||||
|
|
||||||
package android.credentials;
|
package android.credentials;
|
||||||
|
|
||||||
import android.credentials.ListEnabledProvidersResponse;
|
parcelable CredentialProviderInfo;
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener for an listEnabledProviders request.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
interface IListEnabledProvidersCallback {
|
|
||||||
oneway void onResponse(in ListEnabledProvidersResponse response);
|
|
||||||
oneway void onError(String errorType, String message);
|
|
||||||
}
|
|
||||||
215
core/java/android/credentials/CredentialProviderInfo.java
Normal file
215
core/java/android/credentials/CredentialProviderInfo.java
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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 android.credentials;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.TestApi;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ServiceInfo;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ServiceInfo} and meta-data about a credential provider.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@TestApi
|
||||||
|
public final class CredentialProviderInfo implements Parcelable {
|
||||||
|
@NonNull private final ServiceInfo mServiceInfo;
|
||||||
|
@NonNull private final List<String> mCapabilities = new ArrayList<>();
|
||||||
|
@Nullable private final CharSequence mOverrideLabel;
|
||||||
|
private final boolean mIsSystemProvider;
|
||||||
|
private final boolean mIsEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an information instance of the credential provider.
|
||||||
|
*
|
||||||
|
* @param builder the builder object.
|
||||||
|
*/
|
||||||
|
private CredentialProviderInfo(@NonNull Builder builder) {
|
||||||
|
mServiceInfo = builder.mServiceInfo;
|
||||||
|
mCapabilities.addAll(builder.mCapabilities);
|
||||||
|
mIsSystemProvider = builder.mIsSystemProvider;
|
||||||
|
mIsEnabled = builder.mIsEnabled;
|
||||||
|
mOverrideLabel = builder.mOverrideLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns true if the service supports the given {@code credentialType}, false otherwise. */
|
||||||
|
@NonNull
|
||||||
|
public boolean hasCapability(@NonNull String credentialType) {
|
||||||
|
return mCapabilities.contains(credentialType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the service info. */
|
||||||
|
@NonNull
|
||||||
|
public ServiceInfo getServiceInfo() {
|
||||||
|
return mServiceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether it is a system provider. */
|
||||||
|
public boolean isSystemProvider() {
|
||||||
|
return mIsSystemProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the service icon. */
|
||||||
|
@Nullable
|
||||||
|
public Drawable getServiceIcon(@NonNull Context context) {
|
||||||
|
return mServiceInfo.loadIcon(context.getPackageManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the service label. */
|
||||||
|
@Nullable
|
||||||
|
public CharSequence getLabel(@NonNull Context context) {
|
||||||
|
if (mOverrideLabel != null) {
|
||||||
|
return mOverrideLabel;
|
||||||
|
}
|
||||||
|
return mServiceInfo.loadSafeLabel(context.getPackageManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a list of capabilities this provider service can support. */
|
||||||
|
@NonNull
|
||||||
|
public List<String> getCapabilities() {
|
||||||
|
return Collections.unmodifiableList(mCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether the provider is enabled by the user. */
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return mIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the component name for the service. */
|
||||||
|
@NonNull
|
||||||
|
public ComponentName getComponentName() {
|
||||||
|
return mServiceInfo.getComponentName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeTypedObject(mServiceInfo, flags);
|
||||||
|
dest.writeBoolean(mIsSystemProvider);
|
||||||
|
dest.writeStringList(mCapabilities);
|
||||||
|
dest.writeBoolean(mIsEnabled);
|
||||||
|
TextUtils.writeToParcel(mOverrideLabel, dest, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CredentialProviderInfo {"
|
||||||
|
+ "serviceInfo="
|
||||||
|
+ mServiceInfo
|
||||||
|
+ ", "
|
||||||
|
+ "isSystemProvider="
|
||||||
|
+ mIsSystemProvider
|
||||||
|
+ ", "
|
||||||
|
+ "isEnabled="
|
||||||
|
+ mIsEnabled
|
||||||
|
+ ", "
|
||||||
|
+ "overrideLabel="
|
||||||
|
+ mOverrideLabel
|
||||||
|
+ ", "
|
||||||
|
+ "capabilities="
|
||||||
|
+ String.join(",", mCapabilities)
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private CredentialProviderInfo(@NonNull Parcel in) {
|
||||||
|
mServiceInfo = in.readTypedObject(ServiceInfo.CREATOR);
|
||||||
|
mIsSystemProvider = in.readBoolean();
|
||||||
|
in.readStringList(mCapabilities);
|
||||||
|
mIsEnabled = in.readBoolean();
|
||||||
|
mOverrideLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final @NonNull Parcelable.Creator<CredentialProviderInfo> CREATOR =
|
||||||
|
new Parcelable.Creator<CredentialProviderInfo>() {
|
||||||
|
@Override
|
||||||
|
public CredentialProviderInfo[] newArray(int size) {
|
||||||
|
return new CredentialProviderInfo[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CredentialProviderInfo createFromParcel(@NonNull Parcel in) {
|
||||||
|
return new CredentialProviderInfo(in);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A builder for {@link CredentialProviderInfo} objects. */
|
||||||
|
public static final class Builder {
|
||||||
|
|
||||||
|
@NonNull private ServiceInfo mServiceInfo;
|
||||||
|
@NonNull private List<String> mCapabilities = new ArrayList<>();
|
||||||
|
private boolean mIsSystemProvider = false;
|
||||||
|
private boolean mIsEnabled = false;
|
||||||
|
@Nullable private CharSequence mOverrideLabel = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new builder.
|
||||||
|
*
|
||||||
|
* @param serviceInfo the service info of the credential provider service.
|
||||||
|
*/
|
||||||
|
public Builder(@NonNull ServiceInfo serviceInfo) {
|
||||||
|
mServiceInfo = serviceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets whether it is a system provider. */
|
||||||
|
public @NonNull Builder setSystemProvider(boolean isSystemProvider) {
|
||||||
|
mIsSystemProvider = isSystemProvider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the label to be used instead of getting from the system (for unit tests).
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public @NonNull Builder setOverrideLabel(@NonNull CharSequence overrideLabel) {
|
||||||
|
mOverrideLabel = overrideLabel;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets a list of capabilities this provider service can support. */
|
||||||
|
public @NonNull Builder addCapabilities(@NonNull List<String> capabilities) {
|
||||||
|
mCapabilities.addAll(capabilities);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets whether it is enabled by the user. */
|
||||||
|
public @NonNull Builder setEnabled(boolean isEnabled) {
|
||||||
|
mIsEnabled = isEnabled;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Builds a new {@link CredentialProviderInfo} instance. */
|
||||||
|
public @NonNull CredentialProviderInfo build() {
|
||||||
|
return new CredentialProviderInfo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ package android.credentials;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import android.content.pm.ServiceInfo;
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.ClearCredentialStateRequest;
|
import android.credentials.ClearCredentialStateRequest;
|
||||||
import android.credentials.CreateCredentialRequest;
|
import android.credentials.CreateCredentialRequest;
|
||||||
import android.credentials.GetCredentialRequest;
|
import android.credentials.GetCredentialRequest;
|
||||||
@@ -27,7 +27,6 @@ import android.credentials.UnregisterCredentialDescriptionRequest;
|
|||||||
import android.credentials.IClearCredentialStateCallback;
|
import android.credentials.IClearCredentialStateCallback;
|
||||||
import android.credentials.ICreateCredentialCallback;
|
import android.credentials.ICreateCredentialCallback;
|
||||||
import android.credentials.IGetCredentialCallback;
|
import android.credentials.IGetCredentialCallback;
|
||||||
import android.credentials.IListEnabledProvidersCallback;
|
|
||||||
import android.credentials.ISetEnabledProvidersCallback;
|
import android.credentials.ISetEnabledProvidersCallback;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.os.ICancellationSignal;
|
import android.os.ICancellationSignal;
|
||||||
@@ -45,8 +44,6 @@ interface ICredentialManager {
|
|||||||
|
|
||||||
@nullable ICancellationSignal clearCredentialState(in ClearCredentialStateRequest request, in IClearCredentialStateCallback callback, String callingPackage);
|
@nullable ICancellationSignal clearCredentialState(in ClearCredentialStateRequest request, in IClearCredentialStateCallback callback, String callingPackage);
|
||||||
|
|
||||||
@nullable ICancellationSignal listEnabledProviders(in IListEnabledProvidersCallback callback);
|
|
||||||
|
|
||||||
void setEnabledProviders(in List<String> providers, in int userId, in ISetEnabledProvidersCallback callback);
|
void setEnabledProviders(in List<String> providers, in int userId, in ISetEnabledProvidersCallback callback);
|
||||||
|
|
||||||
void registerCredentialDescription(in RegisterCredentialDescriptionRequest request, String callingPackage);
|
void registerCredentialDescription(in RegisterCredentialDescriptionRequest request, String callingPackage);
|
||||||
@@ -55,6 +52,8 @@ interface ICredentialManager {
|
|||||||
|
|
||||||
boolean isEnabledCredentialProviderService(in ComponentName componentName, String callingPackage);
|
boolean isEnabledCredentialProviderService(in ComponentName componentName, String callingPackage);
|
||||||
|
|
||||||
List<ServiceInfo> getCredentialProviderServices(in int userId, in boolean disableSystemAppVerificationForTests, in int providerFilter);
|
List<CredentialProviderInfo> getCredentialProviderServices(in int userId, in int providerFilter);
|
||||||
|
|
||||||
|
List<CredentialProviderInfo> getCredentialProviderServicesForTesting(in int providerFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,40 +34,27 @@ import android.content.pm.ResolveInfo;
|
|||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.credentials.CredentialManager;
|
import android.credentials.CredentialManager;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.text.TextUtils;
|
import android.os.UserHandle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ServiceInfo} and meta-data about a credential provider.
|
* {@link CredentialProviderInfo} generator.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class CredentialProviderInfo {
|
public final class CredentialProviderInfoFactory {
|
||||||
private static final String TAG = "CredentialProviderInfo";
|
private static final String TAG = "CredentialProviderInfoFactory";
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private final ServiceInfo mServiceInfo;
|
|
||||||
@NonNull
|
|
||||||
private final List<String> mCapabilities;
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private final Context mContext;
|
|
||||||
@Nullable
|
|
||||||
private final Drawable mIcon;
|
|
||||||
@Nullable
|
|
||||||
private final CharSequence mLabel;
|
|
||||||
private final boolean mIsSystemProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an information instance of the credential provider.
|
* Constructs an information instance of the credential provider.
|
||||||
@@ -79,14 +66,18 @@ public final class CredentialProviderInfo {
|
|||||||
* @throws PackageManager.NameNotFoundException If provider service is not found
|
* @throws PackageManager.NameNotFoundException If provider service is not found
|
||||||
* @throws SecurityException If provider does not require the relevant permission
|
* @throws SecurityException If provider does not require the relevant permission
|
||||||
*/
|
*/
|
||||||
public CredentialProviderInfo(@NonNull Context context,
|
public static CredentialProviderInfo create(
|
||||||
@NonNull ComponentName serviceComponent, int userId, boolean isSystemProvider)
|
@NonNull Context context,
|
||||||
|
@NonNull ComponentName serviceComponent,
|
||||||
|
int userId,
|
||||||
|
boolean isSystemProvider)
|
||||||
throws PackageManager.NameNotFoundException {
|
throws PackageManager.NameNotFoundException {
|
||||||
this(
|
return create(
|
||||||
context,
|
context,
|
||||||
getServiceInfoOrThrow(serviceComponent, userId),
|
getServiceInfoOrThrow(serviceComponent, userId),
|
||||||
isSystemProvider,
|
isSystemProvider,
|
||||||
/* disableSystemAppVerificationForTests= */ false);
|
/* disableSystemAppVerificationForTests= */ false,
|
||||||
|
/* isEnabled= */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,13 +89,16 @@ public final class CredentialProviderInfo {
|
|||||||
* @param isSystemProvider whether the provider app is a system provider
|
* @param isSystemProvider whether the provider app is a system provider
|
||||||
* @param disableSystemAppVerificationForTests whether to disable system app permission
|
* @param disableSystemAppVerificationForTests whether to disable system app permission
|
||||||
* verification so that tests can install system providers
|
* verification so that tests can install system providers
|
||||||
|
* @param isEnabled whether the user enabled this provider
|
||||||
* @throws SecurityException If provider does not require the relevant permission
|
* @throws SecurityException If provider does not require the relevant permission
|
||||||
*/
|
*/
|
||||||
public CredentialProviderInfo(
|
public static CredentialProviderInfo create(
|
||||||
@NonNull Context context,
|
@NonNull Context context,
|
||||||
@NonNull ServiceInfo serviceInfo,
|
@NonNull ServiceInfo serviceInfo,
|
||||||
boolean isSystemProvider,
|
boolean isSystemProvider,
|
||||||
boolean disableSystemAppVerificationForTests) {
|
boolean disableSystemAppVerificationForTests,
|
||||||
|
boolean isEnabled)
|
||||||
|
throws SecurityException {
|
||||||
verifyProviderPermission(serviceInfo);
|
verifyProviderPermission(serviceInfo);
|
||||||
if (isSystemProvider) {
|
if (isSystemProvider) {
|
||||||
if (!isValidSystemProvider(
|
if (!isValidSystemProvider(
|
||||||
@@ -114,23 +108,11 @@ public final class CredentialProviderInfo {
|
|||||||
"Provider is not a valid system provider: " + serviceInfo);
|
"Provider is not a valid system provider: " + serviceInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mIsSystemProvider = isSystemProvider;
|
|
||||||
mContext = requireNonNull(context, "context must not be null");
|
return populateMetadata(context, serviceInfo)
|
||||||
mServiceInfo = requireNonNull(serviceInfo, "serviceInfo must not be null");
|
.setSystemProvider(isSystemProvider)
|
||||||
mCapabilities = new ArrayList<>();
|
.setEnabled(isEnabled)
|
||||||
mIcon = mServiceInfo.loadIcon(mContext.getPackageManager());
|
.build();
|
||||||
mLabel =
|
|
||||||
mServiceInfo.loadSafeLabel(
|
|
||||||
mContext.getPackageManager(),
|
|
||||||
0 /* do not ellipsize */,
|
|
||||||
TextUtils.SAFE_STRING_FLAG_FIRST_LINE | TextUtils.SAFE_STRING_FLAG_TRIM);
|
|
||||||
Log.i(
|
|
||||||
TAG,
|
|
||||||
"mLabel is : "
|
|
||||||
+ mLabel
|
|
||||||
+ ", for: "
|
|
||||||
+ mServiceInfo.getComponentName().flattenToString());
|
|
||||||
populateProviderCapabilities(context, serviceInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void verifyProviderPermission(ServiceInfo serviceInfo) throws SecurityException {
|
private static void verifyProviderPermission(ServiceInfo serviceInfo) throws SecurityException {
|
||||||
@@ -138,19 +120,14 @@ public final class CredentialProviderInfo {
|
|||||||
if (permission.equals(serviceInfo.permission)) {
|
if (permission.equals(serviceInfo.permission)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Slog.e(
|
|
||||||
TAG,
|
|
||||||
"Credential Provider Service from : "
|
|
||||||
+ serviceInfo.packageName
|
|
||||||
+ "does not require permission"
|
|
||||||
+ permission);
|
|
||||||
throw new SecurityException(
|
throw new SecurityException(
|
||||||
"Service does not require the expected permission : " + permission);
|
"Service does not require the expected permission : " + permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSystemProviderWithValidPermission(
|
private static boolean isSystemProviderWithValidPermission(
|
||||||
ServiceInfo serviceInfo, Context context) {
|
ServiceInfo serviceInfo, Context context) {
|
||||||
|
requireNonNull(context, "context must not be null");
|
||||||
|
|
||||||
final String permission = Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE;
|
final String permission = Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE;
|
||||||
try {
|
try {
|
||||||
ApplicationInfo appInfo =
|
ApplicationInfo appInfo =
|
||||||
@@ -177,67 +154,88 @@ public final class CredentialProviderInfo {
|
|||||||
Context context,
|
Context context,
|
||||||
ServiceInfo serviceInfo,
|
ServiceInfo serviceInfo,
|
||||||
boolean disableSystemAppVerificationForTests) {
|
boolean disableSystemAppVerificationForTests) {
|
||||||
boolean isValidSystemTestProvider =
|
requireNonNull(context, "context must not be null");
|
||||||
isTestSystemProvider(serviceInfo, disableSystemAppVerificationForTests);
|
|
||||||
if (isValidSystemTestProvider) {
|
if (disableSystemAppVerificationForTests) {
|
||||||
return true;
|
Bundle metadata = serviceInfo.metaData;
|
||||||
|
if (metadata == null) {
|
||||||
|
Slog.e(TAG, "isValidSystemProvider - metadata is null: " + serviceInfo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return metadata.getBoolean(
|
||||||
|
CredentialProviderService.TEST_SYSTEM_PROVIDER_META_DATA_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isSystemProviderWithValidPermission(serviceInfo, context);
|
return isSystemProviderWithValidPermission(serviceInfo, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isTestSystemProvider(
|
private static CredentialProviderInfo.Builder populateMetadata(
|
||||||
ServiceInfo serviceInfo, boolean disableSystemAppVerificationForTests) {
|
@NonNull Context context, ServiceInfo serviceInfo) {
|
||||||
if (!disableSystemAppVerificationForTests) {
|
requireNonNull(context, "context must not be null");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bundle metadata = serviceInfo.metaData;
|
final CredentialProviderInfo.Builder builder =
|
||||||
if (metadata == null) {
|
new CredentialProviderInfo.Builder(serviceInfo);
|
||||||
Slog.e(TAG, "metadata is null: " + serviceInfo);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return metadata.getBoolean(CredentialProviderService.TEST_SYSTEM_PROVIDER_META_DATA_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateProviderCapabilities(@NonNull Context context, ServiceInfo serviceInfo) {
|
|
||||||
final PackageManager pm = context.getPackageManager();
|
final PackageManager pm = context.getPackageManager();
|
||||||
|
|
||||||
|
// 1. Get the metadata for the service.
|
||||||
|
final Bundle metadata = serviceInfo.metaData;
|
||||||
|
if (metadata == null) {
|
||||||
|
Log.i(TAG, "populateMetadata - metadata is null");
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Extract the capabilities from the bundle.
|
||||||
try {
|
try {
|
||||||
Bundle metadata = serviceInfo.metaData;
|
|
||||||
Resources resources = pm.getResourcesForApplication(serviceInfo.applicationInfo);
|
Resources resources = pm.getResourcesForApplication(serviceInfo.applicationInfo);
|
||||||
if (metadata == null || resources == null) {
|
if (metadata == null || resources == null) {
|
||||||
Log.i(TAG, "populateProviderCapabilities - metadata or resources is null");
|
Log.i(TAG, "populateMetadata - resources is null");
|
||||||
return;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] capabilities = resources.getStringArray(metadata.getInt(
|
builder.addCapabilities(populateProviderCapabilities(resources, metadata, serviceInfo));
|
||||||
CredentialProviderService.CAPABILITY_META_DATA_KEY));
|
|
||||||
if (capabilities == null || capabilities.length == 0) {
|
|
||||||
Slog.i(TAG, "No capabilities found for provider:" + serviceInfo.packageName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String capability : capabilities) {
|
|
||||||
if (capability.isEmpty()) {
|
|
||||||
Slog.i(TAG, "Skipping empty capability");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Slog.i(TAG, "Capabilities found for provider: " + capability);
|
|
||||||
mCapabilities.add(capability);
|
|
||||||
}
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
Slog.e(TAG, e.getMessage());
|
Slog.e(TAG, e.getMessage());
|
||||||
} catch (Resources.NotFoundException e) {
|
|
||||||
Slog.e(TAG, e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServiceInfo getServiceInfoOrThrow(@NonNull ComponentName serviceComponent,
|
private static List<String> populateProviderCapabilities(
|
||||||
int userId) throws PackageManager.NameNotFoundException {
|
Resources resources, Bundle metadata, ServiceInfo serviceInfo) {
|
||||||
|
List<String> output = new ArrayList<>();
|
||||||
|
String[] capabilities = new String[0];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo(
|
capabilities =
|
||||||
serviceComponent,
|
resources.getStringArray(
|
||||||
PackageManager.GET_META_DATA,
|
metadata.getInt(CredentialProviderService.CAPABILITY_META_DATA_KEY));
|
||||||
userId);
|
} catch (Resources.NotFoundException e) {
|
||||||
|
Slog.e(TAG, "Failed to get capabilities: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capabilities == null || capabilities.length == 0) {
|
||||||
|
Slog.e(TAG, "No capabilities found for provider:" + serviceInfo.packageName);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String capability : capabilities) {
|
||||||
|
if (capability.isEmpty()) {
|
||||||
|
Slog.e(TAG, "Skipping empty capability");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Slog.e(TAG, "Capabilities found for provider: " + capability);
|
||||||
|
output.add(capability);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServiceInfo getServiceInfoOrThrow(
|
||||||
|
@NonNull ComponentName serviceComponent, int userId)
|
||||||
|
throws PackageManager.NameNotFoundException {
|
||||||
|
try {
|
||||||
|
ServiceInfo si =
|
||||||
|
AppGlobals.getPackageManager()
|
||||||
|
.getServiceInfo(serviceComponent, PackageManager.GET_META_DATA, userId);
|
||||||
if (si != null) {
|
if (si != null) {
|
||||||
return si;
|
return si;
|
||||||
}
|
}
|
||||||
@@ -256,6 +254,8 @@ public final class CredentialProviderInfo {
|
|||||||
@NonNull Context context,
|
@NonNull Context context,
|
||||||
@UserIdInt int userId,
|
@UserIdInt int userId,
|
||||||
boolean disableSystemAppVerificationForTests) {
|
boolean disableSystemAppVerificationForTests) {
|
||||||
|
requireNonNull(context, "context must not be null");
|
||||||
|
|
||||||
final List<ServiceInfo> services = new ArrayList<>();
|
final List<ServiceInfo> services = new ArrayList<>();
|
||||||
final List<ResolveInfo> resolveInfos = new ArrayList<>();
|
final List<ResolveInfo> resolveInfos = new ArrayList<>();
|
||||||
|
|
||||||
@@ -268,15 +268,20 @@ public final class CredentialProviderInfo {
|
|||||||
|
|
||||||
for (ResolveInfo resolveInfo : resolveInfos) {
|
for (ResolveInfo resolveInfo : resolveInfos) {
|
||||||
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
|
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
|
||||||
|
if (disableSystemAppVerificationForTests) {
|
||||||
|
if (serviceInfo != null) {
|
||||||
|
services.add(serviceInfo);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PackageManager.ApplicationInfoFlags appInfoFlags =
|
|
||||||
disableSystemAppVerificationForTests
|
|
||||||
? PackageManager.ApplicationInfoFlags.of(0)
|
|
||||||
: PackageManager.ApplicationInfoFlags.of(
|
|
||||||
PackageManager.MATCH_SYSTEM_ONLY);
|
|
||||||
ApplicationInfo appInfo =
|
ApplicationInfo appInfo =
|
||||||
context.getPackageManager()
|
context.getPackageManager()
|
||||||
.getApplicationInfo(serviceInfo.packageName, appInfoFlags);
|
.getApplicationInfo(
|
||||||
|
serviceInfo.packageName,
|
||||||
|
PackageManager.ApplicationInfoFlags.of(
|
||||||
|
PackageManager.MATCH_SYSTEM_ONLY));
|
||||||
|
|
||||||
if (appInfo == null || serviceInfo == null) {
|
if (appInfo == null || serviceInfo == null) {
|
||||||
continue;
|
continue;
|
||||||
@@ -300,19 +305,22 @@ public final class CredentialProviderInfo {
|
|||||||
public static List<CredentialProviderInfo> getAvailableSystemServices(
|
public static List<CredentialProviderInfo> getAvailableSystemServices(
|
||||||
@NonNull Context context,
|
@NonNull Context context,
|
||||||
@UserIdInt int userId,
|
@UserIdInt int userId,
|
||||||
boolean disableSystemAppVerificationForTests) {
|
boolean disableSystemAppVerificationForTests,
|
||||||
|
Set<ServiceInfo> enabledServices) {
|
||||||
requireNonNull(context, "context must not be null");
|
requireNonNull(context, "context must not be null");
|
||||||
|
|
||||||
final List<CredentialProviderInfo> providerInfos = new ArrayList<>();
|
final List<CredentialProviderInfo> providerInfos = new ArrayList<>();
|
||||||
for (ServiceInfo si :
|
for (ServiceInfo si :
|
||||||
getAvailableSystemServiceInfos(
|
getAvailableSystemServiceInfos(
|
||||||
context, userId, disableSystemAppVerificationForTests)) {
|
context, userId, disableSystemAppVerificationForTests)) {
|
||||||
try {
|
try {
|
||||||
CredentialProviderInfo cpi =
|
CredentialProviderInfo cpi =
|
||||||
new CredentialProviderInfo(
|
CredentialProviderInfoFactory.create(
|
||||||
context,
|
context,
|
||||||
si,
|
si,
|
||||||
/* isSystemProvider= */ true,
|
/* isSystemProvider= */ true,
|
||||||
disableSystemAppVerificationForTests);
|
disableSystemAppVerificationForTests,
|
||||||
|
enabledServices.contains(si));
|
||||||
if (cpi.isSystemProvider()) {
|
if (cpi.isSystemProvider()) {
|
||||||
providerInfos.add(cpi);
|
providerInfos.add(cpi);
|
||||||
} else {
|
} else {
|
||||||
@@ -325,45 +333,12 @@ public final class CredentialProviderInfo {
|
|||||||
return providerInfos;
|
return providerInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static @Nullable PackagePolicy getDeviceManagerPolicy(
|
||||||
* Returns true if the service supports the given {@code credentialType}, false otherwise.
|
@NonNull Context context, int userId) {
|
||||||
*/
|
Context newContext = context.createContextAsUser(UserHandle.of(userId), 0);
|
||||||
@NonNull
|
|
||||||
public boolean hasCapability(@NonNull String credentialType) {
|
|
||||||
return mCapabilities.contains(credentialType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the service info. */
|
|
||||||
@NonNull
|
|
||||||
public ServiceInfo getServiceInfo() {
|
|
||||||
return mServiceInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSystemProvider() {
|
|
||||||
return mIsSystemProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the service icon. */
|
|
||||||
@Nullable
|
|
||||||
public Drawable getServiceIcon() {
|
|
||||||
return mIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the service label. */
|
|
||||||
@Nullable
|
|
||||||
public CharSequence getServiceLabel() {
|
|
||||||
return mLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns an immutable list of capabilities this provider service can support. */
|
|
||||||
@NonNull
|
|
||||||
public List<String> getCapabilities() {
|
|
||||||
return Collections.unmodifiableList(mCapabilities);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable PackagePolicy getDeviceManagerPolicy(@NonNull Context context) {
|
|
||||||
try {
|
try {
|
||||||
DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
|
DevicePolicyManager dpm = newContext.getSystemService(DevicePolicyManager.class);
|
||||||
return dpm.getCredentialManagerPolicy();
|
return dpm.getCredentialManagerPolicy();
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
// If the current user is not enrolled in DPM then this can throw a security error.
|
// If the current user is not enrolled in DPM then this can throw a security error.
|
||||||
@@ -381,21 +356,53 @@ public final class CredentialProviderInfo {
|
|||||||
public static List<CredentialProviderInfo> getCredentialProviderServices(
|
public static List<CredentialProviderInfo> getCredentialProviderServices(
|
||||||
@NonNull Context context,
|
@NonNull Context context,
|
||||||
int userId,
|
int userId,
|
||||||
boolean disableSystemAppVerificationForTests,
|
int providerFilter,
|
||||||
int providerFilter) {
|
Set<ServiceInfo> enabledServices) {
|
||||||
requireNonNull(context, "context must not be null");
|
requireNonNull(context, "context must not be null");
|
||||||
|
|
||||||
// Get the device policy.
|
// Get the device policy.
|
||||||
PackagePolicy pp = getDeviceManagerPolicy(context);
|
PackagePolicy pp = getDeviceManagerPolicy(context, userId);
|
||||||
|
|
||||||
// Generate the provider list.
|
// Generate the provider list.
|
||||||
|
final boolean disableSystemAppVerificationForTests = false;
|
||||||
ProviderGenerator generator =
|
ProviderGenerator generator =
|
||||||
new ProviderGenerator(
|
new ProviderGenerator(
|
||||||
context, pp, disableSystemAppVerificationForTests, providerFilter);
|
context, pp, disableSystemAppVerificationForTests, providerFilter);
|
||||||
generator.addUserProviders(
|
generator.addUserProviders(
|
||||||
getUserProviders(context, userId, disableSystemAppVerificationForTests));
|
getUserProviders(
|
||||||
|
context, userId, disableSystemAppVerificationForTests, enabledServices));
|
||||||
generator.addSystemProviders(
|
generator.addSystemProviders(
|
||||||
getAvailableSystemServices(context, userId, disableSystemAppVerificationForTests));
|
getAvailableSystemServices(
|
||||||
|
context, userId, disableSystemAppVerificationForTests, enabledServices));
|
||||||
|
return generator.getProviders();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the valid credential provider services available for the user with the given {@code
|
||||||
|
* userId}. Includes test providers.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static List<CredentialProviderInfo> getCredentialProviderServicesForTesting(
|
||||||
|
@NonNull Context context,
|
||||||
|
int userId,
|
||||||
|
int providerFilter,
|
||||||
|
Set<ServiceInfo> enabledServices) {
|
||||||
|
requireNonNull(context, "context must not be null");
|
||||||
|
|
||||||
|
// Get the device policy.
|
||||||
|
PackagePolicy pp = getDeviceManagerPolicy(context, userId);
|
||||||
|
|
||||||
|
// Generate the provider list.
|
||||||
|
final boolean disableSystemAppVerificationForTests = true;
|
||||||
|
ProviderGenerator generator =
|
||||||
|
new ProviderGenerator(
|
||||||
|
context, pp, disableSystemAppVerificationForTests, providerFilter);
|
||||||
|
generator.addUserProviders(
|
||||||
|
getUserProviders(
|
||||||
|
context, userId, disableSystemAppVerificationForTests, enabledServices));
|
||||||
|
generator.addSystemProviders(
|
||||||
|
getAvailableSystemServices(
|
||||||
|
context, userId, disableSystemAppVerificationForTests, enabledServices));
|
||||||
return generator.getProviders();
|
return generator.getProviders();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +491,8 @@ public final class CredentialProviderInfo {
|
|||||||
private static List<CredentialProviderInfo> getUserProviders(
|
private static List<CredentialProviderInfo> getUserProviders(
|
||||||
@NonNull Context context,
|
@NonNull Context context,
|
||||||
@UserIdInt int userId,
|
@UserIdInt int userId,
|
||||||
boolean disableSystemAppVerificationForTests) {
|
boolean disableSystemAppVerificationForTests,
|
||||||
|
Set<ServiceInfo> enabledServices) {
|
||||||
final List<CredentialProviderInfo> services = new ArrayList<>();
|
final List<CredentialProviderInfo> services = new ArrayList<>();
|
||||||
final List<ResolveInfo> resolveInfos =
|
final List<ResolveInfo> resolveInfos =
|
||||||
context.getPackageManager()
|
context.getPackageManager()
|
||||||
@@ -496,11 +504,12 @@ public final class CredentialProviderInfo {
|
|||||||
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
|
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
|
||||||
try {
|
try {
|
||||||
CredentialProviderInfo cpi =
|
CredentialProviderInfo cpi =
|
||||||
new CredentialProviderInfo(
|
CredentialProviderInfoFactory.create(
|
||||||
context,
|
context,
|
||||||
serviceInfo,
|
serviceInfo,
|
||||||
/* isSystemProvider= */ false,
|
/* isSystemProvider= */ false,
|
||||||
disableSystemAppVerificationForTests);
|
disableSystemAppVerificationForTests,
|
||||||
|
enabledServices.contains(serviceInfo));
|
||||||
if (!cpi.isSystemProvider()) {
|
if (!cpi.isSystemProvider()) {
|
||||||
services.add(cpi);
|
services.add(cpi);
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.when;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.slice.Slice;
|
import android.app.slice.Slice;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.ServiceInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
@@ -47,6 +48,7 @@ import org.mockito.ArgumentCaptor;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -59,6 +61,17 @@ public class CredentialManagerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Activity mMockActivity;
|
private Activity mMockActivity;
|
||||||
|
|
||||||
|
private static final int TEST_USER_ID = 1;
|
||||||
|
private static final CredentialProviderInfo TEST_CREDENTIAL_PROVIDER_INFO =
|
||||||
|
new CredentialProviderInfo.Builder(new ServiceInfo())
|
||||||
|
.setSystemProvider(true)
|
||||||
|
.setOverrideLabel("test")
|
||||||
|
.addCapabilities(Arrays.asList("passkey"))
|
||||||
|
.setEnabled(true)
|
||||||
|
.build();
|
||||||
|
private static final List<CredentialProviderInfo> TEST_CREDENTIAL_PROVIDER_INFO_LIST =
|
||||||
|
Arrays.asList(TEST_CREDENTIAL_PROVIDER_INFO);
|
||||||
|
|
||||||
private GetCredentialRequest mGetRequest;
|
private GetCredentialRequest mGetRequest;
|
||||||
private CreateCredentialRequest mCreateRequest;
|
private CreateCredentialRequest mCreateRequest;
|
||||||
|
|
||||||
@@ -438,95 +451,53 @@ public class CredentialManagerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListEnabledProviders_nullExecutor() {
|
public void testGetCredentialProviderServices_allProviders() throws RemoteException {
|
||||||
assertThrows(NullPointerException.class,
|
verifyGetCredentialProviderServices(CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS);
|
||||||
() -> mCredentialManager.listEnabledProviders(null, null, result -> {
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListEnabledProviders_nullCallback() {
|
public void testGetCredentialProviderServices_userProviders() throws RemoteException {
|
||||||
assertThrows(NullPointerException.class,
|
verifyGetCredentialProviderServices(CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY);
|
||||||
() -> mCredentialManager.listEnabledProviders(null, mExecutor, null));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListEnabledProviders_alreadyCancelled() throws RemoteException {
|
public void testGetCredentialProviderServices_systemProviders() throws RemoteException {
|
||||||
final CancellationSignal cancellation = new CancellationSignal();
|
verifyGetCredentialProviderServices(CredentialManager.PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY);
|
||||||
cancellation.cancel();
|
|
||||||
|
|
||||||
mCredentialManager.listEnabledProviders(cancellation, mExecutor, result -> {
|
|
||||||
});
|
|
||||||
|
|
||||||
verify(mMockCredentialManagerService, never()).listEnabledProviders(any());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListEnabledProviders_cancel() throws RemoteException {
|
public void testGetCredentialProviderServicesForTesting_allProviders() throws RemoteException {
|
||||||
final ICancellationSignal serviceSignal = mock(ICancellationSignal.class);
|
verifyGetCredentialProviderServicesForTesting(CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS);
|
||||||
final CancellationSignal cancellation = new CancellationSignal();
|
|
||||||
|
|
||||||
OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> callback =
|
|
||||||
mock(OutcomeReceiver.class);
|
|
||||||
|
|
||||||
when(mMockCredentialManagerService.listEnabledProviders(any())).thenReturn(serviceSignal);
|
|
||||||
|
|
||||||
mCredentialManager.listEnabledProviders(cancellation, mExecutor, callback);
|
|
||||||
|
|
||||||
verify(mMockCredentialManagerService).listEnabledProviders(any());
|
|
||||||
|
|
||||||
cancellation.cancel();
|
|
||||||
verify(serviceSignal).cancel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListEnabledProviders_failed() throws RemoteException {
|
public void testGetCredentialProviderServicesForTesting_userProviders() throws RemoteException {
|
||||||
ArgumentCaptor<IListEnabledProvidersCallback> callbackCaptor = ArgumentCaptor.forClass(
|
verifyGetCredentialProviderServicesForTesting(CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY);
|
||||||
IListEnabledProvidersCallback.class);
|
|
||||||
ArgumentCaptor<ListEnabledProvidersException> errorCaptor = ArgumentCaptor.forClass(
|
|
||||||
ListEnabledProvidersException.class);
|
|
||||||
|
|
||||||
OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> callback =
|
|
||||||
mock(OutcomeReceiver.class);
|
|
||||||
|
|
||||||
when(mMockCredentialManagerService.listEnabledProviders(
|
|
||||||
callbackCaptor.capture())).thenReturn(mock(ICancellationSignal.class));
|
|
||||||
mCredentialManager.listEnabledProviders(null, mExecutor, callback);
|
|
||||||
verify(mMockCredentialManagerService).listEnabledProviders(any());
|
|
||||||
|
|
||||||
final String errorType = "type";
|
|
||||||
callbackCaptor.getValue().onError("type", "unknown error");
|
|
||||||
verify(callback).onError(errorCaptor.capture());
|
|
||||||
|
|
||||||
assertThat(errorCaptor.getValue().getType()).isEqualTo(errorType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListEnabledProviders_success() throws RemoteException {
|
public void testGetCredentialProviderServicesForTesting_systemProviders() throws RemoteException {
|
||||||
ListEnabledProvidersResponse response = ListEnabledProvidersResponse.create(
|
verifyGetCredentialProviderServicesForTesting(CredentialManager.PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY);
|
||||||
List.of("foo", "bar", "baz"));
|
}
|
||||||
|
|
||||||
OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException> callback =
|
private void verifyGetCredentialProviderServices(int testFilter) throws RemoteException {
|
||||||
mock(OutcomeReceiver.class);
|
when(mMockCredentialManagerService.getCredentialProviderServices(
|
||||||
|
TEST_USER_ID, testFilter)).thenReturn(TEST_CREDENTIAL_PROVIDER_INFO_LIST);
|
||||||
|
|
||||||
ArgumentCaptor<IListEnabledProvidersCallback> callbackCaptor = ArgumentCaptor.forClass(
|
List<CredentialProviderInfo> output =
|
||||||
IListEnabledProvidersCallback.class);
|
mCredentialManager.getCredentialProviderServices(TEST_USER_ID, testFilter);
|
||||||
ArgumentCaptor<ListEnabledProvidersResponse> responseCaptor = ArgumentCaptor.forClass(
|
|
||||||
ListEnabledProvidersResponse.class);
|
|
||||||
|
|
||||||
when(mMockCredentialManagerService.listEnabledProviders(
|
assertThat(output).containsExactlyElementsIn(TEST_CREDENTIAL_PROVIDER_INFO_LIST);
|
||||||
callbackCaptor.capture())).thenReturn(mock(ICancellationSignal.class));
|
}
|
||||||
mCredentialManager.listEnabledProviders(null, mExecutor, callback);
|
|
||||||
|
|
||||||
verify(mMockCredentialManagerService).listEnabledProviders(any());
|
private void verifyGetCredentialProviderServicesForTesting(int testFilter) throws RemoteException {
|
||||||
|
when(mMockCredentialManagerService.getCredentialProviderServicesForTesting(
|
||||||
|
testFilter)).thenReturn(TEST_CREDENTIAL_PROVIDER_INFO_LIST);
|
||||||
|
|
||||||
callbackCaptor.getValue().onResponse(response);
|
List<CredentialProviderInfo> output =
|
||||||
|
mCredentialManager.getCredentialProviderServicesForTesting(testFilter);
|
||||||
|
|
||||||
verify(callback).onResult(responseCaptor.capture());
|
assertThat(output).containsExactlyElementsIn(TEST_CREDENTIAL_PROVIDER_INFO_LIST);
|
||||||
assertThat(responseCaptor.getValue().getProviderComponentNames()).containsExactlyElementsIn(
|
|
||||||
response.getProviderComponentNames());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import android.annotation.Nullable;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.credentials.ClearCredentialStateRequest;
|
import android.credentials.ClearCredentialStateRequest;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.IClearCredentialStateCallback;
|
import android.credentials.IClearCredentialStateCallback;
|
||||||
import android.credentials.ui.ProviderData;
|
import android.credentials.ui.ProviderData;
|
||||||
import android.credentials.ui.RequestInfo;
|
import android.credentials.ui.RequestInfo;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.service.credentials.CallingAppInfo;
|
import android.service.credentials.CallingAppInfo;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.server.credentials.metrics.ApiName;
|
import com.android.server.credentials.metrics.ApiName;
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ import android.credentials.CreateCredentialException;
|
|||||||
import android.credentials.CreateCredentialRequest;
|
import android.credentials.CreateCredentialRequest;
|
||||||
import android.credentials.CreateCredentialResponse;
|
import android.credentials.CreateCredentialResponse;
|
||||||
import android.credentials.CredentialManager;
|
import android.credentials.CredentialManager;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.ICreateCredentialCallback;
|
import android.credentials.ICreateCredentialCallback;
|
||||||
import android.credentials.ui.ProviderData;
|
import android.credentials.ui.ProviderData;
|
||||||
import android.credentials.ui.RequestInfo;
|
import android.credentials.ui.RequestInfo;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.service.credentials.CallingAppInfo;
|
import android.service.credentials.CallingAppInfo;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.server.credentials.metrics.ApiName;
|
import com.android.server.credentials.metrics.ApiName;
|
||||||
|
|||||||
@@ -36,15 +36,14 @@ import android.credentials.CreateCredentialRequest;
|
|||||||
import android.credentials.CredentialDescription;
|
import android.credentials.CredentialDescription;
|
||||||
import android.credentials.CredentialManager;
|
import android.credentials.CredentialManager;
|
||||||
import android.credentials.CredentialOption;
|
import android.credentials.CredentialOption;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.GetCredentialException;
|
import android.credentials.GetCredentialException;
|
||||||
import android.credentials.GetCredentialRequest;
|
import android.credentials.GetCredentialRequest;
|
||||||
import android.credentials.IClearCredentialStateCallback;
|
import android.credentials.IClearCredentialStateCallback;
|
||||||
import android.credentials.ICreateCredentialCallback;
|
import android.credentials.ICreateCredentialCallback;
|
||||||
import android.credentials.ICredentialManager;
|
import android.credentials.ICredentialManager;
|
||||||
import android.credentials.IGetCredentialCallback;
|
import android.credentials.IGetCredentialCallback;
|
||||||
import android.credentials.IListEnabledProvidersCallback;
|
|
||||||
import android.credentials.ISetEnabledProvidersCallback;
|
import android.credentials.ISetEnabledProvidersCallback;
|
||||||
import android.credentials.ListEnabledProvidersResponse;
|
|
||||||
import android.credentials.RegisterCredentialDescriptionRequest;
|
import android.credentials.RegisterCredentialDescriptionRequest;
|
||||||
import android.credentials.UnregisterCredentialDescriptionRequest;
|
import android.credentials.UnregisterCredentialDescriptionRequest;
|
||||||
import android.credentials.ui.IntentFactory;
|
import android.credentials.ui.IntentFactory;
|
||||||
@@ -56,7 +55,7 @@ import android.os.UserHandle;
|
|||||||
import android.provider.DeviceConfig;
|
import android.provider.DeviceConfig;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.service.credentials.CallingAppInfo;
|
import android.service.credentials.CallingAppInfo;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
import android.service.credentials.CredentialProviderInfoFactory;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
@@ -118,10 +117,11 @@ public final class CredentialManagerService
|
|||||||
int resolvedUserId) {
|
int resolvedUserId) {
|
||||||
List<CredentialManagerServiceImpl> services = new ArrayList<>();
|
List<CredentialManagerServiceImpl> services = new ArrayList<>();
|
||||||
List<CredentialProviderInfo> serviceInfos =
|
List<CredentialProviderInfo> serviceInfos =
|
||||||
CredentialProviderInfo.getAvailableSystemServices(
|
CredentialProviderInfoFactory.getAvailableSystemServices(
|
||||||
mContext,
|
mContext,
|
||||||
resolvedUserId,
|
resolvedUserId,
|
||||||
/* disableSystemAppVerificationForTests= */ false);
|
/* disableSystemAppVerificationForTests= */ false,
|
||||||
|
new HashSet<>());
|
||||||
serviceInfos.forEach(
|
serviceInfos.forEach(
|
||||||
info -> {
|
info -> {
|
||||||
services.add(
|
services.add(
|
||||||
@@ -222,10 +222,16 @@ public final class CredentialManagerService
|
|||||||
return hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS);
|
return hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyPermission(String permission) throws SecurityException {
|
private void verifyGetProvidersPermission() throws SecurityException {
|
||||||
if (!hasPermission(permission)) {
|
if (hasPermission(android.Manifest.permission.QUERY_ALL_PACKAGES)) {
|
||||||
throw new SecurityException("Caller is missing permission: " + permission);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SecurityException("Caller is missing permission: QUERY_ALL_PACKAGES or LIST_ENABLED_CREDENTIAL_PROVIDERS");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasPermission(String permission) {
|
private boolean hasPermission(String permission) {
|
||||||
@@ -550,40 +556,6 @@ public final class CredentialManagerService
|
|||||||
providerSessions.forEach(ProviderSession::invokeSession);
|
providerSessions.forEach(ProviderSession::invokeSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("GuardedBy") // ErrorProne requires listEnabledProviders
|
|
||||||
// to be guarded by 'service.mLock', which is the same as mLock.
|
|
||||||
@Override
|
|
||||||
public ICancellationSignal listEnabledProviders(IListEnabledProvidersCallback callback) {
|
|
||||||
Log.i(TAG, "listEnabledProviders");
|
|
||||||
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
|
|
||||||
|
|
||||||
if (!hasWriteSecureSettingsPermission()) {
|
|
||||||
try {
|
|
||||||
callback.onError(
|
|
||||||
PERMISSION_DENIED_ERROR, PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Issue with invoking response: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return cancelTransport;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> enabledProviders = new ArrayList<>();
|
|
||||||
runForUser(
|
|
||||||
(service) -> {
|
|
||||||
enabledProviders.add(service.getComponentName().flattenToString());
|
|
||||||
});
|
|
||||||
|
|
||||||
// Call the callback.
|
|
||||||
try {
|
|
||||||
callback.onResponse(ListEnabledProvidersResponse.create(enabledProviders));
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.i(TAG, "Issue with invoking response: " + e.getMessage());
|
|
||||||
// TODO: Propagate failure
|
|
||||||
}
|
|
||||||
|
|
||||||
return cancelTransport;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabledProviders(
|
public void setEnabledProviders(
|
||||||
List<String> providers, int userId, ISetEnabledProvidersCallback callback) {
|
List<String> providers, int userId, ISetEnabledProvidersCallback callback) {
|
||||||
@@ -677,20 +649,35 @@ public final class CredentialManagerService
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ServiceInfo> getCredentialProviderServices(
|
public List<CredentialProviderInfo> getCredentialProviderServices(
|
||||||
int userId, boolean disableSystemAppVerificationForTests, int providerFilter) {
|
int userId, int providerFilter) {
|
||||||
Log.i(TAG, "getCredentialProviderServices");
|
Log.i(TAG, "getCredentialProviderServices");
|
||||||
verifyPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS);
|
verifyGetProvidersPermission();
|
||||||
|
|
||||||
List<ServiceInfo> services = new ArrayList<>();
|
return CredentialProviderInfoFactory.getCredentialProviderServices(
|
||||||
List<CredentialProviderInfo> providers =
|
mContext, userId, providerFilter, getEnabledProviders());
|
||||||
CredentialProviderInfo.getCredentialProviderServices(
|
}
|
||||||
mContext, userId, disableSystemAppVerificationForTests, providerFilter);
|
|
||||||
for (CredentialProviderInfo p : providers) {
|
@Override
|
||||||
services.add(p.getServiceInfo());
|
public List<CredentialProviderInfo> getCredentialProviderServicesForTesting(
|
||||||
|
int providerFilter) {
|
||||||
|
Log.i(TAG, "getCredentialProviderServicesForTesting");
|
||||||
|
verifyGetProvidersPermission();
|
||||||
|
|
||||||
|
final int userId = UserHandle.getCallingUserId();
|
||||||
|
return CredentialProviderInfoFactory.getCredentialProviderServicesForTesting(
|
||||||
|
mContext, userId, providerFilter, getEnabledProviders());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<ServiceInfo> getEnabledProviders() {
|
||||||
|
Set<ServiceInfo> enabledProviders = new HashSet<>();
|
||||||
|
synchronized (mLock) {
|
||||||
|
runForUser(
|
||||||
|
(service) -> {
|
||||||
|
enabledProviders.add(service.getCredentialProviderInfo().getServiceInfo());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
return enabledProviders;
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -828,11 +815,11 @@ public final class CredentialManagerService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<CredentialProviderInfo> getServicesForCredentialDescription(int userId) {
|
private List<CredentialProviderInfo> getServicesForCredentialDescription(int userId) {
|
||||||
return CredentialProviderInfo.getCredentialProviderServices(
|
return CredentialProviderInfoFactory.getCredentialProviderServices(
|
||||||
mContext,
|
mContext,
|
||||||
userId,
|
userId,
|
||||||
/* disableSystemAppVerificationForTests= */ false,
|
CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS,
|
||||||
CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS);
|
new HashSet<>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ import android.annotation.Nullable;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
import android.credentials.CredentialProviderInfo;
|
||||||
|
import android.service.credentials.CredentialProviderInfoFactory;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
@@ -82,7 +83,7 @@ public final class CredentialManagerServiceImpl extends
|
|||||||
Log.i(TAG, "newServiceInfoLocked with null mInfo , "
|
Log.i(TAG, "newServiceInfoLocked with null mInfo , "
|
||||||
+ serviceComponent.getPackageName());
|
+ serviceComponent.getPackageName());
|
||||||
}
|
}
|
||||||
mInfo = new CredentialProviderInfo(
|
mInfo = CredentialProviderInfoFactory.create(
|
||||||
getContext(), serviceComponent,
|
getContext(), serviceComponent,
|
||||||
mUserId, /*isSystemProvider=*/false);
|
mUserId, /*isSystemProvider=*/false);
|
||||||
return mInfo.getServiceInfo();
|
return mInfo.getServiceInfo();
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.credentials.CredentialManager;
|
import android.credentials.CredentialManager;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.ui.DisabledProviderData;
|
import android.credentials.ui.DisabledProviderData;
|
||||||
import android.credentials.ui.IntentFactory;
|
import android.credentials.ui.IntentFactory;
|
||||||
import android.credentials.ui.ProviderData;
|
import android.credentials.ui.ProviderData;
|
||||||
@@ -31,11 +32,12 @@ import android.os.Bundle;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
import android.service.credentials.CredentialProviderInfoFactory;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -118,11 +120,11 @@ public class CredentialManagerUi {
|
|||||||
.map(ProviderData::getProviderFlattenedComponentName)
|
.map(ProviderData::getProviderFlattenedComponentName)
|
||||||
.collect(Collectors.toUnmodifiableSet());
|
.collect(Collectors.toUnmodifiableSet());
|
||||||
Set<String> allProviders =
|
Set<String> allProviders =
|
||||||
CredentialProviderInfo.getCredentialProviderServices(
|
CredentialProviderInfoFactory.getCredentialProviderServices(
|
||||||
mContext,
|
mContext,
|
||||||
mUserId,
|
mUserId,
|
||||||
/* disableSystemAppVerificationForTests= */ false,
|
CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY,
|
||||||
CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY)
|
new HashSet<>())
|
||||||
.stream()
|
.stream()
|
||||||
.map(CredentialProviderInfo::getServiceInfo)
|
.map(CredentialProviderInfo::getServiceInfo)
|
||||||
.map(ServiceInfo::getComponentName)
|
.map(ServiceInfo::getComponentName)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import static com.android.server.credentials.MetricUtilities.METRICS_PROVIDER_ST
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.GetCredentialException;
|
import android.credentials.GetCredentialException;
|
||||||
import android.credentials.GetCredentialRequest;
|
import android.credentials.GetCredentialRequest;
|
||||||
import android.credentials.GetCredentialResponse;
|
import android.credentials.GetCredentialResponse;
|
||||||
@@ -31,7 +32,6 @@ import android.credentials.ui.RequestInfo;
|
|||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.service.credentials.CallingAppInfo;
|
import android.service.credentials.CallingAppInfo;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.server.credentials.metrics.ApiName;
|
import com.android.server.credentials.metrics.ApiName;
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ import android.annotation.Nullable;
|
|||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.credentials.ClearCredentialStateException;
|
import android.credentials.ClearCredentialStateException;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.ui.ProviderData;
|
import android.credentials.ui.ProviderData;
|
||||||
import android.credentials.ui.ProviderPendingIntentResponse;
|
import android.credentials.ui.ProviderPendingIntentResponse;
|
||||||
import android.service.credentials.CallingAppInfo;
|
import android.service.credentials.CallingAppInfo;
|
||||||
import android.service.credentials.ClearCredentialStateRequest;
|
import android.service.credentials.ClearCredentialStateRequest;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.credentials.CreateCredentialException;
|
import android.credentials.CreateCredentialException;
|
||||||
import android.credentials.CreateCredentialResponse;
|
import android.credentials.CreateCredentialResponse;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.ui.CreateCredentialProviderData;
|
import android.credentials.ui.CreateCredentialProviderData;
|
||||||
import android.credentials.ui.Entry;
|
import android.credentials.ui.Entry;
|
||||||
import android.credentials.ui.ProviderPendingIntentResponse;
|
import android.credentials.ui.ProviderPendingIntentResponse;
|
||||||
@@ -33,7 +34,6 @@ import android.service.credentials.BeginCreateCredentialResponse;
|
|||||||
import android.service.credentials.CallingAppInfo;
|
import android.service.credentials.CallingAppInfo;
|
||||||
import android.service.credentials.CreateCredentialRequest;
|
import android.service.credentials.CreateCredentialRequest;
|
||||||
import android.service.credentials.CreateEntry;
|
import android.service.credentials.CreateEntry;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
|
||||||
import android.service.credentials.CredentialProviderService;
|
import android.service.credentials.CredentialProviderService;
|
||||||
import android.service.credentials.RemoteEntry;
|
import android.service.credentials.RemoteEntry;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.credentials.CredentialOption;
|
import android.credentials.CredentialOption;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.GetCredentialException;
|
import android.credentials.GetCredentialException;
|
||||||
import android.credentials.GetCredentialResponse;
|
import android.credentials.GetCredentialResponse;
|
||||||
import android.credentials.ui.AuthenticationEntry;
|
import android.credentials.ui.AuthenticationEntry;
|
||||||
@@ -35,7 +36,6 @@ import android.service.credentials.BeginGetCredentialRequest;
|
|||||||
import android.service.credentials.BeginGetCredentialResponse;
|
import android.service.credentials.BeginGetCredentialResponse;
|
||||||
import android.service.credentials.CallingAppInfo;
|
import android.service.credentials.CallingAppInfo;
|
||||||
import android.service.credentials.CredentialEntry;
|
import android.service.credentials.CredentialEntry;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
|
||||||
import android.service.credentials.CredentialProviderService;
|
import android.service.credentials.CredentialProviderService;
|
||||||
import android.service.credentials.GetCredentialRequest;
|
import android.service.credentials.GetCredentialRequest;
|
||||||
import android.service.credentials.RemoteEntry;
|
import android.service.credentials.RemoteEntry;
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ import android.annotation.Nullable;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.credentials.Credential;
|
import android.credentials.Credential;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.ui.ProviderData;
|
import android.credentials.ui.ProviderData;
|
||||||
import android.credentials.ui.ProviderPendingIntentResponse;
|
import android.credentials.ui.ProviderPendingIntentResponse;
|
||||||
import android.os.ICancellationSignal;
|
import android.os.ICancellationSignal;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.server.credentials.metrics.CandidateProviderMetric;
|
import com.android.server.credentials.metrics.CandidateProviderMetric;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.credentials.CredentialProviderInfo;
|
||||||
import android.credentials.ui.ProviderData;
|
import android.credentials.ui.ProviderData;
|
||||||
import android.credentials.ui.UserSelectionDialogResult;
|
import android.credentials.ui.UserSelectionDialogResult;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
@@ -30,7 +31,6 @@ import android.os.Handler;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.service.credentials.CallingAppInfo;
|
import android.service.credentials.CallingAppInfo;
|
||||||
import android.service.credentials.CredentialProviderInfo;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
|
|||||||
Reference in New Issue
Block a user