Fetch package info from package manager in CarWatchdogService.
Test: Tested with unit-tests
Bug: 170741935
Change-Id: If1bf8c846a176e426700634e4dc635ed450c385c
Merged-In: If1bf8c846a176e426700634e4dc635ed450c385c
(cherry picked from commit 7ab98c31fad70c1bf14cfbaec5e204840d187145)
diff --git a/service/src/com/android/car/watchdog/CarWatchdogService.java b/service/src/com/android/car/watchdog/CarWatchdogService.java
index c8ab2f5..a07331e 100644
--- a/service/src/com/android/car/watchdog/CarWatchdogService.java
+++ b/service/src/com/android/car/watchdog/CarWatchdogService.java
@@ -27,10 +27,14 @@
import android.annotation.NonNull;
import android.annotation.UserIdInt;
+import android.automotive.watchdog.internal.ApplicationCategoryType;
+import android.automotive.watchdog.internal.ComponentType;
import android.automotive.watchdog.internal.ICarWatchdogServiceForSystem;
+import android.automotive.watchdog.internal.PackageIdentifier;
import android.automotive.watchdog.internal.PackageInfo;
import android.automotive.watchdog.internal.PowerCycle;
import android.automotive.watchdog.internal.StateType;
+import android.automotive.watchdog.internal.UidType;
import android.automotive.watchdog.internal.UserState;
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
import android.car.hardware.power.ICarPowerStateListener;
@@ -38,11 +42,14 @@
import android.car.watchdog.ICarWatchdogServiceCallback;
import android.car.watchdoglib.CarWatchdogDaemonHelper;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -57,9 +64,11 @@
import com.android.car.user.CarUserService;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -85,6 +94,7 @@
registerToDaemon();
}
};
+ private final PackageManager mPackageManager;
private final Object mLock = new Object();
/*
* Keeps the list of car watchdog client according to timeout:
@@ -117,6 +127,7 @@
@VisibleForTesting
public CarWatchdogService(Context context) {
mContext = context;
+ mPackageManager = mContext.getPackageManager();
mCarWatchdogDaemonHelper = new CarWatchdogDaemonHelper(TAG_WATCHDOG);
mWatchdogServiceForSystem = new ICarWatchdogServiceForSystemImpl(this);
}
@@ -558,6 +569,107 @@
}
}
+ private List<PackageInfo> getPackageInfosForUids(
+ int[] uids, List<String> vendorPackagePrefixes) {
+ ArrayList<PackageInfo> packageInfos = new ArrayList<>();
+ String[] packageNames = mPackageManager.getNamesForUids(uids);
+ if (ArrayUtils.isEmpty(packageNames)) {
+ return packageInfos;
+ }
+ for (int i = 0; i < uids.length; i++) {
+ if (packageNames[i].isEmpty()) {
+ continue;
+ }
+ packageInfos.add(getPackageInfo(uids[i], packageNames[i], vendorPackagePrefixes));
+ }
+ return packageInfos;
+ }
+
+ private PackageInfo getPackageInfo(
+ int uid, String packageName, List<String> vendorPackagePrefixes) {
+ PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageIdentifier = new PackageIdentifier();
+ packageInfo.packageIdentifier.uid = uid;
+ packageInfo.packageIdentifier.name = packageName;
+ packageInfo.sharedUidPackages = new ArrayList<>();
+ packageInfo.componentType = ComponentType.UNKNOWN;
+ // TODO(b/170741935): Identify application category type using the package names. Vendor
+ // should define the mappings from package name to the application category type.
+ packageInfo.appCategoryType = ApplicationCategoryType.OTHERS;
+ int userId = UserHandle.getUserId(uid);
+ int appId = UserHandle.getAppId(uid);
+ if (appId >= Process.FIRST_APPLICATION_UID) {
+ packageInfo.uidType = UidType.APPLICATION;
+ } else {
+ packageInfo.uidType = UidType.NATIVE;
+ }
+
+ if (packageName.startsWith("shared:")) {
+ String[] sharedUidPackages = mPackageManager.getPackagesForUid(uid);
+ if (sharedUidPackages == null) {
+ return packageInfo;
+ }
+ boolean seenVendor = false;
+ boolean seenSystem = false;
+ boolean seenThirdParty = false;
+ for (String ownedPackage : sharedUidPackages) {
+ int componentType = getPackageComponentType(
+ userId, ownedPackage, vendorPackagePrefixes);
+ switch(componentType) {
+ case ComponentType.VENDOR:
+ seenVendor = true;
+ break;
+ case ComponentType.SYSTEM:
+ seenSystem = true;
+ break;
+ case ComponentType.THIRD_PARTY:
+ seenThirdParty = true;
+ }
+ }
+ packageInfo.sharedUidPackages = Arrays.asList(sharedUidPackages);
+ if (seenVendor) {
+ packageInfo.componentType = ComponentType.VENDOR;
+ } else if (seenSystem) {
+ packageInfo.componentType = ComponentType.SYSTEM;
+ } else if (seenThirdParty) {
+ packageInfo.componentType = ComponentType.THIRD_PARTY;
+ }
+ } else {
+ packageInfo.componentType = getPackageComponentType(
+ userId, packageName, vendorPackagePrefixes);
+ }
+ return packageInfo;
+ }
+
+ private int getPackageComponentType(
+ int userId, String packageName, List<String> vendorPackagePrefixes) {
+ for (String prefix : vendorPackagePrefixes) {
+ if (packageName.startsWith(prefix)) {
+ return ComponentType.VENDOR;
+ }
+ }
+ try {
+ final ApplicationInfo info = mPackageManager.getApplicationInfoAsUser(packageName,
+ 0 /* flags */, userId);
+ if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0
+ || (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
+ || (info.flags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0
+ || (info.flags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0
+ || (info.flags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
+ return ComponentType.SYSTEM;
+ }
+
+ if ((info.flags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0
+ || (info.flags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
+ return ComponentType.VENDOR;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "Package not found: " + packageName, e);
+ return ComponentType.UNKNOWN;
+ }
+ return ComponentType.THIRD_PARTY;
+ }
+
private static final class ICarWatchdogServiceForSystemImpl
extends ICarWatchdogServiceForSystem.Stub {
private final WeakReference<CarWatchdogService> mService;
@@ -582,9 +694,18 @@
}
@Override
- public List<PackageInfo> getPackageInfosForUids(int[] uids, List<String> prefixes) {
- // TODO(b/170741935): Resolve package names for the given UIDs using package manager.
- return null;
+ public List<PackageInfo> getPackageInfosForUids(
+ int[] uids, List<String> vendorPackagePrefixes) {
+ if (ArrayUtils.isEmpty(uids)) {
+ Slog.w(TAG, "UID list is empty");
+ return null;
+ }
+ CarWatchdogService service = mService.get();
+ if (service == null) {
+ Slog.w(TAG, "CarWatchdogService is not available");
+ return null;
+ }
+ return service.getPackageInfosForUids(uids, vendorPackagePrefixes);
}
}