diff options
19 files changed, 52 insertions, 1216 deletions
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java index 3577fcdf04d6..f20b1706129b 100644 --- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java +++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java @@ -194,7 +194,7 @@ public final class ClientSocketPerfTest { /** * Simple benchmark for the amount of time to send a given number of messages */ - // @Test Temporarily disabled + @Test @Parameters(method = "getParams") public void time(Config config) throws Exception { reset(); diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java index ac5710047db9..af3c405eab82 100644 --- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java +++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java @@ -198,7 +198,7 @@ public final class ServerSocketPerfTest { executor.awaitTermination(5, TimeUnit.SECONDS); } - // @Test Temporarily disabled + @Test @Parameters(method = "getParams") public void throughput(Config config) throws Exception { setup(config); diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java index 27f9f54d9522..cb31bc73b9ba 100644 --- a/core/java/android/app/PropertyInvalidatedCache.java +++ b/core/java/android/app/PropertyInvalidatedCache.java @@ -250,6 +250,7 @@ import java.util.concurrent.atomic.AtomicLong; * @hide */ @TestApi +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class PropertyInvalidatedCache<Query, Result> { /** * This is a configuration class that customizes a cache instance. diff --git a/core/java/android/os/IpcDataCache.java b/core/java/android/os/IpcDataCache.java index bf44d65c4002..d7a308df4e6e 100644 --- a/core/java/android/os/IpcDataCache.java +++ b/core/java/android/os/IpcDataCache.java @@ -242,6 +242,7 @@ import java.util.concurrent.atomic.AtomicLong; */ @TestApi @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES) +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query, Result> { /** * {@inheritDoc} diff --git a/core/jni/android_text_Hyphenator.cpp b/core/jni/android_text_Hyphenator.cpp index 89fdeeb078d0..933781c3e924 100644 --- a/core/jni/android_text_Hyphenator.cpp +++ b/core/jni/android_text_Hyphenator.cpp @@ -14,17 +14,19 @@ * limitations under the License. */ +#include <core_jni_helpers.h> +#include <cutils/trace.h> #include <fcntl.h> +#include <minikin/Hyphenator.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> +#include <tracing_perfetto.h> +#include <unicode/uloc.h> #include <unistd.h> #include <algorithm> -#include <core_jni_helpers.h> -#include <minikin/Hyphenator.h> - namespace android { static std::string buildFileName(const std::string& locale) { @@ -79,6 +81,23 @@ static void addHyphenatorAlias(const std::string& from, const std::string& to) { minikin::addHyphenatorAlias(from, to); } +/* + * Cache the subtag key map by calling uloc_forLanguageTag with a subtag. + * minikin calls uloc_forLanguageTag with an Unicode extension specifying + * the line breaking strictness. Parsing the extension requires loading the key map + * from keyTypeData.res in the ICU. + * "lb" is the key commonly used by minikin. "ca" is a common legacy key mapping to + * the "calendar" key. It ensures that the key map is loaded and cached in icu4c. + * "en-Latn-US" is a common locale used in the Android system regardless what default locale + * is selected in the Settings app. + */ +inline static void cacheUnicodeExtensionSubtagsKeyMap() { + UErrorCode status = U_ZERO_ERROR; + char localeID[ULOC_FULLNAME_CAPACITY] = {}; + uloc_forLanguageTag("en-Latn-US-u-lb-loose-ca-gregory", localeID, ULOC_FULLNAME_CAPACITY, + nullptr, &status); +} + static void init() { // TODO: Confirm that these are the best values. Various sources suggest (1, 1), but that // appears too small. @@ -190,6 +209,10 @@ static void init() { addHyphenatorAlias("und-Orya", "or"); // Oriya addHyphenatorAlias("und-Taml", "ta"); // Tamil addHyphenatorAlias("und-Telu", "te"); // Telugu + + tracing_perfetto::traceBegin(ATRACE_TAG_VIEW, "CacheUnicodeExtensionSubtagsKeyMap"); + cacheUnicodeExtensionSubtagsKeyMap(); + tracing_perfetto::traceEnd(ATRACE_TAG_VIEW); // CacheUnicodeExtensionSubtagsKeyMap } static const JNINativeMethod gMethods[] = { diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 7af307317fc5..b1c48ab39396 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -256,6 +256,7 @@ android_ravenwood_test { "src/android/content/ContextTest.java", "src/android/content/pm/PackageManagerTest.java", "src/android/content/pm/UserInfoTest.java", + "src/android/app/PropertyInvalidatedCacheTests.java", "src/android/database/CursorWindowTest.java", "src/android/os/**/*.java", "src/android/telephony/PinResultTest.java", diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java index cd6abddc20a1..95a4fe4811f0 100644 --- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java +++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java @@ -39,11 +39,7 @@ import org.junit.Test; * atest FrameworksCoreTests:PropertyInvalidatedCacheTests */ @SmallTest -@IgnoreUnderRavenwood(blockedBy = PropertyInvalidatedCache.class) public class PropertyInvalidatedCacheTests { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule(); - // Configuration for creating caches private static final String MODULE = PropertyInvalidatedCache.MODULE_TEST; private static final String API = "testApi"; diff --git a/core/tests/coretests/src/android/os/IpcDataCacheTest.java b/core/tests/coretests/src/android/os/IpcDataCacheTest.java index b03fd6485786..5edf0cad1965 100644 --- a/core/tests/coretests/src/android/os/IpcDataCacheTest.java +++ b/core/tests/coretests/src/android/os/IpcDataCacheTest.java @@ -37,10 +37,7 @@ import org.junit.Test; * atest FrameworksCoreTests:IpcDataCacheTest */ @SmallTest -@IgnoreUnderRavenwood(blockedBy = IpcDataCache.class) public class IpcDataCacheTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule(); // Configuration for creating caches private static final String MODULE = IpcDataCache.MODULE_TEST; diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt index 9c8638930df9..a26fe66da2ab 100644 --- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt @@ -359,3 +359,6 @@ com.android.server.SystemService com.android.server.SystemServiceManager com.android.server.utils.TimingsTraceAndSlog + +android.os.IpcDataCache +android.app.PropertyInvalidatedCache diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java index 4c87e1ce357c..c036605b029f 100644 --- a/services/core/java/com/android/server/am/AppRestrictionController.java +++ b/services/core/java/com/android/server/am/AppRestrictionController.java @@ -373,7 +373,10 @@ public final class AppRestrictionController { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); - switch (intent.getAction()) { + if (action == null) { + return; + } + switch (action) { case Intent.ACTION_PACKAGE_ADDED: { if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); diff --git a/services/core/java/com/android/server/integrity/parser/BinaryFileOperations.java b/services/core/java/com/android/server/integrity/parser/BinaryFileOperations.java deleted file mode 100644 index f09e035ecc78..000000000000 --- a/services/core/java/com/android/server/integrity/parser/BinaryFileOperations.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2020 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.parser; - -import static com.android.server.integrity.model.ComponentBitSize.IS_HASHED_BITS; -import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS; - -import android.content.integrity.IntegrityUtils; - -import com.android.server.integrity.model.BitInputStream; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Helper methods for reading standard data structures from {@link BitInputStream}. - */ -public class BinaryFileOperations { - - /** - * Read an string value with the given size and hash status from a {@code BitInputStream}. - * - * If the value is hashed, get the hex-encoding of the value. Serialized values are in raw form. - * All hashed values are hex-encoded. - */ - public static String getStringValue(BitInputStream bitInputStream) throws IOException { - boolean isHashedValue = bitInputStream.getNext(IS_HASHED_BITS) == 1; - int valueSize = bitInputStream.getNext(VALUE_SIZE_BITS); - return getStringValue(bitInputStream, valueSize, isHashedValue); - } - - /** - * Read an string value with the given size and hash status from a {@code BitInputStream}. - * - * If the value is hashed, get the hex-encoding of the value. Serialized values are in raw form. - * All hashed values are hex-encoded. - */ - public static String getStringValue( - BitInputStream bitInputStream, int valueSize, boolean isHashedValue) - throws IOException { - if (!isHashedValue) { - StringBuilder value = new StringBuilder(); - while (valueSize-- > 0) { - value.append((char) bitInputStream.getNext(/* numOfBits= */ 8)); - } - return value.toString(); - } - ByteBuffer byteBuffer = ByteBuffer.allocate(valueSize); - while (valueSize-- > 0) { - byteBuffer.put((byte) (bitInputStream.getNext(/* numOfBits= */ 8) & 0xFF)); - } - return IntegrityUtils.getHexDigest(byteBuffer.array()); - } - - /** Read an integer value from a {@code BitInputStream}. */ - public static int getIntValue(BitInputStream bitInputStream) throws IOException { - return bitInputStream.getNext(/* numOfBits= */ 32); - } - - /** Read an boolean value from a {@code BitInputStream}. */ - public static boolean getBooleanValue(BitInputStream bitInputStream) throws IOException { - return bitInputStream.getNext(/* numOfBits= */ 1) == 1; - } -} diff --git a/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java b/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java deleted file mode 100644 index ea3a3d5f1c60..000000000000 --- a/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * 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.parser; - -import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START; -import static com.android.server.integrity.model.ComponentBitSize.BYTE_BITS; -import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END; -import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START; -import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS; -import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS; -import static com.android.server.integrity.model.ComponentBitSize.INSTALLER_ALLOWED_BY_MANIFEST_START; -import static com.android.server.integrity.model.ComponentBitSize.IS_HASHED_BITS; -import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS; -import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.SIGNAL_BIT; -import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS; -import static com.android.server.integrity.parser.BinaryFileOperations.getBooleanValue; -import static com.android.server.integrity.parser.BinaryFileOperations.getIntValue; -import static com.android.server.integrity.parser.BinaryFileOperations.getStringValue; - -import android.content.integrity.AtomicFormula; -import android.content.integrity.CompoundFormula; -import android.content.integrity.InstallerAllowedByManifestFormula; -import android.content.integrity.IntegrityFormula; -import android.content.integrity.Rule; - -import com.android.server.integrity.model.BitInputStream; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** A helper class to parse rules into the {@link Rule} model from Binary representation. */ -public class RuleBinaryParser implements RuleParser { - - @Override - public List<Rule> parse(byte[] ruleBytes) throws RuleParseException { - return parse(RandomAccessObject.ofBytes(ruleBytes), Collections.emptyList()); - } - - @Override - public List<Rule> parse(RandomAccessObject randomAccessObject, List<RuleIndexRange> indexRanges) - throws RuleParseException { - try (RandomAccessInputStream randomAccessInputStream = - new RandomAccessInputStream(randomAccessObject)) { - return parseRules(randomAccessInputStream, indexRanges); - } catch (Exception e) { - throw new RuleParseException(e.getMessage(), e); - } - } - - private List<Rule> parseRules( - RandomAccessInputStream randomAccessInputStream, List<RuleIndexRange> indexRanges) - throws IOException { - - // Read the rule binary file format version. - randomAccessInputStream.skip(FORMAT_VERSION_BITS / BYTE_BITS); - - return indexRanges.isEmpty() - ? parseAllRules(randomAccessInputStream) - : parseIndexedRules(randomAccessInputStream, indexRanges); - } - - private List<Rule> parseAllRules(RandomAccessInputStream randomAccessInputStream) - throws IOException { - List<Rule> parsedRules = new ArrayList<>(); - - BitInputStream inputStream = - new BitInputStream(new BufferedInputStream(randomAccessInputStream)); - while (inputStream.hasNext()) { - if (inputStream.getNext(SIGNAL_BIT) == 1) { - parsedRules.add(parseRule(inputStream)); - } - } - - return parsedRules; - } - - private List<Rule> parseIndexedRules( - RandomAccessInputStream randomAccessInputStream, List<RuleIndexRange> indexRanges) - throws IOException { - List<Rule> parsedRules = new ArrayList<>(); - - for (RuleIndexRange range : indexRanges) { - randomAccessInputStream.seek(range.getStartIndex()); - - BitInputStream inputStream = - new BitInputStream( - new BufferedInputStream( - new LimitInputStream( - randomAccessInputStream, - range.getEndIndex() - range.getStartIndex()))); - - // Read the rules until we reach the end index. available() here is not reliable. - while (inputStream.hasNext()) { - if (inputStream.getNext(SIGNAL_BIT) == 1) { - parsedRules.add(parseRule(inputStream)); - } - } - } - - return parsedRules; - } - - private Rule parseRule(BitInputStream bitInputStream) throws IOException { - IntegrityFormula formula = parseFormula(bitInputStream); - int effect = bitInputStream.getNext(EFFECT_BITS); - - if (bitInputStream.getNext(SIGNAL_BIT) != 1) { - throw new IllegalArgumentException("A rule must end with a '1' bit."); - } - - return new Rule(formula, effect); - } - - private IntegrityFormula parseFormula(BitInputStream bitInputStream) throws IOException { - int separator = bitInputStream.getNext(SEPARATOR_BITS); - switch (separator) { - case ATOMIC_FORMULA_START: - return parseAtomicFormula(bitInputStream); - case COMPOUND_FORMULA_START: - return parseCompoundFormula(bitInputStream); - case COMPOUND_FORMULA_END: - return null; - case INSTALLER_ALLOWED_BY_MANIFEST_START: - return new InstallerAllowedByManifestFormula(); - default: - throw new IllegalArgumentException( - String.format("Unknown formula separator: %s", separator)); - } - } - - private CompoundFormula parseCompoundFormula(BitInputStream bitInputStream) throws IOException { - int connector = bitInputStream.getNext(CONNECTOR_BITS); - List<IntegrityFormula> formulas = new ArrayList<>(); - - IntegrityFormula parsedFormula = parseFormula(bitInputStream); - while (parsedFormula != null) { - formulas.add(parsedFormula); - parsedFormula = parseFormula(bitInputStream); - } - - return new CompoundFormula(connector, formulas); - } - - private AtomicFormula parseAtomicFormula(BitInputStream bitInputStream) throws IOException { - int key = bitInputStream.getNext(KEY_BITS); - int operator = bitInputStream.getNext(OPERATOR_BITS); - - switch (key) { - case AtomicFormula.PACKAGE_NAME: - case AtomicFormula.APP_CERTIFICATE: - case AtomicFormula.APP_CERTIFICATE_LINEAGE: - case AtomicFormula.INSTALLER_NAME: - case AtomicFormula.INSTALLER_CERTIFICATE: - case AtomicFormula.STAMP_CERTIFICATE_HASH: - boolean isHashedValue = bitInputStream.getNext(IS_HASHED_BITS) == 1; - int valueSize = bitInputStream.getNext(VALUE_SIZE_BITS); - String stringValue = getStringValue(bitInputStream, valueSize, isHashedValue); - return new AtomicFormula.StringAtomicFormula(key, stringValue, isHashedValue); - case AtomicFormula.VERSION_CODE: - // TODO(b/147880712): temporary hack until our input handles long - long upper = getIntValue(bitInputStream); - long lower = getIntValue(bitInputStream); - long longValue = (upper << 32) | lower; - return new AtomicFormula.LongAtomicFormula(key, operator, longValue); - case AtomicFormula.PRE_INSTALLED: - case AtomicFormula.STAMP_TRUSTED: - boolean booleanValue = getBooleanValue(bitInputStream); - return new AtomicFormula.BooleanAtomicFormula(key, booleanValue); - default: - throw new IllegalArgumentException(String.format("Unknown key: %d", key)); - } - } -} diff --git a/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java b/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java deleted file mode 100644 index 408df5a784ff..000000000000 --- a/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2020 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.parser; - -import android.annotation.Nullable; - -/** - * A wrapper class to represent an indexing range. - */ -public class RuleIndexRange { - private int mStartIndex; - private int mEndIndex; - - /** Constructor with start and end indexes. */ - public RuleIndexRange(int startIndex, int endIndex) { - this.mStartIndex = startIndex; - this.mEndIndex = endIndex; - } - - /** Returns the startIndex. */ - public int getStartIndex() { - return mStartIndex; - } - - /** Returns the end index. */ - public int getEndIndex() { - return mEndIndex; - } - - @Override - public boolean equals(@Nullable Object object) { - return mStartIndex == ((RuleIndexRange) object).getStartIndex() - && mEndIndex == ((RuleIndexRange) object).getEndIndex(); - } - - @Override - public String toString() { - return String.format("Range{%d, %d}", mStartIndex, mEndIndex); - } -} diff --git a/services/core/java/com/android/server/integrity/parser/RuleParseException.java b/services/core/java/com/android/server/integrity/parser/RuleParseException.java deleted file mode 100644 index c0f36a66528a..000000000000 --- a/services/core/java/com/android/server/integrity/parser/RuleParseException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.parser; - -import android.annotation.NonNull; - -/** - * Thrown when rule parsing fails. - */ -public class RuleParseException extends Exception { - public RuleParseException(@NonNull String message) { - super(message); - } - - public RuleParseException(@NonNull String message, @NonNull Throwable cause) { - super(message, cause); - } -} diff --git a/services/core/java/com/android/server/integrity/parser/RuleParser.java b/services/core/java/com/android/server/integrity/parser/RuleParser.java deleted file mode 100644 index 126dacc4fa40..000000000000 --- a/services/core/java/com/android/server/integrity/parser/RuleParser.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.parser; - -import android.content.integrity.Rule; - -import java.util.List; - -/** A helper class to parse rules into the {@link Rule} model. */ -public interface RuleParser { - - /** Parse rules from bytes. */ - List<Rule> parse(byte[] ruleBytes) throws RuleParseException; - - /** Parse rules from an input stream. */ - List<Rule> parse(RandomAccessObject randomAccessObject, List<RuleIndexRange> ruleIndexRanges) - throws RuleParseException; -} diff --git a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java index 980f40ee4a9a..9b02ed0ee0bd 100644 --- a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java +++ b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java @@ -1597,6 +1597,9 @@ public final class NotificationAttentionHelper { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); + if (action == null) { + return; + } if (action.equals(Intent.ACTION_SCREEN_ON)) { // Keep track of screen on/off state, but do not turn off the notification light diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index 42c171bb4351..4e868887ea1b 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -16,6 +16,8 @@ package com.android.server.profcollect; +import android.Manifest; +import android.annotation.RequiresPermission; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobScheduler; @@ -88,10 +90,11 @@ public final class ProfcollectForwardingService extends SystemService { createAndUploadReport(sSelfService); } if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) { - boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); boolean isADB = intent.getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false); if (isADB) { - Log.d(LOG_TAG, "Received broadcast that ADB became " + connected); + boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); + Log.d(LOG_TAG, "Received broadcast that ADB became " + connected + + ", was " + mAdbActive); mAdbActive = connected; } } @@ -117,9 +120,6 @@ public final class ProfcollectForwardingService extends SystemService { mUploadEnabled = context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled); - // TODO: ADB might already be active when our service started. - mAdbActive = false; - final IntentFilter filter = new IntentFilter(); filter.addAction(INTENT_UPLOAD_PROFILES); filter.addAction(UsbManager.ACTION_USB_STATE); @@ -140,7 +140,13 @@ public final class ProfcollectForwardingService extends SystemService { } @Override + @RequiresPermission(Manifest.permission.MANAGE_USB) public void onBootPhase(int phase) { + if (phase == PHASE_SYSTEM_SERVICES_READY) { + UsbManager usbManager = getContext().getSystemService(UsbManager.class); + mAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1); + Log.d(LOG_TAG, "ADB is " + mAdbActive + " on system startup"); + } if (phase == PHASE_BOOT_COMPLETED) { if (mIProfcollect == null) { return; diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/BinaryFileOperationsTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/BinaryFileOperationsTest.java deleted file mode 100644 index 723b6c5af451..000000000000 --- a/services/tests/servicestests/src/com/android/server/integrity/parser/BinaryFileOperationsTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2020 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.parser; - -import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS; -import static com.android.server.integrity.parser.BinaryFileOperations.getBooleanValue; -import static com.android.server.integrity.parser.BinaryFileOperations.getIntValue; -import static com.android.server.integrity.parser.BinaryFileOperations.getStringValue; -import static com.android.server.integrity.utils.TestUtils.getBits; -import static com.android.server.integrity.utils.TestUtils.getBytes; -import static com.android.server.integrity.utils.TestUtils.getValueBits; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.integrity.IntegrityUtils; - -import com.android.server.integrity.model.BitInputStream; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -@RunWith(JUnit4.class) -public class BinaryFileOperationsTest { - - private static final String IS_NOT_HASHED = "0"; - private static final String IS_HASHED = "1"; - private static final String PACKAGE_NAME = "com.test.app"; - private static final String APP_CERTIFICATE = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - - @Test - public void testGetStringValue() throws IOException { - byte[] stringBytes = - getBytes( - IS_NOT_HASHED - + getBits(PACKAGE_NAME.length(), VALUE_SIZE_BITS) - + getValueBits(PACKAGE_NAME)); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(stringBytes)); - - String resultString = getStringValue(inputStream); - - assertThat(resultString).isEqualTo(PACKAGE_NAME); - } - - @Test - public void testGetHashedStringValue() throws IOException { - byte[] ruleBytes = - getBytes( - IS_HASHED - + getBits(APP_CERTIFICATE.length(), VALUE_SIZE_BITS) - + getValueBits(APP_CERTIFICATE)); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - String resultString = getStringValue(inputStream); - - assertThat(resultString) - .isEqualTo(IntegrityUtils.getHexDigest( - APP_CERTIFICATE.getBytes(StandardCharsets.UTF_8))); - } - - @Test - public void testGetStringValue_withSizeAndHashingInfo() throws IOException { - byte[] ruleBytes = getBytes(getValueBits(PACKAGE_NAME)); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - String resultString = getStringValue(inputStream, - PACKAGE_NAME.length(), /* isHashedValue= */false); - - assertThat(resultString).isEqualTo(PACKAGE_NAME); - } - - @Test - public void testGetIntValue() throws IOException { - int randomValue = 15; - byte[] ruleBytes = getBytes(getBits(randomValue, /* numOfBits= */ 32)); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - assertThat(getIntValue(inputStream)).isEqualTo(randomValue); - } - - @Test - public void testGetBooleanValue_true() throws IOException { - String booleanValue = "1"; - byte[] ruleBytes = getBytes(booleanValue); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - assertThat(getBooleanValue(inputStream)).isEqualTo(true); - } - - @Test - public void testGetBooleanValue_false() throws IOException { - String booleanValue = "0"; - byte[] ruleBytes = getBytes(booleanValue); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - assertThat(getBooleanValue(inputStream)).isEqualTo(false); - } -} diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java deleted file mode 100644 index 03363a100841..000000000000 --- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java +++ /dev/null @@ -1,693 +0,0 @@ -/* - * 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.parser; - -import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START; -import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END; -import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START; -import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.DEFAULT_FORMAT_VERSION; -import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS; -import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS; -import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS; -import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS; -import static com.android.server.integrity.utils.TestUtils.getBits; -import static com.android.server.integrity.utils.TestUtils.getBytes; -import static com.android.server.integrity.utils.TestUtils.getValueBits; -import static com.android.server.testutils.TestUtils.assertExpectException; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.integrity.AtomicFormula; -import android.content.integrity.CompoundFormula; -import android.content.integrity.IntegrityUtils; -import android.content.integrity.Rule; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -@RunWith(JUnit4.class) -public class RuleBinaryParserTest { - - private static final String COMPOUND_FORMULA_START_BITS = - getBits(COMPOUND_FORMULA_START, SEPARATOR_BITS); - private static final String COMPOUND_FORMULA_END_BITS = - getBits(COMPOUND_FORMULA_END, SEPARATOR_BITS); - private static final String ATOMIC_FORMULA_START_BITS = - getBits(ATOMIC_FORMULA_START, SEPARATOR_BITS); - private static final int INVALID_FORMULA_SEPARATOR_VALUE = (1 << SEPARATOR_BITS) - 1; - private static final String INVALID_FORMULA_SEPARATOR_BITS = - getBits(INVALID_FORMULA_SEPARATOR_VALUE, SEPARATOR_BITS); - - private static final String NOT = getBits(CompoundFormula.NOT, CONNECTOR_BITS); - private static final String AND = getBits(CompoundFormula.AND, CONNECTOR_BITS); - private static final String OR = getBits(CompoundFormula.OR, CONNECTOR_BITS); - private static final int INVALID_CONNECTOR_VALUE = 3; - private static final String INVALID_CONNECTOR = - getBits(INVALID_CONNECTOR_VALUE, CONNECTOR_BITS); - - private static final String PACKAGE_NAME = getBits(AtomicFormula.PACKAGE_NAME, KEY_BITS); - private static final String APP_CERTIFICATE = getBits(AtomicFormula.APP_CERTIFICATE, KEY_BITS); - private static final String APP_CERTIFICATE_LINEAGE = - getBits(AtomicFormula.APP_CERTIFICATE_LINEAGE, KEY_BITS); - private static final String VERSION_CODE = getBits(AtomicFormula.VERSION_CODE, KEY_BITS); - private static final String PRE_INSTALLED = getBits(AtomicFormula.PRE_INSTALLED, KEY_BITS); - private static final int INVALID_KEY_VALUE = 9; - private static final String INVALID_KEY = getBits(INVALID_KEY_VALUE, KEY_BITS); - - private static final String EQ = getBits(AtomicFormula.EQ, OPERATOR_BITS); - private static final int INVALID_OPERATOR_VALUE = 5; - private static final String INVALID_OPERATOR = getBits(INVALID_OPERATOR_VALUE, OPERATOR_BITS); - - private static final String IS_NOT_HASHED = "0"; - private static final String IS_HASHED = "1"; - - private static final String DENY = getBits(Rule.DENY, EFFECT_BITS); - private static final int INVALID_EFFECT_VALUE = 5; - private static final String INVALID_EFFECT = getBits(INVALID_EFFECT_VALUE, EFFECT_BITS); - - private static final String START_BIT = "1"; - private static final String END_BIT = "1"; - private static final String INVALID_MARKER_BIT = "0"; - - private static final byte[] DEFAULT_FORMAT_VERSION_BYTES = - getBytes(getBits(DEFAULT_FORMAT_VERSION, FORMAT_VERSION_BITS)); - - private static final List<RuleIndexRange> NO_INDEXING = Collections.emptyList(); - - @Test - public void testBinaryStream_validCompoundFormula_noIndexing() throws Exception { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new CompoundFormula( - CompoundFormula.NOT, - Collections.singletonList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false))), - Rule.DENY); - - List<Rule> rules = - binaryParser.parse(RandomAccessObject.ofBytes(rule.array()), NO_INDEXING); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validCompoundFormula_notConnector_noIndexing() throws Exception { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new CompoundFormula( - CompoundFormula.NOT, - Collections.singletonList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false))), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validCompoundFormula_andConnector_noIndexing() throws Exception { - String packageName = "com.test.app"; - String appCertificate = "test_cert"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + AND - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE - + EQ - + IS_NOT_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new CompoundFormula( - CompoundFormula.AND, - Arrays.asList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false), - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, - appCertificate, - /* isHashedValue= */ false))), - Rule.DENY); - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validCompoundFormula_orConnector_noIndexing() throws Exception { - String packageName = "com.test.app"; - String appCertificate = "test_cert"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + OR - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE - + EQ - + IS_NOT_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new CompoundFormula( - CompoundFormula.OR, - Arrays.asList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false), - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, - appCertificate, - /* isHashedValue= */ false))), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormula_stringValue_noIndexing() throws Exception { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormula_hashedValue_noIndexing() throws Exception { - String appCertificate = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE - + EQ - + IS_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, - IntegrityUtils.getHexDigest( - appCertificate.getBytes(StandardCharsets.UTF_8)), - /* isHashedValue= */ true), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormulaWithCertificateLineage() throws Exception { - String appCertificate = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE_LINEAGE - + EQ - + IS_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE_LINEAGE, - IntegrityUtils.getHexDigest( - appCertificate.getBytes(StandardCharsets.UTF_8)), - /* isHashedValue= */ true), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormula_integerValue_noIndexing() throws Exception { - int versionCode = 1; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + VERSION_CODE - + EQ - + getBits(versionCode, /* numOfBits= */ 64) - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.LongAtomicFormula( - AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 1), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormula_booleanValue_noIndexing() throws Exception { - String isPreInstalled = "1"; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + PRE_INSTALLED - + EQ - + isPreInstalled - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.BooleanAtomicFormula( - AtomicFormula.PRE_INSTALLED, true), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_invalidAtomicFormula_noIndexing() { - int versionCode = 1; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + VERSION_CODE - + EQ - + getBits(versionCode, /* numOfBits= */ 64) - + DENY; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex= */ "A rule must end with a '1' bit.", - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_withNoRuleList_noIndexing() throws RuleParseException { - ByteBuffer rule = ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - RuleParser binaryParser = new RuleBinaryParser(); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEmpty(); - } - - @Test - public void testBinaryString_withEmptyRule_noIndexing() { - String ruleBits = START_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ "", - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidCompoundFormula_invalidNumberOfFormulas_noIndexing() { - String packageName = "com.test.app"; - String appCertificate = "test_cert"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE - + EQ - + IS_NOT_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ "Connector NOT must have 1 formula only", - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidOperator_noIndexing() { - int versionCode = 1; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + VERSION_CODE - + INVALID_OPERATOR - + getBits(versionCode, /* numOfBits= */ 64) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown operator: %d", INVALID_OPERATOR_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidEffect_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + INVALID_EFFECT - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown effect: %d", INVALID_EFFECT_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidConnector_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + INVALID_CONNECTOR - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown connector: %d", INVALID_CONNECTOR_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidKey_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + INVALID_KEY - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown key: %d", INVALID_KEY_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidSeparator_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + INVALID_FORMULA_SEPARATOR_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown formula separator: %d", INVALID_FORMULA_SEPARATOR_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidEndMarker_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + INVALID_MARKER_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ "A rule must end with a '1' bit", - () -> binaryParser.parse(rule.array())); - } -} |