Loading AconfigFlags.bp +7 −0 Original line number Diff line number Diff line Loading @@ -966,6 +966,13 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } java_aconfig_library { name: "android.app.flags-aconfig-java-host", aconfig_declarations: "android.app.flags-aconfig", host_supported: true, defaults: ["framework-minus-apex-aconfig-java-defaults"], } // Broadcast Radio aconfig_declarations { name: "android.hardware.radio.flags-aconfig", Loading services/core/java/com/android/server/BinaryTransparencyService.java +122 −48 Original line number Diff line number Diff line Loading @@ -101,6 +101,9 @@ import java.util.Map; import java.util.concurrent.Executors; import java.util.stream.Collectors; import com.android.server.pm.BackgroundInstallControlService; import com.android.server.pm.BackgroundInstallControlCallbackHelper; /** * @hide */ Loading Loading @@ -138,6 +141,10 @@ public class BinaryTransparencyService extends SystemService { static final int MBA_STATUS_NEW_INSTALL = 3; // used for indicating newly installed MBAs that are updated (but unused currently) static final int MBA_STATUS_UPDATED_NEW_INSTALL = 4; // used for indicating preloaded MBAs that are downgraded static final int MBA_STATUS_DOWNGRADED_PRELOADED = 5; // used for indicating MBAs that are uninstalled static final int MBA_STATUS_UNINSTALLED = 6; @VisibleForTesting static final String KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION = Loading Loading @@ -202,7 +209,9 @@ public class BinaryTransparencyService extends SystemService { * @param mbaStatus Assign this value of MBA status to the returned elements. * @return a @{@code List<IBinaryTransparencyService.AppInfo>} */ private @NonNull List<IBinaryTransparencyService.AppInfo> collectAppInfo( @VisibleForTesting @NonNull List<IBinaryTransparencyService.AppInfo> collectAppInfo( PackageState packageState, int mbaStatus) { // compute content digest if (DEBUG) { Loading Loading @@ -336,6 +345,7 @@ public class BinaryTransparencyService extends SystemService { + " packages after considering APEXs."); } if (!android.app.Flags.backgroundInstallControlCallbackApi()) { // proceed with all preloaded apps List<IBinaryTransparencyService.AppInfo> allUpdatedPreloadInfo = collectAllUpdatedPreloadInfo(packagesMeasured); Loading @@ -348,8 +358,7 @@ public class BinaryTransparencyService extends SystemService { + " packages after considering preloads"); } if (!android.app.Flags.backgroundInstallControlCallbackApi() && CompatChanges.isChangeEnabled(LOG_MBA_INFO)) { if (CompatChanges.isChangeEnabled(LOG_MBA_INFO)) { // lastly measure all newly installed MBAs List<IBinaryTransparencyService.AppInfo> allMbaInfo = collectAllSilentInstalledMbaInfo(packagesMeasured); Loading @@ -358,6 +367,7 @@ public class BinaryTransparencyService extends SystemService { writeAppInfoToLog(appInfo); } } } long timeSpentMeasuring = System.currentTimeMillis() - currentTimeMs; digestAllPackagesLatency.logSample(timeSpentMeasuring); if (DEBUG) { Loading Loading @@ -466,7 +476,8 @@ public class BinaryTransparencyService extends SystemService { apexInfo.signerDigests); } private void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo) { @VisibleForTesting void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo) { // Must order by the proto's field number. FrameworkStatsLog.write(FrameworkStatsLog.MOBILE_BUNDLED_APP_INFO_GATHERED, appInfo.packageName, Loading Loading @@ -1165,25 +1176,33 @@ public class BinaryTransparencyService extends SystemService { * TODO: Add a host test for testing registration and callback of BicCallbackHandler * b/380002484 */ @VisibleForTesting static class BicCallbackHandler extends IRemoteCallback.Stub { private static final String BIC_CALLBACK_HANDLER_TAG = "BTS.BicCallbackHandler"; private final BinaryTransparencyServiceImpl mServiceImpl; static final String FLAGGED_PACKAGE_NAME_KEY = "packageName"; private static final String BIC_CALLBACK_HANDLER_TAG = TAG + ".BicCallbackHandler"; private static final int INSTALL_EVENT_TYPE_UNSET = -1; BicCallbackHandler(BinaryTransparencyServiceImpl impl) { mServiceImpl = impl; private final IBicAppInfoHelper mBicAppInfoHelper; @VisibleForTesting BicCallbackHandler(IBicAppInfoHelper bicAppInfoHelper) { mBicAppInfoHelper = bicAppInfoHelper; } @Override public void sendResult(Bundle data) { String packageName = data.getString(FLAGGED_PACKAGE_NAME_KEY); if (packageName == null) return; if (DEBUG) { Slog.d(BIC_CALLBACK_HANDLER_TAG, "background install event detected for " + packageName); String packageName = data.getString( BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY); int installType = data.getInt( BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY, INSTALL_EVENT_TYPE_UNSET); if (packageName == null || installType == INSTALL_EVENT_TYPE_UNSET) { Slog.w(BIC_CALLBACK_HANDLER_TAG, "Package name or install type is " + "unavailable, ignoring event"); return; } Slog.d(BIC_CALLBACK_HANDLER_TAG, "Detected new bic event for: " + packageName); if (installType == BackgroundInstallControlService.INSTALL_EVENT_TYPE_INSTALL) { PackageState packageState = LocalServices.getService(PackageManagerInternal.class) .getPackageStateInternal(packageName); if (packageState == null) { Loading @@ -1191,15 +1210,52 @@ public class BinaryTransparencyService extends SystemService { + packageName); return; } int mbaStatus = MBA_STATUS_NEW_INSTALL; if (packageState.isUpdatedSystemApp()) { return; mbaStatus = MBA_STATUS_UPDATED_PRELOAD; } List<IBinaryTransparencyService.AppInfo> mbaInfo = mServiceImpl.collectAppInfo( packageState, MBA_STATUS_NEW_INSTALL); List<IBinaryTransparencyService.AppInfo> mbaInfo = mBicAppInfoHelper.collectAppInfo( packageState, mbaStatus); for (IBinaryTransparencyService.AppInfo appInfo : mbaInfo) { mServiceImpl.writeAppInfoToLog(appInfo); mBicAppInfoHelper.writeAppInfoToLog(appInfo); } } else if (installType == BackgroundInstallControlService.INSTALL_EVENT_TYPE_UNINSTALL) { IBinaryTransparencyService.AppInfo appInfo = new IBinaryTransparencyService.AppInfo(); // since app is already uninstalled we won't be able to retrieve additional // info on it. appInfo.packageName = packageName; appInfo.mbaStatus = MBA_STATUS_UNINSTALLED; mBicAppInfoHelper.writeAppInfoToLog(appInfo); } else { Slog.w(BIC_CALLBACK_HANDLER_TAG, "Unsupported BIC event: " + installType); } } /** * A wrapper of interface for{@link FrameworkStatsLog and ApkDigests} * for easier testing */ @VisibleForTesting public interface IBicAppInfoHelper { /** * A wrapper of {@link FrameworkStatsLog} * * @param appInfo The app info of the changed MBA to be logged */ public void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo); /** * A wrapper of {@link BinaryTransparencyServiceImpl} * * @param packageState The packageState provided retrieved from PackageManagerInternal * @param mbaStatus The MBA status of the package */ public List<IBinaryTransparencyService.AppInfo> collectAppInfo( PackageState packageState, int mbaStatus); } }; /** Loading Loading @@ -1586,7 +1642,21 @@ public class BinaryTransparencyService extends SystemService { Context.BACKGROUND_INSTALL_CONTROL_SERVICE)); try { iBics.registerBackgroundInstallCallback( new BicCallbackHandler(mServiceImpl)); new BicCallbackHandler( new BicCallbackHandler.IBicAppInfoHelper() { @Override public void writeAppInfoToLog( IBinaryTransparencyService.AppInfo appInfo) { mServiceImpl.writeAppInfoToLog(appInfo); } @Override public List<IBinaryTransparencyService.AppInfo> collectAppInfo( PackageState packageState, int mbaStatus) { return mServiceImpl.collectAppInfo(packageState, mbaStatus); } } )); } catch (RemoteException e) { Slog.e(TAG, "Failed to register BackgroundInstallControl callback."); } Loading Loading @@ -1633,8 +1703,12 @@ public class BinaryTransparencyService extends SystemService { } String packageName = data.getSchemeSpecificPart(); // now we've got to check what package is this if (isPackagePreloaded(packageName) || isPackageAnApex(packageName)) { boolean shouldMeasureMba = !android.app.Flags.backgroundInstallControlCallbackApi() && isPackagePreloaded(packageName); if (shouldMeasureMba || isPackageAnApex(packageName)) { Slog.d(TAG, packageName + " was updated. Scheduling measurement..."); UpdateMeasurementsJobService.scheduleBinaryMeasurements(mContext, BinaryTransparencyService.this); Loading services/core/java/com/android/server/pm/BackgroundInstallControlCallbackHelper.java +4 −3 Original line number Diff line number Diff line Loading @@ -33,9 +33,10 @@ import com.android.server.ServiceThread; public class BackgroundInstallControlCallbackHelper { @VisibleForTesting static final String FLAGGED_PACKAGE_NAME_KEY = "packageName"; @VisibleForTesting static final String FLAGGED_USER_ID_KEY = "userId"; @VisibleForTesting static final String INSTALL_EVENT_TYPE_KEY = "installEventType"; public static final String FLAGGED_PACKAGE_NAME_KEY = "packageName"; public static final String FLAGGED_USER_ID_KEY = "userId"; public static final String INSTALL_EVENT_TYPE_KEY = "installEventType"; private static final String TAG = "BackgroundInstallControlCallbackHelper"; private final Handler mHandler; Loading services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java +81 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; Loading @@ -40,6 +41,7 @@ import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; import android.os.Bundle; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SystemProperties; Loading @@ -50,6 +52,12 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.os.IBinaryTransparencyService; import com.android.server.pm.BackgroundInstallControlService; import com.android.server.pm.BackgroundInstallControlCallbackHelper; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.AndroidPackageSplit; import com.android.server.pm.pkg.PackageStateInternal; import org.junit.After; import org.junit.Assert; Loading @@ -68,6 +76,9 @@ import java.util.List; public class BinaryTransparencyServiceTest { private static final String TAG = "BinaryTransparencyServiceTest"; private static final String TEST_PKG_NAME = "testPackageName"; private static final long TEST_VERSION_CODE = 1L; private Context mContext; private BinaryTransparencyService mBinaryTransparencyService; private BinaryTransparencyService.BinaryTransparencyServiceImpl mTestInterface; Loading @@ -83,6 +94,8 @@ public class BinaryTransparencyServiceTest { private PackageManager mPackageManager; @Mock private PackageManagerInternal mPackageManagerInternal; @Mock private BinaryTransparencyService.BicCallbackHandler.IBicAppInfoHelper mBicAppInfoHelper; @Captor private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> Loading @@ -91,6 +104,9 @@ public class BinaryTransparencyServiceTest { private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mFaceAuthenticatorsRegisteredCaptor; @Captor private ArgumentCaptor<IBinaryTransparencyService.AppInfo> appInfoCaptor; @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading Loading @@ -262,4 +278,69 @@ public class BinaryTransparencyServiceTest { eq("") /* softwareVersion */ ); } @Test public void BicCallbackHandler_uploads_mba_metrics() { Bundle data = setupBicCallbackHandlerTest(false, BinaryTransparencyService.MBA_STATUS_NEW_INSTALL); BinaryTransparencyService.BicCallbackHandler handler = new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper); handler.sendResult(data); verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture()); Assert.assertEquals(TEST_PKG_NAME, appInfoCaptor.getValue().packageName); Assert.assertEquals(TEST_VERSION_CODE, appInfoCaptor.getValue().longVersion); } @Test public void BicCallbackHandler_uploads_mba_metrics_for_preloads() { Bundle data = setupBicCallbackHandlerTest(true, BinaryTransparencyService.MBA_STATUS_UPDATED_PRELOAD); BinaryTransparencyService.BicCallbackHandler handler = new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper); handler.sendResult(data); verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture()); Assert.assertEquals(TEST_PKG_NAME, appInfoCaptor.getValue().packageName); Assert.assertEquals(TEST_VERSION_CODE, appInfoCaptor.getValue().longVersion); } @Test public void BicCallbackHandler_uploads_mba_metrics_for_uninstalls() { Bundle data = new Bundle(); data.putString(BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY, TEST_PKG_NAME); data.putInt(BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY, BackgroundInstallControlService.INSTALL_EVENT_TYPE_UNINSTALL); BinaryTransparencyService.BicCallbackHandler handler = new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper); handler.sendResult(data); verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture()); Assert.assertEquals(TEST_PKG_NAME ,appInfoCaptor.getValue().packageName); Assert.assertEquals(BinaryTransparencyService.MBA_STATUS_UNINSTALLED, appInfoCaptor.getValue().mbaStatus); } private Bundle setupBicCallbackHandlerTest(boolean isUpdatedSystemApp, int expectedBtsMbaStatus) { Bundle data = new Bundle(); data.putString(BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY, TEST_PKG_NAME); data.putInt(BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY, BackgroundInstallControlService.INSTALL_EVENT_TYPE_INSTALL); PackageStateInternal mockPackageState = mock(PackageStateInternal.class); when(mPackageManagerInternal.getPackageStateInternal(TEST_PKG_NAME)) .thenReturn(mockPackageState); when(mockPackageState.isUpdatedSystemApp()).thenReturn(isUpdatedSystemApp); IBinaryTransparencyService.AppInfo appInfo = new IBinaryTransparencyService.AppInfo(); appInfo.packageName = TEST_PKG_NAME; appInfo.longVersion = TEST_VERSION_CODE; when(mBicAppInfoHelper.collectAppInfo(mockPackageState, expectedBtsMbaStatus)) .thenReturn(List.of(appInfo)); return data; } } tests/BinaryTransparencyHostTest/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ java_test_host { ], static_libs: [ "truth", "flag-junit-host", "android.app.flags-aconfig-java-host", ], device_common_data: [ ":BinaryTransparencyTestApp", Loading Loading
AconfigFlags.bp +7 −0 Original line number Diff line number Diff line Loading @@ -966,6 +966,13 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } java_aconfig_library { name: "android.app.flags-aconfig-java-host", aconfig_declarations: "android.app.flags-aconfig", host_supported: true, defaults: ["framework-minus-apex-aconfig-java-defaults"], } // Broadcast Radio aconfig_declarations { name: "android.hardware.radio.flags-aconfig", Loading
services/core/java/com/android/server/BinaryTransparencyService.java +122 −48 Original line number Diff line number Diff line Loading @@ -101,6 +101,9 @@ import java.util.Map; import java.util.concurrent.Executors; import java.util.stream.Collectors; import com.android.server.pm.BackgroundInstallControlService; import com.android.server.pm.BackgroundInstallControlCallbackHelper; /** * @hide */ Loading Loading @@ -138,6 +141,10 @@ public class BinaryTransparencyService extends SystemService { static final int MBA_STATUS_NEW_INSTALL = 3; // used for indicating newly installed MBAs that are updated (but unused currently) static final int MBA_STATUS_UPDATED_NEW_INSTALL = 4; // used for indicating preloaded MBAs that are downgraded static final int MBA_STATUS_DOWNGRADED_PRELOADED = 5; // used for indicating MBAs that are uninstalled static final int MBA_STATUS_UNINSTALLED = 6; @VisibleForTesting static final String KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION = Loading Loading @@ -202,7 +209,9 @@ public class BinaryTransparencyService extends SystemService { * @param mbaStatus Assign this value of MBA status to the returned elements. * @return a @{@code List<IBinaryTransparencyService.AppInfo>} */ private @NonNull List<IBinaryTransparencyService.AppInfo> collectAppInfo( @VisibleForTesting @NonNull List<IBinaryTransparencyService.AppInfo> collectAppInfo( PackageState packageState, int mbaStatus) { // compute content digest if (DEBUG) { Loading Loading @@ -336,6 +345,7 @@ public class BinaryTransparencyService extends SystemService { + " packages after considering APEXs."); } if (!android.app.Flags.backgroundInstallControlCallbackApi()) { // proceed with all preloaded apps List<IBinaryTransparencyService.AppInfo> allUpdatedPreloadInfo = collectAllUpdatedPreloadInfo(packagesMeasured); Loading @@ -348,8 +358,7 @@ public class BinaryTransparencyService extends SystemService { + " packages after considering preloads"); } if (!android.app.Flags.backgroundInstallControlCallbackApi() && CompatChanges.isChangeEnabled(LOG_MBA_INFO)) { if (CompatChanges.isChangeEnabled(LOG_MBA_INFO)) { // lastly measure all newly installed MBAs List<IBinaryTransparencyService.AppInfo> allMbaInfo = collectAllSilentInstalledMbaInfo(packagesMeasured); Loading @@ -358,6 +367,7 @@ public class BinaryTransparencyService extends SystemService { writeAppInfoToLog(appInfo); } } } long timeSpentMeasuring = System.currentTimeMillis() - currentTimeMs; digestAllPackagesLatency.logSample(timeSpentMeasuring); if (DEBUG) { Loading Loading @@ -466,7 +476,8 @@ public class BinaryTransparencyService extends SystemService { apexInfo.signerDigests); } private void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo) { @VisibleForTesting void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo) { // Must order by the proto's field number. FrameworkStatsLog.write(FrameworkStatsLog.MOBILE_BUNDLED_APP_INFO_GATHERED, appInfo.packageName, Loading Loading @@ -1165,25 +1176,33 @@ public class BinaryTransparencyService extends SystemService { * TODO: Add a host test for testing registration and callback of BicCallbackHandler * b/380002484 */ @VisibleForTesting static class BicCallbackHandler extends IRemoteCallback.Stub { private static final String BIC_CALLBACK_HANDLER_TAG = "BTS.BicCallbackHandler"; private final BinaryTransparencyServiceImpl mServiceImpl; static final String FLAGGED_PACKAGE_NAME_KEY = "packageName"; private static final String BIC_CALLBACK_HANDLER_TAG = TAG + ".BicCallbackHandler"; private static final int INSTALL_EVENT_TYPE_UNSET = -1; BicCallbackHandler(BinaryTransparencyServiceImpl impl) { mServiceImpl = impl; private final IBicAppInfoHelper mBicAppInfoHelper; @VisibleForTesting BicCallbackHandler(IBicAppInfoHelper bicAppInfoHelper) { mBicAppInfoHelper = bicAppInfoHelper; } @Override public void sendResult(Bundle data) { String packageName = data.getString(FLAGGED_PACKAGE_NAME_KEY); if (packageName == null) return; if (DEBUG) { Slog.d(BIC_CALLBACK_HANDLER_TAG, "background install event detected for " + packageName); String packageName = data.getString( BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY); int installType = data.getInt( BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY, INSTALL_EVENT_TYPE_UNSET); if (packageName == null || installType == INSTALL_EVENT_TYPE_UNSET) { Slog.w(BIC_CALLBACK_HANDLER_TAG, "Package name or install type is " + "unavailable, ignoring event"); return; } Slog.d(BIC_CALLBACK_HANDLER_TAG, "Detected new bic event for: " + packageName); if (installType == BackgroundInstallControlService.INSTALL_EVENT_TYPE_INSTALL) { PackageState packageState = LocalServices.getService(PackageManagerInternal.class) .getPackageStateInternal(packageName); if (packageState == null) { Loading @@ -1191,15 +1210,52 @@ public class BinaryTransparencyService extends SystemService { + packageName); return; } int mbaStatus = MBA_STATUS_NEW_INSTALL; if (packageState.isUpdatedSystemApp()) { return; mbaStatus = MBA_STATUS_UPDATED_PRELOAD; } List<IBinaryTransparencyService.AppInfo> mbaInfo = mServiceImpl.collectAppInfo( packageState, MBA_STATUS_NEW_INSTALL); List<IBinaryTransparencyService.AppInfo> mbaInfo = mBicAppInfoHelper.collectAppInfo( packageState, mbaStatus); for (IBinaryTransparencyService.AppInfo appInfo : mbaInfo) { mServiceImpl.writeAppInfoToLog(appInfo); mBicAppInfoHelper.writeAppInfoToLog(appInfo); } } else if (installType == BackgroundInstallControlService.INSTALL_EVENT_TYPE_UNINSTALL) { IBinaryTransparencyService.AppInfo appInfo = new IBinaryTransparencyService.AppInfo(); // since app is already uninstalled we won't be able to retrieve additional // info on it. appInfo.packageName = packageName; appInfo.mbaStatus = MBA_STATUS_UNINSTALLED; mBicAppInfoHelper.writeAppInfoToLog(appInfo); } else { Slog.w(BIC_CALLBACK_HANDLER_TAG, "Unsupported BIC event: " + installType); } } /** * A wrapper of interface for{@link FrameworkStatsLog and ApkDigests} * for easier testing */ @VisibleForTesting public interface IBicAppInfoHelper { /** * A wrapper of {@link FrameworkStatsLog} * * @param appInfo The app info of the changed MBA to be logged */ public void writeAppInfoToLog(IBinaryTransparencyService.AppInfo appInfo); /** * A wrapper of {@link BinaryTransparencyServiceImpl} * * @param packageState The packageState provided retrieved from PackageManagerInternal * @param mbaStatus The MBA status of the package */ public List<IBinaryTransparencyService.AppInfo> collectAppInfo( PackageState packageState, int mbaStatus); } }; /** Loading Loading @@ -1586,7 +1642,21 @@ public class BinaryTransparencyService extends SystemService { Context.BACKGROUND_INSTALL_CONTROL_SERVICE)); try { iBics.registerBackgroundInstallCallback( new BicCallbackHandler(mServiceImpl)); new BicCallbackHandler( new BicCallbackHandler.IBicAppInfoHelper() { @Override public void writeAppInfoToLog( IBinaryTransparencyService.AppInfo appInfo) { mServiceImpl.writeAppInfoToLog(appInfo); } @Override public List<IBinaryTransparencyService.AppInfo> collectAppInfo( PackageState packageState, int mbaStatus) { return mServiceImpl.collectAppInfo(packageState, mbaStatus); } } )); } catch (RemoteException e) { Slog.e(TAG, "Failed to register BackgroundInstallControl callback."); } Loading Loading @@ -1633,8 +1703,12 @@ public class BinaryTransparencyService extends SystemService { } String packageName = data.getSchemeSpecificPart(); // now we've got to check what package is this if (isPackagePreloaded(packageName) || isPackageAnApex(packageName)) { boolean shouldMeasureMba = !android.app.Flags.backgroundInstallControlCallbackApi() && isPackagePreloaded(packageName); if (shouldMeasureMba || isPackageAnApex(packageName)) { Slog.d(TAG, packageName + " was updated. Scheduling measurement..."); UpdateMeasurementsJobService.scheduleBinaryMeasurements(mContext, BinaryTransparencyService.this); Loading
services/core/java/com/android/server/pm/BackgroundInstallControlCallbackHelper.java +4 −3 Original line number Diff line number Diff line Loading @@ -33,9 +33,10 @@ import com.android.server.ServiceThread; public class BackgroundInstallControlCallbackHelper { @VisibleForTesting static final String FLAGGED_PACKAGE_NAME_KEY = "packageName"; @VisibleForTesting static final String FLAGGED_USER_ID_KEY = "userId"; @VisibleForTesting static final String INSTALL_EVENT_TYPE_KEY = "installEventType"; public static final String FLAGGED_PACKAGE_NAME_KEY = "packageName"; public static final String FLAGGED_USER_ID_KEY = "userId"; public static final String INSTALL_EVENT_TYPE_KEY = "installEventType"; private static final String TAG = "BackgroundInstallControlCallbackHelper"; private final Handler mHandler; Loading
services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java +81 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; Loading @@ -40,6 +41,7 @@ import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; import android.os.Bundle; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SystemProperties; Loading @@ -50,6 +52,12 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.os.IBinaryTransparencyService; import com.android.server.pm.BackgroundInstallControlService; import com.android.server.pm.BackgroundInstallControlCallbackHelper; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.pkg.AndroidPackageSplit; import com.android.server.pm.pkg.PackageStateInternal; import org.junit.After; import org.junit.Assert; Loading @@ -68,6 +76,9 @@ import java.util.List; public class BinaryTransparencyServiceTest { private static final String TAG = "BinaryTransparencyServiceTest"; private static final String TEST_PKG_NAME = "testPackageName"; private static final long TEST_VERSION_CODE = 1L; private Context mContext; private BinaryTransparencyService mBinaryTransparencyService; private BinaryTransparencyService.BinaryTransparencyServiceImpl mTestInterface; Loading @@ -83,6 +94,8 @@ public class BinaryTransparencyServiceTest { private PackageManager mPackageManager; @Mock private PackageManagerInternal mPackageManagerInternal; @Mock private BinaryTransparencyService.BicCallbackHandler.IBicAppInfoHelper mBicAppInfoHelper; @Captor private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> Loading @@ -91,6 +104,9 @@ public class BinaryTransparencyServiceTest { private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mFaceAuthenticatorsRegisteredCaptor; @Captor private ArgumentCaptor<IBinaryTransparencyService.AppInfo> appInfoCaptor; @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading Loading @@ -262,4 +278,69 @@ public class BinaryTransparencyServiceTest { eq("") /* softwareVersion */ ); } @Test public void BicCallbackHandler_uploads_mba_metrics() { Bundle data = setupBicCallbackHandlerTest(false, BinaryTransparencyService.MBA_STATUS_NEW_INSTALL); BinaryTransparencyService.BicCallbackHandler handler = new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper); handler.sendResult(data); verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture()); Assert.assertEquals(TEST_PKG_NAME, appInfoCaptor.getValue().packageName); Assert.assertEquals(TEST_VERSION_CODE, appInfoCaptor.getValue().longVersion); } @Test public void BicCallbackHandler_uploads_mba_metrics_for_preloads() { Bundle data = setupBicCallbackHandlerTest(true, BinaryTransparencyService.MBA_STATUS_UPDATED_PRELOAD); BinaryTransparencyService.BicCallbackHandler handler = new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper); handler.sendResult(data); verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture()); Assert.assertEquals(TEST_PKG_NAME, appInfoCaptor.getValue().packageName); Assert.assertEquals(TEST_VERSION_CODE, appInfoCaptor.getValue().longVersion); } @Test public void BicCallbackHandler_uploads_mba_metrics_for_uninstalls() { Bundle data = new Bundle(); data.putString(BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY, TEST_PKG_NAME); data.putInt(BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY, BackgroundInstallControlService.INSTALL_EVENT_TYPE_UNINSTALL); BinaryTransparencyService.BicCallbackHandler handler = new BinaryTransparencyService.BicCallbackHandler(mBicAppInfoHelper); handler.sendResult(data); verify(mBicAppInfoHelper, times(1)).writeAppInfoToLog(appInfoCaptor.capture()); Assert.assertEquals(TEST_PKG_NAME ,appInfoCaptor.getValue().packageName); Assert.assertEquals(BinaryTransparencyService.MBA_STATUS_UNINSTALLED, appInfoCaptor.getValue().mbaStatus); } private Bundle setupBicCallbackHandlerTest(boolean isUpdatedSystemApp, int expectedBtsMbaStatus) { Bundle data = new Bundle(); data.putString(BackgroundInstallControlCallbackHelper.FLAGGED_PACKAGE_NAME_KEY, TEST_PKG_NAME); data.putInt(BackgroundInstallControlCallbackHelper.INSTALL_EVENT_TYPE_KEY, BackgroundInstallControlService.INSTALL_EVENT_TYPE_INSTALL); PackageStateInternal mockPackageState = mock(PackageStateInternal.class); when(mPackageManagerInternal.getPackageStateInternal(TEST_PKG_NAME)) .thenReturn(mockPackageState); when(mockPackageState.isUpdatedSystemApp()).thenReturn(isUpdatedSystemApp); IBinaryTransparencyService.AppInfo appInfo = new IBinaryTransparencyService.AppInfo(); appInfo.packageName = TEST_PKG_NAME; appInfo.longVersion = TEST_VERSION_CODE; when(mBicAppInfoHelper.collectAppInfo(mockPackageState, expectedBtsMbaStatus)) .thenReturn(List.of(appInfo)); return data; } }
tests/BinaryTransparencyHostTest/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ java_test_host { ], static_libs: [ "truth", "flag-junit-host", "android.app.flags-aconfig-java-host", ], device_common_data: [ ":BinaryTransparencyTestApp", Loading