Merge "[Ravenwood] Update RATR to setup environment ASAP" into main
diff --git a/ACTIVITY_SECURITY_OWNERS b/ACTIVITY_SECURITY_OWNERS
new file mode 100644
index 0000000..c39842e
--- /dev/null
+++ b/ACTIVITY_SECURITY_OWNERS
@@ -0,0 +1,2 @@
+haok@google.com
+wnan@google.com
\ No newline at end of file
diff --git a/INTENT_OWNERS b/INTENT_OWNERS
index 58b5f2a..c828215 100644
--- a/INTENT_OWNERS
+++ b/INTENT_OWNERS
@@ -1,3 +1,4 @@
include /PACKAGE_MANAGER_OWNERS
include /services/core/java/com/android/server/wm/OWNERS
include /services/core/java/com/android/server/am/OWNERS
+include /ACTIVITY_SECURITY_OWNERS
\ No newline at end of file
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 3577fcd..f20b170 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 @@
/**
* 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 ac57100..af3c405 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 @@
executor.awaitTermination(5, TimeUnit.SECONDS);
}
- // @Test Temporarily disabled
+ @Test
@Parameters(method = "getParams")
public void throughput(Config config) throws Exception {
setup(config);
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index 33f6899..ecb9a73 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -444,8 +444,13 @@
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action == null) {
+ return;
+ }
+
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
- switch (intent.getAction()) {
+ switch (action) {
case Intent.ACTION_USER_REMOVED:
if (userId > 0) {
mHandler.doUserRemoved(userId);
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index a37779e..3e650da 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -666,7 +666,12 @@
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
- switch (intent.getAction()) {
+ final String action = intent.getAction();
+ if (action == null) {
+ return;
+ }
+
+ switch (action) {
case ConnectivityManager.CONNECTIVITY_ACTION: {
updateConnectivityState(intent);
} break;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
index e3ac780..7a21697 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java
@@ -84,9 +84,13 @@
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action == null) {
+ return;
+ }
+
final String pkgName = getPackageName(intent);
final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
- final String action = intent.getAction();
if (pkgUid == -1) {
Slog.e(TAG, "Didn't get package UID in intent (" + action + ")");
return;
diff --git a/core/api/current.txt b/core/api/current.txt
index 2c4c146..6b342a5 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -16232,6 +16232,7 @@
field public static final int UNKNOWN = 0; // 0x0
field public static final int Y8 = 538982489; // 0x20203859
field public static final int YCBCR_P010 = 54; // 0x36
+ field @FlaggedApi("android.media.codec.p210_format_support") public static final int YCBCR_P210 = 60; // 0x3c
field public static final int YUV_420_888 = 35; // 0x23
field public static final int YUV_422_888 = 39; // 0x27
field public static final int YUV_444_888 = 40; // 0x28
@@ -18580,6 +18581,7 @@
field public static final long USAGE_VIDEO_ENCODE = 65536L; // 0x10000L
field public static final int YCBCR_420_888 = 35; // 0x23
field public static final int YCBCR_P010 = 54; // 0x36
+ field @FlaggedApi("android.media.codec.p210_format_support") public static final int YCBCR_P210 = 60; // 0x3c
}
@FlaggedApi("android.hardware.flags.overlayproperties_class_api") public final class OverlayProperties implements android.os.Parcelable {
@@ -22871,6 +22873,7 @@
field public static final int COLOR_FormatYUV444Flexible = 2135181448; // 0x7f444888
field @Deprecated public static final int COLOR_FormatYUV444Interleaved = 29; // 0x1d
field public static final int COLOR_FormatYUVP010 = 54; // 0x36
+ field @FlaggedApi("android.media.codec.p210_format_support") public static final int COLOR_FormatYUVP210 = 60; // 0x3c
field @Deprecated public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
field @Deprecated public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
field public static final String FEATURE_AdaptivePlayback = "adaptive-playback";
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 27f9f54..cb31bc7 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -250,6 +250,7 @@
* @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/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index bca30b4..8de86d5 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -146,6 +146,7 @@
* This exception is thrown when a given package, application, or component
* name cannot be found.
*/
+ @android.ravenwood.annotation.RavenwoodKeepWholeClass
public static class NameNotFoundException extends AndroidException {
public NameNotFoundException() {
}
diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java
index 8ea450c..41585b3 100644
--- a/core/java/android/database/BulkCursorNative.java
+++ b/core/java/android/database/BulkCursorNative.java
@@ -53,7 +53,7 @@
return new BulkCursorProxy(obj);
}
-
+
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -79,7 +79,7 @@
reply.writeNoException();
return true;
}
-
+
case CLOSE_TRANSACTION: {
data.enforceInterface(IBulkCursor.descriptor);
close();
@@ -212,15 +212,22 @@
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
+ // If close() is being called from the finalizer thread, do not wait for a reply from
+ // the remote side.
+ final boolean fromFinalizer =
+ android.database.sqlite.Flags.onewayFinalizerClose()
+ && "FinalizerDaemon".equals(Thread.currentThread().getName());
+ mRemote.transact(CLOSE_TRANSACTION, data, reply,
+ fromFinalizer ? IBinder.FLAG_ONEWAY: 0);
+ if (!fromFinalizer) {
+ DatabaseUtils.readExceptionFromParcel(reply);
+ }
} finally {
data.recycle();
reply.recycle();
}
}
-
+
public int requery(IContentObserver observer) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -282,4 +289,3 @@
}
}
}
-
diff --git a/core/java/android/database/sqlite/flags.aconfig b/core/java/android/database/sqlite/flags.aconfig
index 285f984..c597895 100644
--- a/core/java/android/database/sqlite/flags.aconfig
+++ b/core/java/android/database/sqlite/flags.aconfig
@@ -2,6 +2,13 @@
container: "system"
flag {
+ name: "oneway_finalizer_close"
+ namespace: "system_performance"
+ description: "Make BuildCursorNative.close oneway if in the the finalizer"
+ bug: "368221351"
+}
+
+flag {
name: "sqlite_apis_35"
is_exported: true
namespace: "system_performance"
diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java
index ce0f9f59..0e73978 100644
--- a/core/java/android/hardware/HardwareBuffer.java
+++ b/core/java/android/hardware/HardwareBuffer.java
@@ -66,6 +66,7 @@
DS_FP32UI8,
S_UI8,
YCBCR_P010,
+ YCBCR_P210,
R_8,
R_16,
RG_1616,
@@ -111,6 +112,16 @@
* little-endian value, with the lower 6 bits set to zero.
*/
public static final int YCBCR_P010 = 0x36;
+ /**
+ * <p>Android YUV P210 format.</p>
+ *
+ * P210 is a 4:2:2 YCbCr semiplanar format comprised of a WxH Y plane
+ * followed by a WxH CbCr plane. Each sample is represented by a 16-bit
+ * little-endian value, with the lower 6 bits set to zero.
+ */
+ @FlaggedApi(android.media.codec.Flags.FLAG_P210_FORMAT_SUPPORT)
+ public static final int YCBCR_P210 = 0x3c;
+
/** Format: 8 bits red */
@FlaggedApi(com.android.graphics.hwui.flags.Flags.FLAG_REQUESTED_FORMATS_V)
public static final int R_8 = 0x38;
diff --git a/core/java/android/os/IpcDataCache.java b/core/java/android/os/IpcDataCache.java
index bf44d65..d7a308d 100644
--- a/core/java/android/os/IpcDataCache.java
+++ b/core/java/android/os/IpcDataCache.java
@@ -242,6 +242,7 @@
*/
@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 89fdeeb..933781c 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 @@
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 @@
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 7af3073..b1c48ab 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -256,6 +256,7 @@
"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 cd6abdd..95a4fe4 100644
--- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
+++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
@@ -39,11 +39,7 @@
* 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 b03fd64..5edf0ca 100644
--- a/core/tests/coretests/src/android/os/IpcDataCacheTest.java
+++ b/core/tests/coretests/src/android/os/IpcDataCacheTest.java
@@ -37,10 +37,7 @@
* 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/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index cb3b64c..93d94c9 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import java.lang.annotation.Retention;
@@ -41,6 +42,7 @@
Y8,
Y16,
YCBCR_P010,
+ YCBCR_P210,
NV16,
NV21,
YUY2,
@@ -206,6 +208,26 @@
public static final int YCBCR_P010 = 0x36;
/**
+ * <p>Android YUV P210 format.</p>
+ *
+ * P210 is a 4:2:2 YCbCr semiplanar format comprised of a WxH Y plane
+ * followed by a WxH CbCr plane. Each sample is represented by a 16-bit
+ * little-endian value, with the lower 6 bits set to zero.
+ *
+ * <p>For example, the {@link android.media.Image} object can provide data
+ * in this format from a {@link android.hardware.camera2.CameraDevice}
+ * through a {@link android.media.ImageReader} object if this format is
+ * supported by {@link android.hardware.camera2.CameraDevice}.</p>
+ *
+ * @see android.media.Image
+ * @see android.media.ImageReader
+ * @see android.hardware.camera2.CameraDevice
+ *
+ */
+ @FlaggedApi(android.media.codec.Flags.FLAG_P210_FORMAT_SUPPORT)
+ public static final int YCBCR_P210 = 0x3c;
+
+ /**
* YCbCr format, used for video.
*
* <p>For the {@link android.hardware.camera2} API, the {@link #YUV_420_888} format is
@@ -849,6 +871,8 @@
return 16;
case YCBCR_P010:
return 24;
+ case YCBCR_P210:
+ return 32;
case RAW_DEPTH10:
case RAW10:
return 10;
@@ -899,7 +923,9 @@
case JPEG_R:
return true;
}
-
+ if (android.media.codec.Flags.p210FormatSupport() && format == YCBCR_P210) {
+ return true;
+ }
return false;
}
}
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index 7f936f2..344d19a 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -23,9 +23,6 @@
import android.annotation.SystemApi;
import android.os.Process;
import android.security.keymaster.KeymasterDefs;
-
-import libcore.util.EmptyArray;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.security.spec.AlgorithmParameterSpec;
@@ -33,6 +30,7 @@
import java.security.spec.MGF1ParameterSpec;
import java.util.Collection;
import java.util.Locale;
+import libcore.util.EmptyArray;
/**
* Properties of <a href="{@docRoot}training/articles/keystore.html">Android Keystore</a> keys.
@@ -116,7 +114,7 @@
public static final int PURPOSE_AGREE_KEY = 1 << 6;
/**
- * Purpose of key: Signing attestaions. This purpose is incompatible with all others, meaning
+ * Purpose of key: Signing attestations. This purpose is incompatible with all others, meaning
* that when generating a key with PURPOSE_ATTEST_KEY, no other purposes may be specified. In
* addition, PURPOSE_ATTEST_KEY may not be specified for imported keys.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
index 4988a94..851472f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
@@ -25,6 +25,7 @@
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
import android.window.IBackAnimationRunner;
import android.window.IOnBackInvokedCallback;
@@ -32,6 +33,8 @@
import com.android.internal.jank.Cuj.CujType;
import com.android.wm.shell.common.InteractionJankMonitorUtils;
+import java.lang.ref.WeakReference;
+
/**
* Used to register the animation callback and runner, it will trigger result if gesture was finish
* before it received IBackAnimationRunner#onAnimationStart, so the controller could continue
@@ -80,22 +83,49 @@
return mCallback;
}
+ private Runnable mFinishedCallback;
+ private RemoteAnimationTarget[] mApps;
+ private IRemoteAnimationFinishedCallback mRemoteCallback;
+
+ private static class RemoteAnimationFinishedStub extends IRemoteAnimationFinishedCallback.Stub {
+ //the binder callback should not hold strong reference to it to avoid memory leak.
+ private WeakReference<BackAnimationRunner> mRunnerRef;
+
+ private RemoteAnimationFinishedStub(BackAnimationRunner runner) {
+ mRunnerRef = new WeakReference<>(runner);
+ }
+
+ @Override
+ public void onAnimationFinished() {
+ BackAnimationRunner runner = mRunnerRef.get();
+ if (runner == null) {
+ return;
+ }
+ if (runner.shouldMonitorCUJ(runner.mApps)) {
+ InteractionJankMonitorUtils.endTracing(runner.mCujType);
+ }
+
+ runner.mFinishedCallback.run();
+ for (int i = runner.mApps.length - 1; i >= 0; --i) {
+ SurfaceControl sc = runner.mApps[i].leash;
+ if (sc != null && sc.isValid()) {
+ sc.release();
+ }
+ }
+ runner.mApps = null;
+ runner.mFinishedCallback = null;
+ }
+ }
+
/**
* Called from {@link IBackAnimationRunner}, it will deliver these
* {@link RemoteAnimationTarget}s to the corresponding runner.
*/
void startAnimation(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps, Runnable finishedCallback) {
- final IRemoteAnimationFinishedCallback callback =
- new IRemoteAnimationFinishedCallback.Stub() {
- @Override
- public void onAnimationFinished() {
- if (shouldMonitorCUJ(apps)) {
- InteractionJankMonitorUtils.endTracing(mCujType);
- }
- finishedCallback.run();
- }
- };
+ mFinishedCallback = finishedCallback;
+ mApps = apps;
+ if (mRemoteCallback == null) mRemoteCallback = new RemoteAnimationFinishedStub(this);
mWaitingAnimation = false;
if (shouldMonitorCUJ(apps)) {
InteractionJankMonitorUtils.beginTracing(
@@ -103,7 +133,7 @@
}
try {
getRunner().onAnimationStart(TRANSIT_OLD_UNSET, apps, wallpapers,
- nonApps, callback);
+ nonApps, mRemoteCallback);
} catch (RemoteException e) {
Log.w(TAG, "Failed call onAnimationStart", e);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/OWNERS
new file mode 100644
index 0000000..752d2fd
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/OWNERS
@@ -0,0 +1,2 @@
+# WM Shell sub-module dagger owners
+jorgegil@google.com
\ No newline at end of file
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 8ff4305..3a19f46 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -462,6 +462,33 @@
@SuppressLint("AllUpper")
public static final int COLOR_FormatYUVP010 = 54;
+ /**
+ * P210 is 10-bit-per component 4:2:2 YCbCr semiplanar format.
+ * <p>
+ * This format uses 32 allocated bits per pixel with 20 bits of
+ * data per pixel. Chroma planes are subsampled by 2 both
+ * horizontally. Each chroma and luma component
+ * has 16 allocated bits in little-endian configuration with 10
+ * MSB of actual data.
+ *
+ * <pre>
+ * byte byte
+ * <--------- i --------> | <------ i + 1 ------>
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | UNUSED | Y/Cb/Cr |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * 0 5 6 7 0 7
+ * bit
+ * </pre>
+ *
+ * Use this format with {@link Image}. This format corresponds
+ * to {@link android.graphics.ImageFormat#YCBCR_P210}.
+ * <p>
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(android.media.codec.Flags.FLAG_P210_FORMAT_SUPPORT)
+ public static final int COLOR_FormatYUVP210 = 60;
+
/** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100;
// COLOR_FormatSurface indicates that the data will be a GraphicBuffer metadata reference.
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 5e55f64..678150b 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -584,45 +584,108 @@
* The following table summarizes codec support for containers across android releases:
*
* <table>
- * <thead>
- * <tr>
- * <th rowspan=2>OS Version(s)</th>
- * <td colspan=3>Codec support</th>
- * </tr><tr>
- * <th>{@linkplain OutputFormat#MUXER_OUTPUT_MPEG_4 MP4}</th>
- * <th>{@linkplain OutputFormat#MUXER_OUTPUT_WEBM WEBM}</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>{@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}</td>
- * <td rowspan=6>{@link MediaFormat#MIMETYPE_AUDIO_AAC AAC},<br>
- * {@link MediaFormat#MIMETYPE_AUDIO_AMR_NB NB-AMR},<br>
- * {@link MediaFormat#MIMETYPE_AUDIO_AMR_WB WB-AMR},<br>
- * {@link MediaFormat#MIMETYPE_VIDEO_H263 H.263},<br>
- * {@link MediaFormat#MIMETYPE_VIDEO_MPEG4 MPEG-4},<br>
- * {@link MediaFormat#MIMETYPE_VIDEO_AVC AVC} (H.264)</td>
- * <td rowspan=3>Not supported</td>
- * </tr><tr>
- * <td>{@link android.os.Build.VERSION_CODES#KITKAT}</td>
- * </tr><tr>
- * <td>{@link android.os.Build.VERSION_CODES#KITKAT_WATCH}</td>
- * </tr><tr>
- * <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</td>
- * <td rowspan=3>{@link MediaFormat#MIMETYPE_AUDIO_VORBIS Vorbis},<br>
- * {@link MediaFormat#MIMETYPE_VIDEO_VP8 VP8}</td>
- * </tr><tr>
- * <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</td>
- * </tr><tr>
- * <td>{@link android.os.Build.VERSION_CODES#M}</td>
- * </tr><tr>
- * <td>{@link android.os.Build.VERSION_CODES#N}</td>
- * <td>as above, plus<br>
- * {@link MediaFormat#MIMETYPE_VIDEO_HEVC HEVC} (H.265)</td>
- * <td>as above, plus<br>
- * {@link MediaFormat#MIMETYPE_VIDEO_VP9 VP9}</td>
- * </tr>
- * </tbody>
+ * <thead>
+ * <tr>
+ * <th>Codec</th>
+ * <th>{@linkplain OutputFormat#MUXER_OUTPUT_MPEG_4 MP4}</th>
+ * <th>{@linkplain OutputFormat#MUXER_OUTPUT_WEBM WEBM}</th>
+ * <th>{@linkplain OutputFormat#MUXER_OUTPUT_OGG OGG}</th>
+ * <th>Supported From SDK version</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_AUDIO_AAC AAC}</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>17</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_AUDIO_AMR_NB NB-AMR}</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>17</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_AUDIO_AMR_WB WB-AMR}</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>17</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_VIDEO_H263 H.263}</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>17</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_VIDEO_MPEG4 MPEG-4}</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>17</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_VIDEO_AVC AVC} (H.264)</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>17</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_AUDIO_VORBIS Vorbis}</td>
+ * <td></td>
+ * <td>✓</td>
+ * <td></td>
+ * <td>21</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_VIDEO_VP8 VP8}</td>
+ * <td></td>
+ * <td>✓</td>
+ * <td></td>
+ * <td>21</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_VIDEO_VP9 VP9}</td>
+ * <td></td>
+ * <td>✓</td>
+ * <td></td>
+ * <td>24</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_VIDEO_HEVC HEVC} (H.265)</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>24</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_AUDIO_OPUS OPUS}</td>
+ * <td></td>
+ * <td>✓</td>
+ * <td>✓</td>
+ * <td>26</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_VIDEO_AV1 AV1}</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>31</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MediaFormat#MIMETYPE_VIDEO_DOLBY_VISION Dolby Vision}</td>
+ * <td>✓</td>
+ * <td></td>
+ * <td></td>
+ * <td>32</td>
+ * </tr>
+ * </tbody>
* </table>
*
* @param format The media format for the track. This must not be an empty
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 371e3d2..b0c280b 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -935,6 +935,11 @@
return static_cast<jint>(PublicFormat::PRIVATE);
} else {
BufferItem* buffer = Image_getBufferItem(env, thiz);
+ if (buffer == nullptr) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Image is not initialized");
+ return -1;
+ }
int readerHalFormat = mapPublicFormatToHalFormat(static_cast<PublicFormat>(readerFormat));
int32_t fmt = applyFormatOverrides(
buffer->mGraphicBuffer->getPixelFormat(), readerHalFormat);
@@ -953,6 +958,11 @@
static jobject Image_getHardwareBuffer(JNIEnv* env, jobject thiz) {
BufferItem* buffer = Image_getBufferItem(env, thiz);
+ if (buffer == nullptr) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Image is not initialized");
+ return NULL;
+ }
AHardwareBuffer* b = AHardwareBuffer_from_GraphicBuffer(buffer->mGraphicBuffer.get());
// don't user the public AHardwareBuffer_toHardwareBuffer() because this would force us
// to link against libandroid.so
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
index 121f549..3696000 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
@@ -41,6 +41,7 @@
"/system_ext/etc/NOTICE.xml.gz",
"/vendor_dlkm/etc/NOTICE.xml.gz",
"/odm_dlkm/etc/NOTICE.xml.gz",
+ "/system_dlkm/etc/NOTICE.xml.gz",
};
static final String NOTICE_HTML_FILE_NAME = "NOTICE.html";
diff --git a/packages/SystemUI/animation/lib/OWNERS b/packages/SystemUI/animation/lib/OWNERS
new file mode 100644
index 0000000..7569419
--- /dev/null
+++ b/packages/SystemUI/animation/lib/OWNERS
@@ -0,0 +1,3 @@
+#inherits OWNERS from SystemUI in addition to WEAR framework owners below
+file:platform/frameworks/base:/WEAR_OWNERS
+
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
index b4b8715..016de8e 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
@@ -90,9 +90,7 @@
// Create the "latest" symlink.
Path symlink = Paths.get(tmpdir, basename + "latest.csv");
try {
- if (Files.exists(symlink)) {
- Files.delete(symlink);
- }
+ Files.deleteIfExists(symlink);
Files.createSymbolicLink(symlink, Paths.get(mOutputFile.getName()));
} catch (IOException e) {
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index 9c86389..a26fe66 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -359,3 +359,6 @@
com.android.server.SystemServiceManager
com.android.server.utils.TimingsTraceAndSlog
+
+android.os.IpcDataCache
+android.app.PropertyInvalidatedCache
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 5567707..0c99fcf 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -209,6 +209,10 @@
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
+ if (action == null) {
+ return;
+ }
+
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
if (DEBUG) {
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 8b619a4..9b987e9 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -670,6 +670,17 @@
}
private void readAllPermissions() {
+ readAllPermissionsFromXml();
+ readAllPermissionsFromEnvironment();
+
+ // Apply global feature removal last, after all features have been read.
+ // This only needs to happen once.
+ for (String featureName : mUnavailableFeatures) {
+ removeFeature(featureName);
+ }
+ }
+
+ private void readAllPermissionsFromXml() {
final XmlPullParser parser = Xml.newPullParser();
// Read configuration from system
@@ -1732,7 +1743,13 @@
} finally {
IoUtils.closeQuietly(permReader);
}
+ }
+ // Add features or permission dependent on global system properties (as
+ // opposed to XML permission files).
+ // This only needs to be called once after all features have been parsed
+ // from various partition/apex sources.
+ private void readAllPermissionsFromEnvironment() {
// Some devices can be field-converted to FBE, so offer to splice in
// those features if not already defined by the static config
if (StorageManager.isFileEncrypted()) {
@@ -1773,10 +1790,6 @@
addFeature(PackageManager.FEATURE_EROFS_LEGACY, 0);
}
}
-
- for (String featureName : mUnavailableFeatures) {
- removeFeature(featureName);
- }
}
private @Nullable SignedPackage parseEnhancedConfirmationTrustedPackage(XmlPullParser parser,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f549c7b..d11abf8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2874,8 +2874,12 @@
// Add common services.
// IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
// Enable the check in ApplicationThread.bindApplication() to make sure.
- if (!android.server.Flags.removeJavaServiceManagerCache()) {
- addServiceToMap(mAppBindArgs, "permissionmgr");
+
+ // Removing User Service and App Ops Service from cache breaks boot for auto.
+ // Removing permissionmgr breaks tests for Android Auto due to SELinux restrictions.
+ // TODO: fix SELinux restrictions and remove caching for Android Auto.
+ if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+ || !android.server.Flags.removeJavaServiceManagerCache()) {
addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
@@ -2896,12 +2900,12 @@
// See b/79378449
// Getting the window service and package service binder from servicemanager
// is blocked for Apps. However they are necessary for apps.
- // Removing User Service and App Ops Service from cache breaks boot for auto.
// TODO: remove exception
- addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
addServiceToMap(mAppBindArgs, "package");
addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
+ addServiceToMap(mAppBindArgs, "permissionmgr");
+ addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
}
return mAppBindArgs;
}
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 4c87e1c..c036605 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 @@
@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/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index bbe7b2b..8436c80 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1975,7 +1975,6 @@
void setAudioStatus(boolean mute, int volume) {
if (!isTvDeviceEnabled()
|| !tv().isSystemAudioActivated()
- || !tv().isArcEstablished() // Don't update TV volume when SAM is on and ARC is off
|| getHdmiCecVolumeControl()
== HdmiControlManager.VOLUME_CONTROL_DISABLED) {
return;
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 f09e035e..0000000
--- 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/LimitInputStream.java b/services/core/java/com/android/server/integrity/parser/LimitInputStream.java
deleted file mode 100644
index a91bbb7..0000000
--- a/services/core/java/com/android/server/integrity/parser/LimitInputStream.java
+++ /dev/null
@@ -1,84 +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 java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/** An {@link InputStream} that basically truncates another {@link InputStream} */
-public class LimitInputStream extends FilterInputStream {
- private int mReadBytes;
- private final int mLimit;
-
- public LimitInputStream(InputStream in, int limit) {
- super(in);
- if (limit < 0) {
- throw new IllegalArgumentException("limit " + limit + " cannot be negative");
- }
- mReadBytes = 0;
- mLimit = limit;
- }
-
- @Override
- public int available() throws IOException {
- return Math.min(super.available(), mLimit - mReadBytes);
- }
-
- @Override
- public int read() throws IOException {
- if (mReadBytes == mLimit) {
- return -1;
- }
- mReadBytes++;
- return super.read();
- }
-
- @Override
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (len <= 0) {
- return 0;
- }
- int available = available();
- if (available <= 0) {
- return -1;
- }
- int result = super.read(b, off, Math.min(len, available));
- mReadBytes += result;
- return result;
- }
-
- @Override
- public long skip(long n) throws IOException {
- if (n <= 0) {
- return 0;
- }
- int available = available();
- if (available <= 0) {
- return 0;
- }
- int bytesToSkip = (int) Math.min(available, n);
- long bytesSkipped = super.skip(bytesToSkip);
- mReadBytes += (int) bytesSkipped;
- return bytesSkipped;
- }
-}
diff --git a/services/core/java/com/android/server/integrity/parser/RandomAccessInputStream.java b/services/core/java/com/android/server/integrity/parser/RandomAccessInputStream.java
deleted file mode 100644
index 206e6a1..0000000
--- a/services/core/java/com/android/server/integrity/parser/RandomAccessInputStream.java
+++ /dev/null
@@ -1,97 +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 java.io.IOException;
-import java.io.InputStream;
-
-/** A wrapper around {@link RandomAccessObject} to turn it into a {@link InputStream}. */
-public class RandomAccessInputStream extends InputStream {
-
- private final RandomAccessObject mRandomAccessObject;
-
- private int mPosition;
-
- public RandomAccessInputStream(RandomAccessObject object) throws IOException {
- mRandomAccessObject = object;
- mPosition = 0;
- }
-
- /** Returns the position of the file pointer. */
- public int getPosition() {
- return mPosition;
- }
-
- /** See {@link RandomAccessObject#seek(int)} */
- public void seek(int position) throws IOException {
- mRandomAccessObject.seek(position);
- mPosition = position;
- }
-
- @Override
- public int available() throws IOException {
- return mRandomAccessObject.length() - mPosition;
- }
-
- @Override
- public void close() throws IOException {
- mRandomAccessObject.close();
- }
-
- @Override
- public int read() throws IOException {
- if (available() <= 0) {
- return -1;
- }
- mPosition++;
- return mRandomAccessObject.read();
- }
-
- @Override
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (len <= 0) {
- return 0;
- }
- int available = available();
- if (available <= 0) {
- return -1;
- }
- int result = mRandomAccessObject.read(b, off, Math.min(len, available));
- mPosition += result;
- return result;
- }
-
- @Override
- public long skip(long n) throws IOException {
- if (n <= 0) {
- return 0;
- }
- int available = available();
- if (available <= 0) {
- return 0;
- }
- int skipAmount = (int) Math.min(available, n);
- mPosition += skipAmount;
- mRandomAccessObject.seek(mPosition);
- return skipAmount;
- }
-}
diff --git a/services/core/java/com/android/server/integrity/parser/RandomAccessObject.java b/services/core/java/com/android/server/integrity/parser/RandomAccessObject.java
deleted file mode 100644
index d9b2e38..0000000
--- a/services/core/java/com/android/server/integrity/parser/RandomAccessObject.java
+++ /dev/null
@@ -1,133 +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 java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-
-/** An interface for random access objects like RandomAccessFile or byte arrays. */
-public abstract class RandomAccessObject {
-
- /** See {@link RandomAccessFile#seek(long)}. */
- public abstract void seek(int position) throws IOException;
-
- /** See {@link RandomAccessFile#read()}. */
- public abstract int read() throws IOException;
-
- /** See {@link RandomAccessFile#read(byte[], int, int)}. */
- public abstract int read(byte[] bytes, int off, int len) throws IOException;
-
- /** See {@link RandomAccessFile#close()}. */
- public abstract void close() throws IOException;
-
- /** See {@link java.io.RandomAccessFile#length()}. */
- public abstract int length();
-
- /** Static constructor from a file. */
- public static RandomAccessObject ofFile(File file) throws IOException {
- return new RandomAccessFileObject(file);
- }
-
- /** Static constructor from a byte array. */
- public static RandomAccessObject ofBytes(byte[] bytes) {
- return new RandomAccessByteArrayObject(bytes);
- }
-
- private static class RandomAccessFileObject extends RandomAccessObject {
- private final RandomAccessFile mRandomAccessFile;
- // We cache the length since File.length() invokes file IO.
- private final int mLength;
-
- RandomAccessFileObject(File file) throws IOException {
- long length = file.length();
- if (length > Integer.MAX_VALUE) {
- throw new IOException("Unsupported file size (too big) " + length);
- }
-
- mRandomAccessFile = new RandomAccessFile(file, /* mode= */ "r");
- mLength = (int) length;
- }
-
- @Override
- public void seek(int position) throws IOException {
- mRandomAccessFile.seek(position);
- }
-
- @Override
- public int read() throws IOException {
- return mRandomAccessFile.read();
- }
-
- @Override
- public int read(byte[] bytes, int off, int len) throws IOException {
- return mRandomAccessFile.read(bytes, off, len);
- }
-
- @Override
- public void close() throws IOException {
- mRandomAccessFile.close();
- }
-
- @Override
- public int length() {
- return mLength;
- }
- }
-
- private static class RandomAccessByteArrayObject extends RandomAccessObject {
-
- private final ByteBuffer mBytes;
-
- RandomAccessByteArrayObject(byte[] bytes) {
- mBytes = ByteBuffer.wrap(bytes);
- }
-
- @Override
- public void seek(int position) throws IOException {
- mBytes.position(position);
- }
-
- @Override
- public int read() throws IOException {
- if (!mBytes.hasRemaining()) {
- return -1;
- }
-
- return mBytes.get() & 0xFF;
- }
-
- @Override
- public int read(byte[] bytes, int off, int len) throws IOException {
- int bytesToCopy = Math.min(len, mBytes.remaining());
- if (bytesToCopy <= 0) {
- return 0;
- }
- mBytes.get(bytes, off, len);
- return bytesToCopy;
- }
-
- @Override
- public void close() throws IOException {}
-
- @Override
- public int length() {
- return mBytes.capacity();
- }
- }
-}
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 ea3a3d5..0000000
--- 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 595a035..0000000
--- a/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java
+++ /dev/null
@@ -1,55 +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 that is identified by the {@link
- * RuleIndexingController}.
- */
-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/RuleIndexingController.java b/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java
deleted file mode 100644
index 348a03b..0000000
--- a/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java
+++ /dev/null
@@ -1,128 +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.IndexingFileConstants.END_INDEXING_KEY;
-import static com.android.server.integrity.model.IndexingFileConstants.START_INDEXING_KEY;
-import static com.android.server.integrity.parser.BinaryFileOperations.getIntValue;
-import static com.android.server.integrity.parser.BinaryFileOperations.getStringValue;
-
-import android.content.integrity.AppInstallMetadata;
-
-import com.android.server.integrity.model.BitInputStream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/** Helper class to identify the necessary indexes that needs to be read. */
-public class RuleIndexingController {
-
- private static LinkedHashMap<String, Integer> sPackageNameBasedIndexes;
- private static LinkedHashMap<String, Integer> sAppCertificateBasedIndexes;
- private static LinkedHashMap<String, Integer> sUnindexedRuleIndexes;
-
- /**
- * Provide the indexing file to read and the object will be constructed by reading and
- * identifying the indexes.
- */
- public RuleIndexingController(InputStream inputStream) throws IOException {
- BitInputStream bitInputStream = new BitInputStream(inputStream);
- sPackageNameBasedIndexes = getNextIndexGroup(bitInputStream);
- sAppCertificateBasedIndexes = getNextIndexGroup(bitInputStream);
- sUnindexedRuleIndexes = getNextIndexGroup(bitInputStream);
- }
-
- /**
- * Returns a list of integers with the starting and ending bytes of the rules that needs to be
- * read and evaluated.
- */
- public List<RuleIndexRange> identifyRulesToEvaluate(AppInstallMetadata appInstallMetadata) {
- List<RuleIndexRange> indexRanges = new ArrayList<>();
-
- // Add the range for package name indexes rules.
- indexRanges.add(
- searchIndexingKeysRangeContainingKey(
- sPackageNameBasedIndexes, appInstallMetadata.getPackageName()));
-
- // Add the range for app certificate indexes rules of all certificates.
- for (String appCertificate : appInstallMetadata.getAppCertificates()) {
- indexRanges.add(
- searchIndexingKeysRangeContainingKey(
- sAppCertificateBasedIndexes, appCertificate));
- }
-
- // Add the range for unindexed rules.
- indexRanges.add(
- new RuleIndexRange(
- sUnindexedRuleIndexes.get(START_INDEXING_KEY),
- sUnindexedRuleIndexes.get(END_INDEXING_KEY)));
-
- return indexRanges;
- }
-
- private LinkedHashMap<String, Integer> getNextIndexGroup(BitInputStream bitInputStream)
- throws IOException {
- LinkedHashMap<String, Integer> keyToIndexMap = new LinkedHashMap<>();
- while (bitInputStream.hasNext()) {
- String key = getStringValue(bitInputStream);
- int value = getIntValue(bitInputStream);
-
- keyToIndexMap.put(key, value);
-
- if (key.matches(END_INDEXING_KEY)) {
- break;
- }
- }
- if (keyToIndexMap.size() < 2) {
- throw new IllegalStateException("Indexing file is corrupt.");
- }
- return keyToIndexMap;
- }
-
- private static RuleIndexRange searchIndexingKeysRangeContainingKey(
- LinkedHashMap<String, Integer> indexMap, String searchedKey) {
- List<String> keys = indexMap.keySet().stream().collect(Collectors.toList());
- List<String> identifiedKeyRange =
- searchKeysRangeContainingKey(keys, searchedKey, 0, keys.size() - 1);
- return new RuleIndexRange(
- indexMap.get(identifiedKeyRange.get(0)), indexMap.get(identifiedKeyRange.get(1)));
- }
-
- private static List<String> searchKeysRangeContainingKey(
- List<String> sortedKeyList, String key, int startIndex, int endIndex) {
- if (endIndex <= startIndex) {
- throw new IllegalStateException("Indexing file is corrupt.");
- }
- if (endIndex - startIndex == 1) {
- return Arrays.asList(sortedKeyList.get(startIndex), sortedKeyList.get(endIndex));
- }
-
- int midKeyIndex = startIndex + ((endIndex - startIndex) / 2);
- String midKey = sortedKeyList.get(midKeyIndex);
-
- if (key.compareTo(midKey) >= 0) {
- return searchKeysRangeContainingKey(sortedKeyList, key, midKeyIndex, endIndex);
- } else {
- return searchKeysRangeContainingKey(sortedKeyList, key, startIndex, midKeyIndex);
- }
- }
-}
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 c0f36a6..0000000
--- 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 126dacc..0000000
--- 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 980f40e..9b02ed0 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 @@
@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/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 69c78eb..f9c1037 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4283,6 +4283,10 @@
if (intent == null) {
return;
}
+ final String action = intent.getAction();
+ if (action == null) {
+ return;
+ }
Uri data = intent.getData();
if (data == null) {
return;
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 881bdbd..15fd35e 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -604,6 +604,11 @@
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action == null) {
+ Slog.w(TAG, "Intent broadcast does not contain action: " + intent);
+ return;
+ }
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
if (userId == UserHandle.USER_NULL) {
Slog.w(TAG, "Intent broadcast does not contain user handle: " + intent);
@@ -615,7 +620,7 @@
Slog.w(TAG, "Intent broadcast does not contain package name: " + intent);
return;
}
- switch (intent.getAction()) {
+ switch (action) {
case Intent.ACTION_PACKAGE_REMOVED:
final boolean replacing =
intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 5d2c50c..4310231 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -31,3 +31,7 @@
# Files related to tracing
per-file *TransitionTracer.java = file:platform/development:/tools/winscope/OWNERS
+
+# Files related to activity security
+per-file ActivityStarter.java = file:/ACTIVITY_SECURITY_OWNERS
+per-file ActivityTaskManagerService.java = file:/ACTIVITY_SECURITY_OWNERS
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 105147f..4e86888 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;
@@ -26,6 +28,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.camera2.CameraManager;
+import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
@@ -67,6 +70,8 @@
private int mUsageSetting;
private boolean mUploadEnabled;
+ private boolean mAdbActive;
+
private IProfCollectd mIProfcollect;
private static ProfcollectForwardingService sSelfService;
private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper());
@@ -84,6 +89,15 @@
Log.d(LOG_TAG, "Received broadcast to pack and upload reports");
createAndUploadReport(sSelfService);
}
+ if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) {
+ boolean isADB = intent.getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false);
+ if (isADB) {
+ boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
+ Log.d(LOG_TAG, "Received broadcast that ADB became " + connected
+ + ", was " + mAdbActive);
+ mAdbActive = connected;
+ }
+ }
}
};
@@ -108,6 +122,7 @@
final IntentFilter filter = new IntentFilter();
filter.addAction(INTENT_UPLOAD_PROFILES);
+ filter.addAction(UsbManager.ACTION_USB_STATE);
context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
}
@@ -125,7 +140,13 @@
}
@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;
@@ -281,6 +302,9 @@
if (mIProfcollect == null) {
return;
}
+ if (mAdbActive) {
+ return;
+ }
if (Utils.withFrequency("applaunch_trace_freq", 5)) {
Utils.traceSystem(mIProfcollect, "applaunch");
}
@@ -303,6 +327,9 @@
if (mIProfcollect == null) {
return;
}
+ if (mAdbActive) {
+ return;
+ }
if (Utils.withFrequency("dex2oat_trace_freq", 25)) {
// Dex2oat could take a while before it starts. Add a short delay before start tracing.
Utils.traceSystem(mIProfcollect, "dex2oat", /* delayMs */ 1000);
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt
index 1d668cd..13cf125 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt
@@ -17,6 +17,7 @@
package com.android.server.pm.parsing
import android.content.pm.PackageManager
+import android.content.pm.parsing.ApkLiteParseUtils
import android.platform.test.annotations.Postsubmit
import com.android.internal.pm.parsing.PackageParserException
import com.android.internal.pm.pkg.parsing.ParsingPackageUtils
@@ -81,8 +82,10 @@
val exceptions = buildApks()
.map {
runCatching {
- parser.parsePackage(
+ if (ApkLiteParseUtils.isApkFile(it) || it.isDirectory()) {
+ parser.parsePackage(
it, ParsingPackageUtils.PARSE_IS_SYSTEM_DIR, false /*useCaches*/)
+ }
}
}
.mapNotNull { it.exceptionOrNull() }
diff --git a/services/tests/powerstatstests/Android.bp b/services/tests/powerstatstests/Android.bp
index cedf9db..d786f3fc 100644
--- a/services/tests/powerstatstests/Android.bp
+++ b/services/tests/powerstatstests/Android.bp
@@ -69,7 +69,9 @@
"flag-junit",
],
srcs: [
- "src/com/android/server/power/stats/*.java",
+ // b/375477626 -- somehow this test is failing in presubmit on AOSP.
+ // This module is devlopped internal-fast, so we don't need to run it on AOSP.
+ // "src/com/android/server/power/stats/*.java",
],
java_resources: [
"res/xml/power_profile*.xml",
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 723b6c5..0000000
--- 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 03363a1..0000000
--- 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()));
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java
deleted file mode 100644
index 370bd80..0000000
--- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java
+++ /dev/null
@@ -1,216 +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.model.IndexingFileConstants.END_INDEXING_KEY;
-import static com.android.server.integrity.model.IndexingFileConstants.START_INDEXING_KEY;
-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 static org.testng.Assert.assertThrows;
-
-import android.content.integrity.AppInstallMetadata;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-@RunWith(JUnit4.class)
-public class RuleIndexingControllerTest {
-
- @Test
- public void verifyIndexRangeSearchIsCorrect() throws IOException {
- InputStream inputStream = obtainDefaultIndexingMapForTest();
-
- RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
- AppInstallMetadata appInstallMetadata =
- new AppInstallMetadata.Builder()
- .setPackageName("ddd")
- .setAppCertificates(Collections.singletonList("777"))
- .setAppCertificateLineage(Collections.singletonList("777"))
- .build();
-
- List<RuleIndexRange> resultingIndexes =
- indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
- assertThat(resultingIndexes)
- .containsExactly(
- new RuleIndexRange(200, 300),
- new RuleIndexRange(700, 800),
- new RuleIndexRange(900, 945));
- }
-
- @Test
- public void verifyIndexRangeSearchIsCorrect_multipleAppCertificates() throws IOException {
- InputStream inputStream = obtainDefaultIndexingMapForTest();
-
- RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
- AppInstallMetadata appInstallMetadata =
- new AppInstallMetadata.Builder()
- .setPackageName("ddd")
- .setAppCertificates(Arrays.asList("777", "999"))
- .setAppCertificateLineage(Arrays.asList("777", "999"))
- .build();
-
- List<RuleIndexRange> resultingIndexes =
- indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
- assertThat(resultingIndexes)
- .containsExactly(
- new RuleIndexRange(200, 300),
- new RuleIndexRange(700, 800),
- new RuleIndexRange(800, 900),
- new RuleIndexRange(900, 945));
- }
-
- @Test
- public void verifyIndexRangeSearchIsCorrect_keysInFirstAndLastBlock() throws IOException {
- InputStream inputStream = obtainDefaultIndexingMapForTest();
-
- RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
- AppInstallMetadata appInstallMetadata =
- new AppInstallMetadata.Builder()
- .setPackageName("bbb")
- .setAppCertificates(Collections.singletonList("999"))
- .setAppCertificateLineage(Collections.singletonList("999"))
- .build();
-
- List<RuleIndexRange> resultingIndexes =
- indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
- assertThat(resultingIndexes)
- .containsExactly(
- new RuleIndexRange(100, 200),
- new RuleIndexRange(800, 900),
- new RuleIndexRange(900, 945));
- }
-
- @Test
- public void verifyIndexRangeSearchIsCorrect_keysMatchWithValues() throws IOException {
- InputStream inputStream = obtainDefaultIndexingMapForTest();
-
- RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
- AppInstallMetadata appInstallMetadata =
- new AppInstallMetadata.Builder()
- .setPackageName("ccc")
- .setAppCertificates(Collections.singletonList("444"))
- .setAppCertificateLineage(Collections.singletonList("444"))
- .build();
-
- List<RuleIndexRange> resultingIndexes =
- indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
- assertThat(resultingIndexes)
- .containsExactly(
- new RuleIndexRange(200, 300),
- new RuleIndexRange(700, 800),
- new RuleIndexRange(900, 945));
- }
-
- @Test
- public void verifyIndexRangeSearchIsCorrect_noIndexesAvailable() throws IOException {
- byte[] stringBytes =
- getBytes(
- getKeyValueString(START_INDEXING_KEY, 100)
- + getKeyValueString(END_INDEXING_KEY, 500)
- + getKeyValueString(START_INDEXING_KEY, 500)
- + getKeyValueString(END_INDEXING_KEY, 900)
- + getKeyValueString(START_INDEXING_KEY, 900)
- + getKeyValueString(END_INDEXING_KEY, 945));
- ByteBuffer rule = ByteBuffer.allocate(stringBytes.length);
- rule.put(stringBytes);
- InputStream inputStream = new ByteArrayInputStream(rule.array());
-
- RuleIndexingController indexingController = new RuleIndexingController(inputStream);
-
- AppInstallMetadata appInstallMetadata =
- new AppInstallMetadata.Builder()
- .setPackageName("ccc")
- .setAppCertificates(Collections.singletonList("444"))
- .setAppCertificateLineage(Collections.singletonList("444"))
- .build();
-
- List<RuleIndexRange> resultingIndexes =
- indexingController.identifyRulesToEvaluate(appInstallMetadata);
-
- assertThat(resultingIndexes)
- .containsExactly(
- new RuleIndexRange(100, 500),
- new RuleIndexRange(500, 900),
- new RuleIndexRange(900, 945));
- }
-
- @Test
- public void verifyIndexingFileIsCorrupt() throws IOException {
- byte[] stringBytes =
- getBytes(
- getKeyValueString(START_INDEXING_KEY, 100)
- + getKeyValueString("ccc", 200)
- + getKeyValueString(END_INDEXING_KEY, 300)
- + getKeyValueString(END_INDEXING_KEY, 900));
- ByteBuffer rule = ByteBuffer.allocate(stringBytes.length);
- rule.put(stringBytes);
- InputStream inputStream = new ByteArrayInputStream(rule.array());
-
- assertThrows(IllegalStateException.class,
- () -> new RuleIndexingController(inputStream));
- }
-
- private static InputStream obtainDefaultIndexingMapForTest() {
- byte[] stringBytes =
- getBytes(
- getKeyValueString(START_INDEXING_KEY, 100)
- + getKeyValueString("ccc", 200)
- + getKeyValueString("eee", 300)
- + getKeyValueString("hhh", 400)
- + getKeyValueString(END_INDEXING_KEY, 500)
- + getKeyValueString(START_INDEXING_KEY, 500)
- + getKeyValueString("111", 600)
- + getKeyValueString("444", 700)
- + getKeyValueString("888", 800)
- + getKeyValueString(END_INDEXING_KEY, 900)
- + getKeyValueString(START_INDEXING_KEY, 900)
- + getKeyValueString(END_INDEXING_KEY, 945));
- ByteBuffer rule = ByteBuffer.allocate(stringBytes.length);
- rule.put(stringBytes);
- return new ByteArrayInputStream(rule.array());
- }
-
- private static String getKeyValueString(String key, int value) {
- String isNotHashed = "0";
- return isNotHashed
- + getBits(key.length(), VALUE_SIZE_BITS)
- + getValueBits(key)
- + getBits(value, /* numOfBits= */ 32);
- }
-}