Merge "Add compressed bitmaps to be included in `am dumpheap`" into main
diff --git a/Android.bp b/Android.bp
index 80469d6..900fba0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -386,7 +386,6 @@
// TODO(b/120066492): remove gps_debug and protolog.conf.json when the build
// system propagates "required" properly.
"gps_debug.conf",
- "protolog.conf.json.gz",
"framework-res",
// any install dependencies should go into framework-minus-apex-install-dependencies
// rather than here to avoid bloating incremental build time
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index a126c52..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (C) 2008 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.
-#
-LOCAL_PATH := $(call my-dir)
-
-# TODO: Empty this file after all subdirectories' Android.mk have been
-# converted to Android.bp to avoid using any newly added Android.mk.
-include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/apex/jobscheduler/OWNERS b/apex/jobscheduler/OWNERS
index 58434f1..22b6489 100644
--- a/apex/jobscheduler/OWNERS
+++ b/apex/jobscheduler/OWNERS
@@ -2,7 +2,6 @@
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 b4a45f5..0b1e559 100644
--- a/apex/jobscheduler/framework/java/android/app/job/OWNERS
+++ b/apex/jobscheduler/framework/java/android/app/job/OWNERS
@@ -4,4 +4,3 @@
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 96ec75f..b5c568b 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/api/Android.bp b/api/Android.bp
index 76cdf21..65baf78 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -378,6 +378,18 @@
],
}
+soong_config_module_type {
+ name: "non_updatable_exportable_droidstubs",
+ module_type: "droidstubs",
+ config_namespace: "ANDROID",
+ bool_variables: [
+ "release_hidden_api_exportable_stubs",
+ ],
+ properties: [
+ "dists",
+ ],
+}
+
// We resolve dependencies on APIs in modules by depending on a prebuilt of the whole
// platform (sdk_system_current_android). That prebuilt does not include module-lib APIs,
// so use the prebuilt module-lib stubs for modules that export module-lib stubs that the
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index d94890e..65ec4d4 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -27,7 +27,12 @@
// These modules provide source files for the stub libraries
/////////////////////////////////////////////////////////////////////
-droidstubs {
+soong_config_module_type_import {
+ from: "frameworks/base/api/Android.bp",
+ module_types: ["non_updatable_exportable_droidstubs"],
+}
+
+non_updatable_exportable_droidstubs {
name: "api-stubs-docs-non-updatable",
defaults: [
"android-non-updatable-stubs-defaults",
@@ -54,15 +59,35 @@
targets: ["sdk"],
dir: "apistubs/android/public/api",
dest: "android-non-updatable.txt",
- tag: ".api.txt",
},
{
targets: ["sdk"],
dir: "apistubs/android/public/api",
dest: "android-non-updatable-removed.txt",
- tag: ".removed-api.txt",
},
],
+ soong_config_variables: {
+ release_hidden_api_exportable_stubs: {
+ dists: [
+ {
+ tag: ".exportable.api.txt",
+ },
+ {
+ tag: ".exportable.removed-api.txt",
+ },
+ ],
+ conditions_default: {
+ dists: [
+ {
+ tag: ".api.txt",
+ },
+ {
+ tag: ".removed-api.txt",
+ },
+ ],
+ },
+ },
+ },
api_surface: "public",
}
@@ -86,7 +111,7 @@
"\\)",
]
-droidstubs {
+non_updatable_exportable_droidstubs {
name: "system-api-stubs-docs-non-updatable",
defaults: [
"android-non-updatable-stubs-defaults",
@@ -114,19 +139,39 @@
targets: ["sdk"],
dir: "apistubs/android/system/api",
dest: "android-non-updatable.txt",
- tag: ".api.txt",
},
{
targets: ["sdk"],
dir: "apistubs/android/system/api",
dest: "android-non-updatable-removed.txt",
- tag: ".removed-api.txt",
},
],
+ soong_config_variables: {
+ release_hidden_api_exportable_stubs: {
+ dists: [
+ {
+ tag: ".exportable.api.txt",
+ },
+ {
+ tag: ".exportable.removed-api.txt",
+ },
+ ],
+ conditions_default: {
+ dists: [
+ {
+ tag: ".api.txt",
+ },
+ {
+ tag: ".removed-api.txt",
+ },
+ ],
+ },
+ },
+ },
api_surface: "system",
}
-droidstubs {
+non_updatable_exportable_droidstubs {
name: "test-api-stubs-docs-non-updatable",
defaults: [
"android-non-updatable-stubs-defaults",
@@ -149,31 +194,61 @@
targets: ["sdk"],
dir: "apistubs/android/test/api",
dest: "android.txt",
- tag: ".api.txt",
},
{
targets: ["sdk"],
dir: "apistubs/android/test/api",
dest: "removed.txt",
- tag: ".removed-api.txt",
},
{
targets: ["sdk"],
dir: "apistubs/android/test/api",
dest: "android-non-updatable.txt",
- tag: ".api.txt",
},
{
targets: ["sdk"],
dir: "apistubs/android/test/api",
dest: "android-non-updatable-removed.txt",
- tag: ".removed-api.txt",
},
],
+ soong_config_variables: {
+ release_hidden_api_exportable_stubs: {
+ dists: [
+ {
+ tag: ".exportable.api.txt",
+ },
+ {
+ tag: ".exportable.removed-api.txt",
+ },
+ {
+ tag: ".exportable.api.txt",
+ },
+ {
+ tag: ".exportable.removed-api.txt",
+ },
+ ],
+ conditions_default: {
+ dists: [
+ {
+ tag: ".api.txt",
+ },
+ {
+ tag: ".removed-api.txt",
+ },
+ {
+ tag: ".api.txt",
+ },
+ {
+ tag: ".removed-api.txt",
+ },
+ ],
+ },
+ },
+ },
api_surface: "test",
}
-droidstubs {
+non_updatable_exportable_droidstubs {
name: "module-lib-api-stubs-docs-non-updatable",
defaults: [
"android-non-updatable-stubs-defaults",
@@ -201,15 +276,35 @@
targets: ["sdk"],
dir: "apistubs/android/module-lib/api",
dest: "android-non-updatable.txt",
- tag: ".api.txt",
},
{
targets: ["sdk"],
dir: "apistubs/android/module-lib/api",
dest: "android-non-updatable-removed.txt",
- tag: ".removed-api.txt",
},
],
+ soong_config_variables: {
+ release_hidden_api_exportable_stubs: {
+ dists: [
+ {
+ tag: ".exportable.api.txt",
+ },
+ {
+ tag: ".exportable.removed-api.txt",
+ },
+ ],
+ conditions_default: {
+ dists: [
+ {
+ tag: ".api.txt",
+ },
+ {
+ tag: ".removed-api.txt",
+ },
+ ],
+ },
+ },
+ },
api_surface: "module-lib",
}
diff --git a/api/coverage/tools/ExtractFlaggedApis.kt b/api/coverage/tools/ExtractFlaggedApis.kt
index caa1929..d5adfd0 100644
--- a/api/coverage/tools/ExtractFlaggedApis.kt
+++ b/api/coverage/tools/ExtractFlaggedApis.kt
@@ -16,51 +16,69 @@
package android.platform.coverage
+import com.android.tools.metalava.model.ClassItem
+import com.android.tools.metalava.model.MethodItem
import com.android.tools.metalava.model.text.ApiFile
import java.io.File
import java.io.FileWriter
/** Usage: extract-flagged-apis <api text file> <output .pb file> */
fun main(args: Array<String>) {
- var cb = ApiFile.parseApi(listOf(File(args[0])))
- var builder = FlagApiMap.newBuilder()
+ val cb = ApiFile.parseApi(listOf(File(args[0])))
+ val builder = FlagApiMap.newBuilder()
for (pkg in cb.getPackages().packages) {
- var packageName = pkg.qualifiedName()
+ val packageName = pkg.qualifiedName()
pkg.allClasses()
.filter { it.methods().size > 0 }
.forEach {
- for (method in it.methods()) {
- val flagValue =
- method.modifiers
- .findAnnotation("android.annotation.FlaggedApi")
- ?.findAttribute("value")
- ?.value
- ?.value()
- if (flagValue != null && flagValue is String) {
- var api =
- JavaMethod.newBuilder()
- .setPackageName(packageName)
- .setClassName(it.fullName())
- .setMethodName(method.name())
- for (param in method.parameters()) {
- api.addParameters(param.type().toTypeString())
- }
- if (builder.containsFlagToApi(flagValue)) {
- var updatedApis =
- builder
- .getFlagToApiOrThrow(flagValue)
- .toBuilder()
- .addJavaMethods(api)
- .build()
- builder.putFlagToApi(flagValue, updatedApis)
- } else {
- var apis = FlaggedApis.newBuilder().addJavaMethods(api).build()
- builder.putFlagToApi(flagValue, apis)
- }
- }
- }
+ extractFlaggedApisFromClass(it, it.methods(), packageName, builder)
+ extractFlaggedApisFromClass(it, it.constructors(), packageName, builder)
}
}
val flagApiMap = builder.build()
FileWriter(args[1]).use { it.write(flagApiMap.toString()) }
}
+
+fun extractFlaggedApisFromClass(
+ classItem: ClassItem,
+ methods: List<MethodItem>,
+ packageName: String,
+ builder: FlagApiMap.Builder
+) {
+ val classFlag =
+ classItem.modifiers
+ .findAnnotation("android.annotation.FlaggedApi")
+ ?.findAttribute("value")
+ ?.value
+ ?.value() as? String
+ for (method in methods) {
+ val methodFlag =
+ method.modifiers
+ .findAnnotation("android.annotation.FlaggedApi")
+ ?.findAttribute("value")
+ ?.value
+ ?.value() as? String
+ ?: classFlag
+ val api =
+ JavaMethod.newBuilder()
+ .setPackageName(packageName)
+ .setClassName(classItem.fullName())
+ .setMethodName(method.name())
+ for (param in method.parameters()) {
+ api.addParameters(param.type().toTypeString())
+ }
+ if (methodFlag != null) {
+ addFlaggedApi(builder, api, methodFlag)
+ }
+ }
+}
+
+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)
+ }
+}
diff --git a/cmds/incident_helper/OWNERS b/cmds/incident_helper/OWNERS
index cede4ea..29f44ab 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/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index ff1ea4f..712f3e5 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -42,6 +42,7 @@
# ActivityThread
per-file ActivityThread.java = file:/services/core/java/com/android/server/am/OWNERS
per-file ActivityThread.java = file:/services/core/java/com/android/server/wm/OWNERS
+per-file ActivityThread.java = file:RESOURCES_OWNERS
# Alarm
per-file *Alarm* = file:/apex/jobscheduler/OWNERS
diff --git a/core/java/android/app/RESOURCES_OWNERS b/core/java/android/app/RESOURCES_OWNERS
index 5582803..fe37c0c 100644
--- a/core/java/android/app/RESOURCES_OWNERS
+++ b/core/java/android/app/RESOURCES_OWNERS
@@ -1,3 +1,5 @@
-rtmitchell@google.com
-toddke@google.com
+zyy@google.com
+jakmcbane@google.com
+branliu@google.com
+markpun@google.com
patb@google.com
diff --git a/core/java/android/appwidget/OWNERS b/core/java/android/appwidget/OWNERS
index 554b0de..1910833 100644
--- a/core/java/android/appwidget/OWNERS
+++ b/core/java/android/appwidget/OWNERS
@@ -1,4 +1,5 @@
-pinyaoting@google.com
+fengjial@google.com
sihua@google.com
+pinyaoting@google.com
suprabh@google.com
sunnygoyal@google.com
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 8a55616..445880c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3188,6 +3188,16 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: This device is capable of launching apps in automotive display
+ * compatibility mode.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_CAR_DISPLAY_COMPATIBILITY =
+ "android.software.car.display_compatibility";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature(String, int)}: If this feature is supported, the device supports
* {@link android.security.identity.IdentityCredentialStore} implemented in secure hardware
* at the given feature version.
diff --git a/core/java/android/hardware/devicestate/OWNERS b/core/java/android/hardware/devicestate/OWNERS
new file mode 100644
index 0000000..d9b0e2e
--- /dev/null
+++ b/core/java/android/hardware/devicestate/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/devicestate/OWNERS
diff --git a/core/java/android/net/IVpnManager.aidl b/core/java/android/net/IVpnManager.aidl
index f302378..5149967 100644
--- a/core/java/android/net/IVpnManager.aidl
+++ b/core/java/android/net/IVpnManager.aidl
@@ -60,6 +60,12 @@
LegacyVpnInfo getLegacyVpnInfo(int userId);
boolean updateLockdownVpn();
+ /** Profile store APIs */
+ byte[] getFromVpnProfileStore(String name);
+ boolean putIntoVpnProfileStore(String name, in byte[] blob);
+ boolean removeFromVpnProfileStore(String name);
+ String[] listFromVpnProfileStore(String prefix);
+
/** General system APIs */
VpnConfig getVpnConfig(int userId);
void factoryReset();
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index ff47f3f..c50bc56 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -717,4 +717,81 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Get the vpn profile owned by the calling uid with the given name from the vpn database.
+ *
+ * <p>Note this method should not be used for platform VPN profiles. </p>
+ *
+ * @param name The name of the profile to retrieve.
+ * @return the unstructured blob for the matching vpn profile.
+ * Returns null if no profile with a matching name was found.
+ * @hide
+ */
+ @Nullable
+ public byte[] getFromVpnProfileStore(@NonNull String name) {
+ try {
+ return mService.getFromVpnProfileStore(name);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Put the given vpn profile owned by the calling uid with the given name into the vpn database.
+ * Existing profiles with the same name will be replaced.
+ *
+ * <p>Note this method should not be used for platform VPN profiles.
+ * To update a platform VPN, use provisionVpnProfile() instead. </p>
+ *
+ * @param name The name of the profile to put.
+ * @param blob The profile.
+ * @return true if the profile was successfully added. False otherwise.
+ * @hide
+ */
+ public boolean putIntoVpnProfileStore(@NonNull String name, @NonNull byte[] blob) {
+ try {
+ return mService.putIntoVpnProfileStore(name, blob);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Removes the vpn profile owned by the calling uid with the given name from the vpn database.
+ *
+ * <p>Note this method should not be used for platform VPN profiles.
+ * To remove a platform VPN, use deleteVpnProfile() instead.</p>
+ *
+ * @param name The name of the profile to be removed.
+ * @return true if a profile was removed. False if no profile with a matching name was found.
+ * @hide
+ */
+ public boolean removeFromVpnProfileStore(@NonNull String name) {
+ try {
+ return mService.removeFromVpnProfileStore(name);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns a list of the name suffixes of the vpn profiles owned by the calling uid in the vpn
+ * database matching the given prefix, sorted in ascending order.
+ *
+ * <p>Note this method should not be used for platform VPN profiles. </p>
+ *
+ * @param prefix The prefix to match.
+ * @return an array of strings representing the name suffixes stored in the profile database
+ * matching the given prefix. The return value may be empty but never null.
+ * @hide
+ */
+ @NonNull
+ public String[] listFromVpnProfileStore(@NonNull String prefix) {
+ try {
+ return mService.listFromVpnProfileStore(prefix);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 04d6f61..f785cca 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -210,6 +210,7 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean hasSwappedOutPss;
+ // LINT.IfChange
/** @hide */
public static final int HEAP_UNKNOWN = 0;
/** @hide */
@@ -311,6 +312,7 @@
public static final int OTHER_ART_APP = 30;
/** @hide */
public static final int OTHER_ART_BOOT = 31;
+ // LINT.ThenChange(/system/memory/libmeminfo/include/meminfo/androidprocheaps.h)
/** @hide */
public static final int OTHER_DVK_STAT_ART_START = OTHER_ART_APP - NUM_OTHER_STATS;
/** @hide */
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 8e860c3..0c70750 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -572,6 +572,11 @@
}
res.mReadWriteHelper = ReadWriteHelper.DEFAULT;
}
+
+ if (res.mNativePtr == 0) {
+ Log.e(TAG, "Obtained Parcel object has null native pointer. Invalid state.");
+ }
+
return res;
}
diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS
index 763c79e..5f9f6bd 100644
--- a/core/java/android/service/voice/OWNERS
+++ b/core/java/android/service/voice/OWNERS
@@ -3,5 +3,4 @@
include /core/java/android/app/assist/OWNERS
# The owner here should not be assist owner
-liangyuchen@google.com
adudani@google.com
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index cbbe785..6dd0a90 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1247,7 +1247,7 @@
* 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/net/ConnectivityBlobStore.java b/core/java/com/android/internal/net/ConnectivityBlobStore.java
index 1b18485..f8eb5be 100644
--- a/core/java/com/android/internal/net/ConnectivityBlobStore.java
+++ b/core/java/com/android/internal/net/ConnectivityBlobStore.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.content.ContentValues;
import android.database.Cursor;
+import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
@@ -153,8 +154,11 @@
final List<String> names = new ArrayList<String>();
try (Cursor cursor = mDb.query(TABLENAME,
new String[] {"name"} /* columns */,
- "owner=? AND name LIKE ?" /* selection */,
- new String[] {Integer.toString(ownerUid), prefix + "%"} /* selectionArgs */,
+ "owner=? AND name LIKE ? ESCAPE '\\'" /* selection */,
+ new String[] {
+ Integer.toString(ownerUid),
+ DatabaseUtils.escapeForLike(prefix) + "%"
+ } /* selectionArgs */,
null /* groupBy */,
null /* having */,
"name ASC" /* orderBy */)) {
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index dbe4fba..9fc7ddb 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -415,8 +415,10 @@
*/
private ParseResult<ParsingPackage> parseMonolithicPackage(ParseInput input, File apkFile,
int flags) {
+ // The signature parsing will be done later in method parseBaseApk.
+ int liteParseFlags = flags & ~PARSE_COLLECT_CERTIFICATES;
final ParseResult<PackageLite> liteResult =
- ApkLiteParseUtils.parseMonolithicPackageLite(input, apkFile, flags);
+ ApkLiteParseUtils.parseMonolithicPackageLite(input, apkFile, liteParseFlags);
if (liteResult.isError()) {
return input.error(liteResult);
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 45bb629..8c6bf79 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -301,6 +301,7 @@
"libdebuggerd_client",
"libutils",
"libbinder",
+ "libbinderdebug",
"libbinder_ndk",
"libui",
"libgraphicsenv",
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 3aca751..d687ef3 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -1,6 +1,5 @@
# Camera
-per-file *Camera*,*camera* = cychen@google.com, epeev@google.com, etalvala@google.com
-per-file *Camera*,*camera* = shuzhenwang@google.com, yinchiayeh@google.com, zhijunhe@google.com
+per-file *Camera*,*camera* = file:platform/frameworks/av:/camera/OWNERS
# Connectivity
per-file android_net_* = codewiz@google.com, jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index a98f947..3c2dccd 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -16,97 +16,51 @@
#define LOG_TAG "android.os.Debug"
+#include "android_os_Debug.h"
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
#include <assert.h>
+#include <binderdebug/BinderDebug.h>
+#include <bionic/malloc.h>
#include <ctype.h>
+#include <debuggerd/client.h>
+#include <dmabufinfo/dmabuf_sysfs_stats.h>
+#include <dmabufinfo/dmabufinfo.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <log/log.h>
#include <malloc.h>
+#include <meminfo/androidprocheaps.h>
+#include <meminfo/procmeminfo.h>
+#include <meminfo/sysmeminfo.h>
+#include <memtrack/memtrack.h>
+#include <memunreachable/memunreachable.h>
+#include <nativehelper/JNIPlatformHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
+#include <utils/String8.h>
+#include <utils/misc.h>
+#include <vintf/KernelConfigs.h>
#include <iomanip>
#include <string>
#include <vector>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <bionic/malloc.h>
-#include <debuggerd/client.h>
-#include <log/log.h>
-#include <utils/misc.h>
-#include <utils/String8.h>
-
-#include <nativehelper/JNIPlatformHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
#include "jni.h"
-#include <dmabufinfo/dmabuf_sysfs_stats.h>
-#include <dmabufinfo/dmabufinfo.h>
-#include <meminfo/procmeminfo.h>
-#include <meminfo/sysmeminfo.h>
-#include <memtrack/memtrack.h>
-#include <memunreachable/memunreachable.h>
-#include <android-base/strings.h>
-#include "android_os_Debug.h"
-#include <vintf/KernelConfigs.h>
namespace android
{
-enum {
- HEAP_UNKNOWN,
- HEAP_DALVIK,
- HEAP_NATIVE,
-
- HEAP_DALVIK_OTHER,
- HEAP_STACK,
- HEAP_CURSOR,
- HEAP_ASHMEM,
- HEAP_GL_DEV,
- HEAP_UNKNOWN_DEV,
- HEAP_SO,
- HEAP_JAR,
- HEAP_APK,
- HEAP_TTF,
- HEAP_DEX,
- HEAP_OAT,
- HEAP_ART,
- HEAP_UNKNOWN_MAP,
- HEAP_GRAPHICS,
- HEAP_GL,
- HEAP_OTHER_MEMTRACK,
-
- // Dalvik extra sections (heap).
- HEAP_DALVIK_NORMAL,
- HEAP_DALVIK_LARGE,
- HEAP_DALVIK_ZYGOTE,
- HEAP_DALVIK_NON_MOVING,
-
- // Dalvik other extra sections.
- HEAP_DALVIK_OTHER_LINEARALLOC,
- HEAP_DALVIK_OTHER_ACCOUNTING,
- HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE,
- HEAP_DALVIK_OTHER_APP_CODE_CACHE,
- HEAP_DALVIK_OTHER_COMPILER_METADATA,
- HEAP_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE,
-
- // Boot vdex / app dex / app vdex
- HEAP_DEX_BOOT_VDEX,
- HEAP_DEX_APP_DEX,
- HEAP_DEX_APP_VDEX,
-
- // App art, boot art.
- HEAP_ART_APP,
- HEAP_ART_BOOT,
-
- _NUM_HEAP,
- _NUM_EXCLUSIVE_HEAP = HEAP_OTHER_MEMTRACK+1,
- _NUM_CORE_HEAP = HEAP_NATIVE+1
-};
+using namespace android::meminfo;
struct stat_fields {
jfieldID pss_field;
@@ -146,18 +100,6 @@
static jfieldID otherStats_field;
static jfieldID hasSwappedOutPss_field;
-struct stats_t {
- int pss;
- int swappablePss;
- int rss;
- int privateDirty;
- int sharedDirty;
- int privateClean;
- int sharedClean;
- int swappedOut;
- int swappedOutPss;
-};
-
#define BINDER_STATS "/proc/binder/stats"
static jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz)
@@ -240,190 +182,14 @@
return err;
}
-static bool load_maps(int pid, stats_t* stats, bool* foundSwapPss)
-{
- *foundSwapPss = false;
- uint64_t prev_end = 0;
- int prev_heap = HEAP_UNKNOWN;
-
- std::string smaps_path = base::StringPrintf("/proc/%d/smaps", pid);
- auto vma_scan = [&](const meminfo::Vma& vma) {
- int which_heap = HEAP_UNKNOWN;
- int sub_heap = HEAP_UNKNOWN;
- bool is_swappable = false;
- std::string name;
- if (base::EndsWith(vma.name, " (deleted)")) {
- name = vma.name.substr(0, vma.name.size() - strlen(" (deleted)"));
- } else {
- name = vma.name;
- }
-
- uint32_t namesz = name.size();
- if (base::StartsWith(name, "[heap]")) {
- which_heap = HEAP_NATIVE;
- } else if (base::StartsWith(name, "[anon:libc_malloc]")) {
- which_heap = HEAP_NATIVE;
- } else if (base::StartsWith(name, "[anon:scudo:")) {
- which_heap = HEAP_NATIVE;
- } else if (base::StartsWith(name, "[anon:GWP-ASan")) {
- which_heap = HEAP_NATIVE;
- } else if (base::StartsWith(name, "[stack")) {
- which_heap = HEAP_STACK;
- } else if (base::StartsWith(name, "[anon:stack_and_tls:")) {
- which_heap = HEAP_STACK;
- } else if (base::EndsWith(name, ".so")) {
- which_heap = HEAP_SO;
- is_swappable = true;
- } else if (base::EndsWith(name, ".jar")) {
- which_heap = HEAP_JAR;
- is_swappable = true;
- } else if (base::EndsWith(name, ".apk")) {
- which_heap = HEAP_APK;
- is_swappable = true;
- } else if (base::EndsWith(name, ".ttf")) {
- which_heap = HEAP_TTF;
- is_swappable = true;
- } else if ((base::EndsWith(name, ".odex")) ||
- (namesz > 4 && strstr(name.c_str(), ".dex") != nullptr)) {
- which_heap = HEAP_DEX;
- sub_heap = HEAP_DEX_APP_DEX;
- is_swappable = true;
- } else if (base::EndsWith(name, ".vdex")) {
- which_heap = HEAP_DEX;
- // Handle system@framework@boot and system/framework/boot|apex
- if ((strstr(name.c_str(), "@boot") != nullptr) ||
- (strstr(name.c_str(), "/boot") != nullptr) ||
- (strstr(name.c_str(), "/apex") != nullptr)) {
- sub_heap = HEAP_DEX_BOOT_VDEX;
- } else {
- sub_heap = HEAP_DEX_APP_VDEX;
- }
- is_swappable = true;
- } else if (base::EndsWith(name, ".oat")) {
- which_heap = HEAP_OAT;
- is_swappable = true;
- } else if (base::EndsWith(name, ".art") || base::EndsWith(name, ".art]")) {
- which_heap = HEAP_ART;
- // Handle system@framework@boot* and system/framework/boot|apex*
- if ((strstr(name.c_str(), "@boot") != nullptr) ||
- (strstr(name.c_str(), "/boot") != nullptr) ||
- (strstr(name.c_str(), "/apex") != nullptr)) {
- sub_heap = HEAP_ART_BOOT;
- } else {
- sub_heap = HEAP_ART_APP;
- }
- is_swappable = true;
- } else if (base::StartsWith(name, "/dev/")) {
- which_heap = HEAP_UNKNOWN_DEV;
- if (base::StartsWith(name, "/dev/kgsl-3d0")) {
- which_heap = HEAP_GL_DEV;
- } else if (base::StartsWith(name, "/dev/ashmem/CursorWindow")) {
- which_heap = HEAP_CURSOR;
- } else if (base::StartsWith(name, "/dev/ashmem/jit-zygote-cache")) {
- which_heap = HEAP_DALVIK_OTHER;
- sub_heap = HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE;
- } else if (base::StartsWith(name, "/dev/ashmem")) {
- which_heap = HEAP_ASHMEM;
- }
- } else if (base::StartsWith(name, "/memfd:jit-cache")) {
- which_heap = HEAP_DALVIK_OTHER;
- sub_heap = HEAP_DALVIK_OTHER_APP_CODE_CACHE;
- } else if (base::StartsWith(name, "/memfd:jit-zygote-cache")) {
- which_heap = HEAP_DALVIK_OTHER;
- sub_heap = HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE;
- } else if (base::StartsWith(name, "[anon:")) {
- which_heap = HEAP_UNKNOWN;
- if (base::StartsWith(name, "[anon:dalvik-")) {
- which_heap = HEAP_DALVIK_OTHER;
- if (base::StartsWith(name, "[anon:dalvik-LinearAlloc")) {
- sub_heap = HEAP_DALVIK_OTHER_LINEARALLOC;
- } else if (base::StartsWith(name, "[anon:dalvik-alloc space") ||
- base::StartsWith(name, "[anon:dalvik-main space")) {
- // This is the regular Dalvik heap.
- which_heap = HEAP_DALVIK;
- sub_heap = HEAP_DALVIK_NORMAL;
- } else if (base::StartsWith(name,
- "[anon:dalvik-large object space") ||
- base::StartsWith(
- name, "[anon:dalvik-free list large object space")) {
- which_heap = HEAP_DALVIK;
- sub_heap = HEAP_DALVIK_LARGE;
- } else if (base::StartsWith(name, "[anon:dalvik-non moving space")) {
- which_heap = HEAP_DALVIK;
- sub_heap = HEAP_DALVIK_NON_MOVING;
- } else if (base::StartsWith(name, "[anon:dalvik-zygote space")) {
- which_heap = HEAP_DALVIK;
- sub_heap = HEAP_DALVIK_ZYGOTE;
- } else if (base::StartsWith(name, "[anon:dalvik-indirect ref")) {
- sub_heap = HEAP_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE;
- } else if (base::StartsWith(name, "[anon:dalvik-jit-code-cache") ||
- base::StartsWith(name, "[anon:dalvik-data-code-cache")) {
- sub_heap = HEAP_DALVIK_OTHER_APP_CODE_CACHE;
- } else if (base::StartsWith(name, "[anon:dalvik-CompilerMetadata")) {
- sub_heap = HEAP_DALVIK_OTHER_COMPILER_METADATA;
- } else {
- sub_heap = HEAP_DALVIK_OTHER_ACCOUNTING; // Default to accounting.
- }
- }
- } else if (namesz > 0) {
- which_heap = HEAP_UNKNOWN_MAP;
- } else if (vma.start == prev_end && prev_heap == HEAP_SO) {
- // bss section of a shared library
- which_heap = HEAP_SO;
- }
-
- prev_end = vma.end;
- prev_heap = which_heap;
-
- const meminfo::MemUsage& usage = vma.usage;
- if (usage.swap_pss > 0 && *foundSwapPss != true) {
- *foundSwapPss = true;
- }
-
- uint64_t swapable_pss = 0;
- if (is_swappable && (usage.pss > 0)) {
- float sharing_proportion = 0.0;
- if ((usage.shared_clean > 0) || (usage.shared_dirty > 0)) {
- sharing_proportion = (usage.pss - usage.uss) / (usage.shared_clean + usage.shared_dirty);
- }
- swapable_pss = (sharing_proportion * usage.shared_clean) + usage.private_clean;
- }
-
- stats[which_heap].pss += usage.pss;
- stats[which_heap].swappablePss += swapable_pss;
- stats[which_heap].rss += usage.rss;
- stats[which_heap].privateDirty += usage.private_dirty;
- stats[which_heap].sharedDirty += usage.shared_dirty;
- stats[which_heap].privateClean += usage.private_clean;
- stats[which_heap].sharedClean += usage.shared_clean;
- stats[which_heap].swappedOut += usage.swap;
- stats[which_heap].swappedOutPss += usage.swap_pss;
- if (which_heap == HEAP_DALVIK || which_heap == HEAP_DALVIK_OTHER ||
- which_heap == HEAP_DEX || which_heap == HEAP_ART) {
- stats[sub_heap].pss += usage.pss;
- stats[sub_heap].swappablePss += swapable_pss;
- stats[sub_heap].rss += usage.rss;
- stats[sub_heap].privateDirty += usage.private_dirty;
- stats[sub_heap].sharedDirty += usage.shared_dirty;
- stats[sub_heap].privateClean += usage.private_clean;
- stats[sub_heap].sharedClean += usage.shared_clean;
- stats[sub_heap].swappedOut += usage.swap;
- stats[sub_heap].swappedOutPss += usage.swap_pss;
- }
- return true;
- };
-
- return meminfo::ForEachVmaFromFile(smaps_path, vma_scan);
-}
-
static jboolean android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
jint pid, jobject object)
{
bool foundSwapPss;
- stats_t stats[_NUM_HEAP];
+ AndroidHeapStats stats[_NUM_HEAP];
memset(&stats, 0, sizeof(stats));
- if (!load_maps(pid, stats, &foundSwapPss)) {
+ if (!ExtractAndroidHeapStats(pid, stats, &foundSwapPss)) {
return JNI_FALSE;
}
@@ -815,6 +581,15 @@
return false;
}
+ std::string binderState;
+ android::status_t status = android::getBinderTransactions(pid, binderState);
+ if (status == android::OK) {
+ if (!android::base::WriteStringToFd(binderState, fd)) {
+ PLOG(ERROR) << "Failed to dump binder state info for pid: " << pid;
+ }
+ } else {
+ PLOG(ERROR) << "Failed to get binder state info for pid: " << pid << " status: " << status;
+ }
int res = dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd);
if (fdatasync(fd.get()) != 0) {
PLOG(ERROR) << "Failed flushing trace.";
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index 00d90cc..1a95520 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -11,7 +11,6 @@
# 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/tests/coretests/src/android/text/format/DateIntervalFormatTest.java b/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
index de7244d..71c068d 100644
--- a/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
+++ b/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
@@ -149,7 +149,7 @@
FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
assertEquals("19.–22.01.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY,
FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
- assertEquals("19.01. – 22.04.2009",
+ assertEquals("19.01.\u2009–\u200922.04.2009",
formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH,
FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
assertEquals("19.01.2009\u2009\u2013\u200909.02.2012",
@@ -220,10 +220,10 @@
formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, 0));
assertEquals("19.–22. Jan. 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY,
FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
- assertEquals("Mo., 19. – Do., 22. Jan. 2009",
+ assertEquals("Mo., 19.\u2009–\u2009Do., 22. Jan. 2009",
formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY,
FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
- assertEquals("Montag, 19. – Donnerstag, 22. Januar 2009",
+ assertEquals("Montag, 19.\u2009–\u2009Donnerstag, 22. Januar 2009",
formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
assertEquals("19. Januar\u2009\u2013\u200922. April 2009",
diff --git a/core/tests/coretests/src/com/android/internal/net/ConnectivityBlobStoreTest.java b/core/tests/coretests/src/com/android/internal/net/ConnectivityBlobStoreTest.java
index 68545cf..ad4ccc9 100644
--- a/core/tests/coretests/src/com/android/internal/net/ConnectivityBlobStoreTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/ConnectivityBlobStoreTest.java
@@ -153,4 +153,41 @@
final String[] actual = connectivityBlobStore.list(TEST_NAME /* prefix */);
assertArrayEquals(expected, actual);
}
+
+ @Test
+ public void testList_underscoreInPrefix() throws Exception {
+ final String prefix = TEST_NAME + "_";
+ final String[] unsortedNames = new String[] {
+ prefix + "000",
+ TEST_NAME + "123",
+ };
+ // The '_' in the prefix should not be treated as a wildcard so the only match is "000".
+ final String[] expected = new String[] {"000"};
+ final ConnectivityBlobStore connectivityBlobStore = createConnectivityBlobStore();
+
+ for (int i = 0; i < unsortedNames.length; i++) {
+ assertTrue(connectivityBlobStore.put(unsortedNames[i], TEST_BLOB));
+ }
+ final String[] actual = connectivityBlobStore.list(prefix);
+ assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void testList_percentInPrefix() throws Exception {
+ final String prefix = "%" + TEST_NAME + "%";
+ final String[] unsortedNames = new String[] {
+ TEST_NAME + "12345",
+ prefix + "0",
+ "abc" + TEST_NAME + "987",
+ };
+ // The '%' in the prefix should not be treated as a wildcard so the only match is "0".
+ final String[] expected = new String[] {"0"};
+ final ConnectivityBlobStore connectivityBlobStore = createConnectivityBlobStore();
+
+ for (int i = 0; i < unsortedNames.length; i++) {
+ assertTrue(connectivityBlobStore.put(unsortedNames[i], TEST_BLOB));
+ }
+ final String[] actual = connectivityBlobStore.list(prefix);
+ assertArrayEquals(expected, actual);
+ }
}
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 9320c14..d1aa8e9 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -1432,6 +1432,16 @@
postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc
</font>
</family>
+ <family lang="ja">
+ <font weight="400" style="normal" postScriptName="NotoSerifHentaigana-ExtraLight">
+ NotoSerifHentaigana.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="700" style="normal" postScriptName="NotoSerifHentaigana-ExtraLight">
+ NotoSerifHentaigana.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ </family>
<family lang="ko">
<font weight="400" style="normal" index="1" postScriptName="NotoSansCJKjp-Regular">
NotoSansCJK-Regular.ttc
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 2cac2e1..2f2215f 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 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
similarity index 82%
rename from keystore/java/android/security/Authorization.java
rename to keystore/java/android/security/KeyStoreAuthorization.java
index 6404c4b..14d715f 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/KeyStoreAuthorization.java
@@ -33,15 +33,21 @@
* @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 @@
* @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 @@
* @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 @@
* 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 @@
* @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 @@
* @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 d7b5914..9d4b426 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -304,7 +304,7 @@
_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/media/OWNERS b/media/OWNERS
index 2e9276d..1e5a458 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -4,6 +4,7 @@
essick@google.com
etalvala@google.com
hunga@google.com
+jchowdhary@google.com
jmtrivi@google.com
jsharkey@android.com
lajos@google.com
diff --git a/media/java/android/media/AudioDescriptor.java b/media/java/android/media/AudioDescriptor.java
index 85a653c..b5cae2c 100644
--- a/media/java/android/media/AudioDescriptor.java
+++ b/media/java/android/media/AudioDescriptor.java
@@ -99,7 +99,7 @@
* When encapsulation is required, only playback with {@link android.media.AudioTrack} API is
* supported. But playback with {@link android.media.MediaPlayer} is not.
* When an encapsulation type is required, the {@link AudioFormat} encoding selected when
- * creating the {@link AudioTrack} must match the encapsulation type, e.g
+ * creating the {@link AudioTrack} must match the encapsulation type, e.g.
* AudioFormat#ENCODING_IEC61937 for AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937.
*
* @return an integer representing the encapsulation type
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3dfd572..cff5f20 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3460,7 +3460,7 @@
/* modes for setMode/getMode/setRoute/getRoute */
/**
- * Audio harware modes.
+ * Audio hardware modes.
*/
/**
* Invalid audio mode.
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 45bf5c4..17c4a77 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -65,6 +65,7 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Supplier;
/**
MediaCodec class can be used to access low-level media codecs, i.e. encoder/decoder components.
@@ -2014,6 +2015,23 @@
}
}
+ // HACKY(b/325389296): aconfig flag accessors may not work in all contexts where MediaCodec API
+ // is used, so allow accessors to fail. In those contexts use a default value, normally false.
+
+ /* package private */
+ static boolean GetFlag(Supplier<Boolean> flagValueSupplier) {
+ return GetFlag(flagValueSupplier, false /* defaultValue */);
+ }
+
+ /* package private */
+ static boolean GetFlag(Supplier<Boolean> flagValueSupplier, boolean defaultValue) {
+ try {
+ return flagValueSupplier.get();
+ } catch (java.lang.RuntimeException e) {
+ return defaultValue;
+ }
+ }
+
private boolean mHasSurface = false;
/**
@@ -2346,12 +2364,16 @@
}
// at the moment no codecs support detachable surface
- if (android.media.codec.Flags.nullOutputSurface()) {
+ boolean canDetach = GetFlag(() -> android.media.codec.Flags.nullOutputSurfaceSupport());
+ if (GetFlag(() -> android.media.codec.Flags.nullOutputSurface())) {
// Detached surface flag is only meaningful if surface is null. Otherwise, it is
// ignored.
- if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) {
+ if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0 && !canDetach) {
throw new IllegalArgumentException("Codec does not support detached surface");
}
+ } else {
+ // don't allow detaching if API is disabled
+ canDetach = false;
}
String[] keys = null;
@@ -2393,6 +2415,14 @@
}
native_configure(keys, values, surface, crypto, descramblerBinder, flags);
+
+ if (canDetach) {
+ // If we were able to configure native codec with a detached surface
+ // we now know that we have a surface.
+ if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) {
+ mHasSurface = true;
+ }
+ }
}
/**
@@ -2437,12 +2467,19 @@
if (!mHasSurface) {
throw new IllegalStateException("codec was not configured for an output surface");
}
+
// note: we still have a surface in detached mode, so keep mHasSurface
// we also technically allow calling detachOutputSurface multiple times in a row
- throw new IllegalStateException("codec does not support detaching output surface");
- // native_detachSurface();
+
+ if (GetFlag(() -> android.media.codec.Flags.nullOutputSurfaceSupport())) {
+ native_detachOutputSurface();
+ } else {
+ throw new IllegalStateException("codec does not support detaching output surface");
+ }
}
+ private native void native_detachOutputSurface();
+
/**
* Create a persistent input surface that can be used with codecs that normally have an input
* surface, such as video encoders. A persistent input can be reused by subsequent
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index abad460..8ff4305 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -23,6 +23,7 @@
import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE;
import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
+import static android.media.MediaCodec.GetFlag;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
@@ -827,10 +828,10 @@
features.add(new Feature(FEATURE_MultipleFrames, (1 << 5), false));
features.add(new Feature(FEATURE_DynamicTimestamp, (1 << 6), false));
features.add(new Feature(FEATURE_LowLatency, (1 << 7), true));
- if (android.media.codec.Flags.dynamicColorAspects()) {
+ if (GetFlag(() -> android.media.codec.Flags.dynamicColorAspects())) {
features.add(new Feature(FEATURE_DynamicColorAspects, (1 << 8), true));
}
- if (android.media.codec.Flags.nullOutputSurface()) {
+ if (GetFlag(() -> android.media.codec.Flags.nullOutputSurface())) {
features.add(new Feature(FEATURE_DetachedSurface, (1 << 9), true));
}
@@ -851,10 +852,10 @@
features.add(new Feature(FEATURE_QpBounds, (1 << 3), false));
features.add(new Feature(FEATURE_EncodingStatistics, (1 << 4), false));
features.add(new Feature(FEATURE_HdrEditing, (1 << 5), false));
- if (android.media.codec.Flags.hlgEditing()) {
+ if (GetFlag(() -> android.media.codec.Flags.hlgEditing())) {
features.add(new Feature(FEATURE_HlgEditing, (1 << 6), true));
}
- if (android.media.codec.Flags.regionOfInterest()) {
+ if (GetFlag(() -> android.media.codec.Flags.regionOfInterest())) {
features.add(new Feature(FEATURE_Roi, (1 << 7), true));
}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 0fc80dd..82561f9 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -389,6 +389,14 @@
return err;
}
+status_t JMediaCodec::detachOutputSurface() {
+ status_t err = mCodec->detachOutputSurface();
+ if (err == OK) {
+ mSurfaceTextureClient.clear();
+ }
+ return err;
+}
+
status_t JMediaCodec::createInputSurface(
sp<IGraphicBufferProducer>* bufferProducer) {
return mCodec->createInputSurface(bufferProducer);
@@ -1798,6 +1806,20 @@
throwExceptionAsNecessary(env, err, codec);
}
+static void android_media_MediaCodec_native_detachOutputSurface(
+ JNIEnv *env,
+ jobject thiz) {
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL || codec->initCheck() != OK) {
+ throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
+ return;
+ }
+
+ status_t err = codec->detachOutputSurface();
+ throwExceptionAsNecessary(env, err, codec);
+}
+
sp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface(
JNIEnv* env, jobject object) {
sp<PersistentSurface> persistentSurface;
@@ -4107,6 +4129,10 @@
"(Landroid/view/Surface;)V",
(void *)android_media_MediaCodec_native_setSurface },
+ { "native_detachOutputSurface",
+ "()V",
+ (void *)android_media_MediaCodec_native_detachOutputSurface },
+
{ "createInputSurface", "()Landroid/view/Surface;",
(void *)android_media_MediaCodec_createInputSurface },
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index abb23f5..c9b6b7f6 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -80,6 +80,8 @@
status_t setSurface(
const sp<IGraphicBufferProducer> &surface);
+ status_t detachOutputSurface();
+
status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
status_t setInputSurface(const sp<PersistentSurface> &surface);
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 4b63fbf..55b5e81 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -367,7 +367,7 @@
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_setBufferTransparency(ASurfaceTransaction* aSurfaceTransaction,
ASurfaceControl* aSurfaceControl,
- int8_t transparency) {
+ ASurfaceTransactionTransparency transparency) {
CHECK_NOT_NULL(aSurfaceTransaction);
CHECK_NOT_NULL(aSurfaceControl);
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index ece8851..79373a5 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -9,6 +9,7 @@
method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
method @FlaggedApi("android.nfc.enable_nfc_mainline") public int getAdapterState();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.NfcOemExtension getNfcOemExtension();
method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
@@ -46,6 +47,16 @@
method @FlaggedApi("android.nfc.nfc_vendor_cmd") public void onVendorNciResponse(@IntRange(from=0, to=15) int, int, @NonNull byte[]);
}
+ @FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterCallback(@NonNull android.nfc.NfcOemExtension.Callback);
+ }
+
+ public static interface NfcOemExtension.Callback {
+ method public void onTagConnected(boolean, @NonNull android.nfc.Tag);
+ }
+
}
package android.nfc.cardemulation {
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index 8fea5af..bde63c3 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -28,6 +28,7 @@
import android.nfc.INfcTag;
import android.nfc.INfcCardEmulation;
import android.nfc.INfcFCardEmulation;
+import android.nfc.INfcOemExtensionCallback;
import android.nfc.INfcUnlockHandler;
import android.nfc.ITagRemovedCallback;
import android.nfc.INfcDta;
@@ -91,4 +92,7 @@
int sendVendorNciMessage(int mt, int gid, int oid, in byte[] payload);
void registerVendorExtensionCallback(in INfcVendorNciCallback callbacks);
void unregisterVendorExtensionCallback(in INfcVendorNciCallback callbacks);
+ void registerOemExtensionCallback(INfcOemExtensionCallback callbacks);
+ void unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks);
+ void clearPreference();
}
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
new file mode 100644
index 0000000..6c9096d
--- /dev/null
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 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.nfc;
+
+import android.nfc.Tag;
+
+/**
+ * @hide
+ */
+interface INfcOemExtensionCallback {
+ void onTagConnected(boolean connected, in Tag tag);
+}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 40bbe74..7e0a111 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -556,6 +556,7 @@
final Context mContext;
final HashMap<NfcUnlockHandler, INfcUnlockHandler> mNfcUnlockHandlers;
final Object mLock;
+ final NfcOemExtension mNfcOemExtension;
ITagRemovedCallback mTagRemovedListener; // protected by mLock
@@ -864,6 +865,7 @@
mLock = new Object();
mControllerAlwaysOnListener = new NfcControllerAlwaysOnListener(getService());
mNfcVendorNciCallbackListener = new NfcVendorNciCallbackListener(getService());
+ mNfcOemExtension = new NfcOemExtension(mContext, this);
}
/**
@@ -2919,4 +2921,19 @@
void onVendorNciNotification(
@IntRange(from = 9, to = 15) int gid, int oid, @NonNull byte[] payload);
}
+
+ /**
+ * Returns an instance of {@link NfcOemExtension} associated with {@link NfcAdapter} instance.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ @NonNull public NfcOemExtension getNfcOemExtension() {
+ synchronized (sLock) {
+ if (!sHasNfcFeature) {
+ throw new UnsupportedOperationException();
+ }
+ }
+ return mNfcOemExtension;
+ }
}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
new file mode 100644
index 0000000..1eff58c
--- /dev/null
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -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.nfc;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Used for OEM extension APIs.
+ * This class holds all the APIs and callbacks defined for OEMs/vendors to extend the NFC stack
+ * for their proprietary features.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class NfcOemExtension {
+ private static final String TAG = "NfcOemExtension";
+ private static final int OEM_EXTENSION_RESPONSE_THRESHOLD_MS = 2000;
+ private final NfcAdapter mAdapter;
+ private final NfcOemExtensionCallback mOemNfcExtensionCallback;
+ private final Context mContext;
+ private Executor mExecutor = null;
+ private Callback mCallback = null;
+ private final Object mLock = new Object();
+
+ /**
+ * Interface for Oem extensions for NFC.
+ */
+ public interface Callback {
+ /**
+ * Notify Oem to tag is connected or not
+ * ex - if tag is connected notify cover and Nfctest app if app is in testing mode
+ *
+ * @param connected status of the tag true if tag is connected otherwise false
+ * @param tag Tag details
+ */
+ void onTagConnected(boolean connected, @NonNull Tag tag);
+ }
+
+
+ /**
+ * Constructor to be used only by {@link NfcAdapter}.
+ * @hide
+ */
+ public NfcOemExtension(@NonNull Context context, @NonNull NfcAdapter adapter) {
+ mContext = context;
+ mAdapter = adapter;
+ mOemNfcExtensionCallback = new NfcOemExtensionCallback();
+ }
+
+ /**
+ * Register an {@link Callback} to listen for UWB oem extension callbacks
+ * <p>The provided callback will be invoked by the given {@link Executor}.
+ *
+ * @param executor an {@link Executor} to execute given callback
+ * @param callback oem implementation of {@link Callback}
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public void registerCallback(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Callback callback) {
+ synchronized (mLock) {
+ if (mCallback != null) {
+ Log.e(TAG, "Callback already registered. Unregister existing callback before"
+ + "registering");
+ throw new IllegalArgumentException();
+ }
+ try {
+ NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
+ mCallback = callback;
+ mExecutor = executor;
+ } catch (RemoteException e) {
+ mAdapter.attemptDeadServiceRecovery(e);
+ }
+ }
+ }
+
+ /**
+ * Unregister the specified {@link Callback}
+ *
+ * <p>The same {@link Callback} object used when calling
+ * {@link #registerCallback(Executor, Callback)} must be used.
+ *
+ * <p>Callbacks are automatically unregistered when an application process goes away
+ *
+ * @param callback oem implementation of {@link Callback}
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public void unregisterCallback(@NonNull Callback callback) {
+ synchronized (mLock) {
+ if (mCallback == null || mCallback != callback) {
+ Log.e(TAG, "Callback not registered");
+ throw new IllegalArgumentException();
+ }
+ try {
+ NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
+ mCallback = null;
+ mExecutor = null;
+ } catch (RemoteException e) {
+ mAdapter.attemptDeadServiceRecovery(e);
+ }
+ }
+ }
+
+ /**
+ * Clear NfcService preference, interface method to clear NFC preference values on OEM specific
+ * events. For ex: on soft reset, Nfc default values needs to be overridden by OEM defaults.
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public void clearPreference() {
+ try {
+ NfcAdapter.sService.clearPreference();
+ } catch (RemoteException e) {
+ mAdapter.attemptDeadServiceRecovery(e);
+ }
+ }
+
+ private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
+ @Override
+ public void onTagConnected(boolean connected, Tag tag) throws RemoteException {
+ synchronized (mLock) {
+ if (mCallback == null || mExecutor == null) {
+ return;
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mExecutor.execute(() -> mCallback.onTagConnected(connected, tag));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+}
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index 44924ae..5879595 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -76,3 +76,11 @@
description: "Enable NFC vendor command support"
bug: "289879306"
}
+
+flag {
+ name: "nfc_oem_extension"
+ is_exported: true
+ namespace: "nfc"
+ description: "Enable NFC OEM extension support"
+ bug: "331206243"
+}
diff --git a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java
index a8d8f9a..6f20adf 100644
--- a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java
@@ -39,15 +39,15 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
+import android.util.LongArrayQueue;
import android.util.Slog;
import android.util.Xml;
-import android.utils.BackgroundThread;
-import android.utils.LongArrayQueue;
-import android.utils.XmlUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -137,17 +137,6 @@
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 @@
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 @@
/**
* 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 @@
}
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 @@
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 @@
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 @@
} 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 @@
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 7093ba4..271d552 100644
--- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
+++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
@@ -31,6 +31,7 @@
import android.crashrecovery.flags.Flags;
import android.os.Build;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.PowerManager;
import android.os.RecoverySystem;
import android.os.SystemClock;
@@ -43,11 +44,10 @@
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
-import android.utils.ArrayUtils;
-import android.utils.FileUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.server.PackageWatchdog.FailureReasons;
import com.android.server.PackageWatchdog.PackageHealthObserver;
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
@@ -139,7 +139,7 @@
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/CrashRecovery/services/java/com/android/utils/ArrayUtils.java b/packages/CrashRecovery/services/java/com/android/utils/ArrayUtils.java
deleted file mode 100644
index fa4d6af..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/ArrayUtils.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.utils;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.File;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Copied over from frameworks/base/core/java/com/android/internal/util/ArrayUtils.java
- *
- * @hide
- */
-public class ArrayUtils {
- private ArrayUtils() { /* cannot be instantiated */ }
- public static final File[] EMPTY_FILE = new File[0];
-
-
- /**
- * Return first index of {@code value} in {@code array}, or {@code -1} if
- * not found.
- */
- public static <T> int indexOf(@Nullable T[] array, T value) {
- if (array == null) return -1;
- for (int i = 0; i < array.length; i++) {
- if (Objects.equals(array[i], value)) return i;
- }
- return -1;
- }
-
- /** @hide */
- public static @NonNull File[] defeatNullable(@Nullable File[] val) {
- return (val != null) ? val : EMPTY_FILE;
- }
-
- /**
- * Checks if given array is null or has zero elements.
- */
- public static boolean isEmpty(@Nullable int[] array) {
- return array == null || array.length == 0;
- }
-
- /**
- * True if the byte array is null or has length 0.
- */
- public static boolean isEmpty(@Nullable byte[] array) {
- return array == null || array.length == 0;
- }
-
- /**
- * Converts from List of bytes to byte array
- * @param list
- * @return byte[]
- */
- public static byte[] toPrimitive(List<byte[]> list) {
- if (list.size() == 0) {
- return new byte[0];
- }
- int byteLen = list.get(0).length;
- byte[] array = new byte[list.size() * byteLen];
- for (int i = 0; i < list.size(); i++) {
- for (int j = 0; j < list.get(i).length; j++) {
- array[i * byteLen + j] = list.get(i)[j];
- }
- }
- return array;
- }
-
- /**
- * Adds value to given array if not already present, providing set-like
- * behavior.
- */
- public static @NonNull int[] appendInt(@Nullable int[] cur, int val) {
- return appendInt(cur, val, false);
- }
-
- /**
- * Adds value to given array.
- */
- public static @NonNull int[] appendInt(@Nullable int[] cur, int val,
- boolean allowDuplicates) {
- if (cur == null) {
- return new int[] { val };
- }
- final int n = cur.length;
- if (!allowDuplicates) {
- for (int i = 0; i < n; i++) {
- if (cur[i] == val) {
- return cur;
- }
- }
- }
- int[] ret = new int[n + 1];
- System.arraycopy(cur, 0, ret, 0, n);
- ret[n] = val;
- return ret;
- }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java b/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java
deleted file mode 100644
index afcf689..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * * 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.utils;
-
-import android.annotation.NonNull;
-import android.os.Handler;
-import android.os.HandlerThread;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.concurrent.Executor;
-
-/**
- * Thread for asynchronous event processing. This thread is configured as
- * {@link android.os.Process#THREAD_PRIORITY_BACKGROUND}, which means fewer CPU
- * resources will be dedicated to it, and it will "have less chance of impacting
- * the responsiveness of the user interface."
- * <p>
- * This thread is best suited for tasks that the user is not actively waiting
- * for, or for tasks that the user expects to be executed eventually.
- *
- * @see com.android.internal.os.BackgroundThread
- *
- * TODO: b/326916057 depend on modules-utils-backgroundthread instead
- * @hide
- */
-public final class BackgroundThread extends HandlerThread {
- private static final Object sLock = new Object();
-
- @GuardedBy("sLock")
- private static BackgroundThread sInstance;
- @GuardedBy("sLock")
- private static Handler sHandler;
- @GuardedBy("sLock")
- private static HandlerExecutor sHandlerExecutor;
-
- private BackgroundThread() {
- super(BackgroundThread.class.getName(), android.os.Process.THREAD_PRIORITY_BACKGROUND);
- }
-
- @GuardedBy("sLock")
- private static void ensureThreadLocked() {
- if (sInstance == null) {
- sInstance = new BackgroundThread();
- sInstance.start();
- sHandler = new Handler(sInstance.getLooper());
- sHandlerExecutor = new HandlerExecutor(sHandler);
- }
- }
-
- /**
- * Get the singleton instance of this class.
- *
- * @return the singleton instance of this class
- */
- @NonNull
- public static BackgroundThread get() {
- synchronized (sLock) {
- ensureThreadLocked();
- return sInstance;
- }
- }
-
- /**
- * Get the singleton {@link Handler} for this class.
- *
- * @return the singleton {@link Handler} for this class.
- */
- @NonNull
- public static Handler getHandler() {
- synchronized (sLock) {
- ensureThreadLocked();
- return sHandler;
- }
- }
-
- /**
- * Get the singleton {@link Executor} for this class.
- *
- * @return the singleton {@link Executor} for this class.
- */
- @NonNull
- public static Executor getExecutor() {
- synchronized (sLock) {
- ensureThreadLocked();
- return sHandlerExecutor;
- }
- }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java b/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java
deleted file mode 100644
index e4923bf..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.utils;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Bits and pieces copied from hidden API of android.os.FileUtils.
- *
- * @hide
- */
-public class FileUtils {
- /**
- * Read a text file into a String, optionally limiting the length.
- *
- * @param file to read (will not seek, so things like /proc files are OK)
- * @param max length (positive for head, negative of tail, 0 for no limit)
- * @param ellipsis to add of the file was truncated (can be null)
- * @return the contents of the file, possibly truncated
- * @throws IOException if something goes wrong reading the file
- * @hide
- */
- public static @Nullable String readTextFile(@Nullable File file, @Nullable int max,
- @Nullable String ellipsis) throws IOException {
- InputStream input = new FileInputStream(file);
- // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
- // input stream, bytes read not equal to buffer size is not necessarily the correct
- // indication for EOF; but it is true for BufferedInputStream due to its implementation.
- BufferedInputStream bis = new BufferedInputStream(input);
- try {
- long size = file.length();
- if (max > 0 || (size > 0 && max == 0)) { // "head" mode: read the first N bytes
- if (size > 0 && (max == 0 || size < max)) max = (int) size;
- byte[] data = new byte[max + 1];
- int length = bis.read(data);
- if (length <= 0) return "";
- if (length <= max) return new String(data, 0, length);
- if (ellipsis == null) return new String(data, 0, max);
- return new String(data, 0, max) + ellipsis;
- } else if (max < 0) { // "tail" mode: keep the last N
- int len;
- boolean rolled = false;
- byte[] last = null;
- byte[] data = null;
- do {
- if (last != null) rolled = true;
- byte[] tmp = last;
- last = data;
- data = tmp;
- if (data == null) data = new byte[-max];
- len = bis.read(data);
- } while (len == data.length);
-
- if (last == null && len <= 0) return "";
- if (last == null) return new String(data, 0, len);
- if (len > 0) {
- rolled = true;
- System.arraycopy(last, len, last, 0, last.length - len);
- System.arraycopy(data, 0, last, last.length - len, len);
- }
- if (ellipsis == null || !rolled) return new String(last);
- return ellipsis + new String(last);
- } else { // "cat" mode: size unknown, read it all in streaming fashion
- ByteArrayOutputStream contents = new ByteArrayOutputStream();
- int len;
- byte[] data = new byte[1024];
- do {
- len = bis.read(data);
- if (len > 0) contents.write(data, 0, len);
- } while (len == data.length);
- return contents.toString();
- }
- } finally {
- bis.close();
- input.close();
- }
- }
-
- /**
- * Perform an fsync on the given FileOutputStream. The stream at this
- * point must be flushed but not yet closed.
- *
- * @hide
- */
- public static boolean sync(FileOutputStream stream) {
- try {
- if (stream != null) {
- stream.getFD().sync();
- }
- return true;
- } catch (IOException e) {
- }
- return false;
- }
-
- /**
- * List the files in the directory or return empty file.
- *
- * @hide
- */
- public static @NonNull File[] listFilesOrEmpty(@Nullable File dir) {
- return (dir != null) ? ArrayUtils.defeatNullable(dir.listFiles())
- : ArrayUtils.EMPTY_FILE;
- }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java b/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java
deleted file mode 100644
index fdb15e2..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.utils;
-
-import android.annotation.NonNull;
-import android.os.Handler;
-
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-
-/**
- * An adapter {@link Executor} that posts all executed tasks onto the given
- * {@link Handler}.
- *
- * TODO: b/326916057 depend on modules-utils-backgroundthread instead
- * @hide
- */
-public class HandlerExecutor implements Executor {
- private final Handler mHandler;
-
- public HandlerExecutor(@NonNull Handler handler) {
- mHandler = Objects.requireNonNull(handler);
- }
-
- @Override
- public void execute(Runnable command) {
- if (!mHandler.post(command)) {
- throw new RejectedExecutionException(mHandler + " is shutting down");
- }
- }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java b/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java
deleted file mode 100644
index 5cdc253..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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.utils;
-
-import libcore.util.EmptyArray;
-
-import java.util.NoSuchElementException;
-
-/**
- * Copied from frameworks/base/core/java/android/util/LongArrayQueue.java
- *
- * @hide
- */
-public class LongArrayQueue {
-
- private long[] mValues;
- private int mSize;
- private int mHead;
- private int mTail;
-
- private long[] newUnpaddedLongArray(int num) {
- return new long[num];
- }
- /**
- * Initializes a queue with the given starting capacity.
- *
- * @param initialCapacity the capacity.
- */
- public LongArrayQueue(int initialCapacity) {
- if (initialCapacity == 0) {
- mValues = EmptyArray.LONG;
- } else {
- mValues = newUnpaddedLongArray(initialCapacity);
- }
- mSize = 0;
- mHead = mTail = 0;
- }
-
- /**
- * Initializes a queue with default starting capacity.
- */
- public LongArrayQueue() {
- this(16);
- }
-
- /** @hide */
- public static int growSize(int currentSize) {
- return currentSize <= 4 ? 8 : currentSize * 2;
- }
-
- private void grow() {
- if (mSize < mValues.length) {
- throw new IllegalStateException("Queue not full yet!");
- }
- final int newSize = growSize(mSize);
- final long[] newArray = newUnpaddedLongArray(newSize);
- final int r = mValues.length - mHead; // Number of elements on and to the right of head.
- System.arraycopy(mValues, mHead, newArray, 0, r);
- System.arraycopy(mValues, 0, newArray, r, mHead);
- mValues = newArray;
- mHead = 0;
- mTail = mSize;
- }
-
- /**
- * Returns the number of elements in the queue.
- */
- public int size() {
- return mSize;
- }
-
- /**
- * Removes all elements from this queue.
- */
- public void clear() {
- mSize = 0;
- mHead = mTail = 0;
- }
-
- /**
- * Adds a value to the tail of the queue.
- *
- * @param value the value to be added.
- */
- public void addLast(long value) {
- if (mSize == mValues.length) {
- grow();
- }
- mValues[mTail] = value;
- mTail = (mTail + 1) % mValues.length;
- mSize++;
- }
-
- /**
- * Removes an element from the head of the queue.
- *
- * @return the element at the head of the queue.
- * @throws NoSuchElementException if the queue is empty.
- */
- public long removeFirst() {
- if (mSize == 0) {
- throw new NoSuchElementException("Queue is empty!");
- }
- final long ret = mValues[mHead];
- mHead = (mHead + 1) % mValues.length;
- mSize--;
- return ret;
- }
-
- /**
- * Returns the element at the given position from the head of the queue, where 0 represents the
- * head of the queue.
- *
- * @param position the position from the head of the queue.
- * @return the element found at the given position.
- * @throws IndexOutOfBoundsException if {@code position} < {@code 0} or
- * {@code position} >= {@link #size()}
- */
- public long get(int position) {
- if (position < 0 || position >= mSize) {
- throw new IndexOutOfBoundsException("Index " + position
- + " not valid for a queue of size " + mSize);
- }
- final int index = (mHead + position) % mValues.length;
- return mValues[index];
- }
-
- /**
- * Returns the element at the head of the queue, without removing it.
- *
- * @return the element at the head of the queue.
- * @throws NoSuchElementException if the queue is empty
- */
- public long peekFirst() {
- if (mSize == 0) {
- throw new NoSuchElementException("Queue is empty!");
- }
- return mValues[mHead];
- }
-
- /**
- * Returns the element at the tail of the queue.
- *
- * @return the element at the tail of the queue.
- * @throws NoSuchElementException if the queue is empty.
- */
- public long peekLast() {
- if (mSize == 0) {
- throw new NoSuchElementException("Queue is empty!");
- }
- final int index = (mTail == 0) ? mValues.length - 1 : mTail - 1;
- return mValues[index];
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- if (mSize <= 0) {
- return "{}";
- }
-
- final StringBuilder buffer = new StringBuilder(mSize * 64);
- buffer.append('{');
- buffer.append(get(0));
- for (int i = 1; i < mSize; i++) {
- buffer.append(", ");
- buffer.append(get(i));
- }
- buffer.append('}');
- return buffer.toString();
- }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java b/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java
deleted file mode 100644
index dbbef61..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.utils;
-
-import android.annotation.NonNull;
-import android.system.ErrnoException;
-import android.system.Os;
-
-import com.android.modules.utils.TypedXmlPullParser;
-
-import libcore.util.XmlObjectFactory;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Copied over partly from frameworks/base/core/java/com/android/internal/util/XmlUtils.java
- *
- * @hide
- */
-public class XmlUtils {
-
- private static final String STRING_ARRAY_SEPARATOR = ":";
-
- /** @hide */
- public static final void beginDocument(XmlPullParser parser, String firstElementName)
- throws XmlPullParserException, IOException {
- int type;
- while ((type = parser.next()) != parser.START_TAG
- && type != parser.END_DOCUMENT) {
- // Do nothing
- }
-
- if (type != parser.START_TAG) {
- throw new XmlPullParserException("No start tag found");
- }
-
- if (!parser.getName().equals(firstElementName)) {
- throw new XmlPullParserException("Unexpected start tag: found " + parser.getName()
- + ", expected " + firstElementName);
- }
- }
-
- /** @hide */
- public static boolean nextElementWithin(XmlPullParser parser, int outerDepth)
- throws IOException, XmlPullParserException {
- for (;;) {
- int type = parser.next();
- if (type == XmlPullParser.END_DOCUMENT
- || (type == XmlPullParser.END_TAG && parser.getDepth() == outerDepth)) {
- return false;
- }
- if (type == XmlPullParser.START_TAG
- && parser.getDepth() == outerDepth + 1) {
- return true;
- }
- }
- }
-
- private static XmlPullParser newPullParser() {
- try {
- XmlPullParser parser = XmlObjectFactory.newXmlPullParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_DOCDECL, true);
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- return parser;
- } catch (XmlPullParserException e) {
- throw new AssertionError();
- }
- }
-
- /** @hide */
- public static @NonNull TypedXmlPullParser resolvePullParser(@NonNull InputStream in)
- throws IOException {
- final byte[] magic = new byte[4];
- if (in instanceof FileInputStream) {
- try {
- Os.pread(((FileInputStream) in).getFD(), magic, 0, magic.length, 0);
- } catch (ErrnoException e) {
- throw e.rethrowAsIOException();
- }
- } else {
- if (!in.markSupported()) {
- in = new BufferedInputStream(in);
- }
- in.mark(8);
- in.read(magic);
- in.reset();
- }
-
- final TypedXmlPullParser xml;
- xml = (TypedXmlPullParser) newPullParser();
- try {
- xml.setInput(in, "UTF_8");
- } catch (XmlPullParserException e) {
- throw new IOException(e);
- }
- return xml;
- }
-}
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index f8e207c..d50b596 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -229,7 +229,6 @@
extra_check_modules: ["SystemUILintChecker"],
warning_checks: ["MissingApacheLicenseDetector"],
},
- skip_jarjar_repackage: true,
}
filegroup {
@@ -329,13 +328,12 @@
"WindowManager-Shell",
"LowLightDreamLib",
"motion_tool_lib",
- "androidx.core_core-animation-testing-nodeps",
+ "androidx.core_core-animation-testing",
"androidx.compose.ui_ui",
"flag-junit",
"platform-test-annotations",
"notification_flags_lib",
],
- skip_jarjar_repackage: true,
}
android_library {
@@ -385,7 +383,6 @@
test: true,
extra_check_modules: ["SystemUILintChecker"],
},
- skip_jarjar_repackage: true,
}
android_app {
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
index 085fc29..b05d2ae 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
@@ -387,6 +387,10 @@
unregisterReceiver(mToggleMenuReceiver);
mPrefs.unregisterOnSharedPreferenceChangeListener(mSharedPreferenceChangeListener);
sInitialized = false;
+ if (mA11yMenuLayout != null) {
+ mA11yMenuLayout.clearLayout();
+ mA11yMenuLayout = null;
+ }
return super.onUnbind(intent);
}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
index edd6a48..1be04f8 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
@@ -151,6 +151,14 @@
return mLayout;
}
+ public void clearLayout() {
+ if (mLayout != null) {
+ mWindowManager.removeView(mLayout);
+ mLayout.setOnTouchListener(null);
+ mLayout = null;
+ }
+ }
+
/** Updates view layout with new layout parameters only. */
public void updateViewLayout() {
if (mLayout == null || mLayoutParameter == null) {
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index b900ea0..e945f1e 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -41,7 +41,7 @@
],
static_libs: [
- "androidx.core_core-animation-nodeps",
+ "androidx.core_core-animation",
"androidx.core_core-ktx",
"androidx.annotation_annotation",
"SystemUIShaderLib",
@@ -62,7 +62,7 @@
],
static_libs: [
- "androidx.core_core-animation-nodeps",
+ "androidx.core_core-animation",
"androidx.core_core-ktx",
"androidx.annotation_annotation",
],
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 3349345..c429329 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 @@
}
}
- 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/Android.bp b/services/Android.bp
index 5cb8ec6..32a8bbb 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -219,6 +219,7 @@
required: [
"libukey2_jni_shared",
+ "protolog.conf.json.gz",
],
// Uncomment to enable output of certain warnings (deprecated, unchecked)
@@ -247,6 +248,11 @@
// API stub
// =============================================================
+soong_config_module_type_import {
+ from: "frameworks/base/api/Android.bp",
+ module_types: ["non_updatable_exportable_droidstubs"],
+}
+
stubs_defaults {
name: "services-stubs-default",
installable: false,
@@ -262,10 +268,12 @@
filter_packages: ["com.android."],
}
-droidstubs {
+non_updatable_exportable_droidstubs {
name: "services-non-updatable-stubs",
srcs: [":services-non-updatable-sources"],
- defaults: ["services-stubs-default"],
+ defaults: [
+ "services-stubs-default",
+ ],
check_api: {
current: {
api_file: "api/current.txt",
@@ -282,14 +290,34 @@
targets: ["sdk"],
dir: "apistubs/android/system-server/api",
dest: "android-non-updatable.txt",
- tag: ".api.txt",
},
{
targets: ["sdk"],
dir: "apistubs/android/system-server/api",
dest: "android-non-updatable-removed.txt",
- tag: ".removed-api.txt",
},
],
+ soong_config_variables: {
+ release_hidden_api_exportable_stubs: {
+ dists: [
+ {
+ tag: ".exportable.api.txt",
+ },
+ {
+ tag: ".exportable.removed-api.txt",
+ },
+ ],
+ conditions_default: {
+ dists: [
+ {
+ tag: ".api.txt",
+ },
+ {
+ tag: ".removed-api.txt",
+ },
+ ],
+ },
+ },
+ },
api_surface: "system-server",
}
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index 1d1e2d9..626fa70 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -1007,6 +1007,71 @@
}
}
+ /**
+ * Get the vpn profile owned by the calling uid with the given name from the vpn database.
+ *
+ * <p>Note this method should not be used for platform VPN profiles. </p>
+ *
+ * @param name The name of the profile to retrieve.
+ * @return the unstructured blob for the matching vpn profile.
+ * Returns null if no profile with a matching name was found.
+ * @hide
+ */
+ @Override
+ @Nullable
+ public byte[] getFromVpnProfileStore(@NonNull String name) {
+ return mVpnProfileStore.get(name);
+ }
+
+ /**
+ * Put the given vpn profile owned by the calling uid with the given name into the vpn database.
+ * Existing profiles with the same name will be replaced.
+ *
+ * <p>Note this method should not be used for platform VPN profiles.
+ * To update a platform VPN, use provisionVpnProfile() instead. </p>
+ *
+ * @param name The name of the profile to put.
+ * @param blob The profile.
+ * @return true if the profile was successfully added. False otherwise.
+ * @hide
+ */
+ @Override
+ public boolean putIntoVpnProfileStore(@NonNull String name, @NonNull byte[] blob) {
+ return mVpnProfileStore.put(name, blob);
+ }
+
+ /**
+ * Removes the vpn profile owned by the calling uid with the given name from the vpn database.
+ *
+ * <p>Note this method should not be used for platform VPN profiles.
+ * To remove a platform VPN, use deleteVpnProfile() instead.</p>
+ *
+ * @param name The name of the profile to be removed.
+ * @return true if a profile was removed. False if no profile with a matching name was found.
+ * @hide
+ */
+ @Override
+ public boolean removeFromVpnProfileStore(@NonNull String name) {
+ return mVpnProfileStore.remove(name);
+ }
+
+ /**
+ * Returns a list of the name suffixes of the vpn profiles owned by the calling uid in the vpn
+ * database matching the given prefix, sorted in ascending order.
+ *
+ * <p>Note this method should not be used for platform VPN profiles. </p>
+ *
+ * @param prefix The prefix to match.
+ * @return an array of strings representing the name suffixes stored in the profile database
+ * matching the given prefix. The return value may be empty but never null.
+ * @hide
+ */
+ @Override
+ @NonNull
+ public String[] listFromVpnProfileStore(@NonNull String prefix) {
+ return mVpnProfileStore.list(prefix);
+ }
+
private void ensureRunningOnHandlerThread() {
if (mHandler.getLooper().getThread() != Thread.currentThread()) {
throw new IllegalStateException(
diff --git a/services/core/java/com/android/server/am/LmkdStatsReporter.java b/services/core/java/com/android/server/am/LmkdStatsReporter.java
index 507fd9e..b55f35d 100644
--- a/services/core/java/com/android/server/am/LmkdStatsReporter.java
+++ b/services/core/java/com/android/server/am/LmkdStatsReporter.java
@@ -34,7 +34,6 @@
static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdStatsReporter" : TAG_AM;
public static final int KILL_OCCURRED_MSG_SIZE = 80;
- public static final int STATE_CHANGED_MSG_SIZE = 8;
private static final int PRESSURE_AFTER_KILL = 0;
private static final int NOT_RESPONDING = 1;
@@ -45,6 +44,7 @@
private static final int LOW_MEM_AND_SWAP_UTIL = 6;
private static final int LOW_FILECACHE_AFTER_THRASHING = 7;
private static final int LOW_MEM = 8;
+ private static final int DIRECT_RECL_STUCK = 9;
/**
* Processes the LMK_KILL_OCCURRED packet data
@@ -79,16 +79,6 @@
}
}
- /**
- * Processes the LMK_STATE_CHANGED packet
- * Logs the change in LMKD state which is used as start/stop boundaries for logging
- * LMK_KILL_OCCURRED event.
- * Code: LMK_STATE_CHANGED = 54
- */
- public static void logStateChanged(int state) {
- FrameworkStatsLog.write(FrameworkStatsLog.LMK_STATE_CHANGED, state);
- }
-
private static int mapKillReason(int reason) {
switch (reason) {
case PRESSURE_AFTER_KILL:
@@ -109,6 +99,8 @@
return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_FILECACHE_AFTER_THRASHING;
case LOW_MEM:
return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM;
+ case DIRECT_RECL_STUCK:
+ return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__DIRECT_RECL_STUCK;
default:
return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__UNKNOWN;
}
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index bf7cc10..11db302 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -9,7 +9,6 @@
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 65c2cc5..4dfa71b 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -349,7 +349,8 @@
// LMK_PROCKILL
// LMK_UPDATE_PROPS
// LMK_KILL_OCCURRED
- // LMK_STATE_CHANGED
+ // LMK_START_MONITORING
+ // LMK_BOOT_COMPLETED
static final byte LMK_TARGET = 0;
static final byte LMK_PROCPRIO = 1;
static final byte LMK_PROCREMOVE = 2;
@@ -359,8 +360,8 @@
static final byte LMK_PROCKILL = 6; // Note: this is an unsolicited command
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_STATE_CHANGED = 9; // Msg to subscribed clients on state changed
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
@@ -960,14 +961,6 @@
foregroundServices.first,
foregroundServices.second);
return true;
- case LMK_STATE_CHANGED:
- if (receivedLen
- != LmkdStatsReporter.STATE_CHANGED_MSG_SIZE) {
- return false;
- }
- final int state = inputData.readInt();
- LmkdStatsReporter.logStateChanged(state);
- return true;
default:
return false;
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 5a078dbf..0bfbee6 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4595,6 +4595,7 @@
case AudioSystem.MODE_CALL_SCREENING:
case AudioSystem.MODE_CALL_REDIRECT:
case AudioSystem.MODE_COMMUNICATION_REDIRECT:
+ case AudioSystem.MODE_RINGTONE:
break;
default:
// no-op is enough for all other values
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index c507300..69e87fc 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.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 @@
@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 @@
@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 @@
@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 @@
@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 @@
mBiometricContext = biometricContext;
mStatusBarService = statusBarService;
mSysuiReceiver = sysuiReceiver;
- mKeyStore = keystore;
+ mKeyStoreAuthorization = keyStoreAuthorization;
mRandom = random;
mClientDeathReceiver = clientDeathReceiver;
mPreAuthInfo = preAuthInfo;
@@ -814,14 +814,14 @@
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 91a68ea..bccbee9 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.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 @@
@VisibleForTesting
IStatusBarService mStatusBarService;
@VisibleForTesting
- KeyStore mKeyStore;
- @VisibleForTesting
ITrustManager mTrustManager;
@VisibleForTesting
- IKeystoreAuthorization mKeystoreAuthorization;
+ KeyStoreAuthorization mKeyStoreAuthorization;
@VisibleForTesting
IGateKeeperService mGateKeeper;
@@ -672,19 +666,7 @@
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 @@
return ActivityManager.getService();
}
- public IKeystoreAuthorization getKeystoreAuthorizationService() {
- return Authorization.getService();
+ public KeyStoreAuthorization getKeyStoreAuthorization() {
+ return KeyStoreAuthorization.getInstance();
}
public IGateKeeperService getGateKeeperService() {
@@ -1034,10 +1016,6 @@
return new SettingObserver(context, handler, callbacks);
}
- public KeyStore getKeyStore() {
- return KeyStore.getInstance();
- }
-
/**
* Allows to enable/disable debug logs.
*/
@@ -1130,7 +1108,7 @@
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 @@
@Override
public void onStart() {
- mKeyStore = mInjector.getKeyStore();
mStatusBarService = mInjector.getStatusBarService();
mTrustManager = mInjector.getTrustManager();
mInjector.publishBinderService(this, mImpl);
@@ -1458,7 +1435,7 @@
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 6eba23f..749e12b 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.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 @@
// 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/devicestate/OWNERS b/services/core/java/com/android/server/devicestate/OWNERS
index ae79fc0..43f3f0c 100644
--- a/services/core/java/com/android/server/devicestate/OWNERS
+++ b/services/core/java/com/android/server/devicestate/OWNERS
@@ -1,3 +1,4 @@
ogunwale@google.com
akulian@google.com
-darryljohnson@google.com
+lihongyu@google.com
+kennethford@google.com
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 0f40ca0..2783fef 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 @@
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 @@
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 @@
mFontFileInfoMap.clear();
mLastModifiedMillis = 0;
FileUtils.deleteContents(mFilesDir);
+ mConfigFile.delete();
}
}
}
@@ -487,8 +513,7 @@
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 @@
}
}
}
+ 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/inputmethod/LocaleUtils.java b/services/core/java/com/android/server/inputmethod/LocaleUtils.java
index 7d090db..b1348b3 100644
--- a/services/core/java/com/android/server/inputmethod/LocaleUtils.java
+++ b/services/core/java/com/android/server/inputmethod/LocaleUtils.java
@@ -46,29 +46,44 @@
* @param desired The locale preferred by user.
* @return A score based on the locale matching for the default subtype enabling.
*/
- @IntRange(from = 1, to = 3)
+ @IntRange(from = 1, to = 4)
private static byte calculateMatchingSubScore(@NonNull final ULocale supported,
@NonNull final ULocale desired) {
// Assuming supported/desired is fully expanded.
if (supported.equals(desired)) {
- return 3; // Exact match.
+ return 4; // Exact match.
}
+ // addLikelySubtags is a maximization process as per
+ // https://www.unicode.org/reports/tr35/#Likely_Subtags
+ ULocale maxDesired = ULocale.addLikelySubtags(desired);
+
// Skip language matching since it was already done in calculateMatchingScore.
final String supportedScript = supported.getScript();
- if (supportedScript.isEmpty() || !supportedScript.equals(desired.getScript())) {
+ if (supportedScript.isEmpty() || !supportedScript.equals(maxDesired.getScript())) {
// TODO: Need subscript matching. For example, Hanb should match with Bopo.
return 1;
}
final String supportedCountry = supported.getCountry();
- if (supportedCountry.isEmpty() || !supportedCountry.equals(desired.getCountry())) {
+ if (supportedCountry.isEmpty() || !supportedCountry.equals(maxDesired.getCountry())) {
return 2;
}
// Ignore others e.g. variants, extensions.
- return 3;
+
+ // Since addLikelySubtags can canonicalize subtags, e.g. the deprecated country codes
+ // an locale with an identical script and country before addLikelySubtags is in favour,
+ // and a score of 4 is returned.
+ String desiredScript = desired.getScript();
+ String desiredCountry = desired.getCountry();
+ if ((desiredScript.isEmpty() || desiredScript.equals(maxDesired.getScript()))
+ && (desiredCountry.isEmpty() || desiredCountry.equals(maxDesired.getCountry()))) {
+ return 4;
+ } else {
+ return 3;
+ }
}
private static final class ScoreEntry implements Comparable<ScoreEntry> {
@@ -180,8 +195,7 @@
ULocale.forLocale(preferredLocale));
}
score[j] = calculateMatchingSubScore(
- preferredULocaleCache[j],
- ULocale.addLikelySubtags(ULocale.forLocale(locale)));
+ preferredULocaleCache[j], ULocale.forLocale(locale));
if (canSkip && score[j] != 0) {
canSkip = false;
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index a9a9d87b..ba99d2e 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.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 @@
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 KeyStoreAuthorization getKeyStoreAuthorization() {
+ return KeyStoreAuthorization.getInstance();
+ }
+
public @NonNull UnifiedProfilePasswordCache getUnifiedProfilePasswordCache(KeyStore ks) {
return new UnifiedProfilePasswordCache(ks);
}
@@ -646,6 +651,7 @@
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 @@
}
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/power/batterysaver/OWNERS b/services/core/java/com/android/server/power/batterysaver/OWNERS
index cf23bea..dc2d0b3 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/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 698f6ea..4eea8c6 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -3708,6 +3708,7 @@
public abstract T instantiateObject();
}
+ @SuppressWarnings("ParcelableCreator")
public static class ControllerActivityCounterImpl extends ControllerActivityCounter
implements Parcelable {
private final Clock mClock;
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index e5a8a6d..7794048 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.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 @@
/* 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 @@
* 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 @@
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 @@
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 a2943f3..469acb2 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/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index e06f215..79eb0dc 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -24,3 +24,5 @@
per-file Background*Start* = file:/BAL_OWNERS
per-file Background*Start* = ogunwale@google.com, louischang@google.com
+# File related to activity callers
+per-file ActivityCallerState.java = file:/core/java/android/app/COMPONENT_CALLER_OWNERS
diff --git a/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java b/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java
index ecc70e3..8495de4 100644
--- a/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java
+++ b/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java
@@ -397,4 +397,35 @@
// Even lockdown is enabled but no Vpn is created for SECONDARY_USER.
assertNull(mService.getVpnLockdownAllowlist(SECONDARY_USER.id));
}
+
+ @Test
+ public void testGetFromVpnProfileStore() {
+ final String name = Credentials.VPN + TEST_VPN_PKG;
+ mService.getFromVpnProfileStore(name);
+ verify(mVpnProfileStore).get(name);
+ }
+
+ @Test
+ public void testPutIntoVpnProfileStore() {
+ final String name = Credentials.VPN + TEST_VPN_PKG;
+ final VpnProfile vpnProfile = new VpnProfile(TEST_VPN_PKG);
+ final byte[] encodedProfile = vpnProfile.encode();
+
+ mService.putIntoVpnProfileStore(name, encodedProfile);
+ verify(mVpnProfileStore).put(name, encodedProfile);
+ }
+
+ @Test
+ public void testRemoveFromVpnProfileStore() {
+ final String name = Credentials.VPN + TEST_VPN_PKG;
+ mService.removeFromVpnProfileStore(name);
+ verify(mVpnProfileStore).remove(name);
+ }
+
+ @Test
+ public void testListFromVpnProfileStore() {
+ final String name = Credentials.VPN + TEST_VPN_PKG;
+ mService.listFromVpnProfileStore(name);
+ verify(mVpnProfileStore).list(name);
+ }
}
diff --git a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
index 9115f95..08155c7 100644
--- a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
+++ b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
@@ -3158,13 +3158,6 @@
assertEquals(profile, ikev2VpnProfile.toVpnProfile());
}
- private void assertTransportInfoMatches(NetworkCapabilities nc, int type) {
- assertNotNull(nc);
- VpnTransportInfo ti = (VpnTransportInfo) nc.getTransportInfo();
- assertNotNull(ti);
- assertEquals(type, ti.getType());
- }
-
// Make it public and un-final so as to spy it
public class TestDeps extends Vpn.Dependencies {
TestDeps() {}
diff --git a/services/tests/mockingservicestests/src/com/android/server/OWNERS b/services/tests/mockingservicestests/src/com/android/server/OWNERS
index f801560..0eb8639 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 682569f..697548c 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 @@
// 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 b415682..0532e04 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.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.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 @@
@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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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/Android.bp b/services/tests/servicestests/Android.bp
index fad8115..c333eb7 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -255,3 +255,89 @@
"done && " +
"$(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res",
}
+
+FLAKY_AND_IGNORED = [
+ "androidx.test.filters.FlakyTest",
+ "org.junit.Ignore",
+]
+// Used by content protection TEST_MAPPING
+test_module_config {
+ name: "FrameworksServicesTests_contentprotection",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_filters: ["com.android.server.contentprotection"],
+ exclude_annotations: FLAKY_AND_IGNORED,
+}
+
+test_module_config {
+ name: "FrameworksServicesTests_om",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_filters: ["com.android.server.om."],
+ exclude_annotations: FLAKY_AND_IGNORED,
+}
+
+// Used by contexthub TEST_MAPPING
+test_module_config {
+ name: "FrameworksServicesTests_contexthub_presubmit",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_filters: ["com.android.server.location.contexthub."],
+ // TODO(ron): are these right, does it run anything?
+ include_annotations: ["android.platform.test.annotations.Presubmit"],
+ exclude_annotations: FLAKY_AND_IGNORED,
+}
+
+test_module_config {
+ name: "FrameworksServicesTests_contexthub_postsubmit",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_filters: ["com.android.server.location.contexthub."],
+ // TODO(ron): are these right, does it run anything?
+ include_annotations: ["android.platform.test.annotations.Postsubmit"],
+ exclude_annotations: FLAKY_AND_IGNORED,
+}
+
+// Used by contentcapture
+test_module_config {
+ name: "FrameworksServicesTests_contentcapture",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_filters: ["com.android.server.contentcapture"],
+ exclude_annotations: FLAKY_AND_IGNORED,
+}
+
+test_module_config {
+ name: "FrameworksServicesTests_recoverysystem",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_filters: ["com.android.server.recoverysystem."],
+ exclude_annotations: ["androidx.test.filters.FlakyTest"],
+}
+
+// server pm TEST_MAPPING
+test_module_config {
+ name: "FrameworksServicesTests_pm_presubmit",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_annotations: ["android.platform.test.annotations.Presubmit"],
+ include_filters: ["com.android.server.pm."],
+ exclude_annotations: FLAKY_AND_IGNORED,
+}
+
+test_module_config {
+ name: "FrameworksServicesTests_pm_postsubmit",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_annotations: ["android.platform.test.annotations.Postsubmit"],
+ include_filters: ["com.android.server.pm."],
+ exclude_annotations: FLAKY_AND_IGNORED,
+}
+
+// server os TEST_MAPPING
+test_module_config {
+ name: "FrameworksServicesTests_os",
+ base: "FrameworksServicesTests",
+ test_suites: ["general-tests"],
+ include_filters: ["com.android.server.os."],
+}
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 74eb79d..34092b6 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.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 @@
@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 @@
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 408442b..3eaf9af 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.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 @@
private BiometricCameraManager mBiometricCameraManager;
@Mock
- private IKeystoreAuthorization mKeystoreAuthService;
+ private KeyStoreAuthorization mKeyStoreAuthorization;
@Mock
private IGateKeeperService mGateKeeperService;
@@ -195,7 +194,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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/contentcapture/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/contentcapture/TEST_MAPPING
index 0ffa891..0946229 100644
--- a/services/tests/servicestests/src/com/android/server/contentcapture/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/contentcapture/TEST_MAPPING
@@ -1,18 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksServicesTests",
- "options": [
- {
- "include-filter": "com.android.server.contentcapture"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksServicesTests_contentcapture"
}
]
}
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/contentprotection/TEST_MAPPING
index 419508c..1ad7baa 100644
--- a/services/tests/servicestests/src/com/android/server/contentprotection/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/TEST_MAPPING
@@ -1,18 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksServicesTests",
- "options": [
- {
- "include-filter": "com.android.server.contentprotection"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksServicesTests_contentprotection"
}
]
}
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 3de167e..5fb15e9 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 @@
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/services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java
index 255cb64..26a2bee 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java
@@ -357,6 +357,29 @@
assertEquals(1, dest.size());
assertEquals(availableLocales.get(0), dest.get(0)); // "sr-Latn-RS"
}
+ // Locale with deprecated subtag, e.g. CS for Serbia and Montenegro, should not win
+ // even if the other available locale doesn't have explicit script / country.
+ // On Android, users don't normally use deprecated subtags unless the application requests.
+ {
+ final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-RS");
+ final ArrayList<Locale> availableLocales = new ArrayList<>();
+ availableLocales.add(Locale.forLanguageTag("sr-Cyrl-CS"));
+ availableLocales.add(Locale.forLanguageTag("sr-RS"));
+ final ArrayList<Locale> dest = new ArrayList<>();
+ LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest);
+ assertEquals(1, dest.size());
+ assertEquals(availableLocales.get(1), dest.get(0)); // "sr-RS"
+ }
+ {
+ final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-RS");
+ final ArrayList<Locale> availableLocales = new ArrayList<>();
+ availableLocales.add(Locale.forLanguageTag("sr-Cyrl-CS"));
+ availableLocales.add(Locale.forLanguageTag("sr"));
+ final ArrayList<Locale> dest = new ArrayList<>();
+ LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest);
+ assertEquals(1, dest.size());
+ assertEquals(availableLocales.get(1), dest.get(0)); // "sr"
+ }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING
index 6035250..58f5bb3 100644
--- a/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING
@@ -1,21 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksServicesTests",
- "options": [
- {
- "include-filter": "com.android.server.location.contexthub."
- },
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksServicesTests_contexthub_presubmit"
}
],
"postsubmit": [
@@ -26,6 +12,8 @@
"include-filter": "com.android.server.location.contexthub."
},
{
+ // I believe this include annotation is preventing tests from being run
+ // as there are no matching tests with the Postsubmit annotation.
"include-annotation": "android.platform.test.annotations.Postsubmit"
},
{
diff --git a/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING
index 558e259..944c1df 100644
--- a/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING
@@ -1,12 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksServicesTests",
- "options": [
- {
- "include-filter": "com.android.server.om."
- }
- ]
+ "name": "FrameworksServicesTests_om"
},
{
"name": "PackageManagerServiceHostTests",
diff --git a/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
index 5a46f8c4..2138da9 100644
--- a/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
@@ -1,12 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksServicesTests",
- "options": [
- {
- "include-filter": "com.android.server.os."
- }
- ]
+ "name": "FrameworksServicesTests_os"
}
]
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING
index 85a73bb..861562d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING
@@ -20,21 +20,13 @@
],
"postsubmit": [
{
- "name": "FrameworksServicesTests",
- "options": [
- {
- "include-filter": "com.android.server.pm."
- },
- {
- "include-annotation": "android.platform.test.annotations.Postsubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ // Presubmit is intentional here while testing with SLO checker.
+ // Tests are flaky, waiting to bypass.
+ "name": "FrameworksServicesTests_pm_presubmit"
+ },
+ {
+ // Leave postsubmit here when migrating
+ "name": "FrameworksServicesTests_pm_postsubmit"
}
]
}
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/recoverysystem/TEST_MAPPING
index e9d8b2e..eb7453d 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/TEST_MAPPING
@@ -1,15 +1,7 @@
{
- "presubmit": [
- {
- "name": "FrameworksServicesTests",
- "options": [
- {
- "include-filter": "com.android.server.recoverysystem."
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- }
- ]
-}
\ No newline at end of file
+ "presubmit": [
+ {
+ "name": "FrameworksServicesTests_recoverysystem"
+ }
+ ]
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index 887e5ee..e443696 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -304,8 +304,7 @@
mContentRecorder.updateRecording();
// Resize the output surface.
- final Point newSurfaceSize = new Point(Math.round(mSurfaceSize.x / 2f),
- Math.round(mSurfaceSize.y * 2));
+ final Point newSurfaceSize = new Point(Math.round(mSurfaceSize.x / 2f), mSurfaceSize.y * 2);
doReturn(newSurfaceSize).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize(
anyInt());
mContentRecorder.onConfigurationChanged(
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 55a00fc..48fc2dc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -799,6 +799,7 @@
verify(child).onConfigurationChanged(any());
}
+ @SuppressWarnings("SelfComparison")
@Test
public void testCompareTo() {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
diff --git a/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java b/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
index d9cbea9..ed89190 100644
--- a/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
+++ b/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
@@ -181,7 +181,7 @@
// We only need to look at the broadcast events that occurred before
// this notification related event.
while (dispatchTimestampsMs.size() > 0
- && dispatchTimestampsMs.peekFirst() < timestampMs) {
+ && dispatchTimestampsMs.peekFirst() <= timestampMs) {
final long dispatchTimestampMs = dispatchTimestampsMs.peekFirst();
final long elapsedDurationMs = timestampMs - dispatchTimestampMs;
// Only increment the counts if the broadcast was sent not too long ago, as
diff --git a/test-legacy/Android.bp b/test-legacy/Android.bp
new file mode 100644
index 0000000..236d704
--- /dev/null
+++ b/test-legacy/Android.bp
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 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 {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: [
+ "Android-Apache-2.0",
+ ],
+}
+
+java_library {
+ name: "android.test.legacy",
+ sdk_version: "current",
+ libs: [
+ "android.test.mock.stubs",
+ "junit",
+ ],
+ static_libs: [
+ "android.test.base-minus-junit",
+ "android.test.runner-minus-junit",
+ ],
+ dist: {
+ targets: [
+ "sdk",
+ ],
+ },
+}
diff --git a/test-legacy/Android.mk b/test-legacy/Android.mk
deleted file mode 100644
index da9dc25..0000000
--- a/test-legacy/Android.mk
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Copyright (C) 2018 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.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-# For unbundled build we'll use the prebuilt jar from prebuilts/sdk.
-ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)))
-
-# Build the android.test.legacy library
-# =====================================
-# Built against the SDK so that it can be statically included in APKs
-# without breaking link type checks.
-#
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := android.test.legacy
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-MIT SPDX-license-identifier-Unicode-DFS
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_JAVA_LIBRARIES := junit android.test.mock.stubs
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android.test.base-minus-junit \
- android.test.runner-minus-junit \
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-$(call declare-license-metadata,$(full_classes_jar),\
- SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-MIT SPDX-license-identifier-Unicode-DFS,\
- notice,$(LOCAL_PATH)/../NOTICE,Android,frameworks/base)
-
-# Archive a copy of the classes.jar in SDK build.
-$(call dist-for-goals,sdk,$(full_classes_jar):android.test.legacy.jar)
-
-endif # not TARGET_BUILD_APPS not TARGET_BUILD_PDK=true
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 081da11..489ef44 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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 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 4f27e06..093923f 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -45,13 +45,13 @@
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.util.AtomicFile;
+import android.util.LongArrayQueue;
import android.util.Xml;
-import android.utils.LongArrayQueue;
-import android.utils.XmlUtils;
import androidx.test.InstrumentationRegistry;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.PackageWatchdog.HealthCheckState;
@@ -1224,7 +1224,7 @@
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 @@
}
/**
- * 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 @@
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 @@
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 @@
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 @@
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 @@
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/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
index ba9e4a8..f82d9ca 100644
--- a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
+++ b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
@@ -130,14 +130,13 @@
private static final Pattern PATTERN_SYSTEM_FONT_FILES =
Pattern.compile("^/(system|product)/fonts/");
- private String mKeyId;
private FontManager mFontManager;
private UiDevice mUiDevice;
@Before
public void setUp() throws Exception {
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- mKeyId = insertCert(CERT_PATH);
+ insertCert(CERT_PATH);
mFontManager = context.getSystemService(FontManager.class);
expectCommandToSucceed("cmd font clear");
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
@@ -147,9 +146,6 @@
public void tearDown() throws Exception {
// Ignore errors because this may fail if updatable system font is not enabled.
runShellCommand("cmd font clear", null);
- if (mKeyId != null) {
- expectCommandToSucceed("mini-keyctl unlink " + mKeyId + " .fs-verity");
- }
}
@Test
@@ -369,20 +365,11 @@
assertThat(isFileOpenedBy(fontPath, EMOJI_RENDERING_TEST_APP_ID)).isFalse();
}
- private static String insertCert(String certPath) throws Exception {
- Pair<String, String> result;
- try (InputStream is = new FileInputStream(certPath)) {
- result = runShellCommand("mini-keyctl padd asymmetric fsv_test .fs-verity", is);
- }
+ private static void insertCert(String certPath) throws Exception {
// /data/local/tmp is not readable by system server. Copy a cert file to /data/fonts
final String copiedCert = "/data/fonts/debug_cert.der";
runShellCommand("cp " + certPath + " " + copiedCert, null);
runShellCommand("cmd font install-debug-cert " + copiedCert, null);
- // Assert that there are no errors.
- assertThat(result.second).isEmpty();
- String keyId = result.first.trim();
- assertThat(keyId).matches("^\\d+$");
- return keyId;
}
private int updateFontFile(String fontPath, String signaturePath) throws IOException {
diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp
index c02d8e9..a0bb84d 100644
--- a/tests/UsbManagerTests/Android.bp
+++ b/tests/UsbManagerTests/Android.bp
@@ -21,6 +21,7 @@
// 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 92c2711..c4ebdec 100644
--- a/tests/UsbTests/Android.bp
+++ b/tests/UsbTests/Android.bp
@@ -21,6 +21,7 @@
// 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/testables/OWNERS b/tests/testables/OWNERS
new file mode 100644
index 0000000..a6f1632
--- /dev/null
+++ b/tests/testables/OWNERS
@@ -0,0 +1 @@
+file:/packages/SystemUI/OWNERS
\ No newline at end of file