summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Reema Bajwa <reemabajwa@google.com> 2025-02-18 10:17:57 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-02-18 10:17:57 -0800
commit768289ae3e764c607afcec88676d99f393b62260 (patch)
treea683bc4b2850a0d70c3db5a1907d48e64d873bf6
parente9fca3411bf577b1e37cccdfe2f9e84acd603717 (diff)
parentcfb472975def54d14b692645ddf65d409ebbbd1e (diff)
Merge "Valiate credential provider setup on package" into main
-rw-r--r--core/java/android/service/credentials/CredentialProviderInfoFactory.java6
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java69
2 files changed, 65 insertions, 10 deletions
diff --git a/core/java/android/service/credentials/CredentialProviderInfoFactory.java b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
index 3cd705a3c19c..2266e961852a 100644
--- a/core/java/android/service/credentials/CredentialProviderInfoFactory.java
+++ b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
@@ -88,7 +88,7 @@ public final class CredentialProviderInfoFactory {
int userId,
boolean isSystemProvider,
boolean isPrimary)
- throws PackageManager.NameNotFoundException {
+ throws PackageManager.NameNotFoundException, SecurityException, NullPointerException {
return create(
context,
getServiceInfoOrThrow(serviceComponent, userId),
@@ -117,7 +117,7 @@ public final class CredentialProviderInfoFactory {
boolean disableSystemAppVerificationForTests,
boolean isEnabled,
boolean isPrimary)
- throws SecurityException {
+ throws SecurityException, NullPointerException {
verifyProviderPermission(serviceInfo);
if (isSystemProvider) {
if (!isValidSystemProvider(
@@ -199,7 +199,7 @@ public final class CredentialProviderInfoFactory {
}
private static CredentialProviderInfo.Builder populateMetadata(
- @NonNull Context context, ServiceInfo serviceInfo) {
+ @NonNull Context context, ServiceInfo serviceInfo) throws NullPointerException {
requireNonNull(context, "context must not be null");
final PackageManager pm = context.getPackageManager();
CredentialProviderInfo.Builder builder = new CredentialProviderInfo.Builder(serviceInfo);
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
index 40554ac51b24..7edf646a48f6 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
@@ -21,11 +21,16 @@ import static com.android.server.credentials.CredentialManagerService.getPrimary
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.credentials.CredentialManager;
import android.credentials.CredentialProviderInfo;
+import android.credentials.flags.Flags;
import android.service.credentials.CredentialProviderInfoFactory;
+import android.service.credentials.CredentialProviderService;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -78,14 +83,16 @@ public final class CredentialManagerServiceImpl extends
mInfo = providerInfo;
}
- @Override // from PerUserSystemService when a new setting based service is to be created
+ @Override // from PerUserSystemService when a new service is to be created
@GuardedBy("mLock")
protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
- throws PackageManager.NameNotFoundException {
+ throws PackageManager.NameNotFoundException, SecurityException, NullPointerException {
+ boolean isSystemProvider = false;
if (mInfo != null) {
Slog.i(TAG, "newServiceInfoLocked, mInfo not null : "
+ mInfo.getServiceInfo().getComponentName().flattenToString() + " , "
+ serviceComponent.flattenToString());
+ isSystemProvider = mInfo.isSystemProvider();
} else {
Slog.i(TAG, "newServiceInfoLocked, mInfo null, "
+ serviceComponent.flattenToString());
@@ -94,7 +101,7 @@ public final class CredentialManagerServiceImpl extends
getPrimaryProvidersForUserId(mMaster.getContext(), mUserId);
mInfo = CredentialProviderInfoFactory.create(
getContext(), serviceComponent,
- mUserId, /*isSystemProvider=*/false,
+ mUserId, isSystemProvider,
primaryProviders.contains(serviceComponent));
return mInfo.getServiceInfo();
}
@@ -148,15 +155,63 @@ public final class CredentialManagerServiceImpl extends
* @param packageName package of the app being updated.
*/
@GuardedBy("mLock")
+ @SuppressWarnings("GuardedBy") // ErrorProne requires this.mMaster.mLock which is the case
+ // because this method is called by this.mMaster anyway
protected void handlePackageUpdateLocked(@NonNull String packageName) {
if (mInfo != null && mInfo.getServiceInfo() != null
&& mInfo.getServiceInfo().getComponentName()
.getPackageName().equals(packageName)) {
- try {
- newServiceInfoLocked(mInfo.getServiceInfo().getComponentName());
- } catch (PackageManager.NameNotFoundException e) {
- Slog.e(TAG, "Issue while updating serviceInfo: " + e.getMessage());
+ if (Flags.packageUpdateFixEnabled()) {
+ try {
+ updateCredentialProviderInfo(mInfo.getServiceInfo().getComponentName(),
+ mInfo.isSystemProvider());
+ } catch (SecurityException | PackageManager.NameNotFoundException
+ | NullPointerException e) {
+ Slog.w(TAG, "Unable to update provider, must be removed: " + e.getMessage());
+ mMaster.handleServiceRemovedMultiModeLocked(mInfo.getComponentName(), mUserId);
+ }
+ } else {
+ try {
+ newServiceInfoLocked(mInfo.getServiceInfo().getComponentName());
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "Issue while updating serviceInfo: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void updateCredentialProviderInfo(ComponentName componentName, boolean isSystemProvider)
+ throws SecurityException, PackageManager.NameNotFoundException {
+ Slog.d(TAG, "Updating credential provider: " + componentName.flattenToString());
+ if (!isValidCredentialProviderInfo(componentName, mUserId, isSystemProvider)) {
+ throw new SecurityException("Service has not been set up correctly");
+ }
+ newServiceInfoLocked(componentName);
+ }
+
+ private boolean isValidCredentialProviderInfo(ComponentName componentName, int userId,
+ boolean isSystemProvider) {
+ Context context = getContext();
+ if (context == null) {
+ return false;
+ }
+ String serviceInterface = CredentialProviderService.SERVICE_INTERFACE;
+ if (isSystemProvider) {
+ serviceInterface = CredentialProviderService.SYSTEM_SERVICE_INTERFACE;
+ }
+ final List<ResolveInfo> resolveInfos =
+ context.getPackageManager()
+ .queryIntentServicesAsUser(
+ new Intent(serviceInterface),
+ PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA),
+ userId);
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ if (serviceInfo.getComponentName().equals(componentName)) {
+ return true;
}
}
+ return false;
}
}