diff options
author | Mayank Garg <gargmayank@google.com> | 2022-01-21 00:52:36 -0800 |
---|---|---|
committer | Mayank Garg <gargmayank@google.com> | 2022-02-08 22:33:57 -0800 |
commit | f6f493950854b789f96e385a72c25e052b8f287d (patch) | |
tree | 0a351d1d3c75874b2b1fceb7a6afa7cb9554fb42 /service-builtin | |
parent | 4c59d782c2556150935ca38f18c6f31557b3196f (diff) | |
download | Car-f6f493950854b789f96e385a72c25e052b8f287d.tar.gz |
Added support for dynamic RRO
Also added overlayable.xml file
Remaining task:
Convert overlay from seahwak, cuttlefish and emulator into static RRO.
Bug: 198516172
Test: Checked the following manually:
1. config_car_bugreport_application value updated correctly for emulator for both user and user debug build
2. userDebug build
overlay package name: com.android.car.resources.vendor
targetPackageName: com.android.car.updatable
3. user build
overlay package name: com.google.android.car.resources.vendor
targetPackageName: com.google.android.car.updatable
Change-Id: Ifa70ba0249dd3c703051276572b851dde203d235
Diffstat (limited to 'service-builtin')
-rw-r--r-- | service-builtin/src/com/android/car/UpdatablePackageContext.java | 144 |
1 files changed, 113 insertions, 31 deletions
diff --git a/service-builtin/src/com/android/car/UpdatablePackageContext.java b/service-builtin/src/com/android/car/UpdatablePackageContext.java index 3d247f7f7f..883024c5e1 100644 --- a/service-builtin/src/com/android/car/UpdatablePackageContext.java +++ b/service-builtin/src/com/android/car/UpdatablePackageContext.java @@ -16,11 +16,13 @@ package com.android.car; +import android.annotation.NonNull; import android.annotation.Nullable; import android.car.builtin.content.pm.PackageManagerHelper; import android.car.builtin.util.Slogf; import android.content.Context; import android.content.ContextWrapper; +import android.content.om.OverlayInfo; import android.content.om.OverlayManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -30,6 +32,11 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.text.TextUtils; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + /** Context for updatable package */ public class UpdatablePackageContext extends ContextWrapper { @@ -85,47 +92,122 @@ public class UpdatablePackageContext extends ContextWrapper { return info; } + // TODO(b/198516172): Add detailed description for the priority of RROs, who will replace whom. private static void enableRROForCarServiceUpdatable(Context baseContext) { - String packageName = SystemProperties.get( - PackageManagerHelper.PROPERTY_CAR_SERVICE_OVERLAY_PACKAGE_NAME, + List<String> packages = getEligibleRROPackages(baseContext); + if (packages.isEmpty()) { + Slogf.d(TAG, "No eligible RRO package to enable."); + return; + } + + OverlayManager manager = baseContext.getSystemService(OverlayManager.class); + UserHandle user = baseContext.getUser(); + for (int i = 0; i < packages.size(); i++) { + // This class is called for each user, so need to enable RRO for system and current user + // separately. + String rroPackageName = packages.get(i); + try { + manager.setEnabled(rroPackageName, /* enable= */true, user); + Slogf.d(TAG, "RRO package %s is enabled for User %s", rroPackageName, user); + } catch (Exception e) { + Slogf.w(TAG, e, "RRO package %s is NOT enabled for User %s", rroPackageName, user); + } + } + } + + @NonNull + private static List<String> getEligibleRROPackages(Context baseContext) { + List<String> eligiblePackages = new ArrayList<>(); + + String packageNames = SystemProperties.get( + PackageManagerHelper.PROPERTY_CAR_SERVICE_OVERLAY_PACKAGES, /* default= */ null); - if (TextUtils.isEmpty(packageName)) { + if (TextUtils.isEmpty(packageNames)) { // read only property not defined. No need to dynamically overlay resources. - Slogf.i(TAG, " %s is not set. No need to dynamically overlay resources.", - PackageManagerHelper.PROPERTY_CAR_SERVICE_OVERLAY_PACKAGE_NAME); - return; + Slogf.d(TAG, " %s is not set. No need to dynamically overlay resources.", + PackageManagerHelper.PROPERTY_CAR_SERVICE_OVERLAY_PACKAGES); + return eligiblePackages; } - // check package - try { - PackageInfo info = baseContext.getPackageManager().getPackageInfo(packageName, 0); - if (info == null || info.applicationInfo == null - || !(PackageManagerHelper.isSystemApp(info.applicationInfo) - || PackageManagerHelper.isUpdatedSystemApp(info.applicationInfo) - || PackageManagerHelper.isOemApp(info.applicationInfo) - || PackageManagerHelper.isOdmApp(info.applicationInfo) - || PackageManagerHelper.isVendorApp(info.applicationInfo) - || PackageManagerHelper.isProductApp(info.applicationInfo) - || PackageManagerHelper.isSystemExtApp(info.applicationInfo))) { - Slogf.i(TAG, "%s is not usable: %s", packageName, ((info == null) - ? "package do not exist" : info.applicationInfo)); - return; + Set<String> installedRROPackages = getInstalledRROPackages(baseContext); + + if (installedRROPackages.isEmpty()) { + return eligiblePackages; + } + + String[] packages = packageNames.split(";"); + String rroPackageName; + for (int i = 0; i < packages.length; i++) { + rroPackageName = packages[i].trim(); + + if (rroPackageName.isEmpty()) { + continue; } - } catch (Exception e) { - Slogf.w(TAG, e, "couldn't find package: %s", packageName); - return; + + if (!installedRROPackages.contains(rroPackageName)) { + Slogf.d(TAG, "RRO package %s is not installed.", rroPackageName); + continue; + } + + // Check that package is part of the original image. A third party RRO + // should not be enabled using this. + try { + PackageInfo info = baseContext.getPackageManager().getPackageInfo( + rroPackageName, 0); + // TODO(b/198516172): Move following logic to separate class and test it. + if (info == null || info.applicationInfo == null + || !(PackageManagerHelper.isSystemApp(info.applicationInfo) + || PackageManagerHelper.isUpdatedSystemApp(info.applicationInfo) + || PackageManagerHelper.isOemApp(info.applicationInfo) + || PackageManagerHelper.isOdmApp(info.applicationInfo) + || PackageManagerHelper.isVendorApp(info.applicationInfo) + || PackageManagerHelper.isProductApp(info.applicationInfo) + || PackageManagerHelper.isSystemExtApp(info.applicationInfo))) { + Slogf.d(TAG, "%s is not usable: %s", rroPackageName, ((info == null) + ? "package do not exist" + : info.applicationInfo)); + continue; + } + } catch (Exception e) { + Slogf.w(TAG, e, "couldn't find package: %s", rroPackageName); + continue; + } + + // Add RRO package to the list. + Slogf.d(TAG, "RRO package %s is eligible for enabling.", rroPackageName); + eligiblePackages.add(rroPackageName); + } + return eligiblePackages; + } + + @NonNull + private static Set<String> getInstalledRROPackages(Context baseContext) { + Set<String> installedOverlayPackages = new HashSet<>(); + PackageInfo packageInfo = findUpdatableServicePackage(baseContext); + if (packageInfo == null) { + return installedOverlayPackages; } + String updatablePackageName = packageInfo.packageName; - // package is valid. Enable RRO. This class is called for each user, so need to enable RRO - // for system and current user separately. + OverlayManager manager = baseContext.getSystemService(OverlayManager.class); UserHandle user = baseContext.getUser(); - try { - OverlayManager manager = baseContext.getSystemService(OverlayManager.class); - manager.setEnabled(packageName, true, user); - Slogf.i(TAG, "RRO package %s is enabled for User %s", packageName, user); - } catch (Exception e) { - Slogf.w(TAG, e, "RRO package %s is NOT enabled for User %s", packageName, user); + + List<OverlayInfo> installedOverlays = manager.getOverlayInfosForTarget(updatablePackageName, + user); + + if (installedOverlays == null || installedOverlays.isEmpty()) { + return installedOverlayPackages; } + + for (int i = 0; i < installedOverlays.size(); i++) { + OverlayInfo overlayInfo = installedOverlays.get(i); + installedOverlayPackages.add(overlayInfo.getPackageName()); + } + + Slogf.d(TAG, "Total RROs packages for target package %s are %d.", updatablePackageName, + installedOverlayPackages.size()); + + return installedOverlayPackages; } private UpdatablePackageContext(Context baseContext, Context packageContext) { |