Merge "Replace com.android.internal.util.Preconditions.checkNotNull with java.util.Objects.requireNonNull"
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 27db294..4cc5a67 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -22,6 +22,7 @@
<resources>
<!-- SystemUI Services: The classes of the stuff to start. -->
<string-array name="config_systemUIServiceComponents" translatable="false">
+ <item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.volume.VolumeUI</item>
<item>com.android.systemui.stackdivider.Divider</item>
<item>com.android.systemui.statusbar.tv.TvStatusBar</item>
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index e5292a0..f3d60f5 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -225,11 +225,13 @@
builder.setIsPreInstalled(isSystemApp(packageName));
AppInstallMetadata appInstallMetadata = builder.build();
+ Map<String, String> allowedInstallers = getAllowedInstallers(packageInfo);
- Slog.i(TAG, "To be verified: " + appInstallMetadata);
+ Slog.i(
+ TAG,
+ "To be verified: " + appInstallMetadata + " installers " + allowedInstallers);
IntegrityCheckResult result =
- mEvaluationEngine.evaluate(
- appInstallMetadata, getAllowedInstallers(packageInfo));
+ mEvaluationEngine.evaluate(appInstallMetadata, allowedInstallers);
Slog.i(
TAG,
"Integrity check result: "
@@ -371,7 +373,7 @@
String[] packageAndCert =
packageCertPair.split(INSTALLER_PACKAGE_CERT_DELIMITER);
if (packageAndCert.length == 2) {
- String packageName = packageAndCert[0];
+ String packageName = getPackageNameNormalized(packageAndCert[0]);
String cert = packageAndCert[1];
packageCertMap.put(packageName, cert);
}
@@ -379,21 +381,9 @@
}
}
- Slog.i("DEBUG", "allowed installers map " + packageCertMap);
return packageCertMap;
}
- private boolean getPreInstalled(String packageName) {
- try {
- PackageInfo existingPackageInfo =
- mContext.getPackageManager().getPackageInfo(packageName, 0);
- return existingPackageInfo.applicationInfo != null
- && existingPackageInfo.applicationInfo.isSystemApp();
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
-
private static Signature getSignature(@NonNull PackageInfo packageInfo) {
if (packageInfo.signatures == null || packageInfo.signatures.length < 1) {
throw new IllegalArgumentException("Package signature not found in " + packageInfo);
@@ -463,7 +453,8 @@
PackageInfo basePackageInfo =
mContext.getPackageManager()
.getPackageArchiveInfo(
- baseFile.getAbsolutePath(), PackageManager.GET_SIGNATURES);
+ baseFile.getAbsolutePath(),
+ PackageManager.GET_SIGNATURES | PackageManager.GET_META_DATA);
if (basePackageInfo == null) {
for (File apkFile : multiApkDirectory.listFiles()) {
@@ -477,7 +468,8 @@
mContext.getPackageManager()
.getPackageArchiveInfo(
apkFile.getAbsolutePath(),
- PackageManager.GET_SIGNING_CERTIFICATES);
+ PackageManager.GET_SIGNING_CERTIFICATES
+ | PackageManager.GET_META_DATA);
if (basePackageInfo != null) {
Slog.i(TAG, "Found package info from " + apkFile);
break;
diff --git a/services/core/java/com/android/server/integrity/IntegrityFileManager.java b/services/core/java/com/android/server/integrity/IntegrityFileManager.java
index bdf0279..e224724 100644
--- a/services/core/java/com/android/server/integrity/IntegrityFileManager.java
+++ b/services/core/java/com/android/server/integrity/IntegrityFileManager.java
@@ -24,14 +24,14 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.integrity.model.RuleMetadata;
-import com.android.server.integrity.parser.RuleBinaryParser;
import com.android.server.integrity.parser.RuleMetadataParser;
import com.android.server.integrity.parser.RuleParseException;
import com.android.server.integrity.parser.RuleParser;
-import com.android.server.integrity.serializer.RuleBinarySerializer;
+import com.android.server.integrity.parser.RuleXmlParser;
import com.android.server.integrity.serializer.RuleMetadataSerializer;
import com.android.server.integrity.serializer.RuleSerializeException;
import com.android.server.integrity.serializer.RuleSerializer;
+import com.android.server.integrity.serializer.RuleXmlSerializer;
import java.io.File;
import java.io.FileInputStream;
@@ -75,8 +75,8 @@
private IntegrityFileManager() {
this(
- new RuleBinaryParser(),
- new RuleBinarySerializer(),
+ new RuleXmlParser(),
+ new RuleXmlSerializer(),
Environment.getDataSystemDirectory());
}
diff --git a/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java b/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
index 0ea6efc..07eacbf 100644
--- a/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
+++ b/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
@@ -17,15 +17,21 @@
package com.android.server.integrity.engine;
import android.content.integrity.AppInstallMetadata;
+import android.content.integrity.AtomicFormula;
+import android.content.integrity.CompoundFormula;
+import android.content.integrity.Formula;
import android.content.integrity.Rule;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.integrity.IntegrityFileManager;
import com.android.server.integrity.model.IntegrityCheckResult;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
/**
* The engine used to evaluate rules against app installs.
@@ -42,7 +48,8 @@
private final IntegrityFileManager mIntegrityFileManager;
- private RuleEvaluationEngine(IntegrityFileManager integrityFileManager) {
+ @VisibleForTesting
+ RuleEvaluationEngine(IntegrityFileManager integrityFileManager) {
mIntegrityFileManager = integrityFileManager;
}
@@ -64,6 +71,7 @@
public IntegrityCheckResult evaluate(
AppInstallMetadata appInstallMetadata, Map<String, String> allowedInstallers) {
List<Rule> rules = loadRules(appInstallMetadata);
+ allowedInstallersRule(allowedInstallers).ifPresent(rules::add);
return RuleEvaluator.evaluateRules(rules, appInstallMetadata);
}
@@ -75,4 +83,42 @@
return new ArrayList<>();
}
}
+
+ private static Optional<Rule> allowedInstallersRule(Map<String, String> allowedInstallers) {
+ if (allowedInstallers.isEmpty()) {
+ return Optional.empty();
+ }
+
+ List<Formula> formulas = new ArrayList<>(allowedInstallers.size());
+ allowedInstallers.forEach(
+ (installer, cert) -> {
+ formulas.add(allowedInstallerFormula(installer, cert));
+ });
+
+ // We need this special case since OR-formulas require at least two operands.
+ Formula allInstallersFormula =
+ formulas.size() == 1
+ ? formulas.get(0)
+ : new CompoundFormula(CompoundFormula.OR, formulas);
+
+ return Optional.of(
+ new Rule(
+ new CompoundFormula(
+ CompoundFormula.NOT, Arrays.asList(allInstallersFormula)),
+ Rule.DENY));
+ }
+
+ private static Formula allowedInstallerFormula(String installer, String cert) {
+ return new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_NAME,
+ installer,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_CERTIFICATE,
+ cert,
+ /* isHashedValue= */ false)));
+ }
}
diff --git a/services/core/java/com/android/server/integrity/engine/RuleEvaluator.java b/services/core/java/com/android/server/integrity/engine/RuleEvaluator.java
index ee51d4f..b1c20d2 100644
--- a/services/core/java/com/android/server/integrity/engine/RuleEvaluator.java
+++ b/services/core/java/com/android/server/integrity/engine/RuleEvaluator.java
@@ -21,9 +21,6 @@
import android.annotation.NonNull;
import android.content.integrity.AppInstallMetadata;
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.CompoundFormula;
-import android.content.integrity.Formula;
import android.content.integrity.Rule;
import android.util.Slog;
@@ -56,8 +53,7 @@
List<Rule> rules, AppInstallMetadata appInstallMetadata) {
List<Rule> matchedRules = new ArrayList<>();
for (Rule rule : rules) {
- if (isConjunctionOfFormulas(rule.getFormula())
- && rule.getFormula().isSatisfied(appInstallMetadata)) {
+ if (rule.getFormula().isSatisfied(appInstallMetadata)) {
matchedRules.add(rule);
}
}
@@ -81,25 +77,4 @@
}
return denied ? IntegrityCheckResult.deny(denyRule) : IntegrityCheckResult.allow();
}
-
- private static boolean isConjunctionOfFormulas(Formula formula) {
- if (formula == null) {
- return false;
- }
- if (isAtomicFormula(formula)) {
- return true;
- }
- CompoundFormula compoundFormula = (CompoundFormula) formula;
- return compoundFormula.getConnector() == CompoundFormula.AND
- && compoundFormula.getFormulas().stream().allMatch(RuleEvaluator::isAtomicFormula);
- }
-
- private static boolean isAtomicFormula(Formula formula) {
- if (formula instanceof AtomicFormula) {
- return true;
- }
- CompoundFormula compoundFormula = (CompoundFormula) formula;
- return compoundFormula.getConnector() == CompoundFormula.NOT
- && compoundFormula.getFormulas().get(0) instanceof AtomicFormula;
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluationEngineTest.java b/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluationEngineTest.java
new file mode 100644
index 0000000..d386487
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluationEngineTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.integrity.engine;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.content.integrity.AppInstallMetadata;
+import android.content.integrity.Rule;
+
+import com.android.server.integrity.IntegrityFileManager;
+import com.android.server.integrity.model.IntegrityCheckResult;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(JUnit4.class)
+public class RuleEvaluationEngineTest {
+
+ private static final String INSTALLER_1 = "installer1";
+ private static final String INSTALLER_1_CERT = "installer1_cert";
+ private static final String INSTALLER_2 = "installer2";
+ private static final String INSTALLER_2_CERT = "installer2_cert";
+
+ private static final String RANDOM_INSTALLER = "random";
+ private static final String RANDOM_INSTALLER_CERT = "random_cert";
+
+ @Mock private IntegrityFileManager mIntegrityFileManager;
+
+ private RuleEvaluationEngine mEngine;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mEngine = new RuleEvaluationEngine(mIntegrityFileManager);
+
+ when(mIntegrityFileManager.readRules(any())).thenReturn(new ArrayList<>());
+ }
+
+ @Test
+ public void testAllowedInstallers_empty() {
+ Map<String, String> allowedInstallers = Collections.emptyMap();
+
+ assertEquals(
+ IntegrityCheckResult.Effect.ALLOW,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(INSTALLER_1)
+ .setInstallerCertificate(INSTALLER_1_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ assertEquals(
+ IntegrityCheckResult.Effect.ALLOW,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(INSTALLER_2)
+ .setInstallerCertificate(INSTALLER_2_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ assertEquals(
+ IntegrityCheckResult.Effect.ALLOW,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(RANDOM_INSTALLER)
+ .setInstallerCertificate(RANDOM_INSTALLER_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ }
+
+ @Test
+ public void testAllowedInstallers_oneElement() {
+ Map<String, String> allowedInstallers =
+ Collections.singletonMap(INSTALLER_1, INSTALLER_1_CERT);
+
+ assertEquals(
+ IntegrityCheckResult.Effect.ALLOW,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(INSTALLER_1)
+ .setInstallerCertificate(INSTALLER_1_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ assertEquals(
+ IntegrityCheckResult.Effect.DENY,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(RANDOM_INSTALLER)
+ .setInstallerCertificate(INSTALLER_1_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ assertEquals(
+ IntegrityCheckResult.Effect.DENY,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(INSTALLER_1)
+ .setInstallerCertificate(RANDOM_INSTALLER_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ assertEquals(
+ IntegrityCheckResult.Effect.DENY,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(RANDOM_INSTALLER)
+ .setInstallerCertificate(RANDOM_INSTALLER_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ }
+
+ @Test
+ public void testAllowedInstallers_multipleElement() {
+ List<Rule> rules = new ArrayList<>();
+ Map<String, String> allowedInstallers = new HashMap<>(2);
+ allowedInstallers.put(INSTALLER_1, INSTALLER_1_CERT);
+ allowedInstallers.put(INSTALLER_2, INSTALLER_2_CERT);
+
+ assertEquals(
+ IntegrityCheckResult.Effect.ALLOW,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(INSTALLER_1)
+ .setInstallerCertificate(INSTALLER_1_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ assertEquals(
+ IntegrityCheckResult.Effect.ALLOW,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(INSTALLER_2)
+ .setInstallerCertificate(INSTALLER_2_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ assertEquals(
+ IntegrityCheckResult.Effect.DENY,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(INSTALLER_1)
+ .setInstallerCertificate(INSTALLER_2_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ assertEquals(
+ IntegrityCheckResult.Effect.DENY,
+ mEngine.evaluate(
+ getAppInstallMetadataBuilder()
+ .setInstallerName(INSTALLER_2)
+ .setInstallerCertificate(INSTALLER_1_CERT)
+ .build(),
+ allowedInstallers)
+ .getEffect());
+ }
+
+ /** Returns a builder with all fields filled with some dummy data. */
+ private AppInstallMetadata.Builder getAppInstallMetadataBuilder() {
+ return new AppInstallMetadata.Builder()
+ .setPackageName("abc")
+ .setAppCertificate("abc")
+ .setInstallerCertificate("abc")
+ .setInstallerName("abc")
+ .setVersionCode(-1)
+ .setIsPreInstalled(true);
+ }
+}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 96d2df1..68b16f3 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -74,13 +74,13 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.ISoundTriggerService;
-import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Map;
+import java.util.Objects;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -429,9 +429,9 @@
@Override
public int startRecognitionForService(ParcelUuid soundModelId, Bundle params,
ComponentName detectionService, SoundTrigger.RecognitionConfig config) {
- Preconditions.checkNotNull(soundModelId);
- Preconditions.checkNotNull(detectionService);
- Preconditions.checkNotNull(config);
+ Objects.requireNonNull(soundModelId);
+ Objects.requireNonNull(detectionService);
+ Objects.requireNonNull(config);
enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 404346f..e9db31b 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -76,7 +76,6 @@
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
-import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -89,6 +88,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -117,11 +117,11 @@
mResolver = context.getContentResolver();
mDbHelper = new DatabaseHelper(context);
mServiceStub = new VoiceInteractionManagerServiceStub();
- mAmInternal = Preconditions.checkNotNull(
+ mAmInternal = Objects.requireNonNull(
LocalServices.getService(ActivityManagerInternal.class));
- mAtmInternal = Preconditions.checkNotNull(
+ mAtmInternal = Objects.requireNonNull(
LocalServices.getService(ActivityTaskManagerInternal.class));
- mUserManagerInternal = Preconditions.checkNotNull(
+ mUserManagerInternal = Objects.requireNonNull(
LocalServices.getService(UserManagerInternal.class));
PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
@@ -149,7 +149,7 @@
@Override
public void onBootPhase(int phase) {
if (PHASE_SYSTEM_SERVICES_READY == phase) {
- mShortcutServiceInternal = Preconditions.checkNotNull(
+ mShortcutServiceInternal = Objects.requireNonNull(
LocalServices.getService(ShortcutServiceInternal.class));
mSoundTriggerInternal = LocalServices.getService(SoundTriggerInternal.class);
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {