diff options
70 files changed, 1576 insertions, 467 deletions
diff --git a/apex/jobscheduler/OWNERS b/apex/jobscheduler/OWNERS index 58434f165aa2..22b648975e5f 100644 --- a/apex/jobscheduler/OWNERS +++ b/apex/jobscheduler/OWNERS @@ -2,7 +2,6 @@ ctate@android.com ctate@google.com dplotnikov@google.com jji@google.com -kwekua@google.com omakoto@google.com suprabh@google.com varunshah@google.com diff --git a/apex/jobscheduler/framework/java/android/app/job/OWNERS b/apex/jobscheduler/framework/java/android/app/job/OWNERS index b4a45f585157..0b1e559dda15 100644 --- a/apex/jobscheduler/framework/java/android/app/job/OWNERS +++ b/apex/jobscheduler/framework/java/android/app/job/OWNERS @@ -4,4 +4,3 @@ yamasani@google.com omakoto@google.com ctate@android.com ctate@google.com -kwekua@google.com diff --git a/apex/jobscheduler/service/java/com/android/server/tare/OWNERS b/apex/jobscheduler/service/java/com/android/server/tare/OWNERS index 96ec75f39e4e..b5c568bb158e 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/OWNERS +++ b/apex/jobscheduler/service/java/com/android/server/tare/OWNERS @@ -1,5 +1,4 @@ dplotnikov@google.com -kwekua@google.com mwachens@google.com suprabh@google.com -yamasani@google.com
\ No newline at end of file +yamasani@google.com diff --git a/apex/jobscheduler/service/jni/Android.bp b/apex/jobscheduler/service/jni/Android.bp index 34a1fa2ebc13..e8acff739e52 100644 --- a/apex/jobscheduler/service/jni/Android.bp +++ b/apex/jobscheduler/service/jni/Android.bp @@ -28,4 +28,8 @@ cc_library_shared { "liblog", "libbase", ], + visibility: [ + "//frameworks/base/apex:__subpackages__", + "//visibility:any_system_partition", + ], } diff --git a/api/coverage/tools/Android.bp b/api/coverage/tools/Android.bp index 3e169120dc48..caaca99bdc45 100644 --- a/api/coverage/tools/Android.bp +++ b/api/coverage/tools/Android.bp @@ -30,3 +30,24 @@ java_library_host { type: "full", }, } + +java_test_host { + name: "extract-flagged-apis-test", + srcs: ["ExtractFlaggedApisTest.kt"], + libs: [ + "extract_flagged_apis_proto", + "junit", + "libprotobuf-java-full", + ], + static_libs: [ + "truth", + "truth-liteproto-extension", + "truth-proto-extension", + ], + data: [ + ":extract-flagged-apis", + ], + test_options: { + unit_test: true, + }, +} diff --git a/api/coverage/tools/ExtractFlaggedApis.kt b/api/coverage/tools/ExtractFlaggedApis.kt index d5adfd09b994..5178f09f0301 100644 --- a/api/coverage/tools/ExtractFlaggedApis.kt +++ b/api/coverage/tools/ExtractFlaggedApis.kt @@ -28,12 +28,10 @@ fun main(args: Array<String>) { val builder = FlagApiMap.newBuilder() for (pkg in cb.getPackages().packages) { val packageName = pkg.qualifiedName() - pkg.allClasses() - .filter { it.methods().size > 0 } - .forEach { - extractFlaggedApisFromClass(it, it.methods(), packageName, builder) - extractFlaggedApisFromClass(it, it.constructors(), packageName, builder) - } + pkg.allClasses().forEach { + extractFlaggedApisFromClass(it, it.methods(), packageName, builder) + extractFlaggedApisFromClass(it, it.constructors(), packageName, builder) + } } val flagApiMap = builder.build() FileWriter(args[1]).use { it.write(flagApiMap.toString()) } @@ -45,6 +43,7 @@ fun extractFlaggedApisFromClass( packageName: String, builder: FlagApiMap.Builder ) { + if (methods.isEmpty()) return val classFlag = classItem.modifiers .findAnnotation("android.annotation.FlaggedApi") diff --git a/api/coverage/tools/ExtractFlaggedApisTest.kt b/api/coverage/tools/ExtractFlaggedApisTest.kt new file mode 100644 index 000000000000..ee5aaf15cb57 --- /dev/null +++ b/api/coverage/tools/ExtractFlaggedApisTest.kt @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2024 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 android.platform.coverage + +import com.google.common.truth.extensions.proto.ProtoTruth.assertThat +import com.google.protobuf.TextFormat +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardOpenOption +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(JUnit4::class) +class ExtractFlaggedApisTest { + + companion object { + const val COMMAND = "java -jar extract-flagged-apis.jar %s %s" + } + + private var apiTextFile: Path = Files.createTempFile("current", ".txt") + private var flagToApiMap: Path = Files.createTempFile("flag_api_map", ".textproto") + + @Before + fun setup() { + apiTextFile = Files.createTempFile("current", ".txt") + flagToApiMap = Files.createTempFile("flag_api_map", ".textproto") + } + + @After + fun cleanup() { + Files.deleteIfExists(apiTextFile) + Files.deleteIfExists(flagToApiMap) + } + + @Test + fun extractFlaggedApis_onlyMethodFlag_useMethodFlag() { + val apiText = + """ + // Signature format: 2.0 + package android.net.ipsec.ike { + public final class IkeSession implements java.lang.AutoCloseable { + method @FlaggedApi("com.android.ipsec.flags.dumpsys_api") public void dump(@NonNull java.io.PrintWriter); + } + } + """ + .trimIndent() + Files.write(apiTextFile, apiText.toByteArray(Charsets.UTF_8), StandardOpenOption.APPEND) + + val process = Runtime.getRuntime().exec(createCommand()) + process.waitFor() + + val content = Files.readAllBytes(flagToApiMap).toString(Charsets.UTF_8) + val result = TextFormat.parse(content, FlagApiMap::class.java) + + val expected = FlagApiMap.newBuilder() + val api = + JavaMethod.newBuilder() + .setPackageName("android.net.ipsec.ike") + .setClassName("IkeSession") + .setMethodName("dump") + api.addParameters("java.io.PrintWriter") + addFlaggedApi(expected, api, "com.android.ipsec.flags.dumpsys_api") + assertThat(result).isEqualTo(expected.build()) + } + + @Test + fun extractFlaggedApis_onlyClassFlag_useClassFlag() { + val apiText = + """ + // Signature format: 2.0 + package android.net.ipsec.ike { + @FlaggedApi("com.android.ipsec.flags.dumpsys_api") public final class IkeSession implements java.lang.AutoCloseable { + method public void dump(@NonNull java.io.PrintWriter); + } + } + """ + .trimIndent() + Files.write(apiTextFile, apiText.toByteArray(Charsets.UTF_8), StandardOpenOption.APPEND) + + val process = Runtime.getRuntime().exec(createCommand()) + process.waitFor() + + val content = Files.readAllBytes(flagToApiMap).toString(Charsets.UTF_8) + val result = TextFormat.parse(content, FlagApiMap::class.java) + + val expected = FlagApiMap.newBuilder() + val api = + JavaMethod.newBuilder() + .setPackageName("android.net.ipsec.ike") + .setClassName("IkeSession") + .setMethodName("dump") + api.addParameters("java.io.PrintWriter") + addFlaggedApi(expected, api, "com.android.ipsec.flags.dumpsys_api") + assertThat(result).isEqualTo(expected.build()) + } + + @Test + fun extractFlaggedApis_flaggedConstructorsAreFlaggedApis() { + val apiText = + """ + // Signature format: 2.0 + package android.app.pinner { + @FlaggedApi("android.app.pinner_service_client_api") public class PinnerServiceClient { + ctor @FlaggedApi("android.app.pinner_service_client_api") public PinnerServiceClient(); + } + } + """ + .trimIndent() + Files.write(apiTextFile, apiText.toByteArray(Charsets.UTF_8), StandardOpenOption.APPEND) + + val process = Runtime.getRuntime().exec(createCommand()) + process.waitFor() + + val content = Files.readAllBytes(flagToApiMap).toString(Charsets.UTF_8) + val result = TextFormat.parse(content, FlagApiMap::class.java) + + val expected = FlagApiMap.newBuilder() + val api = + JavaMethod.newBuilder() + .setPackageName("android.app.pinner") + .setClassName("PinnerServiceClient") + .setMethodName("PinnerServiceClient") + addFlaggedApi(expected, api, "android.app.pinner_service_client_api") + assertThat(result).isEqualTo(expected.build()) + } + + private fun addFlaggedApi(builder: FlagApiMap.Builder, api: JavaMethod.Builder, flag: String) { + if (builder.containsFlagToApi(flag)) { + val updatedApis = + builder.getFlagToApiOrThrow(flag).toBuilder().addJavaMethods(api).build() + builder.putFlagToApi(flag, updatedApis) + } else { + val apis = FlaggedApis.newBuilder().addJavaMethods(api).build() + builder.putFlagToApi(flag, apis) + } + } + + private fun createCommand(): Array<String> { + val command = + String.format(COMMAND, apiTextFile.toAbsolutePath(), flagToApiMap.toAbsolutePath()) + return command.split(" ").toTypedArray() + } +} diff --git a/cmds/incident_helper/OWNERS b/cmds/incident_helper/OWNERS index cede4eae50ad..29f44aba75d1 100644 --- a/cmds/incident_helper/OWNERS +++ b/cmds/incident_helper/OWNERS @@ -1,3 +1,2 @@ joeo@google.com -kwekua@google.com yanmin@google.com diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING index 7a449effdf76..af54a2decd89 100644 --- a/cmds/locksettings/TEST_MAPPING +++ b/cmds/locksettings/TEST_MAPPING @@ -11,5 +11,10 @@ } ] } + ], + "postsubmit": [ + { + "name": "CtsDevicePolicyManagerTestCases_LockSettings_NoFlakes" + } ] } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 0e66010ae2c3..1ac887b11603 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1050,6 +1050,8 @@ public final class ActivityThread extends ClientTransactionHandler public boolean managed; public boolean mallocInfo; public boolean runGc; + // compression format to dump bitmaps, null if no bitmaps to be dumped + public String dumpBitmaps; String path; ParcelFileDescriptor fd; RemoteCallback finishCallback; @@ -1442,11 +1444,12 @@ public final class ActivityThread extends ClientTransactionHandler } @Override - public void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, String path, - ParcelFileDescriptor fd, RemoteCallback finishCallback) { + public void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, String dumpBitmaps, + String path, ParcelFileDescriptor fd, RemoteCallback finishCallback) { DumpHeapData dhd = new DumpHeapData(); dhd.managed = managed; dhd.mallocInfo = mallocInfo; + dhd.dumpBitmaps = dumpBitmaps; dhd.runGc = runGc; dhd.path = path; try { @@ -6731,6 +6734,9 @@ public final class ActivityThread extends ClientTransactionHandler System.runFinalization(); System.gc(); } + if (dhd.dumpBitmaps != null) { + Bitmap.dumpAll(dhd.dumpBitmaps); + } try (ParcelFileDescriptor fd = dhd.fd) { if (dhd.managed) { Debug.dumpHprofData(dhd.path, fd.getFileDescriptor()); @@ -6758,6 +6764,9 @@ public final class ActivityThread extends ClientTransactionHandler if (dhd.finishCallback != null) { dhd.finishCallback.sendResult(null); } + if (dhd.dumpBitmaps != null) { + Bitmap.dumpAll(null); // clear dump + } } final void handleDispatchPackageBroadcast(int cmd, String[] packages) { diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 260e9859c72d..b84475e6014f 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -392,7 +392,7 @@ interface IActivityManager { oneway void getMimeTypeFilterAsync(in Uri uri, int userId, in RemoteCallback resultCallback); // Cause the specified process to dump the specified heap. boolean dumpHeap(in String process, int userId, boolean managed, boolean mallocInfo, - boolean runGc, in String path, in ParcelFileDescriptor fd, + boolean runGc, in String dumpBitmaps, in String path, in ParcelFileDescriptor fd, in RemoteCallback finishCallback); @UnsupportedAppUsage boolean isUserRunning(int userid, int flags); diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl index 5541e7aef160..40f3c1a66104 100644 --- a/core/java/android/app/IApplicationThread.aidl +++ b/core/java/android/app/IApplicationThread.aidl @@ -116,7 +116,8 @@ oneway interface IApplicationThread { void scheduleSuicide(); void dispatchPackageBroadcast(int cmd, in String[] packages); void scheduleCrash(in String msg, int typeId, in Bundle extras); - void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, in String path, + void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, + in String dumpBitmaps, in String path, in ParcelFileDescriptor fd, in RemoteCallback finishCallback); void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix, in String[] args); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index cbbe7856178d..6dd0a9077a67 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -1247,7 +1247,7 @@ public final class SurfaceControl implements Parcelable { * surface has no buffer or crop, the surface is boundless and only constrained * by the size of its parent bounds. * - * @param session The surface session, must not be null. + * @param session The surface session. * @param name The surface name, must not be null. * @param w The surface initial width. * @param h The surface initial height. diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java index c14d8d805d29..8063be64f36d 100644 --- a/core/java/com/android/internal/os/BinderInternal.java +++ b/core/java/com/android/internal/os/BinderInternal.java @@ -45,8 +45,8 @@ public class BinderInternal { static ArrayList<Runnable> sGcWatchers = new ArrayList<>(); static Runnable[] sTmpWatchers = new Runnable[1]; static long sLastGcTime; - static final BinderProxyLimitListenerDelegate sBinderProxyLimitListenerDelegate = - new BinderProxyLimitListenerDelegate(); + static final BinderProxyCountEventListenerDelegate sBinderProxyCountEventListenerDelegate = + new BinderProxyCountEventListenerDelegate(); static final class GcWatcher { @Override @@ -226,15 +226,24 @@ public class BinderInternal { * @param low The threshold a binder count must drop below before the callback * can be called again. (This is to avoid many repeated calls to the * callback in a brief period of time) + * @param warning The threshold between {@code high} and {@code low} where if the binder count + * exceeds that, the warning callback would be triggered. */ - public static final native void nSetBinderProxyCountWatermarks(int high, int low); + public static final native void nSetBinderProxyCountWatermarks(int high, int low, int warning); /** * Interface for callback invocation when the Binder Proxy limit is reached. onLimitReached will * be called with the uid of the app causing too many Binder Proxies */ - public interface BinderProxyLimitListener { + public interface BinderProxyCountEventListener { public void onLimitReached(int uid); + + /** + * Call when the number of binder proxies from the uid of the app reaches + * the warning threshold. + */ + default void onWarningThresholdReached(int uid) { + } } /** @@ -243,7 +252,17 @@ public class BinderInternal { * @param uid The uid of the bad behaving app sending too many binders */ public static void binderProxyLimitCallbackFromNative(int uid) { - sBinderProxyLimitListenerDelegate.notifyClient(uid); + sBinderProxyCountEventListenerDelegate.notifyLimitReached(uid); + } + + /** + * Callback used by native code to trigger a callback in java code. The callback will be + * triggered when too many binder proxies from a uid hits the warning limit. + * @param uid The uid of the bad behaving app sending too many binders + */ + @SuppressWarnings("unused") + public static void binderProxyWarningCallbackFromNative(int uid) { + sBinderProxyCountEventListenerDelegate.notifyWarningReached(uid); } /** @@ -252,41 +271,45 @@ public class BinderInternal { * @param handler must not be null, callback will be posted through the handler; * */ - public static void setBinderProxyCountCallback(BinderProxyLimitListener listener, + public static void setBinderProxyCountCallback(BinderProxyCountEventListener listener, @NonNull Handler handler) { Preconditions.checkNotNull(handler, "Must provide NonNull Handler to setBinderProxyCountCallback when setting " - + "BinderProxyLimitListener"); - sBinderProxyLimitListenerDelegate.setListener(listener, handler); + + "BinderProxyCountEventListener"); + sBinderProxyCountEventListenerDelegate.setListener(listener, handler); } /** * Clear the Binder Proxy callback */ public static void clearBinderProxyCountCallback() { - sBinderProxyLimitListenerDelegate.setListener(null, null); + sBinderProxyCountEventListenerDelegate.setListener(null, null); } - static private class BinderProxyLimitListenerDelegate { - private BinderProxyLimitListener mBinderProxyLimitListener; + private static class BinderProxyCountEventListenerDelegate { + private BinderProxyCountEventListener mBinderProxyCountEventListener; private Handler mHandler; - void setListener(BinderProxyLimitListener listener, Handler handler) { + void setListener(BinderProxyCountEventListener listener, Handler handler) { synchronized (this) { - mBinderProxyLimitListener = listener; + mBinderProxyCountEventListener = listener; mHandler = handler; } } - void notifyClient(final int uid) { + void notifyLimitReached(final int uid) { + synchronized (this) { + if (mBinderProxyCountEventListener != null) { + mHandler.post(() -> mBinderProxyCountEventListener.onLimitReached(uid)); + } + } + } + + void notifyWarningReached(final int uid) { synchronized (this) { - if (mBinderProxyLimitListener != null) { - mHandler.post(new Runnable() { - @Override - public void run() { - mBinderProxyLimitListener.onLimitReached(uid); - } - }); + if (mBinderProxyCountEventListener != null) { + mHandler.post(() -> + mBinderProxyCountEventListener.onWarningThresholdReached(uid)); } } } diff --git a/core/jni/OWNERS b/core/jni/OWNERS index d687ef375bc3..1a27367a2b06 100644 --- a/core/jni/OWNERS +++ b/core/jni/OWNERS @@ -109,3 +109,6 @@ per-file android_database_SQLite* = file:/SQLITE_OWNERS # PerformanceHintManager per-file android_os_PerformanceHintManager.cpp = file:/ADPF_OWNERS + +# IF Tools +per-file android_tracing_Perfetto* = file:platform/development:/tools/winscope/OWNERS diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index d2d5186eb8a1..2068bd7bc8ea 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -88,6 +88,7 @@ static struct binderinternal_offsets_t jclass mClass; jmethodID mForceGc; jmethodID mProxyLimitCallback; + jmethodID mProxyWarningCallback; } gBinderInternalOffsets; @@ -1240,7 +1241,7 @@ static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz) gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated; } -static void android_os_BinderInternal_proxyLimitcallback(int uid) +static void android_os_BinderInternal_proxyLimitCallback(int uid) { JNIEnv *env = AndroidRuntime::getJNIEnv(); env->CallStaticVoidMethod(gBinderInternalOffsets.mClass, @@ -1254,6 +1255,20 @@ static void android_os_BinderInternal_proxyLimitcallback(int uid) } } +static void android_os_BinderInternal_proxyWarningCallback(int uid) +{ + JNIEnv *env = AndroidRuntime::getJNIEnv(); + env->CallStaticVoidMethod(gBinderInternalOffsets.mClass, + gBinderInternalOffsets.mProxyWarningCallback, + uid); + + if (env->ExceptionCheck()) { + ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred()); + binder_report_exception(env, excep.get(), + "*** Uncaught exception in binderProxyWarningCallbackFromNative"); + } +} + static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz, jboolean enable) { @@ -1278,9 +1293,10 @@ static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject c } static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz, - jint high, jint low) + jint high, jint low, + jint warning) { - BpBinder::setBinderProxyCountWatermarks(high, low); + BpBinder::setBinderProxyCountWatermarks(high, low, warning); } // ---------------------------------------------------------------------------- @@ -1295,7 +1311,7 @@ static const JNINativeMethod gBinderInternalMethods[] = { { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled }, { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts }, { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount }, - { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks} + { "nSetBinderProxyCountWatermarks", "(III)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks} }; const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal"; @@ -1307,6 +1323,8 @@ static int int_register_android_os_BinderInternal(JNIEnv* env) gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V"); gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V"); + gBinderInternalOffsets.mProxyWarningCallback = + GetStaticMethodIDOrDie(env, clazz, "binderProxyWarningCallbackFromNative", "(I)V"); jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray"); gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass); @@ -1315,7 +1333,8 @@ static int int_register_android_os_BinderInternal(JNIEnv* env) gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put", "(II)V"); - BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback); + BpBinder::setBinderProxyCountEventCallback(android_os_BinderInternal_proxyLimitCallback, + android_os_BinderInternal_proxyWarningCallback); return RegisterMethodsOrDie( env, kBinderInternalPathName, diff --git a/core/proto/OWNERS b/core/proto/OWNERS index 00d90cc19c80..1a95520fdf86 100644 --- a/core/proto/OWNERS +++ b/core/proto/OWNERS @@ -11,7 +11,6 @@ zhouwenjie@google.com # Frameworks ogunwale@google.com jjaggi@google.com -kwekua@google.com roosa@google.com per-file package_item_info.proto = file:/PACKAGE_MANAGER_OWNERS per-file usagestatsservice.proto, usagestatsservice_v2.proto = file:/core/java/android/app/usage/OWNERS diff --git a/core/res/OWNERS b/core/res/OWNERS index 6924248b33cf..3c2bc0dd31a2 100644 --- a/core/res/OWNERS +++ b/core/res/OWNERS @@ -4,7 +4,6 @@ austindelgado@google.com cinek@google.com dsandler@android.com dsandler@google.com -dupin@google.com hackbod@android.com hackbod@google.com ilyamaty@google.com @@ -46,7 +45,7 @@ per-file res/values/config_device_idle.xml = file:/apex/jobscheduler/OWNERS # Wear per-file res/*-watch/* = file:/WEAR_OWNERS -# Peformance +# Performance per-file res/values/config.xml = file:/PERFORMANCE_OWNERS per-file res/values/symbols.xml = file:/PERFORMANCE_OWNERS @@ -60,3 +59,11 @@ per-file res/xml/sms_short_codes.xml = file:/platform/frameworks/opt/telephony:/ # TV Input Framework per-file res/values/config_tv_external_input_logging.xml = file:/services/core/java/com/android/server/tv/OWNERS + +# SysUi Color Team +per-file res/values/colors.xml = arteiro@google.com +per-file res/values/attrs.xml = arteiro@google.com +per-file res/values/styles.xml = arteiro@google.com +per-file res/values/symbols.xml = arteiro@google.com +per-file res/values/themes_device_defaults.xml = arteiro@google.com +per-file res/values/styles_material.xml = arteiro@google.com
\ No newline at end of file diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index c8625b9114da..9bb72d9db6c7 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -28,7 +28,7 @@ standard SMS rate. The user is warned when the destination phone number matches the "pattern" or "premium" regexes, and does not match the "free" or "standard" regexes. --> - <!-- Harmonised European Short Codes are 6 digit numbers starting with 116 (free helplines). + <!-- Harmonised European Short Codes are 7 digit numbers starting with 116 (free helplines). Premium patterns include short codes from: http://aonebill.com/coverage&tariffs and http://mobilcent.com/info-worldwide.asp and extracted from: http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ --> @@ -39,8 +39,8 @@ <!-- Albania: 5 digits, known short codes listed --> <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" /> - <!-- Argentina: 5 digits, known short codes listed --> - <shortcode country="ar" pattern="\\d{5}" free="11711|28291|44077|78887" /> + <!-- Argentina: 6 digits, known short codes listed --> + <shortcode country="ar" pattern="\\d{1,6}" free="11711|28291|44077|78887|191289|39010" /> <!-- Armenia: 3-5 digits, emergency numbers 10[123] --> <shortcode country="am" pattern="\\d{3,5}" premium="11[2456]1|3024" free="10[123]|71522|71512|71502" /> @@ -67,7 +67,7 @@ <shortcode country="bh" pattern="\\d{1,5}" free="81181|85999" /> <!-- Brazil: 1-5 digits (standard system default, not country specific) --> - <shortcode country="br" pattern="\\d{1,5}" free="6000[012]\\d|876|5500|9963|4141|8000" /> + <shortcode country="br" pattern="\\d{1,5}" free="6000[012]\\d|876|5500|9963|4141|8000|2652" /> <!-- Belarus: 4 digits --> <shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" /> @@ -163,7 +163,7 @@ <shortcode country="in" pattern="\\d{1,5}" free="59336|53969" /> <!-- Indonesia: 1-5 digits (standard system default, not country specific) --> - <shortcode country="id" pattern="\\d{1,5}" free="99477|6006|46645|363|93457" /> + <shortcode country="id" pattern="\\d{1,5}" free="99477|6006|46645|363|93457|99265" /> <!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU: http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf --> @@ -172,6 +172,9 @@ <!-- Israel: 1-5 digits, known premium codes listed --> <shortcode country="il" pattern="\\d{1,5}" premium="4422|4545" free="37477|6681" /> + <!-- Iran: 4-6 digits, known premium codes listed --> + <shortcode country="ir" pattern="\\d{4,6}" free="700791|700792" /> + <!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU: https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf --> <shortcode country="it" pattern="\\d{5}" premium="44[0-4]\\d{2}|47[0-4]\\d{2}|48[0-4]\\d{2}|44[5-9]\\d{4}|47[5-9]\\d{4}|48[5-9]\\d{4}|455\\d{2}|499\\d{2}" free="116\\d{3}|4112503|40\\d{0,12}" standard="430\\d{2}|431\\d{2}|434\\d{4}|435\\d{4}|439\\d{7}" /> @@ -219,11 +222,11 @@ <!-- Mozambique: 1-5 digits (standard system default, not country specific) --> <shortcode country="mz" pattern="\\d{1,5}" free="1714" /> - <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed --> - <shortcode country="mx" pattern="\\d{4,6}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101|45453|550346" /> + <!-- Mexico: 4-7 digits (not confirmed), known premium codes listed --> + <shortcode country="mx" pattern="\\d{4,7}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101|45453|550346|3030303" /> <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf --> - <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288|66668" /> + <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288|66668|66966" /> <!-- Namibia: 1-5 digits (standard system default, not country specific) --> <shortcode country="na" pattern="\\d{1,5}" free="40005" /> @@ -255,6 +258,9 @@ <!-- Palestine: 5 digits, known premium codes listed --> <shortcode country="ps" pattern="\\d{1,5}" free="37477|6681" /> + <!-- Paraguay: 6 digits, known premium codes listed --> + <shortcode country="py" pattern="\\d{6}" free="191289" /> + <!-- Poland: 4-5 digits (not confirmed), known premium codes listed, plus EU --> <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}|8012|80921" /> @@ -275,7 +281,7 @@ <shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)|8424" free="6954|8501" standard="2037|2044"/> <!-- Rwanda: 4 digits --> - <shortcode country="rw" pattern="\\d{4}" free="5060" /> + <shortcode country="rw" pattern="\\d{4}" free="5060|5061" /> <!-- Saudi Arabia --> <shortcode country="sa" pattern="\\d{1,5}" free="8145" /> @@ -309,7 +315,10 @@ <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" /> <!-- Tanzania: 1-5 digits (standard system default, not country specific) --> - <shortcode country="tz" pattern="\\d{1,5}" free="15046|15234" /> + <shortcode country="tz" pattern="\\d{1,5}" free="15046|15234|15324" /> + + <!-- Tunisia: 5 digits, known premium codes listed --> + <shortcode country="tn" pattern="\\d{5}" free="85799" /> <!-- Turkey --> <shortcode country="tr" pattern="\\d{1,5}" free="7529|5528|6493|3193" /> @@ -324,8 +333,11 @@ visual voicemail code for T-Mobile: 122 --> <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" standard="44567|244444" free="122|87902|21696|24614|28003|30356|33669|40196|41064|41270|43753|44034|46645|52413|56139|57969|61785|66975|75136|76227|81398|83952|85140|86566|86799|95737|96684|99245|611611|96831" /> - <!--Uruguay : 1-5 digits (standard system default, not country specific) --> - <shortcode country="uy" pattern="\\d{1,5}" free="55002" /> + <!--Uruguay : 1-6 digits (standard system default, not country specific) --> + <shortcode country="uy" pattern="\\d{1,6}" free="55002|191289" /> + + <!-- Venezuela: 1-6 digits (standard system default, not country specific) --> + <shortcode country="ve" pattern="\\d{1,6}" free="538352" /> <!-- Vietnam: 1-5 digits (standard system default, not country specific) --> <shortcode country="vn" pattern="\\d{1,5}" free="5001|9055|8079" /> @@ -336,6 +348,9 @@ <!-- South Africa --> <shortcode country="za" pattern="\\d{1,5}" free="44136|30791|36056|33009" /> + <!-- Yemen --> + <shortcode country="ye" pattern="\\d{1,4}" free="5081" /> + <!-- Zimbabwe --> <shortcode country="zw" pattern="\\d{1,5}" free="33679" /> diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 1a3ec27418a6..871feb65bc75 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -116,6 +116,8 @@ android_test { ":BinderDeathRecipientHelperApp1", ":BinderDeathRecipientHelperApp2", ":com.android.cts.helpers.aosp", + ":BinderProxyCountingTestApp", + ":BinderProxyCountingTestService", ], } diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml index 05b309b2cd52..bf2a5b875dba 100644 --- a/core/tests/coretests/AndroidTest.xml +++ b/core/tests/coretests/AndroidTest.xml @@ -22,6 +22,8 @@ <option name="test-file-name" value="FrameworksCoreTests.apk" /> <option name="test-file-name" value="BinderDeathRecipientHelperApp1.apk" /> <option name="test-file-name" value="BinderDeathRecipientHelperApp2.apk" /> + <option name="test-file-name" value="BinderProxyCountingTestApp.apk" /> + <option name="test-file-name" value="BinderProxyCountingTestService.apk" /> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> diff --git a/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml b/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml index a971730f389d..c8407b80cfac 100644 --- a/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml +++ b/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml @@ -16,6 +16,9 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.frameworks.coretests.binderproxycountingtestapp"> + <queries> + <package android:name="com.android.frameworks.coretests.binderproxycountingtestservice" /> + </queries> <application> <service android:name=".BpcTestAppCmdService" android:exported="true"/> diff --git a/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java b/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java index 5aae1203e559..a7e97d3cd54e 100644 --- a/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java +++ b/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java @@ -17,14 +17,15 @@ package com.android.frameworks.coretests.binderproxycountingtestapp; import android.app.Service; -import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.content.ServiceConnection; +import android.database.ContentObserver; +import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.provider.Settings; import android.util.Log; import com.android.frameworks.coretests.aidl.IBinderProxyCountingService; @@ -49,24 +50,20 @@ public class BpcTestAppCmdService extends Service { private IBpcTestAppCmdService.Stub mBinder = new IBpcTestAppCmdService.Stub() { - private ArrayList<BroadcastReceiver> mBrList = new ArrayList(); + private ArrayList<ContentObserver> mCoList = new ArrayList(); private ArrayList<ITestRemoteCallback> mTrcList = new ArrayList(); + private Handler mHandler = new Handler(); @Override public void createSystemBinders(int count) { int i = 0; while (i++ < count) { - BroadcastReceiver br = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - - } - }; - IntentFilter filt = new IntentFilter(Intent.ACTION_POWER_DISCONNECTED); - synchronized (mBrList) { - mBrList.add(br); + final ContentObserver co = new ContentObserver(mHandler) {}; + synchronized (mCoList) { + mCoList.add(co); } - registerReceiver(br, filt); + getContentResolver().registerContentObserver( + Settings.System.CONTENT_URI, false, co); } } @@ -74,11 +71,11 @@ public class BpcTestAppCmdService extends Service { public void releaseSystemBinders(int count) { int i = 0; while (i++ < count) { - BroadcastReceiver br; - synchronized (mBrList) { - br = mBrList.remove(0); + ContentObserver co; + synchronized (mCoList) { + co = mCoList.remove(0); } - unregisterReceiver(br); + getContentResolver().unregisterContentObserver(co); } } @@ -117,9 +114,9 @@ public class BpcTestAppCmdService extends Service { @Override public void releaseAllBinders() { - synchronized (mBrList) { - while (mBrList.size() > 0) { - unregisterReceiver(mBrList.remove(0)); + synchronized (mCoList) { + while (mCoList.size() > 0) { + getContentResolver().unregisterContentObserver(mCoList.remove(0)); } } synchronized (mTrcList) { @@ -179,4 +176,4 @@ public class BpcTestAppCmdService extends Service { public IBinder onBind(Intent intent) { return mBinder; } -}
\ No newline at end of file +} diff --git a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java index 6bed2a2ec53f..0f1accc4a7e9 100644 --- a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java +++ b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java @@ -55,8 +55,8 @@ public class BpcTestServiceCmdService extends Service { } @Override - public void setBinderProxyWatermarks(int high, int low) { - BinderInternal.nSetBinderProxyCountWatermarks(high, low); + public void setBinderProxyWatermarks(int high, int low, int warning) { + BinderInternal.nSetBinderProxyCountWatermarks(high, low, warning); } @Override @@ -68,12 +68,23 @@ public class BpcTestServiceCmdService extends Service { public void setBinderProxyCountCallback(IBpcCallbackObserver observer) { if (observer != null) { BinderInternal.setBinderProxyCountCallback( - new BinderInternal.BinderProxyLimitListener() { + new BinderInternal.BinderProxyCountEventListener() { @Override public void onLimitReached(int uid) { try { synchronized (observer) { - observer.onCallback(uid); + observer.onLimitReached(uid); + } + } catch (Exception e) { + Log.e(TAG, e.toString()); + } + } + + @Override + public void onWarningThresholdReached(int uid) { + try { + synchronized (observer) { + observer.onWarningThresholdReached(uid); } } catch (Exception e) { Log.e(TAG, e.toString()); @@ -98,4 +109,4 @@ public class BpcTestServiceCmdService extends Service { mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); } -}
\ No newline at end of file +} diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl index c4ebd56bed6c..ada7d92c89e1 100644 --- a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl +++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl @@ -17,5 +17,6 @@ package com.android.frameworks.coretests.aidl; interface IBpcCallbackObserver { - void onCallback(int uid); -}
\ No newline at end of file + void onLimitReached(int uid); + void onWarningThresholdReached(int uid); +} diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl index abdab41ce537..cdcda9d93bd2 100644 --- a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl +++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl @@ -20,7 +20,7 @@ import com.android.frameworks.coretests.aidl.IBpcCallbackObserver; interface IBpcTestServiceCmdService { void forceGc(); int getBinderProxyCount(int uid); - void setBinderProxyWatermarks(int high, int low); + void setBinderProxyWatermarks(int high, int low, int warning); void enableBinderProxyLimit(boolean enable); void setBinderProxyCountCallback(IBpcCallbackObserver observer); -}
\ No newline at end of file +} diff --git a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java index bcd9521019e4..84d299592f26 100644 --- a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java +++ b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java @@ -88,9 +88,10 @@ public class BinderProxyCountingTest { private static final int BIND_SERVICE_TIMEOUT_SEC = 5; private static final int TOO_MANY_BINDERS_TIMEOUT_SEC = 2; + private static final int TOO_MANY_BINDERS_WITH_KILL_TIMEOUT_SEC = 30; - // Keep in sync with sBinderProxyCountLimit in BpBinder.cpp - private static final int BINDER_PROXY_LIMIT = 2500; + // Keep in sync with BINDER_PROXY_HIGH_WATERMARK in ActivityManagerService.java + private static final int BINDER_PROXY_LIMIT = 6000; private static Context sContext; private static UiDevice sUiDevice; @@ -175,18 +176,26 @@ public class BinderProxyCountingTest { } } - private CountDownLatch createBinderLimitLatch() throws RemoteException { - final CountDownLatch latch = new CountDownLatch(1); + private CountDownLatch[] createBinderLimitLatch() throws RemoteException { + final CountDownLatch[] latches = new CountDownLatch[] { + new CountDownLatch(1), new CountDownLatch(1) + }; sBpcTestServiceCmdService.setBinderProxyCountCallback( new IBpcCallbackObserver.Stub() { @Override - public void onCallback(int uid) { + public void onLimitReached(int uid) { if (uid == sTestPkgUid) { - latch.countDown(); + latches[0].countDown(); + } + } + @Override + public void onWarningThresholdReached(int uid) { + if (uid == sTestPkgUid) { + latches[1].countDown(); } } }); - return latch; + return latches; } /** @@ -227,6 +236,7 @@ public class BinderProxyCountingTest { @Test public void testBinderProxyLimitBoundary() throws Exception { final int binderProxyLimit = 2000; + final int binderProxyWarning = 1900; final int rearmThreshold = 1800; try { sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent); @@ -238,19 +248,33 @@ public class BinderProxyCountingTest { // Get the baseline of binders naturally held by the test Package int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); - final CountDownLatch binderLimitLatch = createBinderLimitLatch(); - sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold); + final CountDownLatch[] binderLatches = createBinderLimitLatch(); + sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold, + binderProxyWarning); + + // Create Binder Proxies up to the warning; + sBpcTestAppCmdService.createTestBinders(binderProxyWarning - baseBinderCount); + if (binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid + + " when proxy warning should not have been triggered"); + } + + // Create one more Binder to trigger the warning + sBpcTestAppCmdService.createTestBinders(1); + if (!binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Timed out waiting for uid " + sTestPkgUid + " to trigger the warning"); + } // Create Binder Proxies up to the limit - sBpcTestAppCmdService.createTestBinders(binderProxyLimit - baseBinderCount); - if (binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + sBpcTestAppCmdService.createTestBinders(binderProxyLimit - binderProxyWarning - 1); + if (binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid + " when proxy limit should not have been reached"); } // Create one more Binder to cross the limit sBpcTestAppCmdService.createTestBinders(1); - if (!binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + if (!binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit"); } @@ -274,12 +298,20 @@ public class BinderProxyCountingTest { sBpcTestServiceCmdService.forceGc(); int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); for (int testLimit : testLimits) { - final CountDownLatch binderLimitLatch = createBinderLimitLatch(); + final CountDownLatch[] binderLatches = createBinderLimitLatch(); // Change the BinderProxyLimit - sBpcTestServiceCmdService.setBinderProxyWatermarks(testLimit, baseBinderCount + 10); + sBpcTestServiceCmdService.setBinderProxyWatermarks(testLimit, baseBinderCount + 10, + testLimit - 10); + + // Trigger the new Binder Proxy warning + sBpcTestAppCmdService.createTestBinders(testLimit - 9 - baseBinderCount); + if (!binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Timed out waiting for uid " + sTestPkgUid + " to trigger the warning"); + } + // Exceed the new Binder Proxy Limit - sBpcTestAppCmdService.createTestBinders(testLimit + 1); - if (!binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + sBpcTestAppCmdService.createTestBinders(10); + if (!binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit"); } @@ -297,6 +329,7 @@ public class BinderProxyCountingTest { public void testRearmCallbackThreshold() throws Exception { final int binderProxyLimit = 2000; final int exceedBinderProxyLimit = binderProxyLimit + 10; + final int binderProxyWarning = 1900; final int rearmThreshold = 1800; try { sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent); @@ -305,11 +338,19 @@ public class BinderProxyCountingTest { sBpcTestServiceCmdService.enableBinderProxyLimit(true); sBpcTestServiceCmdService.forceGc(); - final CountDownLatch firstBinderLimitLatch = createBinderLimitLatch(); - sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold); + int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); + final CountDownLatch[] firstBinderLatches = createBinderLimitLatch(); + sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold, + binderProxyWarning); + // Trigger the Binder Proxy Waring + sBpcTestAppCmdService.createTestBinders(binderProxyWarning - baseBinderCount + 1); + if (!firstBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Timed out waiting for uid " + sTestPkgUid + " to trigger warning"); + } + // Exceed the Binder Proxy Limit - sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit); - if (!firstBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - binderProxyWarning); + if (!firstBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit"); } @@ -321,11 +362,20 @@ public class BinderProxyCountingTest { sBpcTestServiceCmdService.forceGc(); currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); - final CountDownLatch secondBinderLimitLatch = createBinderLimitLatch(); + final CountDownLatch[] secondBinderLatches = createBinderLimitLatch(); + + // Exceed the Binder Proxy warning which should not cause a callback since there has + // been no rearm + sBpcTestAppCmdService.createTestBinders(binderProxyWarning - currentBinderCount + 1); + if (secondBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid + + " when the callback has not been rearmed yet"); + } + // Exceed the Binder Proxy limit which should not cause a callback since there has // been no rearm - sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - currentBinderCount); - if (secondBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - binderProxyWarning); + if (secondBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid + " when the callback has not been rearmed yet"); } @@ -337,10 +387,16 @@ public class BinderProxyCountingTest { sBpcTestServiceCmdService.forceGc(); currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); + // Trigger the Binder Proxy Waring + sBpcTestAppCmdService.createTestBinders(binderProxyWarning - currentBinderCount + 1); + if (!secondBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Timed out waiting for uid " + sTestPkgUid + " to trigger warning"); + } + // Exceed the Binder Proxy limit for the last time sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - currentBinderCount); - if (!secondBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + if (!secondBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit"); } sBpcTestAppCmdService.releaseTestBinders(currentBinderCount); @@ -373,7 +429,7 @@ public class BinderProxyCountingTest { // is not unexpected } - if (!binderDeathLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + if (!binderDeathLatch.await(TOO_MANY_BINDERS_WITH_KILL_TIMEOUT_SEC, TimeUnit.SECONDS)) { sBpcTestAppCmdService.releaseSystemBinders(exceedBinderProxyLimit); fail("Timed out waiting for uid " + sTestPkgUid + " to die."); } diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 250362b1e1e3..319f115d7427 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -41,12 +41,15 @@ import dalvik.annotation.optimization.CriticalNative; import libcore.util.NativeAllocationRegistry; import java.io.IOException; +import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.lang.ref.WeakReference; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; +import java.util.ArrayList; +import java.util.WeakHashMap; public final class Bitmap implements Parcelable { private static final String TAG = "Bitmap"; @@ -120,6 +123,11 @@ public final class Bitmap implements Parcelable { } /** + * @hide + */ + private static final WeakHashMap<Bitmap, Void> sAllBitmaps = new WeakHashMap<>(); + + /** * Private constructor that must receive an already allocated native bitmap * int (pointer). */ @@ -162,6 +170,9 @@ public final class Bitmap implements Parcelable { Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), allocationByteCount); } registry.registerNativeAllocation(this, nativeBitmap); + synchronized (Bitmap.class) { + sAllBitmaps.put(this, null); + } } /** @@ -1510,6 +1521,86 @@ public final class Bitmap implements Parcelable { } /** + * @hide + */ + private static final class DumpData { + private int count; + private int format; + private long[] natives; + private byte[][] buffers; + private int max; + + public DumpData(@NonNull CompressFormat format, int max) { + this.max = max; + this.format = format.nativeInt; + this.natives = new long[max]; + this.buffers = new byte[max][]; + this.count = 0; + } + + public void add(long nativePtr, byte[] buffer) { + natives[count] = nativePtr; + buffers[count] = buffer; + count = (count >= max) ? max : count + 1; + } + + public int size() { + return count; + } + } + + /** + * @hide + */ + private static DumpData dumpData = null; + + + /** + * @hide + * + * Dump all the bitmaps with their contents compressed into dumpData + * + * @param format format of the compressed image, null to clear dump data + */ + public static void dumpAll(@Nullable String format) { + if (format == null) { + /* release the dump data */ + dumpData = null; + return; + } + final CompressFormat fmt; + if (format.equals("jpg") || format.equals("jpeg")) { + fmt = CompressFormat.JPEG; + } else if (format.equals("png")) { + fmt = CompressFormat.PNG; + } else if (format.equals("webp")) { + fmt = CompressFormat.WEBP_LOSSLESS; + } else { + Log.w(TAG, "No bitmaps dumped: unrecognized format " + format); + return; + } + + final ArrayList<Bitmap> allBitmaps; + synchronized (Bitmap.class) { + allBitmaps = new ArrayList<>(sAllBitmaps.size()); + for (Bitmap bitmap : sAllBitmaps.keySet()) { + if (bitmap != null && !bitmap.isRecycled()) { + allBitmaps.add(bitmap); + } + } + } + + dumpData = new DumpData(fmt, allBitmaps.size()); + for (Bitmap bitmap : allBitmaps) { + ByteArrayOutputStream bas = new ByteArrayOutputStream(); + if (bitmap.compress(fmt, 90, bas)) { + dumpData.add(bitmap.getNativeInstance(), bas.toByteArray()); + } + } + Log.i(TAG, dumpData.size() + "/" + allBitmaps.size() + " bitmaps dumped"); + } + + /** * Number of bytes of temp storage we use for communicating between the * native compressor and the java OutputStream. */ diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java index efbbfc23736f..24aea371c094 100644 --- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java +++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java @@ -229,4 +229,24 @@ public class AndroidKeyStoreMaintenance { "Keystore error while trying to get apps affected by SID."); } } + + /** + * Deletes all keys in all KeyMint devices. + * Called by RecoverySystem before rebooting to recovery in order to delete all KeyMint keys, + * including synthetic password protector keys (used by LockSettingsService), as well as keys + * protecting DE and metadata encryption keys (used by vold). This ensures that FBE-encrypted + * data is unrecoverable even if the data wipe in recovery is interrupted or skipped. + */ + public static void deleteAllKeys() throws KeyStoreException { + StrictMode.noteDiskWrite(); + try { + getService().deleteAllKeys(); + } catch (RemoteException | NullPointerException e) { + throw new KeyStoreException(SYSTEM_ERROR, + "Failure to connect to Keystore while trying to delete all keys."); + } catch (ServiceSpecificException e) { + throw new KeyStoreException(e.errorCode, + "Keystore error while trying to delete all keys."); + } + } } diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 2cac2e150919..2f2215fd51a2 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -17,7 +17,6 @@ package android.security; import android.compat.annotation.UnsupportedAppUsage; -import android.os.StrictMode; /** * This class provides some constants and helper methods related to Android's Keystore service. @@ -38,17 +37,4 @@ public class KeyStore { public static KeyStore getInstance() { return KEY_STORE; } - - /** - * Add an authentication record to the keystore authorization table. - * - * @param authToken The packed bytes of a hw_auth_token_t to be provided to keymaster. - * @return 0 on success, otherwise an error value corresponding to a - * {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode. - */ - public int addAuthToken(byte[] authToken) { - StrictMode.noteDiskWrite(); - - return Authorization.addAuthToken(authToken); - } } diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/KeyStoreAuthorization.java index 6404c4bc33d6..14d715f03ae1 100644 --- a/keystore/java/android/security/Authorization.java +++ b/keystore/java/android/security/KeyStoreAuthorization.java @@ -33,15 +33,21 @@ import android.util.Log; * @hide This is the client side for IKeystoreAuthorization AIDL. * It shall only be used by biometric authentication providers and Gatekeeper. */ -public class Authorization { - private static final String TAG = "KeystoreAuthorization"; +public class KeyStoreAuthorization { + private static final String TAG = "KeyStoreAuthorization"; public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR; + private static final KeyStoreAuthorization sInstance = new KeyStoreAuthorization(); + + public static KeyStoreAuthorization getInstance() { + return sInstance; + } + /** * @return an instance of IKeystoreAuthorization */ - public static IKeystoreAuthorization getService() { + private IKeystoreAuthorization getService() { return IKeystoreAuthorization.Stub.asInterface( ServiceManager.checkService("android.security.authorization")); } @@ -52,7 +58,7 @@ public class Authorization { * @param authToken created by Android authenticators. * @return 0 if successful or {@code ResponseCode.SYSTEM_ERROR}. */ - public static int addAuthToken(@NonNull HardwareAuthToken authToken) { + public int addAuthToken(@NonNull HardwareAuthToken authToken) { StrictMode.noteSlowCall("addAuthToken"); try { getService().addAuthToken(authToken); @@ -70,7 +76,7 @@ public class Authorization { * @param authToken * @return 0 if successful or a {@code ResponseCode}. */ - public static int addAuthToken(@NonNull byte[] authToken) { + public int addAuthToken(@NonNull byte[] authToken) { return addAuthToken(AuthTokenUtils.toHardwareAuthToken(authToken)); } @@ -82,7 +88,7 @@ public class Authorization { * is LSKF (or equivalent) and thus has made the synthetic password available * @return 0 if successful or a {@code ResponseCode}. */ - public static int onDeviceUnlocked(int userId, @Nullable byte[] password) { + public int onDeviceUnlocked(int userId, @Nullable byte[] password) { StrictMode.noteDiskWrite(); try { getService().onDeviceUnlocked(userId, password); @@ -103,7 +109,7 @@ public class Authorization { * @param weakUnlockEnabled - true if non-strong biometric or trust agent unlock is enabled * @return 0 if successful or a {@code ResponseCode}. */ - public static int onDeviceLocked(int userId, @NonNull long[] unlockingSids, + public int onDeviceLocked(int userId, @NonNull long[] unlockingSids, boolean weakUnlockEnabled) { StrictMode.noteDiskWrite(); try { @@ -125,14 +131,17 @@ public class Authorization { * @return the last authentication time or * {@link BiometricConstants#BIOMETRIC_NO_AUTHENTICATION}. */ - public static long getLastAuthenticationTime( - long userId, @HardwareAuthenticatorType int[] authenticatorTypes) { + public long getLastAuthTime(long userId, @HardwareAuthenticatorType int[] authenticatorTypes) { try { return getService().getLastAuthTime(userId, authenticatorTypes); } catch (RemoteException | NullPointerException e) { - Log.w(TAG, "Can not connect to keystore", e); + Log.w(TAG, "Error getting last auth time: " + e); return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION; } catch (ServiceSpecificException e) { + // This is returned when the feature flag test fails in keystore2 + if (e.errorCode == ResponseCode.PERMISSION_DENIED) { + throw new UnsupportedOperationException(); + } return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION; } } diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp index d7b5914130ee..9d4b426a6759 100644 --- a/libs/androidfw/ZipFileRO.cpp +++ b/libs/androidfw/ZipFileRO.cpp @@ -304,7 +304,7 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry); const int32_t error = ExtractEntryToFile(mHandle, &(zipEntry->entry), fd); if (error) { - ALOGW("ExtractToMemory failed with %s", ErrorCodeString(error)); + ALOGW("ExtractToFile failed with %s", ErrorCodeString(error)); return false; } diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 4b63fbf14d4c..55b5e814ee41 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -367,7 +367,7 @@ void ASurfaceTransaction_reparent(ASurfaceTransaction* aSurfaceTransaction, void ASurfaceTransaction_setVisibility(ASurfaceTransaction* aSurfaceTransaction, ASurfaceControl* aSurfaceControl, - int8_t visibility) { + ASurfaceTransactionVisibility visibility) { CHECK_NOT_NULL(aSurfaceTransaction); CHECK_NOT_NULL(aSurfaceControl); @@ -496,7 +496,7 @@ void ASurfaceTransaction_setScale(ASurfaceTransaction* aSurfaceTransaction, void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* aSurfaceTransaction, ASurfaceControl* aSurfaceControl, - int8_t transparency) { + ASurfaceTransactionTransparency transparency) { CHECK_NOT_NULL(aSurfaceTransaction); CHECK_NOT_NULL(aSurfaceControl); diff --git a/nfc/TEST_MAPPING b/nfc/TEST_MAPPING index 5b5ea3790010..49c778d22038 100644 --- a/nfc/TEST_MAPPING +++ b/nfc/TEST_MAPPING @@ -5,6 +5,9 @@ }, { "name": "CtsNfcTestCases" + }, + { + "name": "CtsNdefTestCases" } ] } diff --git a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java index a8d8f9a1a55d..75a8bdfe5416 100644 --- a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java +++ b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java @@ -137,17 +137,6 @@ public class PackageWatchdog { static final int DEFAULT_BOOT_LOOP_TRIGGER_COUNT = 5; static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10); - // Boot loop at which packageWatchdog starts first mitigation - private static final String BOOT_LOOP_THRESHOLD = - "persist.device_config.configuration.boot_loop_threshold"; - @VisibleForTesting - static final int DEFAULT_BOOT_LOOP_THRESHOLD = 15; - // Once boot_loop_threshold is surpassed next mitigation would be triggered after - // specified number of reboots. - private static final String BOOT_LOOP_MITIGATION_INCREMENT = - "persist.device_config.configuration..boot_loop_mitigation_increment"; - @VisibleForTesting - static final int DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT = 2; // Threshold level at which or above user might experience significant disruption. private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD = @@ -253,15 +242,8 @@ public class PackageWatchdog { mConnectivityModuleConnector = connectivityModuleConnector; mSystemClock = clock; mNumberOfNativeCrashPollsRemaining = NUMBER_OF_NATIVE_CRASH_POLLS; - if (Flags.recoverabilityDetection()) { - mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - SystemProperties.getInt(BOOT_LOOP_MITIGATION_INCREMENT, - DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); - } else { - mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS); - } + mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT, + DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS); loadFromFile(); sPackageWatchdog = this; @@ -526,10 +508,16 @@ public class PackageWatchdog { /** * Called when the system server boots. If the system server is detected to be in a boot loop, * query each observer and perform the mitigation action with the lowest user impact. + * + * Note: PackageWatchdog considers system_server restart loop as bootloop. Full reboots + * are not counted in bootloop. */ @SuppressWarnings("GuardedBy") public void noteBoot() { synchronized (mLock) { + // if boot count has reached threshold, start mitigation. + // We wait until threshold number of restarts only for the first time. Perform + // mitigations for every restart after that. boolean mitigate = mBootThreshold.incrementAndTest(); if (mitigate) { if (!Flags.recoverabilityDetection()) { @@ -557,17 +545,13 @@ public class PackageWatchdog { } if (currentObserverToNotify != null) { if (Flags.recoverabilityDetection()) { - if (currentObserverImpact < getUserImpactLevelLimit() - || (currentObserverImpact >= getUserImpactLevelLimit() - && mBootThreshold.getCount() >= getBootLoopThreshold())) { - int currentObserverMitigationCount = - currentObserverInternal.getBootMitigationCount() + 1; - currentObserverInternal.setBootMitigationCount( - currentObserverMitigationCount); - saveAllObserversBootMitigationCountToMetadata(METADATA_FILE); - currentObserverToNotify.executeBootLoopMitigation( - currentObserverMitigationCount); - } + int currentObserverMitigationCount = + currentObserverInternal.getBootMitigationCount() + 1; + currentObserverInternal.setBootMitigationCount( + currentObserverMitigationCount); + saveAllObserversBootMitigationCountToMetadata(METADATA_FILE); + currentObserverToNotify.executeBootLoopMitigation( + currentObserverMitigationCount); } else { mBootThreshold.setMitigationCount(mitigationCount); mBootThreshold.saveMitigationCountToMetadata(); @@ -647,11 +631,6 @@ public class PackageWatchdog { DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD); } - private int getBootLoopThreshold() { - return SystemProperties.getInt(BOOT_LOOP_THRESHOLD, - DEFAULT_BOOT_LOOP_THRESHOLD); - } - /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. */ @Retention(SOURCE) @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_LEVEL_0, @@ -1827,16 +1806,10 @@ public class PackageWatchdog { private final int mBootTriggerCount; private final long mTriggerWindow; - private final int mBootMitigationIncrement; BootThreshold(int bootTriggerCount, long triggerWindow) { - this(bootTriggerCount, triggerWindow, /*bootMitigationIncrement=*/ 1); - } - - BootThreshold(int bootTriggerCount, long triggerWindow, int bootMitigationIncrement) { this.mBootTriggerCount = bootTriggerCount; this.mTriggerWindow = triggerWindow; - this.mBootMitigationIncrement = bootMitigationIncrement; } public void reset() { @@ -1915,6 +1888,7 @@ public class PackageWatchdog { } else { readMitigationCountFromMetadataIfNecessary(); } + final long now = mSystemClock.uptimeMillis(); if (now - getStart() < 0) { Slog.e(TAG, "Window was less than zero. Resetting start to current time."); @@ -1939,20 +1913,32 @@ public class PackageWatchdog { setCount(count); EventLogTags.writeRescueNote(Process.ROOT_UID, count, window); if (Flags.recoverabilityDetection()) { - boolean mitigate = (count >= mBootTriggerCount) - && (count - mBootTriggerCount) % mBootMitigationIncrement == 0; - return mitigate; + // After a reboot (e.g. by WARM_REBOOT or mainline rollback) we apply + // mitigations without waiting for DEFAULT_BOOT_LOOP_TRIGGER_COUNT. + return (count >= mBootTriggerCount) + || (performedMitigationsDuringWindow() && count > 1); } return count >= mBootTriggerCount; } } @GuardedBy("mLock") + private boolean performedMitigationsDuringWindow() { + for (ObserverInternal observerInternal: mAllObservers.values()) { + if (observerInternal.getBootMitigationCount() > 0) { + return true; + } + } + return false; + } + + @GuardedBy("mLock") private void resetAllObserversBootMitigationCount() { for (int i = 0; i < mAllObservers.size(); i++) { final ObserverInternal observer = mAllObservers.valueAt(i); observer.setBootMitigationCount(0); } + saveAllObserversBootMitigationCountToMetadata(METADATA_FILE); } @GuardedBy("mLock") diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java index 7093ba42f40d..f86eb61c365f 100644 --- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java +++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java @@ -139,7 +139,7 @@ public class RescueParty { static final String NAMESPACE_TO_PACKAGE_MAPPING_FLAG = "namespace_to_package_mapping"; @VisibleForTesting - static final long DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN = 10; + static final long DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN = 1440; private static final String NAME = "rescue-party-observer"; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java index 76c228252484..d5962886266d 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java @@ -99,9 +99,10 @@ public class SystemUIService extends Service { if (Build.IS_DEBUGGABLE) { // b/71353150 - looking for leaked binder proxies BinderInternal.nSetBinderProxyCountEnabled(true); - BinderInternal.nSetBinderProxyCountWatermarks(1000,900); + BinderInternal.nSetBinderProxyCountWatermarks( + /* high= */ 1000, /* low= */ 900, /* warning= */ 950); BinderInternal.setBinderProxyCountCallback( - new BinderInternal.BinderProxyLimitListener() { + new BinderInternal.BinderProxyCountEventListener() { @Override public void onLimitReached(int uid) { Slog.w(SystemUIApplication.TAG, diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java index 3349345b1391..c4293291de51 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java @@ -345,9 +345,7 @@ public class ShadeCarrierGroupController { } } - if (mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()) { - Log.d(TAG, "ignoring old pipeline callback because new mobile icon is enabled"); - } else { + if (!mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()) { for (int i = 0; i < SIM_SLOTS; i++) { mCarrierGroups[i].updateState(mInfos[i], singleCarrier); } diff --git a/services/core/Android.bp b/services/core/Android.bp index 267f27864838..7b0bc8f501d8 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -169,7 +169,9 @@ java_library_static { "android.hardware.health-V3-java", // AIDL "android.hardware.health-translate-java", "android.hardware.light-V1-java", + "android.hardware.security.authgraph-V1-java", "android.hardware.security.rkp-V3-java", + "android.hardware.security.secretkeeper-V1-java", "android.hardware.tv.cec-V1.1-java", "android.hardware.tv.hdmi.cec-V1-java", "android.hardware.tv.hdmi.connection-V1-java", @@ -206,6 +208,7 @@ java_library_static { "service-jobscheduler-deviceidle.flags-aconfig-java", "net_flags_lib", "core_os_flags_lib", + "connectivity_flags_lib", ], javac_shard_size: 50, javacflags: [ diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 09c1dea2f65a..d35892e152db 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -413,6 +413,7 @@ import com.android.internal.os.BackgroundThread; import com.android.internal.os.BinderCallHeavyHitterWatcher.BinderCallHeavyHitterListener; import com.android.internal.os.BinderCallHeavyHitterWatcher.HeavyHitterContainer; import com.android.internal.os.BinderInternal; +import com.android.internal.os.BinderInternal.BinderProxyCountEventListener; import com.android.internal.os.BinderTransactionNameResolver; import com.android.internal.os.ByteTransferPipe; import com.android.internal.os.IResultReceiver; @@ -610,8 +611,8 @@ public class ActivityManagerService extends IActivityManager.Stub private static final int MINIMUM_MEMORY_GROWTH_THRESHOLD = 10 * 1000; // 10 MB /** - * The number of binder proxies we need to have before we start warning and - * dumping debug info. + * The number of binder proxies we need to have before we start dumping debug info + * and kill the offenders. */ private static final int BINDER_PROXY_HIGH_WATERMARK = 6000; @@ -621,6 +622,11 @@ public class ActivityManagerService extends IActivityManager.Stub */ private static final int BINDER_PROXY_LOW_WATERMARK = 5500; + /** + * The number of binder proxies we need to have before we start warning. + */ + private static final int BINDER_PROXY_WARNING_WATERMARK = 5750; + // Max character limit for a notification title. If the notification title is larger than this // the notification will not be legible to the user. private static final int MAX_BUGREPORT_TITLE_SIZE = 100; @@ -8926,33 +8932,10 @@ public class ActivityManagerService extends IActivityManager.Stub t.traceBegin("setBinderProxies"); BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK, - BINDER_PROXY_LOW_WATERMARK); + BINDER_PROXY_LOW_WATERMARK, BINDER_PROXY_WARNING_WATERMARK); BinderInternal.nSetBinderProxyCountEnabled(true); - BinderInternal.setBinderProxyCountCallback( - (uid) -> { - Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " - + Process.myUid()); - BinderProxy.dumpProxyDebugInfo(); - if (uid == Process.SYSTEM_UID) { - Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); - } else { - killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), - ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE, - ApplicationExitInfo.SUBREASON_EXCESSIVE_BINDER_OBJECTS, - "Too many Binders sent to SYSTEM"); - // We need to run a GC here, because killing the processes involved - // actually isn't guaranteed to free up the proxies; in fact, if the - // GC doesn't run for a long time, we may even exceed the global - // proxy limit for a process (20000), resulting in system_server itself - // being killed. - // Note that the GC here might not actually clean up all the proxies, - // because the binder reference decrements will come in asynchronously; - // but if new processes belonging to the UID keep adding proxies, we - // will get another callback here, and run the GC again - this time - // cleaning up the old proxies. - VMRuntime.getRuntime().requestConcurrentGC(); - } - }, BackgroundThread.getHandler()); + BinderInternal.setBinderProxyCountCallback(new MyBinderProxyCountEventListener(), + BackgroundThread.getHandler()); t.traceEnd(); // setBinderProxies t.traceEnd(); // ActivityManagerStartApps @@ -8967,6 +8950,45 @@ public class ActivityManagerService extends IActivityManager.Stub } } + private class MyBinderProxyCountEventListener implements BinderProxyCountEventListener { + @Override + public void onLimitReached(int uid) { + Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " + + Process.myUid()); + BinderProxy.dumpProxyDebugInfo(); + if (uid == Process.SYSTEM_UID) { + Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); + } else { + killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), + ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE, + ApplicationExitInfo.SUBREASON_EXCESSIVE_BINDER_OBJECTS, + "Too many Binders sent to SYSTEM"); + // We need to run a GC here, because killing the processes involved + // actually isn't guaranteed to free up the proxies; in fact, if the + // GC doesn't run for a long time, we may even exceed the global + // proxy limit for a process (20000), resulting in system_server itself + // being killed. + // Note that the GC here might not actually clean up all the proxies, + // because the binder reference decrements will come in asynchronously; + // but if new processes belonging to the UID keep adding proxies, we + // will get another callback here, and run the GC again - this time + // cleaning up the old proxies. + VMRuntime.getRuntime().requestConcurrentGC(); + } + } + + @Override + public void onWarningThresholdReached(int uid) { + if (com.android.server.am.Flags.logExcessiveBinderProxies()) { + Slog.w(TAG, "Uid " + uid + " sent too many (" + + BINDER_PROXY_WARNING_WATERMARK + ") Binders to uid " + Process.myUid()); + FrameworkStatsLog.write( + FrameworkStatsLog.EXCESSIVE_BINDER_PROXY_COUNT_REPORTED, + uid); + } + } + } + private void watchDeviceProvisioning(Context context) { // setting system property based on whether device is provisioned @@ -17297,7 +17319,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo, - boolean runGc, String path, ParcelFileDescriptor fd, RemoteCallback finishCallback) { + boolean runGc, String dumpBitmaps, + String path, ParcelFileDescriptor fd, RemoteCallback finishCallback) { try { // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to // its own permission (same as profileControl). @@ -17331,7 +17354,8 @@ public class ActivityManagerService extends IActivityManager.Stub } }, null); - thread.dumpHeap(managed, mallocInfo, runGc, path, fd, intermediateCallback); + thread.dumpHeap(managed, mallocInfo, runGc, dumpBitmaps, + path, fd, intermediateCallback); fd = null; return true; } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index c8f6303eb145..7c6673145d34 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -1231,6 +1231,7 @@ final class ActivityManagerShellCommand extends ShellCommand { final PrintWriter err = getErrPrintWriter(); boolean managed = true; boolean mallocInfo = false; + String dumpBitmaps = null; int userId = UserHandle.USER_CURRENT; boolean runGc = false; @@ -1249,6 +1250,11 @@ final class ActivityManagerShellCommand extends ShellCommand { } else if (opt.equals("-m")) { managed = false; mallocInfo = true; + } else if (opt.equals("-b")) { + dumpBitmaps = getNextArg(); + if (dumpBitmaps == null) { + dumpBitmaps = "png"; // default to PNG in dumping bitmaps + } } else { err.println("Error: Unknown option: " + opt); return -1; @@ -1280,8 +1286,8 @@ final class ActivityManagerShellCommand extends ShellCommand { } }, null); - if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd, - finishCallback)) { + if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, dumpBitmaps, + heapFile, fd, finishCallback)) { err.println("HEAP DUMP FAILED on process " + process); return -1; } @@ -4270,11 +4276,14 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" --user <USER_ID> | current: When supplying a process name,"); pw.println(" specify user of process to profile; uses current user if not"); pw.println(" specified."); - pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>"); + pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] [-b <format>] "); + pw.println(" <PROCESS> <FILE>"); pw.println(" Dump the heap of a process. The given <PROCESS> argument may"); pw.println(" be either a process name or pid. Options are:"); pw.println(" -n: dump native heap instead of managed heap"); pw.println(" -g: force GC before dumping the heap"); + pw.println(" -b <format>: dump contents of bitmaps in the format specified,"); + pw.println(" which can be \"png\", \"jpg\" or \"webp\"."); pw.println(" --user <USER_ID> | current: When supplying a process name,"); pw.println(" specify user of process to dump; uses current user if not specified."); pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>"); diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java index 2e0aec973bd6..9b091b3a9c17 100644 --- a/services/core/java/com/android/server/am/AppProfiler.java +++ b/services/core/java/com/android/server/am/AppProfiler.java @@ -1046,7 +1046,9 @@ public class AppProfiler { + mProfile.mApp + " to " + mDumpUri.getPath()); } thread.dumpHeap(/* managed= */ true, - /* mallocInfo= */ false, /* runGc= */ false, + /* mallocInfo= */ false, + /* runGc= */ false, + /* dumpbitmaps= */ null, mDumpUri.getPath(), fd, /* finishCallback= */ null); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS index bf7cc10637a7..11db302ebbd5 100644 --- a/services/core/java/com/android/server/am/OWNERS +++ b/services/core/java/com/android/server/am/OWNERS @@ -9,7 +9,6 @@ mwachens@google.com sudheersai@google.com suprabh@google.com varunshah@google.com -kwekua@google.com bookatz@google.com jji@google.com diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index e876527fc513..4dfa71b7ad36 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -350,6 +350,7 @@ public final class ProcessList { // LMK_UPDATE_PROPS // LMK_KILL_OCCURRED // LMK_START_MONITORING + // LMK_BOOT_COMPLETED static final byte LMK_TARGET = 0; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCREMOVE = 2; @@ -360,6 +361,7 @@ public final class ProcessList { static final byte LMK_UPDATE_PROPS = 7; static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event static final byte LMK_START_MONITORING = 9; // Start monitoring if delayed earlier + static final byte LMK_BOOT_COMPLETED = 10; // Low Memory Killer Daemon command codes. // These must be kept in sync with async_event_type definitions in lmkd.h diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index d9e8dddddae4..c666915ddca5 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -28,3 +28,10 @@ flag { description: "Restrict network access for certain applications in BFGS process state" bug: "304347838" } + +flag { + namespace: "backstage_power" + name: "log_excessive_binder_proxies" + description: "Log the excessive incoming binder proxies into statsd" + bug: "298263955" +} diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java index c5073001a672..69e87fca659a 100644 --- a/services/core/java/com/android/server/biometrics/AuthSession.java +++ b/services/core/java/com/android/server/biometrics/AuthSession.java @@ -56,7 +56,7 @@ import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.IBinder; import android.os.RemoteException; -import android.security.KeyStore; +import android.security.KeyStoreAuthorization; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; @@ -111,7 +111,7 @@ public final class AuthSession implements IBinder.DeathRecipient { @NonNull private final BiometricContext mBiometricContext; private final IStatusBarService mStatusBarService; @VisibleForTesting final IBiometricSysuiReceiver mSysuiReceiver; - private final KeyStore mKeyStore; + private final KeyStoreAuthorization mKeyStoreAuthorization; private final Random mRandom; private final ClientDeathReceiver mClientDeathReceiver; final PreAuthInfo mPreAuthInfo; @@ -158,7 +158,7 @@ public final class AuthSession implements IBinder.DeathRecipient { @NonNull BiometricContext biometricContext, @NonNull IStatusBarService statusBarService, @NonNull IBiometricSysuiReceiver sysuiReceiver, - @NonNull KeyStore keystore, + @NonNull KeyStoreAuthorization keyStoreAuthorization, @NonNull Random random, @NonNull ClientDeathReceiver clientDeathReceiver, @NonNull PreAuthInfo preAuthInfo, @@ -172,8 +172,8 @@ public final class AuthSession implements IBinder.DeathRecipient { @NonNull PromptInfo promptInfo, boolean debugEnabled, @NonNull List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties) { - this(context, biometricContext, statusBarService, sysuiReceiver, keystore, random, - clientDeathReceiver, preAuthInfo, token, requestId, operationId, userId, + this(context, biometricContext, statusBarService, sysuiReceiver, keyStoreAuthorization, + random, clientDeathReceiver, preAuthInfo, token, requestId, operationId, userId, sensorReceiver, clientReceiver, opPackageName, promptInfo, debugEnabled, fingerprintSensorProperties, BiometricFrameworkStatsLogger.getInstance()); } @@ -183,7 +183,7 @@ public final class AuthSession implements IBinder.DeathRecipient { @NonNull BiometricContext biometricContext, @NonNull IStatusBarService statusBarService, @NonNull IBiometricSysuiReceiver sysuiReceiver, - @NonNull KeyStore keystore, + @NonNull KeyStoreAuthorization keyStoreAuthorization, @NonNull Random random, @NonNull ClientDeathReceiver clientDeathReceiver, @NonNull PreAuthInfo preAuthInfo, @@ -203,7 +203,7 @@ public final class AuthSession implements IBinder.DeathRecipient { mBiometricContext = biometricContext; mStatusBarService = statusBarService; mSysuiReceiver = sysuiReceiver; - mKeyStore = keystore; + mKeyStoreAuthorization = keyStoreAuthorization; mRandom = random; mClientDeathReceiver = clientDeathReceiver; mPreAuthInfo = preAuthInfo; @@ -814,14 +814,14 @@ public final class AuthSession implements IBinder.DeathRecipient { switch (reason) { case BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED: if (credentialAttestation != null) { - mKeyStore.addAuthToken(credentialAttestation); + mKeyStoreAuthorization.addAuthToken(credentialAttestation); } else { Slog.e(TAG, "credentialAttestation is null"); } case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED: case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED: if (mTokenEscrow != null) { - final int result = mKeyStore.addAuthToken(mTokenEscrow); + final int result = mKeyStoreAuthorization.addAuthToken(mTokenEscrow); Slog.d(TAG, "addAuthToken: " + result); } else { Slog.e(TAG, "mTokenEscrow is null"); diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 91a68ea67b3b..bccbee90e234 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -65,15 +65,11 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.ServiceSpecificException; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import android.security.Authorization; import android.security.GateKeeper; -import android.security.KeyStore; -import android.security.authorization.IKeystoreAuthorization; -import android.security.authorization.ResponseCode; +import android.security.KeyStoreAuthorization; import android.service.gatekeeper.IGateKeeperService; import android.text.TextUtils; import android.util.ArraySet; @@ -123,11 +119,9 @@ public class BiometricService extends SystemService { @VisibleForTesting IStatusBarService mStatusBarService; @VisibleForTesting - KeyStore mKeyStore; - @VisibleForTesting ITrustManager mTrustManager; @VisibleForTesting - IKeystoreAuthorization mKeystoreAuthorization; + KeyStoreAuthorization mKeyStoreAuthorization; @VisibleForTesting IGateKeeperService mGateKeeper; @@ -672,19 +666,7 @@ public class BiometricService extends SystemService { int[] authTypesArray = hardwareAuthenticators.stream() .mapToInt(Integer::intValue) .toArray(); - try { - return mKeystoreAuthorization.getLastAuthTime(secureUserId, authTypesArray); - } catch (RemoteException e) { - Slog.w(TAG, "Error getting last auth time: " + e); - return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION; - } catch (ServiceSpecificException e) { - // This is returned when the feature flag test fails in keystore2 - if (e.errorCode == ResponseCode.PERMISSION_DENIED) { - throw new UnsupportedOperationException(); - } - - return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION; - } + return mKeyStoreAuthorization.getLastAuthTime(secureUserId, authTypesArray); } @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) @@ -1009,8 +991,8 @@ public class BiometricService extends SystemService { return ActivityManager.getService(); } - public IKeystoreAuthorization getKeystoreAuthorizationService() { - return Authorization.getService(); + public KeyStoreAuthorization getKeyStoreAuthorization() { + return KeyStoreAuthorization.getInstance(); } public IGateKeeperService getGateKeeperService() { @@ -1034,10 +1016,6 @@ public class BiometricService extends SystemService { return new SettingObserver(context, handler, callbacks); } - public KeyStore getKeyStore() { - return KeyStore.getInstance(); - } - /** * Allows to enable/disable debug logs. */ @@ -1130,7 +1108,7 @@ public class BiometricService extends SystemService { mBiometricContext = injector.getBiometricContext(context); mUserManager = injector.getUserManager(context); mBiometricCameraManager = injector.getBiometricCameraManager(context); - mKeystoreAuthorization = injector.getKeystoreAuthorizationService(); + mKeyStoreAuthorization = injector.getKeyStoreAuthorization(); mGateKeeper = injector.getGateKeeperService(); try { @@ -1150,7 +1128,6 @@ public class BiometricService extends SystemService { @Override public void onStart() { - mKeyStore = mInjector.getKeyStore(); mStatusBarService = mInjector.getStatusBarService(); mTrustManager = mInjector.getTrustManager(); mInjector.publishBinderService(this, mImpl); @@ -1458,7 +1435,7 @@ public class BiometricService extends SystemService { final boolean debugEnabled = mInjector.isDebugEnabled(getContext(), userId); mAuthSession = new AuthSession(getContext(), mBiometricContext, mStatusBarService, - createSysuiReceiver(requestId), mKeyStore, mRandom, + createSysuiReceiver(requestId), mKeyStoreAuthorization, mRandom, createClientDeathReceiver(requestId), preAuthInfo, token, requestId, operationId, userId, createBiometricSensorReceiver(requestId), receiver, opPackageName, promptInfo, debugEnabled, diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java index 6eba23f45fdf..749e12b4fe14 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -30,7 +30,7 @@ import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricRequestConstants; import android.os.IBinder; import android.os.RemoteException; -import android.security.KeyStore; +import android.security.KeyStoreAuthorization; import android.util.EventLog; import android.util.Slog; @@ -255,7 +255,7 @@ public abstract class AuthenticationClient<T, O extends AuthenticateOptions> // For BP, BiometricService will add the authToken to Keystore. if (!isBiometricPrompt() && mIsStrongBiometric) { - final int result = KeyStore.getInstance().addAuthToken(byteToken); + final int result = KeyStoreAuthorization.getInstance().addAuthToken(byteToken); if (result != 0) { Slog.d(TAG, "Error adding auth token : " + result); } else { diff --git a/services/core/java/com/android/server/connectivity/Android.bp b/services/core/java/com/android/server/connectivity/Android.bp new file mode 100644 index 000000000000..a374ec2cea9a --- /dev/null +++ b/services/core/java/com/android/server/connectivity/Android.bp @@ -0,0 +1,10 @@ +aconfig_declarations { + name: "connectivity_flags", + package: "com.android.server.connectivity", + srcs: ["flags.aconfig"], +} + +java_aconfig_library { + name: "connectivity_flags_lib", + aconfig_declarations: "connectivity_flags", +} diff --git a/services/core/java/com/android/server/connectivity/flags.aconfig b/services/core/java/com/android/server/connectivity/flags.aconfig new file mode 100644 index 000000000000..32593d4bcdaa --- /dev/null +++ b/services/core/java/com/android/server/connectivity/flags.aconfig @@ -0,0 +1,8 @@ +package: "com.android.server.connectivity" + +flag { + name: "replace_vpn_profile_store" + namespace: "android_core_networking" + description: "This flag controls the usage of VpnBlobStore to replace LegacyVpnProfileStore." + bug: "307903113" +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java index 0f40ca082663..2783fefa5b71 100644 --- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java +++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java @@ -198,8 +198,7 @@ final class UpdatableFontDir { File signatureFile = new File(dir, FONT_SIGNATURE_FILE); if (!signatureFile.exists()) { Slog.i(TAG, "The signature file is missing."); - FileUtils.deleteContentsAndDir(dir); - continue; + return; } byte[] signature; try { @@ -224,10 +223,36 @@ final class UpdatableFontDir { FontFileInfo fontFileInfo = validateFontFile(fontFile, signature); if (fontConfig == null) { - fontConfig = getSystemFontConfig(); + // Use preinstalled font config for checking revision number. + fontConfig = mConfigSupplier.apply(Collections.emptyMap()); } addFileToMapIfSameOrNewer(fontFileInfo, fontConfig, true /* deleteOldFile */); } + + // Treat as error if post script name of font family was not installed. + for (int i = 0; i < config.fontFamilies.size(); ++i) { + FontUpdateRequest.Family family = config.fontFamilies.get(i); + for (int j = 0; j < family.getFonts().size(); ++j) { + FontUpdateRequest.Font font = family.getFonts().get(j); + if (mFontFileInfoMap.containsKey(font.getPostScriptName())) { + continue; + } + + if (fontConfig == null) { + fontConfig = mConfigSupplier.apply(Collections.emptyMap()); + } + + if (getFontByPostScriptName(font.getPostScriptName(), fontConfig) != null) { + continue; + } + + Slog.e(TAG, "Unknown font that has PostScript name " + + font.getPostScriptName() + " is requested in FontFamily " + + family.getName()); + return; + } + } + success = true; } catch (Throwable t) { // If something happened during loading system fonts, clear all contents in finally @@ -239,6 +264,7 @@ final class UpdatableFontDir { mFontFileInfoMap.clear(); mLastModifiedMillis = 0; FileUtils.deleteContents(mFilesDir); + mConfigFile.delete(); } } } @@ -487,8 +513,7 @@ final class UpdatableFontDir { return shouldAddToMap; } - private long getPreinstalledFontRevision(FontFileInfo info, FontConfig fontConfig) { - String psName = info.getPostScriptName(); + private FontConfig.Font getFontByPostScriptName(String psName, FontConfig fontConfig) { FontConfig.Font targetFont = null; for (int i = 0; i < fontConfig.getFontFamilies().size(); i++) { FontConfig.FontFamily family = fontConfig.getFontFamilies().get(i); @@ -513,6 +538,13 @@ final class UpdatableFontDir { } } } + return targetFont; + } + + private long getPreinstalledFontRevision(FontFileInfo info, FontConfig fontConfig) { + String psName = info.getPostScriptName(); + FontConfig.Font targetFont = getFontByPostScriptName(psName, fontConfig); + if (targetFont == null) { return -1; } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index a9a9d87bfaf7..ba99d2e4a950 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -103,7 +103,7 @@ import android.os.storage.StorageManager; import android.provider.DeviceConfig; import android.provider.Settings; import android.security.AndroidKeyStoreMaintenance; -import android.security.Authorization; +import android.security.KeyStoreAuthorization; import android.security.keystore.KeyProperties; import android.security.keystore.KeyProtection; import android.security.keystore.recovery.KeyChainProtectionParams; @@ -289,6 +289,7 @@ public class LockSettingsService extends ILockSettings.Stub { private final SyntheticPasswordManager mSpManager; private final KeyStore mKeyStore; + private final KeyStoreAuthorization mKeyStoreAuthorization; private final RecoverableKeyStoreManager mRecoverableKeyStoreManager; private final UnifiedProfilePasswordCache mUnifiedProfilePasswordCache; @@ -623,6 +624,10 @@ public class LockSettingsService extends ILockSettings.Stub { } } + public KeyStoreAuthorization getKeyStoreAuthorization() { + return KeyStoreAuthorization.getInstance(); + } + public @NonNull UnifiedProfilePasswordCache getUnifiedProfilePasswordCache(KeyStore ks) { return new UnifiedProfilePasswordCache(ks); } @@ -646,6 +651,7 @@ public class LockSettingsService extends ILockSettings.Stub { mInjector = injector; mContext = injector.getContext(); mKeyStore = injector.getKeyStore(); + mKeyStoreAuthorization = injector.getKeyStoreAuthorization(); mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(); mHandler = injector.getHandler(injector.getServiceThread()); mStrongAuth = injector.getStrongAuth(); @@ -1434,7 +1440,7 @@ public class LockSettingsService extends ILockSettings.Stub { } private void unlockKeystore(int userId, SyntheticPassword sp) { - Authorization.onDeviceUnlocked(userId, sp.deriveKeyStorePassword()); + mKeyStoreAuthorization.onDeviceUnlocked(userId, sp.deriveKeyStorePassword()); } @VisibleForTesting /** Note: this method is overridden in unit tests */ diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING index ddf3d76e97ae..256d9ba86a6f 100644 --- a/services/core/java/com/android/server/locksettings/TEST_MAPPING +++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING @@ -24,5 +24,11 @@ } ] } + ], + "postsubmit": [ + { + // TODO(b/332974906): Promote in presubmit-large. + "name": "CtsDevicePolicyManagerTestCases_LockSettings_NoFlakes" + } ] } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 994d3ca1124f..6f8a46be089f 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -786,7 +786,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } } if (deadCallbackHolders != null) { - mControllerCallbackHolders.removeAll(deadCallbackHolders); + removeControllerHoldersSafely(deadCallbackHolders); } } @@ -813,7 +813,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } } if (deadCallbackHolders != null) { - mControllerCallbackHolders.removeAll(deadCallbackHolders); + removeControllerHoldersSafely(deadCallbackHolders); } } @@ -848,7 +848,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } } if (deadCallbackHolders != null) { - mControllerCallbackHolders.removeAll(deadCallbackHolders); + removeControllerHoldersSafely(deadCallbackHolders); } } @@ -875,7 +875,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } } if (deadCallbackHolders != null) { - mControllerCallbackHolders.removeAll(deadCallbackHolders); + removeControllerHoldersSafely(deadCallbackHolders); } } @@ -902,7 +902,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } } if (deadCallbackHolders != null) { - mControllerCallbackHolders.removeAll(deadCallbackHolders); + removeControllerHoldersSafely(deadCallbackHolders); } } @@ -929,7 +929,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } } if (deadCallbackHolders != null) { - mControllerCallbackHolders.removeAll(deadCallbackHolders); + removeControllerHoldersSafely(deadCallbackHolders); } } @@ -954,7 +954,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } } if (deadCallbackHolders != null) { - mControllerCallbackHolders.removeAll(deadCallbackHolders); + removeControllerHoldersSafely(deadCallbackHolders); } } @@ -979,7 +979,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } } // After notifying clear all listeners - mControllerCallbackHolders.clear(); + removeControllerHoldersSafely(null); } private PlaybackState getStateWithUpdatedPosition() { @@ -1027,6 +1027,17 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR return -1; } + private void removeControllerHoldersSafely( + Collection<ISessionControllerCallbackHolder> holders) { + synchronized (mLock) { + if (holders == null) { + mControllerCallbackHolders.clear(); + } else { + mControllerCallbackHolders.removeAll(holders); + } + } + } + private PlaybackInfo getVolumeAttributes() { int volumeType; AudioAttributes attributes; diff --git a/services/core/java/com/android/server/power/batterysaver/OWNERS b/services/core/java/com/android/server/power/batterysaver/OWNERS index cf23bea97289..dc2d0b320d58 100644 --- a/services/core/java/com/android/server/power/batterysaver/OWNERS +++ b/services/core/java/com/android/server/power/batterysaver/OWNERS @@ -1,3 +1,2 @@ -kwekua@google.com omakoto@google.com -yamasani@google.com
\ No newline at end of file +yamasani@google.com diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index c2e2dadde857..dc4618413715 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -30,6 +30,7 @@ import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_ import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER; import android.annotation.IntDef; +import android.annotation.Nullable; import android.apex.CompressedApexInfo; import android.apex.CompressedApexInfoList; import android.content.Context; @@ -37,6 +38,7 @@ import android.content.IntentSender; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.hardware.boot.IBootControl; +import android.hardware.security.secretkeeper.ISecretkeeper; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.Binder; @@ -52,6 +54,7 @@ import android.os.ServiceManager; import android.os.ShellCallback; import android.os.SystemProperties; import android.provider.DeviceConfig; +import android.security.AndroidKeyStoreMaintenance; import android.util.ArrayMap; import android.util.ArraySet; import android.util.FastImmutableArraySet; @@ -67,6 +70,7 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.pm.ApexManager; import com.android.server.recoverysystem.hal.BootControlHIDL; +import com.android.server.utils.Slogf; import libcore.io.IoUtils; @@ -118,6 +122,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo static final String LSKF_CAPTURED_TIMESTAMP_PREF = "lskf_captured_timestamp"; static final String LSKF_CAPTURED_COUNT_PREF = "lskf_captured_count"; + static final String RECOVERY_WIPE_DATA_COMMAND = "--wipe_data"; + private final Injector mInjector; private final Context mContext; @@ -521,18 +527,57 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo @Override // Binder call public void rebootRecoveryWithCommand(String command) { if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]"); + + boolean isForcedWipe = command != null && command.contains(RECOVERY_WIPE_DATA_COMMAND); synchronized (sRequestLock) { if (!setupOrClearBcb(true, command)) { Slog.e(TAG, "rebootRecoveryWithCommand failed to setup BCB"); return; } + if (isForcedWipe) { + deleteSecrets(); + // TODO: consider adding a dedicated forced-wipe-reboot method to PowerManager and + // calling here. + } + // Having set up the BCB, go ahead and reboot. PowerManager pm = mInjector.getPowerManager(); pm.reboot(PowerManager.REBOOT_RECOVERY); } } + private static void deleteSecrets() { + Slogf.w(TAG, "deleteSecrets"); + try { + AndroidKeyStoreMaintenance.deleteAllKeys(); + } catch (android.security.KeyStoreException e) { + Log.wtf(TAG, "Failed to delete all keys from keystore.", e); + } + + try { + ISecretkeeper secretKeeper = getSecretKeeper(); + if (secretKeeper != null) { + Slogf.i(TAG, "ISecretkeeper.deleteAll();"); + secretKeeper.deleteAll(); + } + } catch (RemoteException e) { + Log.wtf(TAG, "Failed to delete all secrets from secretkeeper.", e); + } + } + + private static @Nullable ISecretkeeper getSecretKeeper() { + ISecretkeeper result = null; + try { + result = ISecretkeeper.Stub.asInterface( + ServiceManager.waitForDeclaredService(ISecretkeeper.DESCRIPTOR + "/default")); + } catch (SecurityException e) { + Slog.w(TAG, "Does not have permissions to get AIDL secretkeeper service"); + } + + return result; + } + private void enforcePermissionForResumeOnReboot() { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY) != PackageManager.PERMISSION_GRANTED diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index 2a9325544833..c8bcc5128c3a 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -54,8 +54,10 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.ext.SdkExtensions; import android.provider.DeviceConfig; +import android.util.ArrayMap; import android.util.Log; import android.util.LongArrayQueue; +import android.util.Pair; import android.util.Slog; import android.util.SparseBooleanArray; import android.util.SparseIntArray; @@ -173,6 +175,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba // Accessed on the handler thread only. private long mRelativeBootTime = calculateRelativeBootTime(); + private final ArrayMap<Integer, Pair<Context, BroadcastReceiver>> mUserBroadcastReceivers; + RollbackManagerServiceImpl(Context context) { mContext = context; // Note that we're calling onStart here because this object is only constructed on @@ -210,6 +214,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } }); + mUserBroadcastReceivers = new ArrayMap<>(); + UserManager userManager = mContext.getSystemService(UserManager.class); for (UserHandle user : userManager.getUserHandles(true)) { registerUserCallbacks(user); @@ -275,7 +281,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } }, enableRollbackTimedOutFilter, null, getHandler()); - IntentFilter userAddedIntentFilter = new IntentFilter(Intent.ACTION_USER_ADDED); + IntentFilter userIntentFilter = new IntentFilter(); + userIntentFilter.addAction(Intent.ACTION_USER_ADDED); + userIntentFilter.addAction(Intent.ACTION_USER_REMOVED); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -287,9 +295,15 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba return; } registerUserCallbacks(UserHandle.of(newUserId)); + } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { + final int newUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + if (newUserId == -1) { + return; + } + unregisterUserCallbacks(UserHandle.of(newUserId)); } } - }, userAddedIntentFilter, null, getHandler()); + }, userIntentFilter, null, getHandler()); registerTimeChangeReceiver(); } @@ -335,7 +349,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba filter.addAction(Intent.ACTION_PACKAGE_REPLACED); filter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); filter.addDataScheme("package"); - context.registerReceiver(new BroadcastReceiver() { + BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { assertInWorkerThread(); @@ -354,7 +368,21 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba onPackageFullyRemoved(packageName); } } - }, filter, null, getHandler()); + }; + context.registerReceiver(receiver, filter, null, getHandler()); + mUserBroadcastReceivers.put(user.getIdentifier(), new Pair(context, receiver)); + } + + @AnyThread + private void unregisterUserCallbacks(UserHandle user) { + Pair<Context, BroadcastReceiver> pair = mUserBroadcastReceivers.get(user.getIdentifier()); + if (pair == null || pair.first == null || pair.second == null) { + Slog.e(TAG, "No receiver found for the user" + user); + return; + } + + pair.first.unregisterReceiver(pair.second); + mUserBroadcastReceivers.remove(user.getIdentifier()); } @ExtThread diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index e5a8a6dd2a3a..7794048e615c 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -61,7 +61,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import android.security.Authorization; +import android.security.KeyStoreAuthorization; import android.service.trust.GrantTrustResult; import android.service.trust.TrustAgentService; import android.text.TextUtils; @@ -156,6 +156,7 @@ public class TrustManagerService extends SystemService { /* package */ final TrustArchive mArchive = new TrustArchive(); private final Context mContext; private final LockPatternUtils mLockPatternUtils; + private final KeyStoreAuthorization mKeyStoreAuthorization; private final UserManager mUserManager; private final ActivityManager mActivityManager; private FingerprintManager mFingerprintManager; @@ -249,25 +250,27 @@ public class TrustManagerService extends SystemService { * cases. */ protected static class Injector { - private final LockPatternUtils mLockPatternUtils; - private final Looper mLooper; + private final Context mContext; - public Injector(LockPatternUtils lockPatternUtils, Looper looper) { - mLockPatternUtils = lockPatternUtils; - mLooper = looper; + public Injector(Context context) { + mContext = context; } LockPatternUtils getLockPatternUtils() { - return mLockPatternUtils; + return new LockPatternUtils(mContext); + } + + KeyStoreAuthorization getKeyStoreAuthorization() { + return KeyStoreAuthorization.getInstance(); } Looper getLooper() { - return mLooper; + return Looper.myLooper(); } } public TrustManagerService(Context context) { - this(context, new Injector(new LockPatternUtils(context), Looper.myLooper())); + this(context, new Injector(context)); } protected TrustManagerService(Context context, Injector injector) { @@ -277,6 +280,7 @@ public class TrustManagerService extends SystemService { mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); mLockPatternUtils = injector.getLockPatternUtils(); + mKeyStoreAuthorization = injector.getKeyStoreAuthorization(); mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper()); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); } @@ -908,16 +912,16 @@ public class TrustManagerService extends SystemService { int authUserId = mLockPatternUtils.isProfileWithUnifiedChallenge(userId) ? resolveProfileParent(userId) : userId; - Authorization.onDeviceLocked(userId, getBiometricSids(authUserId), + mKeyStoreAuthorization.onDeviceLocked(userId, getBiometricSids(authUserId), isWeakUnlockMethodEnabled(authUserId)); } else { - Authorization.onDeviceLocked(userId, getBiometricSids(userId), false); + mKeyStoreAuthorization.onDeviceLocked(userId, getBiometricSids(userId), false); } } else { // Notify Keystore that the device is now unlocked for the user. Note that for unlocks // with LSKF, this is redundant with the call from LockSettingsService which provides // the password. However, for unlocks with biometric or trust agent, this is required. - Authorization.onDeviceUnlocked(userId, /* password= */ null); + mKeyStoreAuthorization.onDeviceUnlocked(userId, /* password= */ null); } } diff --git a/services/core/java/com/android/server/utils/quota/OWNERS b/services/core/java/com/android/server/utils/quota/OWNERS index a2943f39db24..469acb23f0b9 100644 --- a/services/core/java/com/android/server/utils/quota/OWNERS +++ b/services/core/java/com/android/server/utils/quota/OWNERS @@ -1,4 +1,3 @@ dplotnikov@google.com -kwekua@google.com omakoto@google.com yamasani@google.com diff --git a/services/devicepolicy/TEST_MAPPING b/services/devicepolicy/TEST_MAPPING index 0d5534ba74df..b8cb4a91d6f1 100644 --- a/services/devicepolicy/TEST_MAPPING +++ b/services/devicepolicy/TEST_MAPPING @@ -26,5 +26,12 @@ } ] } + ], + "postsubmit": [ + { + // TODO(b/332974906): Promote in presubmit presubmit-devicepolicy. + "name": "CtsDevicePolicyManagerTestCases_NoFlakes_NoLarge", + "name": "CtsDevicePolicyManagerTestCases_ParentProfileApiDisabled" + } ] } diff --git a/services/tests/mockingservicestests/src/com/android/server/OWNERS b/services/tests/mockingservicestests/src/com/android/server/OWNERS index f80156021408..0eb8639bd005 100644 --- a/services/tests/mockingservicestests/src/com/android/server/OWNERS +++ b/services/tests/mockingservicestests/src/com/android/server/OWNERS @@ -1,5 +1,5 @@ per-file *Alarm* = file:/apex/jobscheduler/OWNERS per-file *AppStateTracker* = file:/apex/jobscheduler/OWNERS per-file *DeviceIdleController* = file:/apex/jobscheduler/OWNERS -per-file SensitiveContentProtectionManagerServiceTest.java = file:/core/java/android/permission/OWNERS +per-file SensitiveContentProtectionManagerService* = file:/core/java/android/permission/OWNERS per-file RescuePartyTest.java = file:/packages/CrashRecovery/OWNERS diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java index 682569f1d9ab..697548cbe2b4 100644 --- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java @@ -1111,16 +1111,9 @@ public class RescuePartyTest { // mock properties in BootThreshold try { - if (Flags.recoverabilityDetection()) { - mSpyBootThreshold = spy(watchdog.new BootThreshold( - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); - } else { - mSpyBootThreshold = spy(watchdog.new BootThreshold( + mSpyBootThreshold = spy(watchdog.new BootThreshold( PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); - } mCrashRecoveryPropertiesMap = new HashMap<>(); doAnswer((Answer<Integer>) invocationOnMock -> { diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java index b41568298dbc..0532e04257d4 100644 --- a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java @@ -55,6 +55,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; +import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; @@ -63,8 +64,7 @@ import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; -import android.security.Authorization; -import android.security.authorization.IKeystoreAuthorization; +import android.security.KeyStoreAuthorization; import android.service.trust.TrustAgentService; import android.testing.TestableContext; import android.view.IWindowManager; @@ -96,7 +96,6 @@ public class TrustManagerServiceTest { @Rule public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this) .spyStatic(ActivityManager.class) - .spyStatic(Authorization.class) .mockStatic(ServiceManager.class) .mockStatic(WindowManagerGlobal.class) .build(); @@ -126,14 +125,13 @@ public class TrustManagerServiceTest { private @Mock DevicePolicyManager mDevicePolicyManager; private @Mock FaceManager mFaceManager; private @Mock FingerprintManager mFingerprintManager; - private @Mock IKeystoreAuthorization mKeystoreAuthorization; + private @Mock KeyStoreAuthorization mKeyStoreAuthorization; private @Mock LockPatternUtils mLockPatternUtils; private @Mock PackageManager mPackageManager; private @Mock UserManager mUserManager; private @Mock IWindowManager mWindowManager; private HandlerThread mHandlerThread; - private TrustManagerService.Injector mInjector; private TrustManagerService mService; private ITrustManager mTrustManager; @@ -145,8 +143,6 @@ public class TrustManagerServiceTest { when(mFaceManager.getSensorProperties()).thenReturn(List.of()); when(mFingerprintManager.getSensorProperties()).thenReturn(List.of()); - doReturn(mKeystoreAuthorization).when(() -> Authorization.getService()); - when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager); when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true); when(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).thenReturn(mKnownTrustAgents); @@ -193,8 +189,7 @@ public class TrustManagerServiceTest { mHandlerThread = new HandlerThread("handler"); mHandlerThread.start(); - mInjector = new TrustManagerService.Injector(mLockPatternUtils, mHandlerThread.getLooper()); - mService = new TrustManagerService(mMockContext, mInjector); + mService = new TrustManagerService(mMockContext, new MockInjector(mMockContext)); // Get the ITrustManager from the new TrustManagerService. mService.onStart(); @@ -204,6 +199,27 @@ public class TrustManagerServiceTest { mTrustManager = ITrustManager.Stub.asInterface(binderArgumentCaptor.getValue()); } + private class MockInjector extends TrustManagerService.Injector { + MockInjector(Context context) { + super(context); + } + + @Override + LockPatternUtils getLockPatternUtils() { + return mLockPatternUtils; + } + + @Override + KeyStoreAuthorization getKeyStoreAuthorization() { + return mKeyStoreAuthorization; + } + + @Override + Looper getLooper() { + return mHandlerThread.getLooper(); + } + } + @After public void tearDown() { LocalServices.removeServiceForTest(SystemServiceManager.class); @@ -371,14 +387,14 @@ public class TrustManagerServiceTest { when(mWindowManager.isKeyguardLocked()).thenReturn(false); mTrustManager.reportKeyguardShowingChanged(); - verify(mKeystoreAuthorization).onDeviceUnlocked(PARENT_USER_ID, null); - verify(mKeystoreAuthorization).onDeviceUnlocked(PROFILE_USER_ID, null); + verify(mKeyStoreAuthorization).onDeviceUnlocked(PARENT_USER_ID, null); + verify(mKeyStoreAuthorization).onDeviceUnlocked(PROFILE_USER_ID, null); when(mWindowManager.isKeyguardLocked()).thenReturn(true); mTrustManager.reportKeyguardShowingChanged(); - verify(mKeystoreAuthorization) + verify(mKeyStoreAuthorization) .onDeviceLocked(eq(PARENT_USER_ID), eq(PARENT_BIOMETRIC_SIDS), eq(false)); - verify(mKeystoreAuthorization) + verify(mKeyStoreAuthorization) .onDeviceLocked(eq(PROFILE_USER_ID), eq(PARENT_BIOMETRIC_SIDS), eq(false)); } @@ -392,10 +408,10 @@ public class TrustManagerServiceTest { setupMocksForProfile(/* unifiedChallenge= */ false); mTrustManager.setDeviceLockedForUser(PROFILE_USER_ID, false); - verify(mKeystoreAuthorization).onDeviceUnlocked(PROFILE_USER_ID, null); + verify(mKeyStoreAuthorization).onDeviceUnlocked(PROFILE_USER_ID, null); mTrustManager.setDeviceLockedForUser(PROFILE_USER_ID, true); - verify(mKeystoreAuthorization) + verify(mKeyStoreAuthorization) .onDeviceLocked(eq(PROFILE_USER_ID), eq(PROFILE_BIOMETRIC_SIDS), eq(false)); } @@ -572,11 +588,11 @@ public class TrustManagerServiceTest { private void verifyWeakUnlockValue(boolean expectedWeakUnlockEnabled) throws Exception { when(mWindowManager.isKeyguardLocked()).thenReturn(false); mTrustManager.reportKeyguardShowingChanged(); - verify(mKeystoreAuthorization).onDeviceUnlocked(TEST_USER_ID, null); + verify(mKeyStoreAuthorization).onDeviceUnlocked(TEST_USER_ID, null); when(mWindowManager.isKeyguardLocked()).thenReturn(true); mTrustManager.reportKeyguardShowingChanged(); - verify(mKeystoreAuthorization).onDeviceLocked(eq(TEST_USER_ID), any(), + verify(mKeyStoreAuthorization).onDeviceLocked(eq(TEST_USER_ID), any(), eq(expectedWeakUnlockEnabled)); } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java index 74eb79d7554c..34092b6855b1 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java @@ -68,7 +68,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.security.KeyStore; +import android.security.KeyStoreAuthorization; import androidx.test.filters.SmallTest; @@ -105,7 +105,7 @@ public class AuthSessionTest { @Mock private IBiometricServiceReceiver mClientReceiver; @Mock private IStatusBarService mStatusBarService; @Mock private IBiometricSysuiReceiver mSysuiReceiver; - @Mock private KeyStore mKeyStore; + @Mock private KeyStoreAuthorization mKeyStoreAuthorization; @Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver; @Mock private BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger; @Mock private BiometricCameraManager mBiometricCameraManager; @@ -665,9 +665,10 @@ public class AuthSessionTest { final PreAuthInfo preAuthInfo = createPreAuthInfo(sensors, userId, promptInfo, checkDevicePolicyManager); return new AuthSession(mContext, mBiometricContext, mStatusBarService, mSysuiReceiver, - mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, mToken, requestId, - operationId, userId, mSensorReceiver, mClientReceiver, TEST_PACKAGE, promptInfo, - false /* debugEnabled */, mFingerprintSensorProps, mBiometricFrameworkStatsLogger); + mKeyStoreAuthorization, mRandom, mClientDeathReceiver, preAuthInfo, mToken, + requestId, operationId, userId, mSensorReceiver, mClientReceiver, TEST_PACKAGE, + promptInfo, false /* debugEnabled */, mFingerprintSensorProps, + mBiometricFrameworkStatsLogger); } private PromptInfo createPromptInfo(@Authenticators.Types int authenticators) { diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java index 408442bcceed..3eaf9af65593 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java @@ -80,8 +80,7 @@ import android.os.UserManager; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.security.GateKeeper; -import android.security.KeyStore; -import android.security.authorization.IKeystoreAuthorization; +import android.security.KeyStoreAuthorization; import android.service.gatekeeper.IGateKeeperService; import android.view.Display; import android.view.DisplayInfo; @@ -173,7 +172,7 @@ public class BiometricServiceTest { private BiometricCameraManager mBiometricCameraManager; @Mock - private IKeystoreAuthorization mKeystoreAuthService; + private KeyStoreAuthorization mKeyStoreAuthorization; @Mock private IGateKeeperService mGateKeeperService; @@ -195,7 +194,7 @@ public class BiometricServiceTest { when(mInjector.getStatusBarService()).thenReturn(mock(IStatusBarService.class)); when(mInjector.getSettingObserver(any(), any(), any())) .thenReturn(mock(BiometricService.SettingObserver.class)); - when(mInjector.getKeyStore()).thenReturn(mock(KeyStore.class)); + when(mInjector.getKeyStoreAuthorization()).thenReturn(mock(KeyStoreAuthorization.class)); when(mInjector.isDebugEnabled(any(), anyInt())).thenReturn(false); when(mInjector.getBiometricStrengthController(any())) .thenReturn(mock(BiometricStrengthController.class)); @@ -231,7 +230,7 @@ public class BiometricServiceTest { mStatusBarService, null /* handler */, mAuthSessionCoordinator); when(mInjector.getBiometricContext(any())).thenReturn(mBiometricContextProvider); - when(mInjector.getKeystoreAuthorizationService()).thenReturn(mKeystoreAuthService); + when(mInjector.getKeyStoreAuthorization()).thenReturn(mKeyStoreAuthorization); when(mInjector.getGateKeeperService()).thenReturn(mGateKeeperService); when(mGateKeeperService.getSecureUserId(anyInt())).thenReturn(42L); @@ -661,9 +660,9 @@ public class BiometricServiceTest { waitForIdle(); // HAT sent to keystore if (isStrongBiometric) { - verify(mBiometricService.mKeyStore).addAuthToken(AdditionalMatchers.aryEq(HAT)); + verify(mKeyStoreAuthorization).addAuthToken(AdditionalMatchers.aryEq(HAT)); } else { - verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class)); + verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class)); } // Send onAuthenticated to client verify(mReceiver1).onAuthenticationSucceeded( @@ -726,7 +725,7 @@ public class BiometricServiceTest { waitForIdle(); // Waiting for SystemUI to send confirmation callback assertEquals(STATE_AUTH_PENDING_CONFIRM, mBiometricService.mAuthSession.getState()); - verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class)); + verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class)); // SystemUI sends confirm, HAT is sent to keystore and client is notified. mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed( @@ -734,9 +733,9 @@ public class BiometricServiceTest { null /* credentialAttestation */); waitForIdle(); if (isStrongBiometric) { - verify(mBiometricService.mKeyStore).addAuthToken(AdditionalMatchers.aryEq(HAT)); + verify(mKeyStoreAuthorization).addAuthToken(AdditionalMatchers.aryEq(HAT)); } else { - verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class)); + verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class)); } verify(mReceiver1).onAuthenticationSucceeded( BiometricPrompt.AUTHENTICATION_RESULT_TYPE_BIOMETRIC); @@ -1292,7 +1291,7 @@ public class BiometricServiceTest { eq(TYPE_FACE), eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED), eq(0 /* vendorCode */)); - verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class)); + verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class)); assertNull(mBiometricService.mAuthSession); } @@ -1796,7 +1795,7 @@ public class BiometricServiceTest { final long expectedResult = 31337L; - when(mKeystoreAuthService.getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators))) + when(mKeyStoreAuthorization.getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators))) .thenReturn(expectedResult); mBiometricService = new BiometricService(mContext, mInjector); @@ -1805,7 +1804,8 @@ public class BiometricServiceTest { Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL); assertEquals(expectedResult, result); - verify(mKeystoreAuthService).getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators)); + verify(mKeyStoreAuthorization).getLastAuthTime(eq(secureUserId), + eq(hardwareAuthenticators)); } // Helper methods diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java index 3de167e72ba0..5fb15e9c4df0 100644 --- a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java +++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java @@ -1001,6 +1001,563 @@ public final class UpdatableFontDirTest { assertThat(mUpdatableFontFilesDir.list()).hasLength(0); } + private UpdatableFontDir createNewUpdateDir() { + UpdatableFontDir dir = new UpdatableFontDir( + mUpdatableFontFilesDir, mParser, mFakeFsverityUtil, + mConfigFile, mCurrentTimeSupplier, mConfigSupplier); + dir.loadFontFileMap(); + return dir; + } + + private UpdatableFontDir installTestFontFamilies(int version) { + UpdatableFontDir dir = createNewUpdateDir(); + try { + dir.update(Arrays.asList( + newFontUpdateRequest("foo.ttf," + version + ",foo", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf," + version + ",bar", GOOD_SIGNATURE), + newAddFontFamilyRequest("<family name='foobar'>" + + " <font>foo.ttf</font>" + + " <font>bar.ttf</font>" + + "</family>"))); + } catch (Exception e) { + throw new RuntimeException(e); + } + return dir; + } + + private UpdatableFontDir installTestFontFile(int numFonts, int version) { + UpdatableFontDir dir = createNewUpdateDir(); + List<FontUpdateRequest> requests = new ArrayList<>(); + if (numFonts <= 0 || numFonts > 3) { + throw new IllegalArgumentException("numFont must be 1, 2 or 3"); + } + try { + requests.add(newFontUpdateRequest("foo.ttf," + version + ",foo", GOOD_SIGNATURE)); + if (numFonts >= 2) { + requests.add(newFontUpdateRequest("bar.ttf," + version + ",bar", GOOD_SIGNATURE)); + } + if (numFonts == 3) { + requests.add(newFontUpdateRequest("baz.ttf," + version + ",baz", GOOD_SIGNATURE)); + } + dir.update(requests); + } catch (Exception e) { + throw new RuntimeException(e); + } + return dir; + } + + private List<File> collectSignatureFiles() { + return Arrays.stream(mUpdatableFontFilesDir.listFiles()) + .map((file) -> file.listFiles((unused, s) -> s.endsWith(".fsv_sig"))) + .flatMap(Arrays::stream) + .toList(); + } + + private List<File> collectFontFiles() { + return Arrays.stream(mUpdatableFontFilesDir.listFiles()) + .map((file) -> file.listFiles((unused, s) -> s.endsWith(".ttf"))) + .flatMap(Arrays::stream) + .toList(); + } + + private void removeAll(List<File> files) { + files.forEach((File file) -> { + if (file.isDirectory()) { + removeAll(List.of(file.listFiles())); + } else { + assertThat(file.delete()).isTrue(); + } + }); + } + + private void assertTestFontFamilyInstalled(UpdatableFontDir dir, int version) { + try { + assertNamedFamilyExists(dir.getSystemFontConfig(), "foobar"); + assertThat(dir.getFontFamilyMap()).containsKey("foobar"); + assertThat(dir.getFontFamilyMap().get("foobar").getFamilies().size()).isEqualTo(1); + FontConfig.FontFamily foobar = dir.getFontFamilyMap().get("foobar").getFamilies() + .get(0); + assertThat(foobar.getFontList()).hasSize(2); + assertThat(foobar.getFontList().get(0).getFile()) + .isEqualTo(dir.getPostScriptMap().get("foo")); + assertThat(mParser.getRevision(dir.getPostScriptMap().get("foo"))).isEqualTo(version); + assertThat(foobar.getFontList().get(1).getFile()) + .isEqualTo(dir.getPostScriptMap().get("bar")); + assertThat(mParser.getRevision(dir.getPostScriptMap().get("bar"))).isEqualTo(version); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void assertTestFontInstalled(UpdatableFontDir dir, int version) { + try { + assertThat(dir.getPostScriptMap().containsKey("foo")).isTrue(); + assertThat(mParser.getRevision(dir.getPostScriptMap().get("foo"))).isEqualTo(version); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void signatureMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete one signature file + assertThat(collectSignatureFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1); + + // Delete one signature file + assertThat(collectSignatureFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf and bar.ttf + installTestFontFile(2 /* numFonts */, 1 /* version */); + + // Delete one signature file + assertThat(collectSignatureFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf and bar.ttf + installTestFontFile(2 /* numFonts */, 1 /* version */); + + // Delete one signature file + assertThat(collectSignatureFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(2 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all signature files + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureAllMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all signature files + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureAllMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all signature files + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void signatureAllMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all signature files + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete one font file + assertThat(collectFontFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1); + + // Delete one font file + assertThat(collectFontFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf and bar.ttf + installTestFontFile(2 /* numFonts */, 1 /* version */); + + // Delete one font file + assertThat(collectFontFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf and bar.ttf + installTestFontFile(2 /* numFonts */, 1 /* version */); + + // Delete one font file + assertThat(collectFontFiles().get(0).delete()).isTrue(); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(2 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontAllMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontAllMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontAllMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontDirAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(List.of(mUpdatableFontFilesDir.listFiles())); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontDirAllMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(List.of(mUpdatableFontFilesDir.listFiles())); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontDirAllMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(List.of(mUpdatableFontFilesDir.listFiles())); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void fontDirAllMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(List.of(mUpdatableFontFilesDir.listFiles())); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void dirContentAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void dirContentAllMissingCase_fontFamilyInstalled_fontInstallLater() { + // Install font families, foo.ttf, bar.ttf. + installTestFontFamilies(1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + + @Test + public void dirContentAllMissingCase_fontFileInstalled_fontFamilyInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFamilies(2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontFamilyInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontFamilyInstalled(nextDir, 2 /* version */); + } + + @Test + public void dirContentAllMissingCase_fontFileInstalled_fontFileInstallLater() { + // Install font file, foo.ttf + installTestFontFile(1 /* numFonts */, 1 /* version */); + + // Delete all font files + removeAll(collectFontFiles()); + removeAll(collectSignatureFiles()); + + // New instance of UpdatableFontDir, this emulate a device reboot. + UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */); + + // Make sure the font installation succeeds. + assertTestFontInstalled(dir, 2 /* version */); + + // Make sure after the reboot, the configuration remains. + UpdatableFontDir nextDir = createNewUpdateDir(); + assertTestFontInstalled(nextDir, 2 /* version */); + } + private FontUpdateRequest newFontUpdateRequest(String content, String signature) throws Exception { File file = File.createTempFile("font", "ttf", mCacheDir); diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java index 081da11f2aa8..489ef4444e1d 100644 --- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java +++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java @@ -66,6 +66,7 @@ import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.MockitoSession; import org.mockito.quality.Strictness; @@ -220,43 +221,36 @@ public class CrashRecoveryTest { RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog); verify(rescuePartyObserver, never()).executeBootLoopMitigation(1); - int bootCounter = 0; + for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) { watchdog.noteBoot(); - bootCounter += 1; } + verify(rescuePartyObserver).executeBootLoopMitigation(1); verify(rescuePartyObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - bootCounter += 1; - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(2); verify(rescuePartyObserver, never()).executeBootLoopMitigation(3); - int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter; - for (int i = 0; i < bootLoopThreshold; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(3); verify(rescuePartyObserver, never()).executeBootLoopMitigation(4); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(4); verify(rescuePartyObserver, never()).executeBootLoopMitigation(5); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(5); verify(rescuePartyObserver, never()).executeBootLoopMitigation(6); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(6); verify(rescuePartyObserver, never()).executeBootLoopMitigation(7); } @@ -268,11 +262,11 @@ public class CrashRecoveryTest { setUpRollbackPackageHealthObserver(watchdog); verify(rollbackObserver, never()).executeBootLoopMitigation(1); - int bootCounter = 0; + for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) { watchdog.noteBoot(); - bootCounter += 1; } + verify(rollbackObserver).executeBootLoopMitigation(1); verify(rollbackObserver, never()).executeBootLoopMitigation(2); @@ -280,19 +274,16 @@ public class CrashRecoveryTest { when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL)); - int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter; - for (int i = 0; i < bootLoopThreshold; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rollbackObserver).executeBootLoopMitigation(2); verify(rollbackObserver, never()).executeBootLoopMitigation(3); // Update the list of available rollbacks after executing bootloop mitigation once when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL)); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rollbackObserver, never()).executeBootLoopMitigation(3); } @@ -305,27 +296,21 @@ public class CrashRecoveryTest { verify(rescuePartyObserver, never()).executeBootLoopMitigation(1); verify(rollbackObserver, never()).executeBootLoopMitigation(1); - int bootCounter = 0; for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) { watchdog.noteBoot(); - bootCounter += 1; } verify(rescuePartyObserver).executeBootLoopMitigation(1); verify(rescuePartyObserver, never()).executeBootLoopMitigation(2); verify(rollbackObserver, never()).executeBootLoopMitigation(1); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - bootCounter += 1; - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(2); verify(rescuePartyObserver, never()).executeBootLoopMitigation(3); verify(rollbackObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - bootCounter += 1; - } + watchdog.noteBoot(); + verify(rescuePartyObserver, never()).executeBootLoopMitigation(3); verify(rollbackObserver).executeBootLoopMitigation(1); verify(rollbackObserver, never()).executeBootLoopMitigation(2); @@ -333,43 +318,46 @@ public class CrashRecoveryTest { when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL)); - int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter; - for (int i = 0; i < bootLoopThreshold; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(3); verify(rescuePartyObserver, never()).executeBootLoopMitigation(4); verify(rollbackObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(4); verify(rescuePartyObserver, never()).executeBootLoopMitigation(5); verify(rollbackObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(5); verify(rescuePartyObserver, never()).executeBootLoopMitigation(6); verify(rollbackObserver, never()).executeBootLoopMitigation(2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver, never()).executeBootLoopMitigation(6); verify(rollbackObserver).executeBootLoopMitigation(2); verify(rollbackObserver, never()).executeBootLoopMitigation(3); // Update the list of available rollbacks after executing bootloop mitigation when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL)); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) { - watchdog.noteBoot(); - } + watchdog.noteBoot(); + verify(rescuePartyObserver).executeBootLoopMitigation(6); verify(rescuePartyObserver, never()).executeBootLoopMitigation(7); verify(rollbackObserver, never()).executeBootLoopMitigation(3); + + moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1); + Mockito.reset(rescuePartyObserver); + + for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) { + watchdog.noteBoot(); + } + verify(rescuePartyObserver).executeBootLoopMitigation(1); + verify(rescuePartyObserver, never()).executeBootLoopMitigation(2); } RollbackPackageHealthObserver setUpRollbackPackageHealthObserver(PackageWatchdog watchdog) { @@ -506,16 +494,9 @@ public class CrashRecoveryTest { } try { - if (Flags.recoverabilityDetection()) { - mSpyBootThreshold = spy(watchdog.new BootThreshold( - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); - } else { - mSpyBootThreshold = spy(watchdog.new BootThreshold( + mSpyBootThreshold = spy(watchdog.new BootThreshold( PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); - } doAnswer((Answer<Integer>) invocationOnMock -> { String storedValue = mCrashRecoveryPropertiesMap @@ -640,5 +621,16 @@ public class CrashRecoveryTest { public long uptimeMillis() { return mUpTimeMillis; } + public void moveTimeForward(long milliSeconds) { + mUpTimeMillis += milliSeconds; + } + } + + private void moveTimeForwardAndDispatch(long milliSeconds) { + // Exhaust all due runnables now which shouldn't be executed after time-leap + mTestLooper.dispatchAll(); + mTestClock.moveTimeForward(milliSeconds); + mTestLooper.moveTimeForward(milliSeconds); + mTestLooper.dispatchAll(); } } diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index 4f27e06083ba..1fdf97a4c821 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -1224,7 +1224,7 @@ public class PackageWatchdogTest { PackageWatchdog watchdog = createWatchdog(); TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1); watchdog.registerHealthObserver(bootObserver); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD; i++) { + for (int i = 0; i < 15; i++) { watchdog.noteBoot(); } assertThat(bootObserver.mitigatedBootLoop()).isTrue(); @@ -1262,22 +1262,6 @@ public class PackageWatchdogTest { } /** - * Ensure that boot loop mitigation is not done when the number of boots does not meet the - * threshold. - */ - @Test - public void testBootLoopDetection_doesNotMeetThresholdRecoverabilityHighImpact() { - PackageWatchdog watchdog = createWatchdog(); - TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1, - PackageHealthObserverImpact.USER_IMPACT_LEVEL_80); - watchdog.registerHealthObserver(bootObserver); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; i++) { - watchdog.noteBoot(); - } - assertThat(bootObserver.mitigatedBootLoop()).isFalse(); - } - - /** * Ensure that boot loop mitigation is done for the observer with the lowest user impact */ @Test @@ -1306,7 +1290,7 @@ public class PackageWatchdogTest { bootObserver2.setImpact(PackageHealthObserverImpact.USER_IMPACT_LEVEL_30); watchdog.registerHealthObserver(bootObserver1); watchdog.registerHealthObserver(bootObserver2); - for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD; i++) { + for (int i = 0; i < 15; i++) { watchdog.noteBoot(); } assertThat(bootObserver1.mitigatedBootLoop()).isTrue(); @@ -1349,9 +1333,7 @@ public class PackageWatchdogTest { watchdog.noteBoot(); } for (int i = 0; i < 4; i++) { - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) { watchdog.noteBoot(); - } } moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1); @@ -1360,38 +1342,7 @@ public class PackageWatchdogTest { watchdog.noteBoot(); } for (int i = 0; i < 4; i++) { - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) { watchdog.noteBoot(); - } - } - - assertThat(bootObserver.mBootMitigationCounts).isEqualTo(List.of(1, 2, 3, 4, 1, 2, 3, 4)); - } - - @Test - public void testMultipleBootLoopMitigationRecoverabilityHighImpact() { - PackageWatchdog watchdog = createWatchdog(); - TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1, - PackageHealthObserverImpact.USER_IMPACT_LEVEL_80); - watchdog.registerHealthObserver(bootObserver); - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; j++) { - watchdog.noteBoot(); - } - for (int i = 0; i < 4; i++) { - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) { - watchdog.noteBoot(); - } - } - - moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1); - - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; j++) { - watchdog.noteBoot(); - } - for (int i = 0; i < 4; i++) { - for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) { - watchdog.noteBoot(); - } } assertThat(bootObserver.mBootMitigationCounts).isEqualTo(List.of(1, 2, 3, 4, 1, 2, 3, 4)); @@ -1642,8 +1593,7 @@ public class PackageWatchdogTest { mSpyBootThreshold = spy(watchdog.new BootThreshold( PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); + PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); watchdog.saveAllObserversBootMitigationCountToMetadata(filePath); @@ -1798,16 +1748,9 @@ public class PackageWatchdogTest { mCrashRecoveryPropertiesMap = new HashMap<>(); try { - if (Flags.recoverabilityDetection()) { - mSpyBootThreshold = spy(watchdog.new BootThreshold( - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, - PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS, - PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT)); - } else { - mSpyBootThreshold = spy(watchdog.new BootThreshold( + mSpyBootThreshold = spy(watchdog.new BootThreshold( PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT, PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS)); - } doAnswer((Answer<Integer>) invocationOnMock -> { String storedValue = mCrashRecoveryPropertiesMap diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp index c02d8e96abb0..a0bb84d09664 100644 --- a/tests/UsbManagerTests/Android.bp +++ b/tests/UsbManagerTests/Android.bp @@ -21,6 +21,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_base_license"], + default_team: "trendy_team_android_usb", } android_test { diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp index 92c271165ad7..c4ebdecae735 100644 --- a/tests/UsbTests/Android.bp +++ b/tests/UsbTests/Android.bp @@ -21,6 +21,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_base_license"], + default_team: "trendy_team_android_usb", } android_test { |