diff options
53 files changed, 389 insertions, 1950 deletions
diff --git a/ACTIVITY_SECURITY_OWNERS b/ACTIVITY_SECURITY_OWNERS new file mode 100644 index 000000000000..c39842e1b7a3 --- /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 58b5f2a61be0..c828215ef225 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 3577fcdf04d6..f20b1706129b 100644 --- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java +++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java @@ -194,7 +194,7 @@ public final class ClientSocketPerfTest { /** * Simple benchmark for the amount of time to send a given number of messages */ - // @Test Temporarily disabled + @Test @Parameters(method = "getParams") public void time(Config config) throws Exception { reset(); diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java index ac5710047db9..af3c405eab82 100644 --- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java +++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java @@ -198,7 +198,7 @@ public final class ServerSocketPerfTest { executor.awaitTermination(5, TimeUnit.SECONDS); } - // @Test Temporarily disabled + @Test @Parameters(method = "getParams") public void throughput(Config config) throws Exception { setup(config); diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java index 33f6899239c6..ecb9a738aa32 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 @@ public class AppStateTrackerImpl implements AppStateTracker { 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 a37779e681fb..3e650da2e66f 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 @@ public class DeviceIdleController extends SystemService 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 e3ac780abf09..7a21697331af 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 @@ public final class BackgroundJobsController extends StateController { 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 2c4c1463ba62..6b342a541c97 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -16232,6 +16232,7 @@ package android.graphics { 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 @@ package android.hardware { 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 @@ package android.media { 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 27f9f54d9522..cb31bc73b9ba 100644 --- a/core/java/android/app/PropertyInvalidatedCache.java +++ b/core/java/android/app/PropertyInvalidatedCache.java @@ -250,6 +250,7 @@ import java.util.concurrent.atomic.AtomicLong; * @hide */ @TestApi +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class PropertyInvalidatedCache<Query, Result> { /** * This is a configuration class that customizes a cache instance. diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index bca30b4fec5a..8de86d5b60a0 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -146,6 +146,7 @@ public abstract class PackageManager { * 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 8ea450c6ca44..41585b3571d6 100644 --- a/core/java/android/database/BulkCursorNative.java +++ b/core/java/android/database/BulkCursorNative.java @@ -53,7 +53,7 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor return new BulkCursorProxy(obj); } - + @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { @@ -79,7 +79,7 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor reply.writeNoException(); return true; } - + case CLOSE_TRANSACTION: { data.enforceInterface(IBulkCursor.descriptor); close(); @@ -212,15 +212,22 @@ final class BulkCursorProxy implements IBulkCursor { 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 @@ final class BulkCursorProxy implements IBulkCursor { } } } - diff --git a/core/java/android/database/sqlite/flags.aconfig b/core/java/android/database/sqlite/flags.aconfig index 285f984faab7..c597895899b6 100644 --- a/core/java/android/database/sqlite/flags.aconfig +++ b/core/java/android/database/sqlite/flags.aconfig @@ -2,6 +2,13 @@ package: "android.database.sqlite" 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 ce0f9f598897..0e73978127c9 100644 --- a/core/java/android/hardware/HardwareBuffer.java +++ b/core/java/android/hardware/HardwareBuffer.java @@ -66,6 +66,7 @@ public final class HardwareBuffer implements Parcelable, AutoCloseable { DS_FP32UI8, S_UI8, YCBCR_P010, + YCBCR_P210, R_8, R_16, RG_1616, @@ -111,6 +112,16 @@ public final class HardwareBuffer implements Parcelable, AutoCloseable { * 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 bf44d65c4002..d7a308df4e6e 100644 --- a/core/java/android/os/IpcDataCache.java +++ b/core/java/android/os/IpcDataCache.java @@ -242,6 +242,7 @@ import java.util.concurrent.atomic.AtomicLong; */ @TestApi @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES) +@android.ravenwood.annotation.RavenwoodKeepWholeClass public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query, Result> { /** * {@inheritDoc} diff --git a/core/jni/android_text_Hyphenator.cpp b/core/jni/android_text_Hyphenator.cpp index 89fdeeb078d0..933781c3e924 100644 --- a/core/jni/android_text_Hyphenator.cpp +++ b/core/jni/android_text_Hyphenator.cpp @@ -14,17 +14,19 @@ * limitations under the License. */ +#include <core_jni_helpers.h> +#include <cutils/trace.h> #include <fcntl.h> +#include <minikin/Hyphenator.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> +#include <tracing_perfetto.h> +#include <unicode/uloc.h> #include <unistd.h> #include <algorithm> -#include <core_jni_helpers.h> -#include <minikin/Hyphenator.h> - namespace android { static std::string buildFileName(const std::string& locale) { @@ -79,6 +81,23 @@ static void addHyphenatorAlias(const std::string& from, const std::string& to) { minikin::addHyphenatorAlias(from, to); } +/* + * Cache the subtag key map by calling uloc_forLanguageTag with a subtag. + * minikin calls uloc_forLanguageTag with an Unicode extension specifying + * the line breaking strictness. Parsing the extension requires loading the key map + * from keyTypeData.res in the ICU. + * "lb" is the key commonly used by minikin. "ca" is a common legacy key mapping to + * the "calendar" key. It ensures that the key map is loaded and cached in icu4c. + * "en-Latn-US" is a common locale used in the Android system regardless what default locale + * is selected in the Settings app. + */ +inline static void cacheUnicodeExtensionSubtagsKeyMap() { + UErrorCode status = U_ZERO_ERROR; + char localeID[ULOC_FULLNAME_CAPACITY] = {}; + uloc_forLanguageTag("en-Latn-US-u-lb-loose-ca-gregory", localeID, ULOC_FULLNAME_CAPACITY, + nullptr, &status); +} + static void init() { // TODO: Confirm that these are the best values. Various sources suggest (1, 1), but that // appears too small. @@ -190,6 +209,10 @@ static void init() { addHyphenatorAlias("und-Orya", "or"); // Oriya addHyphenatorAlias("und-Taml", "ta"); // Tamil addHyphenatorAlias("und-Telu", "te"); // Telugu + + tracing_perfetto::traceBegin(ATRACE_TAG_VIEW, "CacheUnicodeExtensionSubtagsKeyMap"); + cacheUnicodeExtensionSubtagsKeyMap(); + tracing_perfetto::traceEnd(ATRACE_TAG_VIEW); // CacheUnicodeExtensionSubtagsKeyMap } static const JNINativeMethod gMethods[] = { diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 7af307317fc5..b1c48ab39396 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -256,6 +256,7 @@ android_ravenwood_test { "src/android/content/ContextTest.java", "src/android/content/pm/PackageManagerTest.java", "src/android/content/pm/UserInfoTest.java", + "src/android/app/PropertyInvalidatedCacheTests.java", "src/android/database/CursorWindowTest.java", "src/android/os/**/*.java", "src/android/telephony/PinResultTest.java", diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java index cd6abddc20a1..95a4fe4811f0 100644 --- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java +++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java @@ -39,11 +39,7 @@ import org.junit.Test; * atest FrameworksCoreTests:PropertyInvalidatedCacheTests */ @SmallTest -@IgnoreUnderRavenwood(blockedBy = PropertyInvalidatedCache.class) public class PropertyInvalidatedCacheTests { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule(); - // Configuration for creating caches private static final String MODULE = PropertyInvalidatedCache.MODULE_TEST; private static final String API = "testApi"; diff --git a/core/tests/coretests/src/android/os/IpcDataCacheTest.java b/core/tests/coretests/src/android/os/IpcDataCacheTest.java index b03fd6485786..5edf0cad1965 100644 --- a/core/tests/coretests/src/android/os/IpcDataCacheTest.java +++ b/core/tests/coretests/src/android/os/IpcDataCacheTest.java @@ -37,10 +37,7 @@ import org.junit.Test; * atest FrameworksCoreTests:IpcDataCacheTest */ @SmallTest -@IgnoreUnderRavenwood(blockedBy = IpcDataCache.class) public class IpcDataCacheTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule(); // Configuration for creating caches private static final String MODULE = IpcDataCache.MODULE_TEST; diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java index cb3b64c3e6cd..93d94c9cd7eb 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 @@ public class ImageFormat { Y8, Y16, YCBCR_P010, + YCBCR_P210, NV16, NV21, YUY2, @@ -206,6 +208,26 @@ public class ImageFormat { 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 @@ public class ImageFormat { return 16; case YCBCR_P010: return 24; + case YCBCR_P210: + return 32; case RAW_DEPTH10: case RAW10: return 10; @@ -899,7 +923,9 @@ public class ImageFormat { 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 7f936f28ac4f..344d19af9173 100644 --- a/keystore/java/android/security/keystore/KeyProperties.java +++ b/keystore/java/android/security/keystore/KeyProperties.java @@ -23,9 +23,6 @@ import android.annotation.StringDef; 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.ECParameterSpec; 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 abstract class KeyProperties { 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 4988a9481d21..851472f7d4c1 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.util.Log; 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.annotations.VisibleForTesting; 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 @@ public class BackAnimationRunner { 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 @@ public class BackAnimationRunner { } 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 000000000000..752d2fd721a5 --- /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 8ff4305a9817..3a19f466f7c1 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -462,6 +462,33 @@ public final class MediaCodecInfo { @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 5e55f64da985..678150b9f3a1 100644 --- a/media/java/android/media/MediaMuxer.java +++ b/media/java/android/media/MediaMuxer.java @@ -584,45 +584,108 @@ final public class MediaMuxer { * 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 371e3d2deda5..b0c280b426bf 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -935,6 +935,11 @@ static jint Image_getFormat(JNIEnv* env, jobject thiz, jint readerFormat) 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 jint Image_getFormat(JNIEnv* env, jobject thiz, jint readerFormat) 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 121f5492a5ab..36960002e220 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 @@ public class LicenseHtmlLoaderCompat extends AsyncLoaderCompat<File> { "/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 000000000000..7569419bf4a4 --- /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 b4b871524291..016de8e45291 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 @@ public class RavenwoodTestStats { // 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 9c8638930df9..a26fe66da2ab 100644 --- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt @@ -359,3 +359,6 @@ com.android.server.SystemService com.android.server.SystemServiceManager com.android.server.utils.TimingsTraceAndSlog + +android.os.IpcDataCache +android.app.PropertyInvalidatedCache diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 55677078f939..0c99fcfd221a 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 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku @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 8b619a40f19b..9b987e9850c4 100644 --- a/services/core/java/com/android/server/SystemConfig.java +++ b/services/core/java/com/android/server/SystemConfig.java @@ -670,6 +670,17 @@ public class SystemConfig { } 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 @@ public class SystemConfig { } 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 @@ public class SystemConfig { 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 f549c7b2d303..d11abf85c7d2 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 @@ public class ActivityManagerService extends IActivityManager.Stub // 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 @@ public class ActivityManagerService extends IActivityManager.Stub // 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 4c87e1ce357c..c036605b029f 100644 --- a/services/core/java/com/android/server/am/AppRestrictionController.java +++ b/services/core/java/com/android/server/am/AppRestrictionController.java @@ -373,7 +373,10 @@ public final class AppRestrictionController { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); - switch (intent.getAction()) { + if (action == null) { + return; + } + switch (action) { case Intent.ACTION_PACKAGE_ADDED: { if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index bbe7b2b038c9..8436c809337b 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 @@ public class HdmiControlService extends SystemService { 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 f09e035ecc78..000000000000 --- a/services/core/java/com/android/server/integrity/parser/BinaryFileOperations.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.parser; - -import static com.android.server.integrity.model.ComponentBitSize.IS_HASHED_BITS; -import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS; - -import android.content.integrity.IntegrityUtils; - -import com.android.server.integrity.model.BitInputStream; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Helper methods for reading standard data structures from {@link BitInputStream}. - */ -public class BinaryFileOperations { - - /** - * Read an string value with the given size and hash status from a {@code BitInputStream}. - * - * If the value is hashed, get the hex-encoding of the value. Serialized values are in raw form. - * All hashed values are hex-encoded. - */ - public static String getStringValue(BitInputStream bitInputStream) throws IOException { - boolean isHashedValue = bitInputStream.getNext(IS_HASHED_BITS) == 1; - int valueSize = bitInputStream.getNext(VALUE_SIZE_BITS); - return getStringValue(bitInputStream, valueSize, isHashedValue); - } - - /** - * Read an string value with the given size and hash status from a {@code BitInputStream}. - * - * If the value is hashed, get the hex-encoding of the value. Serialized values are in raw form. - * All hashed values are hex-encoded. - */ - public static String getStringValue( - BitInputStream bitInputStream, int valueSize, boolean isHashedValue) - throws IOException { - if (!isHashedValue) { - StringBuilder value = new StringBuilder(); - while (valueSize-- > 0) { - value.append((char) bitInputStream.getNext(/* numOfBits= */ 8)); - } - return value.toString(); - } - ByteBuffer byteBuffer = ByteBuffer.allocate(valueSize); - while (valueSize-- > 0) { - byteBuffer.put((byte) (bitInputStream.getNext(/* numOfBits= */ 8) & 0xFF)); - } - return IntegrityUtils.getHexDigest(byteBuffer.array()); - } - - /** Read an integer value from a {@code BitInputStream}. */ - public static int getIntValue(BitInputStream bitInputStream) throws IOException { - return bitInputStream.getNext(/* numOfBits= */ 32); - } - - /** Read an boolean value from a {@code BitInputStream}. */ - public static boolean getBooleanValue(BitInputStream bitInputStream) throws IOException { - return bitInputStream.getNext(/* numOfBits= */ 1) == 1; - } -} diff --git a/services/core/java/com/android/server/integrity/parser/LimitInputStream.java b/services/core/java/com/android/server/integrity/parser/LimitInputStream.java deleted file mode 100644 index a91bbb7dbae1..000000000000 --- 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 206e6a1f0197..000000000000 --- 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 d9b2e38b0062..000000000000 --- 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 ea3a3d5f1c60..000000000000 --- a/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.parser; - -import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START; -import static com.android.server.integrity.model.ComponentBitSize.BYTE_BITS; -import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END; -import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START; -import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS; -import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS; -import static com.android.server.integrity.model.ComponentBitSize.INSTALLER_ALLOWED_BY_MANIFEST_START; -import static com.android.server.integrity.model.ComponentBitSize.IS_HASHED_BITS; -import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS; -import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.SIGNAL_BIT; -import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS; -import static com.android.server.integrity.parser.BinaryFileOperations.getBooleanValue; -import static com.android.server.integrity.parser.BinaryFileOperations.getIntValue; -import static com.android.server.integrity.parser.BinaryFileOperations.getStringValue; - -import android.content.integrity.AtomicFormula; -import android.content.integrity.CompoundFormula; -import android.content.integrity.InstallerAllowedByManifestFormula; -import android.content.integrity.IntegrityFormula; -import android.content.integrity.Rule; - -import com.android.server.integrity.model.BitInputStream; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** A helper class to parse rules into the {@link Rule} model from Binary representation. */ -public class RuleBinaryParser implements RuleParser { - - @Override - public List<Rule> parse(byte[] ruleBytes) throws RuleParseException { - return parse(RandomAccessObject.ofBytes(ruleBytes), Collections.emptyList()); - } - - @Override - public List<Rule> parse(RandomAccessObject randomAccessObject, List<RuleIndexRange> indexRanges) - throws RuleParseException { - try (RandomAccessInputStream randomAccessInputStream = - new RandomAccessInputStream(randomAccessObject)) { - return parseRules(randomAccessInputStream, indexRanges); - } catch (Exception e) { - throw new RuleParseException(e.getMessage(), e); - } - } - - private List<Rule> parseRules( - RandomAccessInputStream randomAccessInputStream, List<RuleIndexRange> indexRanges) - throws IOException { - - // Read the rule binary file format version. - randomAccessInputStream.skip(FORMAT_VERSION_BITS / BYTE_BITS); - - return indexRanges.isEmpty() - ? parseAllRules(randomAccessInputStream) - : parseIndexedRules(randomAccessInputStream, indexRanges); - } - - private List<Rule> parseAllRules(RandomAccessInputStream randomAccessInputStream) - throws IOException { - List<Rule> parsedRules = new ArrayList<>(); - - BitInputStream inputStream = - new BitInputStream(new BufferedInputStream(randomAccessInputStream)); - while (inputStream.hasNext()) { - if (inputStream.getNext(SIGNAL_BIT) == 1) { - parsedRules.add(parseRule(inputStream)); - } - } - - return parsedRules; - } - - private List<Rule> parseIndexedRules( - RandomAccessInputStream randomAccessInputStream, List<RuleIndexRange> indexRanges) - throws IOException { - List<Rule> parsedRules = new ArrayList<>(); - - for (RuleIndexRange range : indexRanges) { - randomAccessInputStream.seek(range.getStartIndex()); - - BitInputStream inputStream = - new BitInputStream( - new BufferedInputStream( - new LimitInputStream( - randomAccessInputStream, - range.getEndIndex() - range.getStartIndex()))); - - // Read the rules until we reach the end index. available() here is not reliable. - while (inputStream.hasNext()) { - if (inputStream.getNext(SIGNAL_BIT) == 1) { - parsedRules.add(parseRule(inputStream)); - } - } - } - - return parsedRules; - } - - private Rule parseRule(BitInputStream bitInputStream) throws IOException { - IntegrityFormula formula = parseFormula(bitInputStream); - int effect = bitInputStream.getNext(EFFECT_BITS); - - if (bitInputStream.getNext(SIGNAL_BIT) != 1) { - throw new IllegalArgumentException("A rule must end with a '1' bit."); - } - - return new Rule(formula, effect); - } - - private IntegrityFormula parseFormula(BitInputStream bitInputStream) throws IOException { - int separator = bitInputStream.getNext(SEPARATOR_BITS); - switch (separator) { - case ATOMIC_FORMULA_START: - return parseAtomicFormula(bitInputStream); - case COMPOUND_FORMULA_START: - return parseCompoundFormula(bitInputStream); - case COMPOUND_FORMULA_END: - return null; - case INSTALLER_ALLOWED_BY_MANIFEST_START: - return new InstallerAllowedByManifestFormula(); - default: - throw new IllegalArgumentException( - String.format("Unknown formula separator: %s", separator)); - } - } - - private CompoundFormula parseCompoundFormula(BitInputStream bitInputStream) throws IOException { - int connector = bitInputStream.getNext(CONNECTOR_BITS); - List<IntegrityFormula> formulas = new ArrayList<>(); - - IntegrityFormula parsedFormula = parseFormula(bitInputStream); - while (parsedFormula != null) { - formulas.add(parsedFormula); - parsedFormula = parseFormula(bitInputStream); - } - - return new CompoundFormula(connector, formulas); - } - - private AtomicFormula parseAtomicFormula(BitInputStream bitInputStream) throws IOException { - int key = bitInputStream.getNext(KEY_BITS); - int operator = bitInputStream.getNext(OPERATOR_BITS); - - switch (key) { - case AtomicFormula.PACKAGE_NAME: - case AtomicFormula.APP_CERTIFICATE: - case AtomicFormula.APP_CERTIFICATE_LINEAGE: - case AtomicFormula.INSTALLER_NAME: - case AtomicFormula.INSTALLER_CERTIFICATE: - case AtomicFormula.STAMP_CERTIFICATE_HASH: - boolean isHashedValue = bitInputStream.getNext(IS_HASHED_BITS) == 1; - int valueSize = bitInputStream.getNext(VALUE_SIZE_BITS); - String stringValue = getStringValue(bitInputStream, valueSize, isHashedValue); - return new AtomicFormula.StringAtomicFormula(key, stringValue, isHashedValue); - case AtomicFormula.VERSION_CODE: - // TODO(b/147880712): temporary hack until our input handles long - long upper = getIntValue(bitInputStream); - long lower = getIntValue(bitInputStream); - long longValue = (upper << 32) | lower; - return new AtomicFormula.LongAtomicFormula(key, operator, longValue); - case AtomicFormula.PRE_INSTALLED: - case AtomicFormula.STAMP_TRUSTED: - boolean booleanValue = getBooleanValue(bitInputStream); - return new AtomicFormula.BooleanAtomicFormula(key, booleanValue); - default: - throw new IllegalArgumentException(String.format("Unknown key: %d", key)); - } - } -} diff --git a/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java b/services/core/java/com/android/server/integrity/parser/RuleIndexRange.java deleted file mode 100644 index 595a035baf1d..000000000000 --- 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 348a03be7317..000000000000 --- 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 c0f36a66528a..000000000000 --- a/services/core/java/com/android/server/integrity/parser/RuleParseException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.parser; - -import android.annotation.NonNull; - -/** - * Thrown when rule parsing fails. - */ -public class RuleParseException extends Exception { - public RuleParseException(@NonNull String message) { - super(message); - } - - public RuleParseException(@NonNull String message, @NonNull Throwable cause) { - super(message, cause); - } -} diff --git a/services/core/java/com/android/server/integrity/parser/RuleParser.java b/services/core/java/com/android/server/integrity/parser/RuleParser.java deleted file mode 100644 index 126dacc4fa40..000000000000 --- a/services/core/java/com/android/server/integrity/parser/RuleParser.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.parser; - -import android.content.integrity.Rule; - -import java.util.List; - -/** A helper class to parse rules into the {@link Rule} model. */ -public interface RuleParser { - - /** Parse rules from bytes. */ - List<Rule> parse(byte[] ruleBytes) throws RuleParseException; - - /** Parse rules from an input stream. */ - List<Rule> parse(RandomAccessObject randomAccessObject, List<RuleIndexRange> ruleIndexRanges) - throws RuleParseException; -} diff --git a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java index 980f40ee4a9a..9b02ed0ee0bd 100644 --- a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java +++ b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java @@ -1597,6 +1597,9 @@ public final class NotificationAttentionHelper { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); + if (action == null) { + return; + } if (action.equals(Intent.ACTION_SCREEN_ON)) { // Keep track of screen on/off state, but do not turn off the notification light diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 69c78eb155eb..f9c103762815 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 @@ public class PackageManagerService implements PackageSender, TestUtilityService 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 881bdbd3bc6a..15fd35e15f83 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 @@ public class SliceManagerService extends ISliceManager.Stub { 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 @@ public class SliceManagerService extends ISliceManager.Stub { 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 5d2c50c8aaca..431023163d0a 100644 --- a/services/core/java/com/android/server/wm/OWNERS +++ b/services/core/java/com/android/server/wm/OWNERS @@ -31,3 +31,7 @@ per-file ActivityCallerState.java = file:/core/java/android/app/COMPONENT_CALLER # 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 105147fe212d..4e868887ea1b 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -16,6 +16,8 @@ package com.android.server.profcollect; +import android.Manifest; +import android.annotation.RequiresPermission; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobScheduler; @@ -26,6 +28,7 @@ import android.content.Context; 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 @@ public final class ProfcollectForwardingService extends SystemService { 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 @@ public final class ProfcollectForwardingService extends SystemService { 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 @@ public final class ProfcollectForwardingService extends SystemService { 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 @@ public final class ProfcollectForwardingService extends SystemService { } @Override + @RequiresPermission(Manifest.permission.MANAGE_USB) public void onBootPhase(int phase) { + if (phase == PHASE_SYSTEM_SERVICES_READY) { + UsbManager usbManager = getContext().getSystemService(UsbManager.class); + mAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1); + Log.d(LOG_TAG, "ADB is " + mAdbActive + " on system startup"); + } if (phase == PHASE_BOOT_COMPLETED) { if (mIProfcollect == null) { return; @@ -281,6 +302,9 @@ public final class ProfcollectForwardingService extends SystemService { if (mIProfcollect == null) { return; } + if (mAdbActive) { + return; + } if (Utils.withFrequency("applaunch_trace_freq", 5)) { Utils.traceSystem(mIProfcollect, "applaunch"); } @@ -303,6 +327,9 @@ public final class ProfcollectForwardingService extends SystemService { 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 1d668cd3e8f2..13cf1252cadf 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 @@ class SystemPartitionParseTest { 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 cedf9dbe734f..d786f3fc52a0 100644 --- a/services/tests/powerstatstests/Android.bp +++ b/services/tests/powerstatstests/Android.bp @@ -69,7 +69,9 @@ android_ravenwood_test { "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 723b6c5af451..000000000000 --- a/services/tests/servicestests/src/com/android/server/integrity/parser/BinaryFileOperationsTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.parser; - -import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS; -import static com.android.server.integrity.parser.BinaryFileOperations.getBooleanValue; -import static com.android.server.integrity.parser.BinaryFileOperations.getIntValue; -import static com.android.server.integrity.parser.BinaryFileOperations.getStringValue; -import static com.android.server.integrity.utils.TestUtils.getBits; -import static com.android.server.integrity.utils.TestUtils.getBytes; -import static com.android.server.integrity.utils.TestUtils.getValueBits; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.integrity.IntegrityUtils; - -import com.android.server.integrity.model.BitInputStream; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -@RunWith(JUnit4.class) -public class BinaryFileOperationsTest { - - private static final String IS_NOT_HASHED = "0"; - private static final String IS_HASHED = "1"; - private static final String PACKAGE_NAME = "com.test.app"; - private static final String APP_CERTIFICATE = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - - @Test - public void testGetStringValue() throws IOException { - byte[] stringBytes = - getBytes( - IS_NOT_HASHED - + getBits(PACKAGE_NAME.length(), VALUE_SIZE_BITS) - + getValueBits(PACKAGE_NAME)); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(stringBytes)); - - String resultString = getStringValue(inputStream); - - assertThat(resultString).isEqualTo(PACKAGE_NAME); - } - - @Test - public void testGetHashedStringValue() throws IOException { - byte[] ruleBytes = - getBytes( - IS_HASHED - + getBits(APP_CERTIFICATE.length(), VALUE_SIZE_BITS) - + getValueBits(APP_CERTIFICATE)); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - String resultString = getStringValue(inputStream); - - assertThat(resultString) - .isEqualTo(IntegrityUtils.getHexDigest( - APP_CERTIFICATE.getBytes(StandardCharsets.UTF_8))); - } - - @Test - public void testGetStringValue_withSizeAndHashingInfo() throws IOException { - byte[] ruleBytes = getBytes(getValueBits(PACKAGE_NAME)); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - String resultString = getStringValue(inputStream, - PACKAGE_NAME.length(), /* isHashedValue= */false); - - assertThat(resultString).isEqualTo(PACKAGE_NAME); - } - - @Test - public void testGetIntValue() throws IOException { - int randomValue = 15; - byte[] ruleBytes = getBytes(getBits(randomValue, /* numOfBits= */ 32)); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - assertThat(getIntValue(inputStream)).isEqualTo(randomValue); - } - - @Test - public void testGetBooleanValue_true() throws IOException { - String booleanValue = "1"; - byte[] ruleBytes = getBytes(booleanValue); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - assertThat(getBooleanValue(inputStream)).isEqualTo(true); - } - - @Test - public void testGetBooleanValue_false() throws IOException { - String booleanValue = "0"; - byte[] ruleBytes = getBytes(booleanValue); - BitInputStream inputStream = new BitInputStream(new ByteArrayInputStream(ruleBytes)); - - assertThat(getBooleanValue(inputStream)).isEqualTo(false); - } -} diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java deleted file mode 100644 index 03363a100841..000000000000 --- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.parser; - -import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START; -import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END; -import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START; -import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.DEFAULT_FORMAT_VERSION; -import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS; -import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS; -import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS; -import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS; -import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS; -import static com.android.server.integrity.utils.TestUtils.getBits; -import static com.android.server.integrity.utils.TestUtils.getBytes; -import static com.android.server.integrity.utils.TestUtils.getValueBits; -import static com.android.server.testutils.TestUtils.assertExpectException; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.integrity.AtomicFormula; -import android.content.integrity.CompoundFormula; -import android.content.integrity.IntegrityUtils; -import android.content.integrity.Rule; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -@RunWith(JUnit4.class) -public class RuleBinaryParserTest { - - private static final String COMPOUND_FORMULA_START_BITS = - getBits(COMPOUND_FORMULA_START, SEPARATOR_BITS); - private static final String COMPOUND_FORMULA_END_BITS = - getBits(COMPOUND_FORMULA_END, SEPARATOR_BITS); - private static final String ATOMIC_FORMULA_START_BITS = - getBits(ATOMIC_FORMULA_START, SEPARATOR_BITS); - private static final int INVALID_FORMULA_SEPARATOR_VALUE = (1 << SEPARATOR_BITS) - 1; - private static final String INVALID_FORMULA_SEPARATOR_BITS = - getBits(INVALID_FORMULA_SEPARATOR_VALUE, SEPARATOR_BITS); - - private static final String NOT = getBits(CompoundFormula.NOT, CONNECTOR_BITS); - private static final String AND = getBits(CompoundFormula.AND, CONNECTOR_BITS); - private static final String OR = getBits(CompoundFormula.OR, CONNECTOR_BITS); - private static final int INVALID_CONNECTOR_VALUE = 3; - private static final String INVALID_CONNECTOR = - getBits(INVALID_CONNECTOR_VALUE, CONNECTOR_BITS); - - private static final String PACKAGE_NAME = getBits(AtomicFormula.PACKAGE_NAME, KEY_BITS); - private static final String APP_CERTIFICATE = getBits(AtomicFormula.APP_CERTIFICATE, KEY_BITS); - private static final String APP_CERTIFICATE_LINEAGE = - getBits(AtomicFormula.APP_CERTIFICATE_LINEAGE, KEY_BITS); - private static final String VERSION_CODE = getBits(AtomicFormula.VERSION_CODE, KEY_BITS); - private static final String PRE_INSTALLED = getBits(AtomicFormula.PRE_INSTALLED, KEY_BITS); - private static final int INVALID_KEY_VALUE = 9; - private static final String INVALID_KEY = getBits(INVALID_KEY_VALUE, KEY_BITS); - - private static final String EQ = getBits(AtomicFormula.EQ, OPERATOR_BITS); - private static final int INVALID_OPERATOR_VALUE = 5; - private static final String INVALID_OPERATOR = getBits(INVALID_OPERATOR_VALUE, OPERATOR_BITS); - - private static final String IS_NOT_HASHED = "0"; - private static final String IS_HASHED = "1"; - - private static final String DENY = getBits(Rule.DENY, EFFECT_BITS); - private static final int INVALID_EFFECT_VALUE = 5; - private static final String INVALID_EFFECT = getBits(INVALID_EFFECT_VALUE, EFFECT_BITS); - - private static final String START_BIT = "1"; - private static final String END_BIT = "1"; - private static final String INVALID_MARKER_BIT = "0"; - - private static final byte[] DEFAULT_FORMAT_VERSION_BYTES = - getBytes(getBits(DEFAULT_FORMAT_VERSION, FORMAT_VERSION_BITS)); - - private static final List<RuleIndexRange> NO_INDEXING = Collections.emptyList(); - - @Test - public void testBinaryStream_validCompoundFormula_noIndexing() throws Exception { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new CompoundFormula( - CompoundFormula.NOT, - Collections.singletonList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false))), - Rule.DENY); - - List<Rule> rules = - binaryParser.parse(RandomAccessObject.ofBytes(rule.array()), NO_INDEXING); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validCompoundFormula_notConnector_noIndexing() throws Exception { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new CompoundFormula( - CompoundFormula.NOT, - Collections.singletonList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false))), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validCompoundFormula_andConnector_noIndexing() throws Exception { - String packageName = "com.test.app"; - String appCertificate = "test_cert"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + AND - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE - + EQ - + IS_NOT_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new CompoundFormula( - CompoundFormula.AND, - Arrays.asList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false), - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, - appCertificate, - /* isHashedValue= */ false))), - Rule.DENY); - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validCompoundFormula_orConnector_noIndexing() throws Exception { - String packageName = "com.test.app"; - String appCertificate = "test_cert"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + OR - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE - + EQ - + IS_NOT_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new CompoundFormula( - CompoundFormula.OR, - Arrays.asList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false), - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, - appCertificate, - /* isHashedValue= */ false))), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormula_stringValue_noIndexing() throws Exception { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, - packageName, - /* isHashedValue= */ false), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormula_hashedValue_noIndexing() throws Exception { - String appCertificate = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE - + EQ - + IS_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, - IntegrityUtils.getHexDigest( - appCertificate.getBytes(StandardCharsets.UTF_8)), - /* isHashedValue= */ true), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormulaWithCertificateLineage() throws Exception { - String appCertificate = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE_LINEAGE - + EQ - + IS_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE_LINEAGE, - IntegrityUtils.getHexDigest( - appCertificate.getBytes(StandardCharsets.UTF_8)), - /* isHashedValue= */ true), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormula_integerValue_noIndexing() throws Exception { - int versionCode = 1; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + VERSION_CODE - + EQ - + getBits(versionCode, /* numOfBits= */ 64) - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.LongAtomicFormula( - AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 1), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_validAtomicFormula_booleanValue_noIndexing() throws Exception { - String isPreInstalled = "1"; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + PRE_INSTALLED - + EQ - + isPreInstalled - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - Rule expectedRule = - new Rule( - new AtomicFormula.BooleanAtomicFormula( - AtomicFormula.PRE_INSTALLED, true), - Rule.DENY); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEqualTo(Collections.singletonList(expectedRule)); - } - - @Test - public void testBinaryString_invalidAtomicFormula_noIndexing() { - int versionCode = 1; - String ruleBits = - START_BIT - + ATOMIC_FORMULA_START_BITS - + VERSION_CODE - + EQ - + getBits(versionCode, /* numOfBits= */ 64) - + DENY; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex= */ "A rule must end with a '1' bit.", - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_withNoRuleList_noIndexing() throws RuleParseException { - ByteBuffer rule = ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - RuleParser binaryParser = new RuleBinaryParser(); - - List<Rule> rules = binaryParser.parse(rule.array()); - - assertThat(rules).isEmpty(); - } - - @Test - public void testBinaryString_withEmptyRule_noIndexing() { - String ruleBits = START_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ "", - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidCompoundFormula_invalidNumberOfFormulas_noIndexing() { - String packageName = "com.test.app"; - String appCertificate = "test_cert"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + ATOMIC_FORMULA_START_BITS - + APP_CERTIFICATE - + EQ - + IS_NOT_HASHED - + getBits(appCertificate.length(), VALUE_SIZE_BITS) - + getValueBits(appCertificate) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ "Connector NOT must have 1 formula only", - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidOperator_noIndexing() { - int versionCode = 1; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + VERSION_CODE - + INVALID_OPERATOR - + getBits(versionCode, /* numOfBits= */ 64) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown operator: %d", INVALID_OPERATOR_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidEffect_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + INVALID_EFFECT - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown effect: %d", INVALID_EFFECT_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidConnector_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + INVALID_CONNECTOR - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown connector: %d", INVALID_CONNECTOR_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidKey_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + INVALID_KEY - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown key: %d", INVALID_KEY_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidSeparator_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + INVALID_FORMULA_SEPARATOR_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + END_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ String.format( - "Unknown formula separator: %d", INVALID_FORMULA_SEPARATOR_VALUE), - () -> binaryParser.parse(rule.array())); - } - - @Test - public void testBinaryString_invalidRule_invalidEndMarker_noIndexing() { - String packageName = "com.test.app"; - String ruleBits = - START_BIT - + COMPOUND_FORMULA_START_BITS - + NOT - + ATOMIC_FORMULA_START_BITS - + PACKAGE_NAME - + EQ - + IS_NOT_HASHED - + getBits(packageName.length(), VALUE_SIZE_BITS) - + getValueBits(packageName) - + COMPOUND_FORMULA_END_BITS - + DENY - + INVALID_MARKER_BIT; - byte[] ruleBytes = getBytes(ruleBits); - ByteBuffer rule = - ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length); - rule.put(DEFAULT_FORMAT_VERSION_BYTES); - rule.put(ruleBytes); - RuleParser binaryParser = new RuleBinaryParser(); - - assertExpectException( - RuleParseException.class, - /* expectedExceptionMessageRegex */ "A rule must end with a '1' bit", - () -> binaryParser.parse(rule.array())); - } -} 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 370bd80003bd..000000000000 --- 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); - } -} |