Support signed build for car framework module
- Allow both com.android and com.google.android (=signed build).
- Clean up duplicate definitions for updatable and module
build.
Bug: 214625143
Test: build, bootup
Change-Id: I65f992f93f13cde06af47f5e4646acbea5e3444e
diff --git a/apex_car_framework/Android.bp b/apex_car_framework/Android.bp
index b0521b4..60d071d 100644
--- a/apex_car_framework/Android.bp
+++ b/apex_car_framework/Android.bp
@@ -32,7 +32,7 @@
//],
apps: [
- "CarServiceModule",
+ "CarServiceUpdatable",
"ScriptExecutor",
],
compile_multilib: "both",
diff --git a/car-test-lib/Android.bp b/car-test-lib/Android.bp
index 2411479..975721a 100644
--- a/car-test-lib/Android.bp
+++ b/car-test-lib/Android.bp
@@ -27,7 +27,7 @@
},
},
static_libs: [
- "car-service-test-lib",
+ "car-service-test-static-lib",
],
libs: [
"android.car",
diff --git a/car_product/build/car.mk b/car_product/build/car.mk
index db155f8..e672d06 100644
--- a/car_product/build/car.mk
+++ b/car_product/build/car.mk
@@ -251,7 +251,7 @@
PRODUCT_HIDDENAPI_STUBS_TEST := android.car-module.stubs.test
else # !USE_CAR_FRAMEWORK_APEX
PRODUCT_BOOT_JARS += android.car
- PRODUCT_PACKAGES += android.car CarServiceUpdatable car-frameworks-service-module
+ PRODUCT_PACKAGES += android.car CarServiceUpdatableNonModule car-frameworks-service-module
PRODUCT_SYSTEM_SERVER_JARS += car-frameworks-service-module
PRODUCT_HIDDENAPI_STUBS := android.car-stubs-dex
diff --git a/service-builtin/src/com/android/car/UpdatablePackageContext.java b/service-builtin/src/com/android/car/UpdatablePackageContext.java
index 84c4511..3d247f7 100644
--- a/service-builtin/src/com/android/car/UpdatablePackageContext.java
+++ b/service-builtin/src/com/android/car/UpdatablePackageContext.java
@@ -16,12 +16,14 @@
package com.android.car;
+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.OverlayManager;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.SystemProperties;
@@ -31,7 +33,9 @@
/** Context for updatable package */
public class UpdatablePackageContext extends ContextWrapper {
- public static final String UPDATABLE_CAR_SERVICE_PACKAGE_NAME = "com.android.car.updatable";
+ // TODO(b/216134347): Find a better way to find the package.
+ private static final String[] UPDATABLE_CAR_SERVICE_PACKAGE_CANDIDATES =
+ { "com.android.car.updatable", "com.google.android.car.updatable" };
private static final String TAG = UpdatablePackageContext.class.getSimpleName();
@@ -42,8 +46,7 @@
public static UpdatablePackageContext create(Context baseContext) {
Context packageContext;
try {
- PackageInfo info = baseContext.getPackageManager().getPackageInfo(
- UPDATABLE_CAR_SERVICE_PACKAGE_NAME, 0);
+ PackageInfo info = findUpdatableServicePackage(baseContext);
if (info == null || info.applicationInfo == null || !(info.applicationInfo.isSystemApp()
|| info.applicationInfo.isUpdatedSystemApp())) {
throw new IllegalStateException(
@@ -56,8 +59,7 @@
// CONTEXT_IGNORE_SECURITY: UID is different but ok as the package is trustable system
// app
- packageContext = baseContext.createPackageContext(
- UPDATABLE_CAR_SERVICE_PACKAGE_NAME,
+ packageContext = baseContext.createPackageContext(info.packageName,
Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
} catch (Exception e) {
throw new RuntimeException("Cannot load updatable package code", e);
@@ -66,6 +68,23 @@
return new UpdatablePackageContext(baseContext, packageContext);
}
+ @Nullable
+ private static PackageInfo findUpdatableServicePackage(Context baseContext) {
+ PackageInfo info = null;
+ for (int i = 0; i < UPDATABLE_CAR_SERVICE_PACKAGE_CANDIDATES.length; i++) {
+ try {
+ info = baseContext.getPackageManager().getPackageInfo(
+ UPDATABLE_CAR_SERVICE_PACKAGE_CANDIDATES[i], /* flags= */ 0);
+ if (info != null) {
+ break;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // ignore
+ }
+ }
+ return info;
+ }
+
private static void enableRROForCarServiceUpdatable(Context baseContext) {
String packageName = SystemProperties.get(
PackageManagerHelper.PROPERTY_CAR_SERVICE_OVERLAY_PACKAGE_NAME,
@@ -82,14 +101,14 @@
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))) {
+ || 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));
+ ? "package do not exist" : info.applicationInfo));
return;
}
} catch (Exception e) {
diff --git a/service/Android.bp b/service/Android.bp
index 33ec799..663256b 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -20,7 +20,6 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-
genrule {
name: "statslog-Car-java-gen",
tools: ["stats-log-api-gen"],
@@ -29,123 +28,8 @@
out: ["com/android/car/CarStatsLog.java"],
}
-car_service_sources = [
- ":iscriptexecutor_aidl",
- "proto/**/*.proto",
- ":cartelemetry-cardata-proto-srcs",
- "src/**/*.java",
- ":statslog-Car-java-gen",
-]
-
-common_lib_deps = [
- "android.automotive.telemetry.internal-V1-java", // ICarTelemetryInternal
- "android.car.cluster.navigation",
- "android.car.watchdoglib",
- "android.frameworks.automotive.powerpolicy.internal-V1-java",
- "android.hidl.base-V1.0-java",
- "android.hardware.automotive.audiocontrol-V1.0-java",
- "android.hardware.automotive.audiocontrol-V2.0-java",
- "android.hardware.automotive.audiocontrol-V1-java",
- "android.hardware.automotive.vehicle-V2.0-java",
- "android.hardware.automotive.vehicle-V1-java",
- "android.hardware.health-V1.0-java",
- "android.hardware.health-V2.0-java",
- "android.hardware.automotive.occupant_awareness-V1-java",
- "vehicle-hal-support-lib",
- "com.android.car.procfsinspector-client",
-]
-
-android_app {
- name: "CarServiceUpdatable",
-
- srcs: car_service_sources,
-
- resource_dirs: ["res"],
-
- // Resource is still com.android.car.R
- aaptflags: [
- "--custom-package com.android.car",
- ],
-
- platform_apis: true,
-
- optimize: {
- proguard_flags_files: ["proguard.flags"],
- enabled: false,
- },
-
- libs: [
- "android.car",
- "android.car.builtin",
- "framework-annotations-lib",
- "framework-connectivity",
- "framework-statsd",
- "framework-wifi",
- "modules-utils-preconditions",
- "modules-utils-shell-command-handler",
- ],
-
- static_libs: common_lib_deps,
-
- proto: {
- type: "lite",
- },
-
- aidl: {
- include_dirs: [
- // TODO(b/198195711): Remove once we compile against SDK.
- "frameworks/native/aidl/binder", // For PersistableBundle.aidl
- ],
- },
-
- required: ["allowed_privapp_com.android.car"],
-
- // Disable build in PDK, missing aidl import breaks build
- product_variables: {
- pdk: {
- enabled: false,
- },
- },
-}
-
-// TODO(b/194941497): SHIPSTOP - remove this
-// This will generate empty stub version for the added source. This is useful to add dependency
-// which is still using hidden API. Any component added to android.car.module should be removed
-// from this.
-droidstubs {
- name: "carservice-stub-for-hidden-api-check-docs",
- // Code under here are still having hidden API inside
- srcs: [
- "src/com/android/car/CarLocalServices.java",
- //"src/com/android/car/hal/UserHalService.java",
- //"src/com/android/car/systeminterface/SystemStateInterface.java",
- //"src/com/android/car/systeminterface/DisplayInterface.java",
- ],
- // metalava still hides hidden methods even with --hidden, so needs additional annotation
- // to include them
- args: "--hide CallbackInterface --hide UnhiddenSystemApi " +
- "--stub-packages com.android.car* --package " +
- "--show-annotation android.annotation.SystemApi " +
- "--show-annotation com.android.internal.annotations.VisibleForTesting " +
- "--show-annotation android.car.annotation.MandatoryFeature " +
- "--show-annotation android.car.annotation.OptionalFeature " +
- "--show-annotation com.android.car.internal.VisibleForHiddenApiCheck ",
-
- installable: false,
-
- libs: [
- "android.car-module.impl",
- "android.car.builtin",
- "framework-annotations-lib",
- "framework-statsd",
- "modules-utils-preconditions",
- ],
- visibility: ["//packages/services/Car/service"],
-}
-
-// TODO(b/194941497): SHIPSTOP - remove CarServiceModule & android.car.module
-android_app {
- name: "CarServiceModule",
+java_defaults {
+ name: "carservice-updatable-min-java-defaults",
srcs: [
// add full source for all codes under p/s/Car to reduce unnecessary library allow listing.
@@ -173,11 +57,6 @@
"--custom-package com.android.car",
],
- sdk_version: "module_current",
- min_sdk_version: "current",
- apex_available: ["com.android.car.framework"],
- platform_apis: false,
-
libs: [
"android.car-module.impl",
"android.car.builtin",
@@ -213,6 +92,46 @@
proguard_flags_files: ["proguard.flags"],
enabled: false,
},
+
+ // Disable build in PDK, missing aidl import breaks build
+ product_variables: {
+ pdk: {
+ enabled: false,
+ },
+ },
+}
+
+java_defaults {
+ name: "carservice-updatable-java-defaults",
+
+ visibility: [
+ "//packages/services/Car:__subpackages__",
+ ],
+
+ defaults: [ "carservice-updatable-min-java-defaults" ],
+
+ sdk_version: "module_current",
+ // TODO(b/202884646) Change into T sdk version
+ min_sdk_version: "current",
+ platform_apis: false,
+}
+
+// Non-module build
+android_app {
+ name: "CarServiceUpdatableNonModule",
+
+ defaults: ["carservice-updatable-java-defaults"],
+
+ required: ["allowed_privapp_com.android.car"],
+}
+
+// Added to car.framework module
+android_app {
+ name: "CarServiceUpdatable",
+
+ defaults: ["carservice-updatable-java-defaults"],
+
+ apex_available: ["com.android.car.framework"],
}
java_library {
@@ -265,70 +184,7 @@
android_library {
name: "car-service-test-static-lib",
- srcs: car_service_sources,
-
- resource_dirs: ["res"],
-
- // Resource is still com.android.car.R
- aaptflags: [
- "--custom-package com.android.car",
- ],
-
- libs: [
- "android.car",
- "android.car.builtin",
- ],
-
- static_libs: common_lib_deps,
-
- aidl: {
- include_dirs: [
- // TODO(b/198195711): Remove once we compile against SDK.
- "frameworks/native/aidl/binder", // For PersistableBundle.aidl
- ],
- },
-
- product_variables: {
- pdk: {
- enabled: false,
- },
- },
-}
-
-//####################################################################################
-// Build a library to help generate a testing library for external apps.
-// We do not want to use statically linked libraries, as this will bloat the output jar with classes
-// that can conflict with the user's environment.
-//####################################################################################
-android_library {
- name: "car-service-test-lib",
-
- srcs: car_service_sources,
-
- resource_dirs: ["res"],
-
- // Resource is still com.android.car.R
- aaptflags: [
- "--custom-package com.android.car",
- ],
-
- libs: common_lib_deps + [
- "android.car",
- "android.car.builtin",
- ],
-
- aidl: {
- include_dirs: [
- // TODO(b/198195711): Remove once we compile against SDK.
- "frameworks/native/aidl/binder", // For PersistableBundle.aidl
- ],
- },
-
- product_variables: {
- pdk: {
- enabled: false,
- },
- },
+ defaults: ["carservice-updatable-java-defaults"],
}
filegroup {
diff --git a/service/src/com/android/car/telemetry/databroker/DataBrokerImpl.java b/service/src/com/android/car/telemetry/databroker/DataBrokerImpl.java
index 177b3bb..c384947 100644
--- a/service/src/com/android/car/telemetry/databroker/DataBrokerImpl.java
+++ b/service/src/com/android/car/telemetry/databroker/DataBrokerImpl.java
@@ -25,6 +25,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -63,13 +65,17 @@
*/
public class DataBrokerImpl implements DataBroker {
- private static final int MSG_HANDLE_TASK = 1;
- private static final int MSG_BIND_TO_SCRIPT_EXECUTOR = 2;
+ @VisibleForTesting
+ static final int MSG_HANDLE_TASK = 1;
+ @VisibleForTesting
+ static final int MSG_BIND_TO_SCRIPT_EXECUTOR = 2;
/** Bind to script executor 5 times before entering disabled state. */
private static final int MAX_BIND_SCRIPT_EXECUTOR_ATTEMPTS = 5;
- private static final String SCRIPT_EXECUTOR_PACKAGE = "com.android.car.scriptexecutor";
+ // TODO(b/216134347): Find a better way to find the package.
+ private static final String[] SCRIPT_EXECUTOR_PACKAGE_CANDIDATES =
+ {"com.android.car.scriptexecutor", "com.google.android.car.scriptexecutor"};
private static final String SCRIPT_EXECUTOR_CLASS =
"com.android.car.scriptexecutor.ScriptExecutor";
@@ -167,13 +173,38 @@
Slogf.w(CarLog.TAG_TELEMETRY, "publisher failed", error);
}
+ @Nullable
+ private String findExecutorPackage() {
+ PackageInfo info = null;
+ for (int i = 0; i < SCRIPT_EXECUTOR_PACKAGE_CANDIDATES.length; i++) {
+ try {
+ info = mContext.getPackageManager().getPackageInfo(
+ SCRIPT_EXECUTOR_PACKAGE_CANDIDATES[i], /* flags= */ 0);
+ if (info != null) {
+ break;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // ignore
+ }
+ }
+ if (info == null) {
+ return null;
+ }
+ return info.packageName;
+ }
+
private void bindScriptExecutor() {
// do not re-bind if broker is in a disabled state or if script executor is nonnull
if (mDisabled || mScriptExecutor != null) {
return;
}
+ String executorPackage = findExecutorPackage();
+ if (executorPackage == null) {
+ Slogf.w(CarLog.TAG_TELEMETRY, "Cannot find executor package");
+ return;
+ }
Intent intent = new Intent();
- intent.setComponent(new ComponentName(SCRIPT_EXECUTOR_PACKAGE, SCRIPT_EXECUTOR_CLASS));
+ intent.setComponent(new ComponentName(executorPackage, SCRIPT_EXECUTOR_CLASS));
boolean success = mContext.bindServiceAsUser(
intent,
mServiceConnection,
diff --git a/tests/carservice_unit_test/src/com/android/car/telemetry/databroker/DataBrokerTest.java b/tests/carservice_unit_test/src/com/android/car/telemetry/databroker/DataBrokerTest.java
index 561068b..15728ff 100644
--- a/tests/carservice_unit_test/src/com/android/car/telemetry/databroker/DataBrokerTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/telemetry/databroker/DataBrokerTest.java
@@ -33,12 +33,15 @@
import android.car.telemetry.MetricsConfigKey;
import android.content.Context;
import android.content.ServiceConnection;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.util.Log;
import com.android.car.CarPropertyService;
import com.android.car.telemetry.ResultStore;
@@ -47,6 +50,7 @@
import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutor;
import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutorListener;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -67,6 +71,8 @@
@RunWith(MockitoJUnitRunner.class)
public class DataBrokerTest extends AbstractExtendedMockitoCarServiceTestCase {
+ private static final String TAG = DataBrokerTest.class.getSimpleName();
+
private static final int PROP_ID = 100;
private static final int PROP_AREA = 200;
private static final int PRIORITY_HIGH = 1;
@@ -114,6 +120,8 @@
@Mock
private Context mMockContext;
@Mock
+ private PackageManager mMockPackageManager;
+ @Mock
private CarPropertyService mMockCarPropertyService;
@Mock
private DataBroker.ScriptFinishedCallback mMockScriptFinishedCallback;
@@ -130,6 +138,17 @@
public void setUp() throws Exception {
when(mMockCarPropertyService.getPropertyList())
.thenReturn(Collections.singletonList(PROP_CONFIG));
+ mockPackageManager();
+
+ mFakeScriptExecutor = new FakeScriptExecutor();
+ when(mMockScriptExecutorBinder.queryLocalInterface(anyString()))
+ .thenReturn(mFakeScriptExecutor);
+ when(mMockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(i -> {
+ ServiceConnection conn = i.getArgument(1);
+ conn.onServiceConnected(null, mMockScriptExecutorBinder);
+ return true;
+ });
+
PublisherFactory factory = new PublisherFactory(
mMockCarPropertyService, mMockHandler, mMockContext,
Files.createTempDirectory("telemetry_test").toFile());
@@ -142,15 +161,6 @@
return true;
});
- mFakeScriptExecutor = new FakeScriptExecutor();
- when(mMockScriptExecutorBinder.queryLocalInterface(anyString()))
- .thenReturn(mFakeScriptExecutor);
- when(mMockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(i -> {
- ServiceConnection conn = i.getArgument(1);
- conn.onServiceConnected(null, mMockScriptExecutorBinder);
- return true;
- });
-
mHighPriorityTask = new ScriptExecutionTask(
new DataSubscriber(mDataBroker, METRICS_CONFIG_FOO, SUBSCRIBER_FOO),
mData,
@@ -163,6 +173,24 @@
false);
}
+ private void mockPackageManager() throws Exception {
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+ PackageInfo info = new PackageInfo();
+ info.packageName = "com.android.car.scriptexecutor";
+ when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(info);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (mDataBroker != null) {
+ // Remove all to make sure that those are not kicked in after test.
+ mDataBroker.getTelemetryHandler().removeMessages(DataBrokerImpl.MSG_HANDLE_TASK);
+ mDataBroker.getTelemetryHandler().removeMessages(
+ DataBrokerImpl.MSG_BIND_TO_SCRIPT_EXECUTOR);
+ }
+ Log.i(TAG, "tearDown completed");
+ }
+
@Override
protected void onSessionBuilder(CustomMockitoSessionBuilder builder) {
builder.spyStatic(ParcelFileDescriptor.class);
@@ -383,6 +411,7 @@
public void testScheduleNextTask_bindScriptExecutorFailedOnce_shouldRebind()
throws Exception {
Mockito.reset(mMockContext);
+ mockPackageManager();
when(mMockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(
new Answer() {
private int mCount = 0;
@@ -415,6 +444,7 @@
throws Exception {
// fail 6 future attempts to bind to it
Mockito.reset(mMockContext);
+ mockPackageManager();
when(mMockContext.bindServiceAsUser(any(), any(), anyInt(), any()))
.thenReturn(false, false, false, false, false, false);
mDataBroker.mBindScriptExecutorDelayMillis = 0L; // immediately rebind for testing purpose