diff --git a/core/java/android/content/integrity/AppInstallMetadata.java b/core/java/android/content/integrity/AppInstallMetadata.java index 4ec94762ac346..4f38fae271f6d 100644 --- a/core/java/android/content/integrity/AppInstallMetadata.java +++ b/core/java/android/content/integrity/AppInstallMetadata.java @@ -42,6 +42,8 @@ public final class AppInstallMetadata { private final List mInstallerCertificates; private final long mVersionCode; private final boolean mIsPreInstalled; + private final boolean mIsStampPresent; + private final boolean mIsStampVerified; private final boolean mIsStampTrusted; // Raw string encoding for the SHA-256 hash of the certificate of the stamp. private final String mStampCertificateHash; @@ -54,6 +56,8 @@ public final class AppInstallMetadata { this.mInstallerCertificates = builder.mInstallerCertificates; this.mVersionCode = builder.mVersionCode; this.mIsPreInstalled = builder.mIsPreInstalled; + this.mIsStampPresent = builder.mIsStampPresent; + this.mIsStampVerified = builder.mIsStampVerified; this.mIsStampTrusted = builder.mIsStampTrusted; this.mStampCertificateHash = builder.mStampCertificateHash; this.mAllowedInstallersAndCertificates = builder.mAllowedInstallersAndCertificates; @@ -89,6 +93,16 @@ public final class AppInstallMetadata { return mIsPreInstalled; } + /** @see AppInstallMetadata.Builder#setIsStampPresent(boolean) */ + public boolean isStampPresent() { + return mIsStampPresent; + } + + /** @see AppInstallMetadata.Builder#setIsStampVerified(boolean) */ + public boolean isStampVerified() { + return mIsStampVerified; + } + /** @see AppInstallMetadata.Builder#setIsStampTrusted(boolean) */ public boolean isStampTrusted() { return mIsStampTrusted; @@ -108,14 +122,16 @@ public final class AppInstallMetadata { public String toString() { return String.format( "AppInstallMetadata { PackageName = %s, AppCerts = %s, InstallerName = %s," - + " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b, " - + "StampTrusted = %b, StampCert = %s }", + + " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b, StampPresent =" + + " %b, StampVerified = %b, StampTrusted = %b, StampCert = %s }", mPackageName, mAppCertificates, mInstallerName == null ? "null" : mInstallerName, mInstallerCertificates == null ? "null" : mInstallerCertificates, mVersionCode, mIsPreInstalled, + mIsStampPresent, + mIsStampVerified, mIsStampTrusted, mStampCertificateHash == null ? "null" : mStampCertificateHash); } @@ -128,6 +144,8 @@ public final class AppInstallMetadata { private List mInstallerCertificates; private long mVersionCode; private boolean mIsPreInstalled; + private boolean mIsStampPresent; + private boolean mIsStampVerified; private boolean mIsStampTrusted; private String mStampCertificateHash; private Map mAllowedInstallersAndCertificates; @@ -221,16 +239,24 @@ public final class AppInstallMetadata { } /** - * Set certificate hash of the stamp embedded in the APK. + * Set whether the stamp embedded in the APK is present or not. * - *

It is represented as the raw string encoding for the SHA-256 hash of the certificate - * of the stamp. - * - * @see AppInstallMetadata#getStampCertificateHash() + * @see AppInstallMetadata#isStampPresent() */ @NonNull - public Builder setStampCertificateHash(@NonNull String stampCertificateHash) { - this.mStampCertificateHash = Objects.requireNonNull(stampCertificateHash); + public Builder setIsStampPresent(boolean isStampPresent) { + this.mIsStampPresent = isStampPresent; + return this; + } + + /** + * Set whether the stamp embedded in the APK is verified or not. + * + * @see AppInstallMetadata#isStampVerified() + */ + @NonNull + public Builder setIsStampVerified(boolean isStampVerified) { + this.mIsStampVerified = isStampVerified; return this; } @@ -245,6 +271,20 @@ public final class AppInstallMetadata { return this; } + /** + * Set certificate hash of the stamp embedded in the APK. + * + *

It is represented as the raw string encoding for the SHA-256 hash of the certificate + * of the stamp. + * + * @see AppInstallMetadata#getStampCertificateHash() + */ + @NonNull + public Builder setStampCertificateHash(@NonNull String stampCertificateHash) { + this.mStampCertificateHash = Objects.requireNonNull(stampCertificateHash); + return this; + } + /** * Build {@link AppInstallMetadata}. * diff --git a/core/java/android/content/integrity/AtomicFormula.java b/core/java/android/content/integrity/AtomicFormula.java index 977a631cecd85..f363a54edc16b 100644 --- a/core/java/android/content/integrity/AtomicFormula.java +++ b/core/java/android/content/integrity/AtomicFormula.java @@ -368,11 +368,10 @@ public abstract class AtomicFormula extends IntegrityFormula { "Key %s cannot be used with StringAtomicFormula", keyToString(key))); mValue = hashValue(key, value); mIsHashedValue = - key == APP_CERTIFICATE + (key == APP_CERTIFICATE || key == INSTALLER_CERTIFICATE - || key == STAMP_CERTIFICATE_HASH - ? true - : !mValue.equals(value); + || key == STAMP_CERTIFICATE_HASH) + || !mValue.equals(value); } StringAtomicFormula(Parcel in) { diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java index 54dd69d706854..f773825a7ff8b 100644 --- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java @@ -52,7 +52,10 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.UserHandle; import android.provider.Settings; +import android.security.FileIntegrityManager; import android.util.Slog; +import android.util.apk.SourceStampVerificationResult; +import android.util.apk.SourceStampVerifier; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -108,8 +111,10 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { private static final String ALLOWED_INSTALLER_DELIMITER = ","; private static final String INSTALLER_PACKAGE_CERT_DELIMITER = "\\|"; - private static final Set PACKAGE_INSTALLER = new HashSet<>( - Arrays.asList("com.google.android.packageinstaller", "com.android.packageinstaller")); + private static final Set PACKAGE_INSTALLER = + new HashSet<>( + Arrays.asList( + "com.google.android.packageinstaller", "com.android.packageinstaller")); // Access to files inside mRulesDir is protected by mRulesLock; private final Context mContext; @@ -117,6 +122,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { private final PackageManagerInternal mPackageManagerInternal; private final RuleEvaluationEngine mEvaluationEngine; private final IntegrityFileManager mIntegrityFileManager; + private final FileIntegrityManager mFileIntegrityManager; /** Create an instance of {@link AppIntegrityManagerServiceImpl}. */ public static AppIntegrityManagerServiceImpl create(Context context) { @@ -128,6 +134,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { LocalServices.getService(PackageManagerInternal.class), RuleEvaluationEngine.getRuleEvaluationEngine(), IntegrityFileManager.getInstance(), + (FileIntegrityManager) context.getSystemService(Context.FILE_INTEGRITY_SERVICE), handlerThread.getThreadHandler()); } @@ -137,11 +144,13 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { PackageManagerInternal packageManagerInternal, RuleEvaluationEngine evaluationEngine, IntegrityFileManager integrityFileManager, + FileIntegrityManager fileIntegrityManager, Handler handler) { mContext = context; mPackageManagerInternal = packageManagerInternal; mEvaluationEngine = evaluationEngine; mIntegrityFileManager = integrityFileManager; + mFileIntegrityManager = fileIntegrityManager; mHandler = handler; IntentFilter integrityVerificationFilter = new IntentFilter(); @@ -183,8 +192,11 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { success = false; } - FrameworkStatsLog.write(FrameworkStatsLog.INTEGRITY_RULES_PUSHED, success, - ruleProvider, version); + FrameworkStatsLog.write( + FrameworkStatsLog.INTEGRITY_RULES_PUSHED, + success, + ruleProvider, + version); Intent intent = new Intent(); intent.putExtra(EXTRA_STATUS, success ? STATUS_SUCCESS : STATUS_FAILURE); @@ -242,8 +254,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { String installerPackageName = getInstallerPackageName(intent); // Skip integrity verification if the verifier is doing the install. - if (!integrityCheckIncludesRuleProvider() - && isRuleProvider(installerPackageName)) { + if (!integrityCheckIncludesRuleProvider() && isRuleProvider(installerPackageName)) { Slog.i(TAG, "Verifier doing the install. Skipping integrity check."); mPackageManagerInternal.setIntegrityVerificationResult( verificationId, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW); @@ -274,15 +285,17 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { builder.setInstallerCertificates(installerCertificates); builder.setIsPreInstalled(isSystemApp(packageName)); builder.setAllowedInstallersAndCert(getAllowedInstallers(packageInfo)); + extractSourceStamp(intent.getData(), builder); AppInstallMetadata appInstallMetadata = builder.build(); Slog.i( TAG, - "To be verified: " + appInstallMetadata + " installers " + getAllowedInstallers( - packageInfo)); - IntegrityCheckResult result = - mEvaluationEngine.evaluate(appInstallMetadata); + "To be verified: " + + appInstallMetadata + + " installers " + + getAllowedInstallers(packageInfo)); + IntegrityCheckResult result = mEvaluationEngine.evaluate(appInstallMetadata); Slog.i( TAG, "Integrity check result: " @@ -323,7 +336,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { * Verify the UID and return the installer package name. * * @return the package name of the installer, or null if it cannot be determined or it is - * installed via adb. + * installed via adb. */ @Nullable private String getInstallerPackageName(Intent intent) { @@ -442,7 +455,8 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { String cert = packageAndCert[1]; packageCertMap.put(packageName, cert); } else if (packageAndCert.length == 1) { - packageCertMap.put(getPackageNameNormalized(packageAndCert[0]), + packageCertMap.put( + getPackageNameNormalized(packageAndCert[0]), INSTALLER_CERTIFICATE_NOT_EVALUATED); } } @@ -452,6 +466,41 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { return packageCertMap; } + /** Extract the source stamp embedded in the APK, if present. */ + private void extractSourceStamp(Uri dataUri, AppInstallMetadata.Builder appInstallMetadata) { + File installationPath = getInstallationPath(dataUri); + if (installationPath == null) { + throw new IllegalArgumentException("Installation path is null, package not found"); + } + SourceStampVerificationResult sourceStampVerificationResult = + SourceStampVerifier.verify(installationPath.getAbsolutePath()); + appInstallMetadata.setIsStampPresent(sourceStampVerificationResult.isPresent()); + appInstallMetadata.setIsStampVerified(sourceStampVerificationResult.isVerified()); + if (sourceStampVerificationResult.isVerified()) { + X509Certificate sourceStampCertificate = + (X509Certificate) sourceStampVerificationResult.getCertificate(); + // Sets source stamp certificate digest. + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] certificateDigest = digest.digest(sourceStampCertificate.getEncoded()); + appInstallMetadata.setStampCertificateHash(getHexDigest(certificateDigest)); + } catch (NoSuchAlgorithmException | CertificateEncodingException e) { + throw new IllegalArgumentException( + "Error computing source stamp certificate digest", e); + } + // Checks if the source stamp certificate is trusted. + try { + appInstallMetadata.setIsStampTrusted( + mFileIntegrityManager.isApkVeritySupported() + && mFileIntegrityManager.isAppSourceCertificateTrusted( + sourceStampCertificate)); + } catch (CertificateEncodingException e) { + throw new IllegalArgumentException( + "Error checking if source stamp certificate is trusted", e); + } + } + } + private static Signature[] getSignatures(@NonNull PackageInfo packageInfo) { SigningInfo signingInfo = packageInfo.signingInfo; @@ -505,8 +554,16 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { ParsedPackage pkg = parser.parsePackage(installationPath, 0, false); int flags = PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_META_DATA; pkg.setSigningDetails(ParsingPackageUtils.collectCertificates(pkg, false)); - return PackageInfoUtils.generate(pkg, null, flags, 0, 0, null, new PackageUserState(), - UserHandle.getCallingUserId(), null); + return PackageInfoUtils.generate( + pkg, + null, + flags, + 0, + 0, + null, + new PackageUserState(), + UserHandle.getCallingUserId(), + null); } catch (Exception e) { Slog.w(TAG, "Exception reading " + dataUri, e); return null; @@ -633,9 +690,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { private boolean integrityCheckIncludesRuleProvider() { return Settings.Global.getInt( - mContext.getContentResolver(), - Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, - 0) + mContext.getContentResolver(), + Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, + 0) == 1; } } diff --git a/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk b/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk new file mode 100644 index 0000000000000..8056e0bf6e50d Binary files /dev/null and b/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk differ diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java index d9101bf6a48bb..e2b63e2bb9b7b 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java @@ -28,6 +28,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; @@ -61,6 +62,7 @@ import android.net.Uri; import android.os.Handler; import android.os.Message; import android.provider.Settings; +import android.security.FileIntegrityManager; import androidx.test.InstrumentationRegistry; @@ -96,6 +98,9 @@ public class AppIntegrityManagerServiceImplTest { private static final String TEST_APP_TWO_CERT_PATH = "AppIntegrityManagerServiceImplTest/DummyAppTwoCerts.apk"; + private static final String TEST_APP_SOURCE_STAMP_PATH = + "AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk"; + private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; private static final String VERSION = "version"; private static final String TEST_FRAMEWORK_PACKAGE = "com.android.frameworks.servicestests"; @@ -111,6 +116,8 @@ public class AppIntegrityManagerServiceImplTest { // We use SHA256 for package names longer than 32 characters. private static final String INSTALLER_SHA256 = "30F41A7CBF96EE736A54DD6DF759B50ED3CC126ABCEF694E167C324F5976C227"; + private static final String SOURCE_STAMP_CERTIFICATE_HASH = + "681B0E56A796350C08647352A4DB800CC44B2ADC8F4C72FA350BD05D4D50264D"; private static final String DUMMY_APP_TWO_CERTS_CERT_1 = "C0369C2A1096632429DFA8433068AECEAD00BAC337CA92A175036D39CC9AFE94"; @@ -121,27 +128,22 @@ public class AppIntegrityManagerServiceImplTest { private static final String ADB_INSTALLER = "adb"; private static final String PLAY_STORE_CERT = "play_store_cert"; - @org.junit.Rule - public MockitoRule mMockitoRule = MockitoJUnit.rule(); + @org.junit.Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); - @Mock - PackageManagerInternal mPackageManagerInternal; - @Mock - Context mMockContext; - @Mock - Resources mMockResources; - @Mock - RuleEvaluationEngine mRuleEvaluationEngine; - @Mock - IntegrityFileManager mIntegrityFileManager; - @Mock - Handler mHandler; + @Mock PackageManagerInternal mPackageManagerInternal; + @Mock Context mMockContext; + @Mock Resources mMockResources; + @Mock RuleEvaluationEngine mRuleEvaluationEngine; + @Mock IntegrityFileManager mIntegrityFileManager; + @Mock Handler mHandler; + FileIntegrityManager mFileIntegrityManager; private final Context mRealContext = InstrumentationRegistry.getTargetContext(); private PackageManager mSpyPackageManager; private File mTestApk; private File mTestApkTwoCerts; + private File mTestApkSourceStamp; // under test private AppIntegrityManagerServiceImpl mService; @@ -158,19 +160,28 @@ public class AppIntegrityManagerServiceImplTest { Files.copy(inputStream, mTestApkTwoCerts.toPath(), REPLACE_EXISTING); } + mTestApkSourceStamp = File.createTempFile("AppIntegritySourceStamp", ".apk"); + try (InputStream inputStream = mRealContext.getAssets().open(TEST_APP_SOURCE_STAMP_PATH)) { + Files.copy(inputStream, mTestApkSourceStamp.toPath(), REPLACE_EXISTING); + } + + mFileIntegrityManager = + (FileIntegrityManager) + mRealContext.getSystemService(Context.FILE_INTEGRITY_SERVICE); mService = new AppIntegrityManagerServiceImpl( mMockContext, mPackageManagerInternal, mRuleEvaluationEngine, mIntegrityFileManager, + mFileIntegrityManager, mHandler); mSpyPackageManager = spy(mRealContext.getPackageManager()); // setup mocks to prevent NPE when(mMockContext.getPackageManager()).thenReturn(mSpyPackageManager); when(mMockContext.getResources()).thenReturn(mMockResources); - when(mMockResources.getStringArray(anyInt())).thenReturn(new String[]{}); + when(mMockResources.getStringArray(anyInt())).thenReturn(new String[] {}); when(mIntegrityFileManager.initialized()).thenReturn(true); // These are needed to override the Settings.Global.get result. when(mMockContext.getContentResolver()).thenReturn(mRealContext.getContentResolver()); @@ -181,6 +192,7 @@ public class AppIntegrityManagerServiceImplTest { public void tearDown() throws Exception { mTestApk.delete(); mTestApkTwoCerts.delete(); + mTestApkSourceStamp.delete(); } @Test @@ -241,7 +253,8 @@ public class AppIntegrityManagerServiceImplTest { IntentSender mockReceiver = mock(IntentSender.class); List rules = Arrays.asList( - new Rule(IntegrityFormula.Application.packageNameEquals(PACKAGE_NAME), + new Rule( + IntegrityFormula.Application.packageNameEquals(PACKAGE_NAME), Rule.DENY)); mService.updateRuleSet(VERSION, new ParceledListSlice<>(rules), mockReceiver); @@ -261,7 +274,8 @@ public class AppIntegrityManagerServiceImplTest { IntentSender mockReceiver = mock(IntentSender.class); List rules = Arrays.asList( - new Rule(IntegrityFormula.Application.packageNameEquals(PACKAGE_NAME), + new Rule( + IntegrityFormula.Application.packageNameEquals(PACKAGE_NAME), Rule.DENY)); mService.updateRuleSet(VERSION, new ParceledListSlice<>(rules), mockReceiver); @@ -305,8 +319,7 @@ public class AppIntegrityManagerServiceImplTest { ArgumentCaptor metadataCaptor = ArgumentCaptor.forClass(AppInstallMetadata.class); - verify(mRuleEvaluationEngine) - .evaluate(metadataCaptor.capture()); + verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture()); AppInstallMetadata appInstallMetadata = metadataCaptor.getValue(); assertEquals(PACKAGE_NAME, appInstallMetadata.getPackageName()); assertThat(appInstallMetadata.getAppCertificates()).containsExactly(APP_CERT); @@ -341,8 +354,33 @@ public class AppIntegrityManagerServiceImplTest { ArgumentCaptor.forClass(AppInstallMetadata.class); verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture()); AppInstallMetadata appInstallMetadata = metadataCaptor.getValue(); - assertThat(appInstallMetadata.getAppCertificates()).containsExactly( - DUMMY_APP_TWO_CERTS_CERT_1, DUMMY_APP_TWO_CERTS_CERT_2); + assertThat(appInstallMetadata.getAppCertificates()) + .containsExactly(DUMMY_APP_TWO_CERTS_CERT_1, DUMMY_APP_TWO_CERTS_CERT_2); + } + + @Test + public void handleBroadcast_correctArgs_sourceStamp() throws Exception { + whitelistUsAsRuleProvider(); + makeUsSystemApp(); + ArgumentCaptor broadcastReceiverCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + verify(mMockContext) + .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any()); + Intent intent = makeVerificationIntent(); + intent.setDataAndType(Uri.fromFile(mTestApkSourceStamp), PACKAGE_MIME_TYPE); + when(mRuleEvaluationEngine.evaluate(any())).thenReturn(IntegrityCheckResult.allow()); + + broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent); + runJobInHandler(); + + ArgumentCaptor metadataCaptor = + ArgumentCaptor.forClass(AppInstallMetadata.class); + verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture()); + AppInstallMetadata appInstallMetadata = metadataCaptor.getValue(); + assertTrue(appInstallMetadata.isStampPresent()); + assertTrue(appInstallMetadata.isStampVerified()); + assertFalse(appInstallMetadata.isStampTrusted()); + assertEquals(SOURCE_STAMP_CERTIFICATE_HASH, appInstallMetadata.getStampCertificateHash()); } @Test @@ -445,7 +483,7 @@ public class AppIntegrityManagerServiceImplTest { private void whitelistUsAsRuleProvider() { Resources mockResources = mock(Resources.class); when(mockResources.getStringArray(R.array.config_integrityRuleProviderPackages)) - .thenReturn(new String[]{TEST_FRAMEWORK_PACKAGE}); + .thenReturn(new String[] {TEST_FRAMEWORK_PACKAGE}); when(mMockContext.getResources()).thenReturn(mockResources); } @@ -478,8 +516,8 @@ public class AppIntegrityManagerServiceImplTest { PackageInfo packageInfo = mRealContext .getPackageManager() - .getPackageInfo(TEST_FRAMEWORK_PACKAGE, - PackageManager.GET_SIGNING_CERTIFICATES); + .getPackageInfo( + TEST_FRAMEWORK_PACKAGE, PackageManager.GET_SIGNING_CERTIFICATES); doReturn(packageInfo).when(mSpyPackageManager).getPackageInfo(eq(INSTALLER), anyInt()); doReturn(1).when(mSpyPackageManager).getPackageUid(eq(INSTALLER), anyInt()); return makeVerificationIntent(INSTALLER); @@ -501,10 +539,16 @@ public class AppIntegrityManagerServiceImplTest { private void setIntegrityCheckIncludesRuleProvider(boolean shouldInclude) throws Exception { int value = shouldInclude ? 1 : 0; - Settings.Global.putInt(mRealContext.getContentResolver(), - Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, value); - assertThat(Settings.Global.getInt(mRealContext.getContentResolver(), - Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, -1) == 1).isEqualTo( - shouldInclude); + Settings.Global.putInt( + mRealContext.getContentResolver(), + Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, + value); + assertThat( + Settings.Global.getInt( + mRealContext.getContentResolver(), + Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, + -1) + == 1) + .isEqualTo(shouldInclude); } }