Merge "[Mainline] Copy the findBestComponent method from EuiccConnector to Settings"

This commit is contained in:
Betty Chang
2020-01-17 03:27:32 +00:00
committed by Android (Google) Code Review
2 changed files with 105 additions and 35 deletions

View File

@@ -16,24 +16,30 @@
package com.android.settings.applications;
import android.Manifest;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.location.LocationManager;
import android.os.RemoteException;
import android.os.UserManager;
import android.service.euicc.EuiccService;
import android.telecom.DefaultDialerManager;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.internal.telephony.SmsApplication;
import com.android.internal.telephony.euicc.EuiccConnector;
import com.android.settings.R;
import java.util.ArrayList;
@@ -41,12 +47,17 @@ import java.util.List;
import java.util.Set;
public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvider {
private static final String TAG = "AppFeatureProviderImpl";
protected final Context mContext;
private final PackageManager mPm;
private final IPackageManager mPms;
private final DevicePolicyManager mDpm;
private final UserManager mUm;
/** Flags to use when querying PackageManager for Euicc component implementations. */
private static final int EUICC_QUERY_FLAGS =
PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
| PackageManager.GET_RESOLVED_FILTER;
public ApplicationFeatureProviderImpl(Context context, PackageManager pm,
IPackageManager pms, DevicePolicyManager dpm) {
@@ -143,7 +154,7 @@ public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvide
}
// Keep Euicc Service enabled.
final ComponentInfo euicc = EuiccConnector.findBestComponent(mPm);
final ComponentInfo euicc = findEuiccService(mPm);
if (euicc != null) {
keepEnabledPackages.add(euicc.packageName);
}
@@ -239,4 +250,89 @@ public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvide
mCallback.onListOfAppsResult(list);
}
}
/**
* Return the component info of the EuiccService to bind to, or null if none were found.
*/
@VisibleForTesting
ComponentInfo findEuiccService(PackageManager packageManager) {
final Intent intent = new Intent(EuiccService.EUICC_SERVICE_INTERFACE);
final List<ResolveInfo> resolveInfoList =
packageManager.queryIntentServices(intent, EUICC_QUERY_FLAGS);
final ComponentInfo bestComponent = findEuiccService(packageManager, resolveInfoList);
if (bestComponent == null) {
Log.w(TAG, "No valid EuiccService implementation found");
}
return bestComponent;
}
private ComponentInfo findEuiccService(
PackageManager packageManager, List<ResolveInfo> resolveInfoList) {
int bestPriority = Integer.MIN_VALUE;
ComponentInfo bestComponent = null;
if (resolveInfoList != null) {
for (ResolveInfo resolveInfo : resolveInfoList) {
if (!isValidEuiccComponent(packageManager, resolveInfo)) {
continue;
}
if (resolveInfo.filter.getPriority() > bestPriority) {
bestPriority = resolveInfo.filter.getPriority();
bestComponent = getComponentInfo(resolveInfo);
}
}
}
return bestComponent;
}
private boolean isValidEuiccComponent(
PackageManager packageManager, ResolveInfo resolveInfo) {
final ComponentInfo componentInfo = getComponentInfo(resolveInfo);
final String packageName = componentInfo.packageName;
// Verify that the app is privileged (via granting of a privileged permission).
if (packageManager.checkPermission(
Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS, packageName)
!= PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "Package " + packageName
+ " does not declare WRITE_EMBEDDED_SUBSCRIPTIONS");
return false;
}
// Verify that only the system can access the component.
final String permission;
if (componentInfo instanceof ServiceInfo) {
permission = ((ServiceInfo) componentInfo).permission;
} else if (componentInfo instanceof ActivityInfo) {
permission = ((ActivityInfo) componentInfo).permission;
} else {
throw new IllegalArgumentException("Can only verify services/activities");
}
if (!TextUtils.equals(permission, Manifest.permission.BIND_EUICC_SERVICE)) {
Log.e(TAG, "Package " + packageName
+ " does not require the BIND_EUICC_SERVICE permission");
return false;
}
// Verify that the component declares a priority.
if (resolveInfo.filter == null || resolveInfo.filter.getPriority() == 0) {
Log.e(TAG, "Package " + packageName + " does not specify a priority");
return false;
}
return true;
}
private ComponentInfo getComponentInfo(ResolveInfo resolveInfo) {
if (resolveInfo.activityInfo != null) {
return resolveInfo.activityInfo;
}
if (resolveInfo.serviceInfo != null) {
return resolveInfo.serviceInfo;
}
if (resolveInfo.providerInfo != null) {
return resolveInfo.providerInfo;
}
throw new IllegalStateException("Missing ComponentInfo!");
}
}