summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp7
-rw-r--r--Android.bp1
-rw-r--r--ProtoLibraries.bp1
-rw-r--r--STABILITY_OWNERS2
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java36
-rw-r--r--core/java/android/security/flags.aconfig2
-rw-r--r--core/java/android/view/inputmethod/RemoteInputConnectionImpl.java163
-rw-r--r--core/java/android/widget/RemoteCollectionItemsAdapter.java45
-rw-r--r--core/java/android/widget/RemoteViews.java4
-rw-r--r--core/java/android/widget/RemoteViewsAdapter.java7
-rw-r--r--core/java/com/android/internal/util/RingBuffer.java39
-rw-r--r--keystore/java/android/security/Authorization.java6
-rw-r--r--libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp3
-rw-r--r--libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h3
-rw-r--r--libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp3
-rw-r--r--libs/hwui/pipeline/skia/SkiaVulkanPipeline.h3
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp20
-rw-r--r--libs/hwui/renderthread/CanvasContext.h5
-rw-r--r--libs/hwui/renderthread/IRenderPipeline.h3
-rw-r--r--media/java/android/media/MediaFormat.java31
-rw-r--r--services/core/java/com/android/server/BootReceiver.java83
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyLogger.java9
-rw-r--r--services/core/java/com/android/server/os/NativeTombstoneManager.java135
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java78
-rw-r--r--services/core/jni/Android.bp11
-rw-r--r--services/core/jni/OWNERS4
-rw-r--r--services/core/jni/com_android_server_BootReceiver.cpp57
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java206
-rw-r--r--services/tests/servicestests/src/com/android/server/BootReceiverTest.java97
-rw-r--r--services/usage/java/com/android/server/usage/BroadcastResponseStatsLogger.java20
-rw-r--r--test-base/Android.bp3
-rw-r--r--test-mock/Android.bp3
-rw-r--r--test-runner/Android.bp3
35 files changed, 584 insertions, 512 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 02fee102b4c3..bd693850f45e 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -13,6 +13,8 @@
// limitations under the License.
aconfig_srcjars = [
+ // !!! KEEP THIS LIST ALPHABETICAL !!!
+ ":aconfig_mediacodec_flags_java_lib{.generated_srcjars}",
":android.content.pm.flags-aconfig-java{.generated_srcjars}",
":android.content.res.flags-aconfig-java{.generated_srcjars}",
":android.hardware.biometrics.flags-aconfig-java{.generated_srcjars}",
@@ -21,10 +23,11 @@ aconfig_srcjars = [
":android.os.flags-aconfig-java{.generated_srcjars}",
":android.security.flags-aconfig-java{.generated_srcjars}",
":com.android.hardware.camera2-aconfig-java{.generated_srcjars}",
- ":com.android.window.flags.window-aconfig-java{.generated_srcjars}",
":com.android.hardware.input-aconfig-java{.generated_srcjars}",
- ":com.android.text.flags-aconfig-java{.generated_srcjars}",
":com.android.net.flags-aconfig-java{.generated_srcjars}",
+ ":com.android.text.flags-aconfig-java{.generated_srcjars}",
+ ":com.android.window.flags.window-aconfig-java{.generated_srcjars}",
+ // !!! KEEP THIS LIST ALPHABETICAL !!!
]
filegroup {
diff --git a/Android.bp b/Android.bp
index 5f02a15ad185..2113e4b85248 100644
--- a/Android.bp
+++ b/Android.bp
@@ -205,7 +205,6 @@ java_library {
"apex_aidl_interface-java",
"packagemanager_aidl-java",
"framework-protos",
- "libtombstone_proto_java",
"updatable-driver-protos",
"ota_metadata_proto_java",
"android.hidl.base-V1.0-java",
diff --git a/ProtoLibraries.bp b/ProtoLibraries.bp
index d03bbd249b00..e7adf203334e 100644
--- a/ProtoLibraries.bp
+++ b/ProtoLibraries.bp
@@ -34,6 +34,7 @@ gensrcs {
":ipconnectivity-proto-src",
":libstats_atom_enum_protos",
":libstats_atom_message_protos",
+ ":libtombstone_proto-src",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
],
diff --git a/STABILITY_OWNERS b/STABILITY_OWNERS
deleted file mode 100644
index a7ecb4dfdd44..000000000000
--- a/STABILITY_OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-gaillard@google.com
-
diff --git a/core/api/current.txt b/core/api/current.txt
index 48f58c09871d..b6b8b6e65cd3 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -23631,6 +23631,7 @@ package android.media {
field public static final String KEY_HDR10_PLUS_INFO = "hdr10-plus-info";
field public static final String KEY_HDR_STATIC_INFO = "hdr-static-info";
field public static final String KEY_HEIGHT = "height";
+ field @FlaggedApi("com.android.media.codec.flags.codec_importance") public static final String KEY_IMPORTANCE = "importance";
field public static final String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period";
field public static final String KEY_IS_ADTS = "is-adts";
field public static final String KEY_IS_AUTOSELECT = "is-autoselect";
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index ec181dac6b36..27f6a266597c 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -156,22 +156,6 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
}
/**
- * @hide
- */
- public static class AdapterChildHostView extends AppWidgetHostView {
-
- public AdapterChildHostView(Context context) {
- super(context);
- }
-
- @Override
- public Context getRemoteContextEnsuringCorrectCachedApkPath() {
- // To reduce noise in error messages
- return null;
- }
- }
-
- /**
* Set the AppWidget that will be displayed by this view. This method also adds default padding
* to widgets, as described in {@link #getDefaultPaddingForWidget(Context, ComponentName, Rect)}
* and can be overridden in order to add custom padding.
@@ -937,31 +921,17 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
setColorResources(RemoteViews.ColorResources.create(mContext, colorMapping));
}
- private void setColorResourcesStates(RemoteViews.ColorResources colorResources) {
- mColorResources = colorResources;
- mColorMappingChanged = true;
- mViewMode = VIEW_MODE_NOINIT;
- }
-
/** @hide **/
public void setColorResources(RemoteViews.ColorResources colorResources) {
if (colorResources == mColorResources) {
return;
}
- setColorResourcesStates(colorResources);
+ mColorResources = colorResources;
+ mColorMappingChanged = true;
+ mViewMode = VIEW_MODE_NOINIT;
reapplyLastRemoteViews();
}
- /**
- * @hide
- */
- public void setColorResourcesNoReapply(RemoteViews.ColorResources colorResources) {
- if (colorResources == mColorResources) {
- return;
- }
- setColorResourcesStates(colorResources);
- }
-
/** Check if, in the current context, the two color mappings are equivalent. */
private boolean isSameColorMapping(SparseIntArray oldColors, SparseIntArray newColors) {
if (oldColors.size() != newColors.size()) {
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 30524a1132fa..1994058441d5 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -53,7 +53,7 @@ flag {
flag {
name: "frp_enforcement"
- namespace: "android_hw_security"
+ namespace: "hardware_backed_security"
description: "This flag controls whether PDB enforces FRP"
bug: "290312729"
is_fixed_read_only: true
diff --git a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
index 7694754de6ff..c9ffdae890c5 100644
--- a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
+++ b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
@@ -49,7 +49,6 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewRootImpl;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
import com.android.internal.inputmethod.IRemoteInputConnection;
@@ -60,6 +59,7 @@ import java.lang.annotation.Retention;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -164,18 +164,15 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
boolean cancellable();
}
- @GuardedBy("mLock")
- @Nullable
- private InputConnection mInputConnection;
+ @NonNull
+ private final AtomicReference<InputConnection> mInputConnectionRef;
+ @NonNull
+ private final AtomicBoolean mDeactivateRequested = new AtomicBoolean(false);
@NonNull
private final Looper mLooper;
private final Handler mH;
- private final Object mLock = new Object();
- @GuardedBy("mLock")
- private boolean mFinished = false;
-
private final InputMethodManager mParentInputMethodManager;
private final WeakReference<View> mServedView;
@@ -193,7 +190,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
RemoteInputConnectionImpl(@NonNull Looper looper,
@NonNull InputConnection inputConnection,
@NonNull InputMethodManager inputMethodManager, @Nullable View servedView) {
- mInputConnection = inputConnection;
+ mInputConnectionRef = new AtomicReference<>(inputConnection);
mLooper = looper;
mH = new Handler(mLooper);
mParentInputMethodManager = inputMethodManager;
@@ -211,9 +208,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
*/
@Nullable
public InputConnection getInputConnection() {
- synchronized (mLock) {
- return mInputConnection;
- }
+ return mInputConnectionRef.get();
}
/**
@@ -229,13 +224,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
* {@link InputConnection#closeConnection()} as a result of {@link #deactivate()}.
*/
private boolean isFinished() {
- synchronized (mLock) {
- return mFinished;
- }
- }
-
- private boolean isActive() {
- return mParentInputMethodManager.isActive() && !isFinished();
+ return mInputConnectionRef.get() == null;
}
private View getServedView() {
@@ -372,28 +361,18 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
*/
@Dispatching(cancellable = false)
public void deactivate() {
- if (isFinished()) {
+ if (mDeactivateRequested.getAndSet(true)) {
// This is a small performance optimization. Still only the 1st call of
- // reportFinish() will take effect.
+ // deactivate() will take effect.
return;
}
dispatch(() -> {
// Deactivate the notifier when finishing typing.
notifyTypingHint(false /* isTyping */, true /* deactivate */);
- // Note that we do not need to worry about race condition here, because 1) mFinished is
- // updated only inside this block, and 2) the code here is running on a Handler hence we
- // assume multiple closeConnection() tasks will not be handled at the same time.
- if (isFinished()) {
- return;
- }
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#closeConnection");
try {
InputConnection ic = getInputConnection();
- // Note we do NOT check isActive() here, because this is safe
- // for an IME to call at any time, and we need to allow it
- // through to clean up our state after the IME has switched to
- // another client.
if (ic == null) {
return;
}
@@ -403,10 +382,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
// TODO(b/199934664): See if we can remove this by providing a default impl.
}
} finally {
- synchronized (mLock) {
- mInputConnection = null;
- mFinished = true;
- }
+ mInputConnectionRef.set(null);
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
}
@@ -460,8 +436,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
public String toString() {
return "RemoteInputConnectionImpl{"
+ "connection=" + getInputConnection()
- + " finished=" + isFinished()
- + " mParentInputMethodManager.isActive()=" + mParentInputMethodManager.isActive()
+ + " mDeactivateRequested=" + mDeactivateRequested.get()
+ " mServedView=" + mServedView.get()
+ "}";
}
@@ -474,16 +449,14 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
* {@link DumpableInputConnection#dumpDebug(ProtoOutputStream, long)}.
*/
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
- synchronized (mLock) {
- // Check that the call is initiated in the target thread of the current InputConnection
- // {@link InputConnection#getHandler} since the messages to IInputConnectionWrapper are
- // executed on this thread. Otherwise the messages are dispatched to the correct thread
- // in IInputConnectionWrapper, but this is not wanted while dumpng, for performance
- // reasons.
- if ((mInputConnection instanceof DumpableInputConnection)
- && mLooper.isCurrentThread()) {
- ((DumpableInputConnection) mInputConnection).dumpDebug(proto, fieldId);
- }
+ final InputConnection ic = mInputConnectionRef.get();
+ // Check that the call is initiated in the target thread of the current InputConnection
+ // {@link InputConnection#getHandler} since the messages to IInputConnectionWrapper are
+ // executed on this thread. Otherwise the messages are dispatched to the correct thread
+ // in IInputConnectionWrapper, but this is not wanted while dumping, for performance
+ // reasons.
+ if ((ic instanceof DumpableInputConnection) && mLooper.isCurrentThread()) {
+ ((DumpableInputConnection) ic).dumpDebug(proto, fieldId);
}
}
@@ -498,7 +471,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
public void dispatchReportFullscreenMode(boolean enabled) {
dispatch(() -> {
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
return;
}
ic.reportFullscreenMode(enabled);
@@ -514,7 +487,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return null; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
return null;
}
@@ -536,7 +509,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return null; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
return null;
}
@@ -558,7 +531,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return null; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "getSelectedText on inactive InputConnection");
return null;
}
@@ -580,7 +553,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return null; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "getSurroundingText on inactive InputConnection");
return null;
}
@@ -608,7 +581,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return 0; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
return 0;
}
@@ -625,7 +598,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return null; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "getExtractedText on inactive InputConnection");
return null;
}
@@ -642,7 +615,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "commitText on inactive InputConnection");
return;
}
@@ -660,7 +633,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "commitText on inactive InputConnection");
return;
}
@@ -676,7 +649,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "commitCompletion on inactive InputConnection");
return;
}
@@ -692,7 +665,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "commitCorrection on inactive InputConnection");
return;
}
@@ -712,7 +685,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "setSelection on inactive InputConnection");
return;
}
@@ -728,7 +701,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "performEditorAction on inactive InputConnection");
return;
}
@@ -744,7 +717,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "performContextMenuAction on inactive InputConnection");
return;
}
@@ -760,7 +733,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "setComposingRegion on inactive InputConnection");
return;
}
@@ -781,7 +754,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "setComposingRegion on inactive InputConnection");
return;
}
@@ -798,7 +771,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "setComposingText on inactive InputConnection");
return;
}
@@ -816,7 +789,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "setComposingText on inactive InputConnection");
return;
}
@@ -845,11 +818,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- // Note we do NOT check isActive() here, because this is safe
- // for an IME to call at any time, and we need to allow it
- // through to clean up our state after the IME has switched to
- // another client.
- if (ic == null) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "finishComposingTextFromImm on inactive InputConnection");
return;
}
@@ -873,11 +842,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- // Note we do NOT check isActive() here, because this is safe
- // for an IME to call at any time, and we need to allow it
- // through to clean up our state after the IME has switched to
- // another client.
- if (ic == null) {
+ if (ic == null && mDeactivateRequested.get()) {
Log.w(TAG, "finishComposingText on inactive InputConnection");
return;
}
@@ -893,7 +858,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "sendKeyEvent on inactive InputConnection");
return;
}
@@ -909,7 +874,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
return;
}
@@ -926,7 +891,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
return;
}
@@ -944,7 +909,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
return;
}
@@ -964,7 +929,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "beginBatchEdit on inactive InputConnection");
return;
}
@@ -980,7 +945,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "endBatchEdit on inactive InputConnection");
return;
}
@@ -996,7 +961,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "performSpellCheck on inactive InputConnection");
return;
}
@@ -1013,7 +978,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "performPrivateCommand on inactive InputConnection");
return;
}
@@ -1051,7 +1016,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "performHandwritingGesture on inactive InputConnection");
if (resultReceiver != null) {
resultReceiver.send(
@@ -1091,7 +1056,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "previewHandwritingGesture on inactive InputConnection");
return; // cancelled
}
@@ -1139,7 +1104,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
@InputConnection.CursorUpdateMode int cursorUpdateMode,
@InputConnection.CursorUpdateFilter int cursorUpdateFilter, int imeDisplayId) {
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "requestCursorUpdates on inactive InputConnection");
return false;
}
@@ -1177,7 +1142,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "requestTextBoundsInfo on inactive InputConnection");
resultReceiver.send(TextBoundsInfoResult.CODE_CANCELLED, null);
return;
@@ -1221,7 +1186,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return false; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "commitContent on inactive InputConnection");
return false;
}
@@ -1246,7 +1211,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "setImeConsumesInput on inactive InputConnection");
return;
}
@@ -1270,7 +1235,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "replaceText on inactive InputConnection");
return;
}
@@ -1289,7 +1254,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "commitText on inactive InputConnection");
return;
}
@@ -1309,7 +1274,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "setSelection on inactive InputConnection");
return;
}
@@ -1326,7 +1291,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return null; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "getSurroundingText on inactive InputConnection");
return null;
}
@@ -1354,7 +1319,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
return;
}
@@ -1370,7 +1335,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "sendKeyEvent on inactive InputConnection");
return;
}
@@ -1386,7 +1351,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "performEditorAction on inactive InputConnection");
return;
}
@@ -1402,7 +1367,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "performContextMenuAction on inactive InputConnection");
return;
}
@@ -1419,7 +1384,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return 0; // cancelled
}
final InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
return 0;
}
@@ -1435,7 +1400,7 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
return; // cancelled
}
InputConnection ic = getInputConnection();
- if (ic == null || !isActive()) {
+ if (ic == null || mDeactivateRequested.get()) {
Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
return;
}
diff --git a/core/java/android/widget/RemoteCollectionItemsAdapter.java b/core/java/android/widget/RemoteCollectionItemsAdapter.java
index 9b396aeea9eb..d84330828bf7 100644
--- a/core/java/android/widget/RemoteCollectionItemsAdapter.java
+++ b/core/java/android/widget/RemoteCollectionItemsAdapter.java
@@ -18,7 +18,6 @@ package android.widget;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.appwidget.AppWidgetHostView;
import android.util.SparseIntArray;
import android.view.View;
import android.view.ViewGroup;
@@ -26,6 +25,8 @@ import android.widget.RemoteViews.ColorResources;
import android.widget.RemoteViews.InteractionHandler;
import android.widget.RemoteViews.RemoteCollectionItems;
+import com.android.internal.R;
+
import java.util.stream.IntStream;
/**
@@ -177,14 +178,40 @@ class RemoteCollectionItemsAdapter extends BaseAdapter {
RemoteViews item = mItems.getItemView(position);
item.addFlags(RemoteViews.FLAG_WIDGET_IS_COLLECTION_CHILD);
+ View reapplyView = getViewToReapply(convertView, item);
+
+ // Reapply the RemoteViews if we can.
+ if (reapplyView != null) {
+ try {
+ item.reapply(
+ parent.getContext(),
+ reapplyView,
+ mInteractionHandler,
+ null /* size */,
+ mColorResources);
+ return reapplyView;
+ } catch (RuntimeException e) {
+ // We can't reapply for some reason, we'll fallback to an apply and inflate a
+ // new view.
+ }
+ }
+
+ return item.apply(
+ parent.getContext(),
+ parent,
+ mInteractionHandler,
+ null /* size */,
+ mColorResources);
+ }
+
+ /** Returns {@code convertView} if it can be used to reapply {@code item}, or null otherwise. */
+ @Nullable
+ private static View getViewToReapply(@Nullable View convertView, @NonNull RemoteViews item) {
+ if (convertView == null) return null;
+
+ Object layoutIdTag = convertView.getTag(R.id.widget_frame);
+ if (!(layoutIdTag instanceof Integer)) return null;
- AppWidgetHostView newView = convertView instanceof AppWidgetHostView.AdapterChildHostView
- widgetChildView
- ? widgetChildView
- : new AppWidgetHostView.AdapterChildHostView(parent.getContext());
- newView.setInteractionHandler(mInteractionHandler);
- newView.setColorResourcesNoReapply(mColorResources);
- newView.updateAppWidget(item);
- return newView;
+ return item.getLayoutId() == (Integer) layoutIdTag ? convertView : null;
}
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index eb3f96e7a652..a740b651142d 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -6913,13 +6913,13 @@ public class RemoteViews implements Parcelable, Filter {
View parent = (View) view.getParent();
// Break the for loop on the first encounter of:
// 1) an AdapterView,
- // 2) an AppWidgetHostView that is not a child of an adapter view, or
+ // 2) an AppWidgetHostView that is not a RemoteViewsFrameLayout, or
// 3) a null parent.
// 2) and 3) are unexpected and catch the case where a child is not
// correctly parented in an AdapterView.
while (parent != null && !(parent instanceof AdapterView<?>)
&& !((parent instanceof AppWidgetHostView)
- && !(parent instanceof AppWidgetHostView.AdapterChildHostView))) {
+ && !(parent instanceof RemoteViewsAdapter.RemoteViewsFrameLayout))) {
parent = (View) parent.getParent();
}
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 2f28a8704cd3..61a7599e8f73 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -368,7 +368,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
* A FrameLayout which contains a loading view, and manages the re/applying of RemoteViews when
* they are loaded.
*/
- static class RemoteViewsFrameLayout extends AppWidgetHostView.AdapterChildHostView {
+ static class RemoteViewsFrameLayout extends AppWidgetHostView {
private final FixedSizeRemoteViewsCache mCache;
public int cacheIndex = -1;
@@ -408,6 +408,11 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
}
@Override
+ protected Context getRemoteContextEnsuringCorrectCachedApkPath() {
+ return null;
+ }
+
+ @Override
protected View getErrorView() {
// Use the default loading view as the error view.
return getDefaultView();
diff --git a/core/java/com/android/internal/util/RingBuffer.java b/core/java/com/android/internal/util/RingBuffer.java
index 8fc4c30e54ab..7f8c8a1cae04 100644
--- a/core/java/com/android/internal/util/RingBuffer.java
+++ b/core/java/com/android/internal/util/RingBuffer.java
@@ -19,7 +19,10 @@ package com.android.internal.util;
import static com.android.internal.util.Preconditions.checkArgumentPositive;
import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
+import java.util.function.IntFunction;
+import java.util.function.Supplier;
/**
* A simple ring buffer structure with bounded capacity backed by an array.
@@ -29,16 +32,35 @@ import java.util.Arrays;
*/
public class RingBuffer<T> {
+ private final Supplier<T> mNewItem;
// Array for storing events.
private final T[] mBuffer;
// Cursor keeping track of the logical end of the array. This cursor never
// wraps and instead keeps track of the total number of append() operations.
private long mCursor = 0;
+ /**
+ * @deprecated This uses reflection to create new instances.
+ * Use {@link #RingBuffer(Supplier, IntFunction, int)}} instead.
+ */
+ @Deprecated
public RingBuffer(Class<T> c, int capacity) {
+ this(() -> (T) createNewItem(c), cap -> (T[]) Array.newInstance(c, cap), capacity);
+ }
+
+ private static Object createNewItem(Class c) {
+ try {
+ return c.getDeclaredConstructor().newInstance();
+ } catch (IllegalAccessException | InstantiationException | NoSuchMethodException
+ | InvocationTargetException e) {
+ return null;
+ }
+ }
+
+ public RingBuffer(Supplier<T> newItem, IntFunction<T[]> newBacking, int capacity) {
checkArgumentPositive(capacity, "A RingBuffer cannot have 0 capacity");
- // Java cannot create generic arrays without a runtime hint.
- mBuffer = (T[]) Array.newInstance(c, capacity);
+ mBuffer = newBacking.apply(capacity);
+ mNewItem = newItem;
}
public int size() {
@@ -68,22 +90,11 @@ public class RingBuffer<T> {
public T getNextSlot() {
final int nextSlotIdx = indexOf(mCursor++);
if (mBuffer[nextSlotIdx] == null) {
- mBuffer[nextSlotIdx] = createNewItem();
+ mBuffer[nextSlotIdx] = mNewItem.get();
}
return mBuffer[nextSlotIdx];
}
- /**
- * @return a new object of type <T> or null if a new object could not be created.
- */
- protected T createNewItem() {
- try {
- return (T) mBuffer.getClass().getComponentType().newInstance();
- } catch (IllegalAccessException | InstantiationException e) {
- return null;
- }
- }
-
public T[] toArray() {
// Only generic way to create a T[] from another T[]
T[] out = Arrays.copyOf(mBuffer, size(), (Class<T[]>) mBuffer.getClass());
diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java
index 4ec5e1b67c5d..6404c4bc33d6 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/Authorization.java
@@ -100,12 +100,14 @@ public class Authorization {
*
* @param userId - the user's Android user ID
* @param unlockingSids - list of biometric SIDs with which the device may be unlocked again
+ * @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 static int onDeviceLocked(int userId, @NonNull long[] unlockingSids,
+ boolean weakUnlockEnabled) {
StrictMode.noteDiskWrite();
try {
- getService().onDeviceLocked(userId, unlockingSids);
+ getService().onDeviceLocked(userId, unlockingSids, weakUnlockEnabled);
return 0;
} catch (RemoteException | NullPointerException e) {
Log.w(TAG, "Can not connect to keystore", e);
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index cf31173d266e..56f1e64396af 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -115,7 +115,7 @@ IRenderPipeline::DrawResult SkiaOpenGLPipeline::draw(
const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler,
- const HardwareBufferRenderParams& bufferParams) {
+ const HardwareBufferRenderParams& bufferParams, std::mutex& profilerLock) {
if (!isCapturingSkp() && !mHardwareBuffer) {
mEglManager.damageFrame(frame, dirty);
}
@@ -167,6 +167,7 @@ IRenderPipeline::DrawResult SkiaOpenGLPipeline::draw(
// Draw visual debugging features
if (CC_UNLIKELY(Properties::showDirtyRegions ||
ProfileType::None != Properties::getProfileType())) {
+ std::scoped_lock lock(profilerLock);
SkCanvas* profileCanvas = surface->getCanvas();
SkiaProfileRenderer profileRenderer(profileCanvas, frame.width(), frame.height());
profiler->draw(profileRenderer);
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index f0461bef170c..0325593f7170 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -42,7 +42,8 @@ public:
const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
const std::vector<sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler,
- const renderthread::HardwareBufferRenderParams& bufferParams) override;
+ const renderthread::HardwareBufferRenderParams& bufferParams,
+ std::mutex& profilerLock) override;
GrSurfaceOrigin getSurfaceOrigin() override { return kBottomLeft_GrSurfaceOrigin; }
bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) override;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 86096d5bd01c..7d192321f13e 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -75,7 +75,7 @@ IRenderPipeline::DrawResult SkiaVulkanPipeline::draw(
const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler,
- const HardwareBufferRenderParams& bufferParams) {
+ const HardwareBufferRenderParams& bufferParams, std::mutex& profilerLock) {
sk_sp<SkSurface> backBuffer;
SkMatrix preTransform;
if (mHardwareBuffer) {
@@ -103,6 +103,7 @@ IRenderPipeline::DrawResult SkiaVulkanPipeline::draw(
// Draw visual debugging features
if (CC_UNLIKELY(Properties::showDirtyRegions ||
ProfileType::None != Properties::getProfileType())) {
+ std::scoped_lock lock(profilerLock);
SkCanvas* profileCanvas = backBuffer->getCanvas();
SkAutoCanvasRestore saver(profileCanvas, true);
profileCanvas->concat(mVkSurface->getCurrentPreTransform());
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 284cde537ec0..37b86f136fbb 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -42,7 +42,8 @@ public:
const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
const std::vector<sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler,
- const renderthread::HardwareBufferRenderParams& bufferParams) override;
+ const renderthread::HardwareBufferRenderParams& bufferParams,
+ std::mutex& profilerLock) override;
GrSurfaceOrigin getSurfaceOrigin() override { return kTopLeft_GrSurfaceOrigin; }
bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) override;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 618c896afa96..f6907831e11f 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -592,14 +592,10 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) {
{
// FrameInfoVisualizer accesses the frame events, which cannot be mutated mid-draw
// or it can lead to memory corruption.
- // This lock is overly broad, but it's the quickest fix since this mutex is otherwise
- // not visible to IRenderPipeline much less FrameInfoVisualizer. And since this is
- // the thread we're primarily concerned about being responsive, this being too broad
- // shouldn't pose a performance issue.
- std::scoped_lock lock(mFrameMetricsReporterMutex);
drawResult = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry,
&mLayerUpdateQueue, mContentDrawBounds, mOpaque,
- mLightInfo, mRenderNodes, &(profiler()), mBufferParams);
+ mLightInfo, mRenderNodes, &(profiler()), mBufferParams,
+ profilerLock());
}
uint64_t frameCompleteNr = getFrameNumber();
@@ -729,7 +725,7 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) {
mCurrentFrameInfo->markFrameCompleted();
mCurrentFrameInfo->set(FrameInfoIndex::GpuCompleted)
= mCurrentFrameInfo->get(FrameInfoIndex::FrameCompleted);
- std::scoped_lock lock(mFrameMetricsReporterMutex);
+ std::scoped_lock lock(mFrameInfoMutex);
mJankTracker.finishFrame(*mCurrentFrameInfo, mFrameMetricsReporter, frameCompleteNr,
mSurfaceControlGenerationId);
}
@@ -758,7 +754,7 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) {
void CanvasContext::reportMetricsWithPresentTime() {
{ // acquire lock
- std::scoped_lock lock(mFrameMetricsReporterMutex);
+ std::scoped_lock lock(mFrameInfoMutex);
if (mFrameMetricsReporter == nullptr) {
return;
}
@@ -793,7 +789,7 @@ void CanvasContext::reportMetricsWithPresentTime() {
forthBehind->set(FrameInfoIndex::DisplayPresentTime) = presentTime;
{ // acquire lock
- std::scoped_lock lock(mFrameMetricsReporterMutex);
+ std::scoped_lock lock(mFrameInfoMutex);
if (mFrameMetricsReporter != nullptr) {
mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/,
frameNumber, surfaceControlId);
@@ -802,7 +798,7 @@ void CanvasContext::reportMetricsWithPresentTime() {
}
void CanvasContext::addFrameMetricsObserver(FrameMetricsObserver* observer) {
- std::scoped_lock lock(mFrameMetricsReporterMutex);
+ std::scoped_lock lock(mFrameInfoMutex);
if (mFrameMetricsReporter.get() == nullptr) {
mFrameMetricsReporter.reset(new FrameMetricsReporter());
}
@@ -816,7 +812,7 @@ void CanvasContext::addFrameMetricsObserver(FrameMetricsObserver* observer) {
}
void CanvasContext::removeFrameMetricsObserver(FrameMetricsObserver* observer) {
- std::scoped_lock lock(mFrameMetricsReporterMutex);
+ std::scoped_lock lock(mFrameInfoMutex);
if (mFrameMetricsReporter.get() != nullptr) {
mFrameMetricsReporter->removeObserver(observer);
if (!mFrameMetricsReporter->hasObservers()) {
@@ -853,7 +849,7 @@ void CanvasContext::onSurfaceStatsAvailable(void* context, int32_t surfaceContro
FrameInfo* frameInfo = instance->getFrameInfoFromLast4(frameNumber, surfaceControlId);
if (frameInfo != nullptr) {
- std::scoped_lock lock(instance->mFrameMetricsReporterMutex);
+ std::scoped_lock lock(instance->mFrameInfoMutex);
frameInfo->set(FrameInfoIndex::FrameCompleted) = std::max(gpuCompleteTime,
frameInfo->get(FrameInfoIndex::SwapBuffersCompleted));
frameInfo->set(FrameInfoIndex::GpuCompleted) = std::max(
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 32ac5af94c14..3978fbcc3a21 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -161,6 +161,7 @@ public:
void notifyFramePending();
FrameInfoVisualizer& profiler() { return mProfiler; }
+ std::mutex& profilerLock() { return mFrameInfoMutex; }
void dumpFrames(int fd);
void resetFrameStats();
@@ -340,8 +341,8 @@ private:
JankTracker mJankTracker;
FrameInfoVisualizer mProfiler;
std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter
- GUARDED_BY(mFrameMetricsReporterMutex);
- std::mutex mFrameMetricsReporterMutex;
+ GUARDED_BY(mFrameInfoMutex);
+ std::mutex mFrameInfoMutex;
std::set<RenderNode*> mPrefetchedLayers;
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 6c2cb9d71c55..023c29a3ab85 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -67,7 +67,8 @@ public:
const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
const std::vector<sp<RenderNode>>& renderNodes,
FrameInfoVisualizer* profiler,
- const HardwareBufferRenderParams& bufferParams) = 0;
+ const HardwareBufferRenderParams& bufferParams,
+ std::mutex& profilerLock) = 0;
virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
virtual DeferredLayerUpdater* createTextureLayer() = 0;
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 46db77708521..587e35b4b1fc 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -16,6 +16,9 @@
package android.media;
+import static com.android.media.codec.flags.Flags.FLAG_CODEC_IMPORTANCE;
+
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1635,6 +1638,34 @@ public final class MediaFormat {
*/
public static final String KEY_ALLOW_FRAME_DROP = "allow-frame-drop";
+ /**
+ * A key describing the desired codec importance for the application.
+ * <p>
+ * The associated value is a positive integer including zero.
+ * Higher value means lesser importance.
+ * <p>
+ * The resource manager may use the codec importance, along with other factors
+ * when reclaiming codecs from an application.
+ * The specifics of reclaim policy is device dependent, but specifying the codec importance,
+ * will allow the resource manager to prioritize reclaiming less important codecs
+ * (assigned higher values) from the (reclaim) requesting application first.
+ * So, the codec importance is only relevant within the context of that application.
+ * <p>
+ * The codec importance can be set:
+ * <ul>
+ * <li>through {@link MediaCodec#configure}. </li>
+ * <li>through {@link MediaCodec#setParameters} if the codec has been configured already,
+ * which allows the users to change the codec importance multiple times.
+ * </ul>
+ * Any change/update in codec importance is guaranteed upon the completion of the function call
+ * that sets the codec importance. So, in case of concurrent codec operations,
+ * make sure to wait for the change in codec importance, before using another codec.
+ * Note that unless specified, by default the codecs will have highest importance (of value 0).
+ *
+ */
+ @FlaggedApi(FLAG_CODEC_IMPORTANCE)
+ public static final String KEY_IMPORTANCE = "importance";
+
/* package private */ MediaFormat(@NonNull Map<String, Object> map) {
mMap = map;
}
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index 5cdfca7392e3..926d7a4d3ea6 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -48,8 +48,6 @@ import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.am.DropboxRateLimiter;
-import com.android.server.os.TombstoneProtos;
-import com.android.server.os.TombstoneProtos.Tombstone;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -62,14 +60,11 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermissions;
-import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
/**
* Performs a number of miscellaneous, non-system-critical actions
@@ -332,12 +327,12 @@ public class BootReceiver extends BroadcastReceiver {
*
* @param ctx Context
* @param tombstone path to the tombstone
- * @param tombstoneProto the parsed proto tombstone
+ * @param proto whether the tombstone is stored as proto
* @param processName the name of the process corresponding to the tombstone
* @param tmpFileLock the lock for reading/writing tmp files
*/
public static void addTombstoneToDropBox(
- Context ctx, File tombstone, Tombstone tombstoneProto, String processName,
+ Context ctx, File tombstone, boolean proto, String processName,
ReentrantLock tmpFileLock) {
final DropBoxManager db = ctx.getSystemService(DropBoxManager.class);
if (db == null) {
@@ -347,33 +342,31 @@ public class BootReceiver extends BroadcastReceiver {
// Check if we should rate limit and abort early if needed.
DropboxRateLimiter.RateLimitResult rateLimitResult =
- sDropboxRateLimiter.shouldRateLimit(TAG_TOMBSTONE_PROTO_WITH_HEADERS, processName);
+ sDropboxRateLimiter.shouldRateLimit(
+ proto ? TAG_TOMBSTONE_PROTO_WITH_HEADERS : TAG_TOMBSTONE, processName);
if (rateLimitResult.shouldRateLimit()) return;
HashMap<String, Long> timestamps = readTimestamps();
try {
- // Remove the memory data from the proto.
- Tombstone tombstoneProtoWithoutMemory = removeMemoryFromTombstone(tombstoneProto);
-
- final byte[] tombstoneBytes = tombstoneProtoWithoutMemory.toByteArray();
-
- // Use JNI to call the c++ proto to text converter and add the headers to the tombstone.
- String tombstoneWithoutMemory = new StringBuilder(getBootHeadersToLogAndUpdate())
- .append(rateLimitResult.createHeader())
- .append(getTombstoneText(tombstoneBytes))
- .toString();
-
- // Add the tombstone without memory data to dropbox.
- db.addText(TAG_TOMBSTONE, tombstoneWithoutMemory);
-
- // Add the tombstone proto to dropbox.
- if (recordFileTimestamp(tombstone, timestamps)) {
- tmpFileLock.lock();
- try {
- addAugmentedProtoToDropbox(tombstone, tombstoneBytes, db, rateLimitResult);
- } finally {
- tmpFileLock.unlock();
+ if (proto) {
+ if (recordFileTimestamp(tombstone, timestamps)) {
+ // We need to attach the count indicating the number of dropped dropbox entries
+ // due to rate limiting. Do this by enclosing the proto tombsstone in a
+ // container proto that has the dropped entry count and the proto tombstone as
+ // bytes (to avoid the complexity of reading and writing nested protos).
+ tmpFileLock.lock();
+ try {
+ addAugmentedProtoToDropbox(tombstone, db, rateLimitResult);
+ } finally {
+ tmpFileLock.unlock();
+ }
}
+ } else {
+ // Add the header indicating how many events have been dropped due to rate limiting.
+ final String headers = getBootHeadersToLogAndUpdate()
+ + rateLimitResult.createHeader();
+ addFileToDropBox(db, timestamps, headers, tombstone.getPath(), LOG_SIZE,
+ TAG_TOMBSTONE);
}
} catch (IOException e) {
Slog.e(TAG, "Can't log tombstone", e);
@@ -382,8 +375,11 @@ public class BootReceiver extends BroadcastReceiver {
}
private static void addAugmentedProtoToDropbox(
- File tombstone, byte[] tombstoneBytes, DropBoxManager db,
+ File tombstone, DropBoxManager db,
DropboxRateLimiter.RateLimitResult rateLimitResult) throws IOException {
+ // Read the proto tombstone file as bytes.
+ final byte[] tombstoneBytes = Files.readAllBytes(tombstone.toPath());
+
final File tombstoneProtoWithHeaders = File.createTempFile(
tombstone.getName(), ".tmp", TOMBSTONE_TMP_DIR);
Files.setPosixFilePermissions(
@@ -416,8 +412,6 @@ public class BootReceiver extends BroadcastReceiver {
}
}
- private static native String getTombstoneText(byte[] tombstoneBytes);
-
private static void addLastkToDropBox(
DropBoxManager db, HashMap<String, Long> timestamps,
String headers, String footers, String filename, int maxSize,
@@ -435,31 +429,6 @@ public class BootReceiver extends BroadcastReceiver {
addFileWithFootersToDropBox(db, timestamps, headers, footers, filename, maxSize, tag);
}
- /** Removes memory information from the Tombstone proto. */
- @VisibleForTesting
- public static Tombstone removeMemoryFromTombstone(Tombstone tombstoneProto) {
- Tombstone.Builder tombstoneBuilder = tombstoneProto.toBuilder()
- .clearMemoryMappings()
- .clearThreads()
- .putAllThreads(tombstoneProto.getThreadsMap().entrySet()
- .stream()
- .map(BootReceiver::clearMemoryDump)
- .collect(Collectors.toMap(e->e.getKey(), e->e.getValue())));
-
- if (tombstoneProto.hasSignalInfo()) {
- tombstoneBuilder.setSignalInfo(
- tombstoneProto.getSignalInfo().toBuilder().clearFaultAdjacentMetadata());
- }
-
- return tombstoneBuilder.build();
- }
-
- private static AbstractMap.SimpleEntry<Integer, TombstoneProtos.Thread> clearMemoryDump(
- Map.Entry<Integer, TombstoneProtos.Thread> e) {
- return new AbstractMap.SimpleEntry<Integer, TombstoneProtos.Thread>(
- e.getKey(), e.getValue().toBuilder().clearMemoryDump().build());
- }
-
private static void addFileToDropBox(
DropBoxManager db, HashMap<String, Long> timestamps,
String headers, String filename, int maxSize, String tag) throws IOException {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index 4d19eade5a05..d7188c7f10c6 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -42,7 +42,6 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
-import com.android.internal.annotations.Keep;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.RingBuffer;
import com.android.server.am.ProcessList;
@@ -414,7 +413,7 @@ public class NetworkPolicyLogger {
private static final Date sDate = new Date();
public LogBuffer(int capacity) {
- super(Data.class, capacity);
+ super(Data::new, Data[]::new, capacity);
}
public void uidStateChanged(int uid, int procState, long procStateSeq,
@@ -690,12 +689,8 @@ public class NetworkPolicyLogger {
/**
* Container class for all networkpolicy events data.
- *
- * Note: This class needs to be public for RingBuffer class to be able to create
- * new instances of this.
*/
- @Keep
- public static final class Data {
+ private static final class Data {
public int type;
public long timeStamp;
diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java
index b7e737448d2d..ab0d0d2626db 100644
--- a/services/core/java/com/android/server/os/NativeTombstoneManager.java
+++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java
@@ -41,13 +41,14 @@ import android.system.Os;
import android.system.StructStat;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoParseException;
import com.android.internal.annotations.GuardedBy;
import com.android.server.BootReceiver;
import com.android.server.ServiceThread;
import com.android.server.os.TombstoneProtos.Cause;
import com.android.server.os.TombstoneProtos.Tombstone;
-import com.android.server.os.protobuf.CodedInputStream;
import libcore.io.IoUtils;
@@ -127,21 +128,18 @@ public final class NativeTombstoneManager {
return;
}
+ String processName = "UNKNOWN";
final boolean isProtoFile = filename.endsWith(".pb");
- if (!isProtoFile) {
- return;
- }
+ File protoPath = isProtoFile ? path : new File(path.getAbsolutePath() + ".pb");
- Optional<ParsedTombstone> parsedTombstone = handleProtoTombstone(path, true);
+ Optional<TombstoneFile> parsedTombstone = handleProtoTombstone(protoPath, isProtoFile);
if (parsedTombstone.isPresent()) {
- BootReceiver.addTombstoneToDropBox(
- mContext, path, parsedTombstone.get().getTombstone(),
- parsedTombstone.get().getProcessName(), mTmpFileLock);
+ processName = parsedTombstone.get().getProcessName();
}
+ BootReceiver.addTombstoneToDropBox(mContext, path, isProtoFile, processName, mTmpFileLock);
}
- private Optional<ParsedTombstone> handleProtoTombstone(
- File path, boolean addToList) {
+ private Optional<TombstoneFile> handleProtoTombstone(File path, boolean addToList) {
final String filename = path.getName();
if (!filename.endsWith(".pb")) {
Slog.w(TAG, "unexpected tombstone name: " + path);
@@ -171,7 +169,7 @@ public final class NativeTombstoneManager {
return Optional.empty();
}
- final Optional<ParsedTombstone> parsedTombstone = TombstoneFile.parse(pfd);
+ final Optional<TombstoneFile> parsedTombstone = TombstoneFile.parse(pfd);
if (!parsedTombstone.isPresent()) {
IoUtils.closeQuietly(pfd);
return Optional.empty();
@@ -184,7 +182,7 @@ public final class NativeTombstoneManager {
previous.dispose();
}
- mTombstones.put(number, parsedTombstone.get().getTombstoneFile());
+ mTombstones.put(number, parsedTombstone.get());
}
}
@@ -332,27 +330,6 @@ public final class NativeTombstoneManager {
}
}
- static class ParsedTombstone {
- TombstoneFile mTombstoneFile;
- Tombstone mTombstone;
- ParsedTombstone(TombstoneFile tombstoneFile, Tombstone tombstone) {
- mTombstoneFile = tombstoneFile;
- mTombstone = tombstone;
- }
-
- public String getProcessName() {
- return mTombstoneFile.getProcessName();
- }
-
- public TombstoneFile getTombstoneFile() {
- return mTombstoneFile;
- }
-
- public Tombstone getTombstone() {
- return mTombstone;
- }
- }
-
static class TombstoneFile {
final ParcelFileDescriptor mPfd;
@@ -435,21 +412,67 @@ public final class NativeTombstoneManager {
}
}
- static Optional<ParsedTombstone> parse(ParcelFileDescriptor pfd) {
- Tombstone tombstoneProto;
- try (FileInputStream is = new FileInputStream(pfd.getFileDescriptor())) {
- final byte[] tombstoneBytes = is.readAllBytes();
+ static Optional<TombstoneFile> parse(ParcelFileDescriptor pfd) {
+ final FileInputStream is = new FileInputStream(pfd.getFileDescriptor());
+ final ProtoInputStream stream = new ProtoInputStream(is);
+
+ int pid = 0;
+ int uid = 0;
+ String processName = null;
+ String crashReason = "";
+ String selinuxLabel = "";
+
+ try {
+ while (stream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ switch (stream.getFieldNumber()) {
+ case (int) Tombstone.PID:
+ pid = stream.readInt(Tombstone.PID);
+ break;
+
+ case (int) Tombstone.UID:
+ uid = stream.readInt(Tombstone.UID);
+ break;
+
+ case (int) Tombstone.COMMAND_LINE:
+ if (processName == null) {
+ processName = stream.readString(Tombstone.COMMAND_LINE);
+ }
+ break;
- tombstoneProto = Tombstone.parseFrom(
- CodedInputStream.newInstance(tombstoneBytes));
- } catch (IOException ex) {
+ case (int) Tombstone.CAUSES:
+ if (!crashReason.equals("")) {
+ // Causes appear in decreasing order of likelihood. For now we only
+ // want the most likely crash reason here, so ignore all others.
+ break;
+ }
+ long token = stream.start(Tombstone.CAUSES);
+ cause:
+ while (stream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ switch (stream.getFieldNumber()) {
+ case (int) Cause.HUMAN_READABLE:
+ crashReason = stream.readString(Cause.HUMAN_READABLE);
+ break cause;
+
+ default:
+ break;
+ }
+ }
+ stream.end(token);
+ break;
+
+ case (int) Tombstone.SELINUX_LABEL:
+ selinuxLabel = stream.readString(Tombstone.SELINUX_LABEL);
+ break;
+
+ default:
+ break;
+ }
+ }
+ } catch (IOException | ProtoParseException ex) {
Slog.e(TAG, "Failed to parse tombstone", ex);
return Optional.empty();
}
- int pid = tombstoneProto.getPid();
- int uid = tombstoneProto.getUid();
-
if (!UserHandle.isApp(uid)) {
Slog.e(TAG, "Tombstone's UID (" + uid + ") not an app, ignoring");
return Optional.empty();
@@ -466,7 +489,6 @@ public final class NativeTombstoneManager {
final int userId = UserHandle.getUserId(uid);
final int appId = UserHandle.getAppId(uid);
- String selinuxLabel = tombstoneProto.getSelinuxLabel();
if (!selinuxLabel.startsWith("u:r:untrusted_app")) {
Slog.e(TAG, "Tombstone has invalid selinux label (" + selinuxLabel + "), ignoring");
return Optional.empty();
@@ -478,30 +500,11 @@ public final class NativeTombstoneManager {
result.mAppId = appId;
result.mPid = pid;
result.mUid = uid;
- result.mProcessName = getCmdLineProcessName(tombstoneProto);
+ result.mProcessName = processName == null ? "" : processName;
result.mTimestampMs = timestampMs;
- result.mCrashReason = getCrashReason(tombstoneProto);
+ result.mCrashReason = crashReason;
- return Optional.of(new ParsedTombstone(result, tombstoneProto));
- }
-
- private static String getCmdLineProcessName(Tombstone tombstoneProto) {
- for (String cmdline : tombstoneProto.getCommandLineList()) {
- if (cmdline != null) {
- return cmdline;
- }
- }
- return "";
- }
-
- private static String getCrashReason(Tombstone tombstoneProto) {
- for (Cause cause : tombstoneProto.getCausesList()) {
- if (cause.getHumanReadable() != null
- && !cause.getHumanReadable().equals("")) {
- return cause.getHumanReadable();
- }
- }
- return "";
+ return Optional.of(result);
}
public IParcelFileDescriptorRetriever getPfdRetriever() {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index ed9445c26740..ba8a76c9ddde 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -44,6 +44,9 @@ import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
+import android.hardware.biometrics.SensorProperties;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -157,6 +160,8 @@ public class TrustManagerService extends SystemService {
private final LockPatternUtils mLockPatternUtils;
private final UserManager mUserManager;
private final ActivityManager mActivityManager;
+ private FingerprintManager mFingerprintManager;
+ private FaceManager mFaceManager;
private VirtualDeviceManagerInternal mVirtualDeviceManager;
private enum TrustState {
@@ -294,6 +299,8 @@ public class TrustManagerService extends SystemService {
mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
mReceiver.register(mContext);
mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
+ mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
+ mFaceManager = mContext.getSystemService(FaceManager.class);
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
mTrustAgentsCanRun = true;
refreshAgentList(UserHandle.USER_ALL);
@@ -895,7 +902,19 @@ public class TrustManagerService extends SystemService {
private void notifyKeystoreOfDeviceLockState(int userId, boolean isLocked) {
if (isLocked) {
- Authorization.onDeviceLocked(userId, getBiometricSids(userId));
+ if (android.security.Flags.fixUnlockedDeviceRequiredKeysV2()) {
+ // A profile with unified challenge is unlockable not by its own biometrics and
+ // trust agents, but rather by those of the parent user. Therefore, when protecting
+ // the profile's UnlockedDeviceRequired keys, we must use the parent's list of
+ // biometric SIDs and weak unlock methods, not the profile's.
+ int authUserId = mLockPatternUtils.isProfileWithUnifiedChallenge(userId)
+ ? resolveProfileParent(userId) : userId;
+
+ Authorization.onDeviceLocked(userId, getBiometricSids(authUserId),
+ isWeakUnlockMethodEnabled(authUserId));
+ } else {
+ Authorization.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
@@ -1442,16 +1461,59 @@ public class TrustManagerService extends SystemService {
if (biometricManager == null) {
return new long[0];
}
- if (android.security.Flags.fixUnlockedDeviceRequiredKeysV2()
- && mLockPatternUtils.isProfileWithUnifiedChallenge(userId)) {
- // Profiles with unified challenge have their own set of biometrics, but the device
- // unlock happens via the parent user. In this case Keystore needs to be given the list
- // of biometric SIDs from the parent user, not the profile.
- userId = resolveProfileParent(userId);
- }
return biometricManager.getAuthenticatorIds(userId);
}
+ // Returns whether the device can become unlocked for the specified user via one of that user's
+ // non-strong biometrics or trust agents. This assumes that the device is currently locked, or
+ // is becoming locked, for the user.
+ private boolean isWeakUnlockMethodEnabled(int userId) {
+
+ // Check whether the system currently allows the use of non-strong biometrics for the user,
+ // *and* the user actually has a non-strong biometric enrolled.
+ //
+ // The biometrics framework ostensibly supports multiple sensors per modality. However,
+ // that feature is unused and untested. So, we simply consider one sensor per modality.
+ //
+ // Also, currently we just consider fingerprint and face, matching Keyguard. If Keyguard
+ // starts supporting other biometric modalities, this will need to be updated.
+ if (mStrongAuthTracker.isBiometricAllowedForUser(/* isStrongBiometric= */ false, userId)) {
+ DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
+ int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userId);
+
+ if (mFingerprintManager != null
+ && (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) == 0
+ && mFingerprintManager.hasEnrolledTemplates(userId)
+ && isWeakOrConvenienceSensor(
+ mFingerprintManager.getSensorProperties().get(0))) {
+ Slog.i(TAG, "User is unlockable by non-strong fingerprint auth");
+ return true;
+ }
+
+ if (mFaceManager != null
+ && (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_FACE) == 0
+ && mFaceManager.hasEnrolledTemplates(userId)
+ && isWeakOrConvenienceSensor(mFaceManager.getSensorProperties().get(0))) {
+ Slog.i(TAG, "User is unlockable by non-strong face auth");
+ return true;
+ }
+ }
+
+ // Check whether it's possible for the device to be actively unlocked by a trust agent.
+ if (getUserTrustStateInner(userId) == TrustState.TRUSTABLE
+ || (isAutomotive() && isTrustUsuallyManagedInternal(userId))) {
+ Slog.i(TAG, "User is unlockable by trust agent");
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean isWeakOrConvenienceSensor(SensorProperties sensor) {
+ return sensor.getSensorStrength() == SensorProperties.STRENGTH_WEAK
+ || sensor.getSensorStrength() == SensorProperties.STRENGTH_CONVENIENCE;
+ }
+
// User lifecycle
@Override
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 591a55972b81..8cd55c7dd506 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -37,7 +37,6 @@ cc_library_static {
"com_android_server_adb_AdbDebuggingManager.cpp",
"com_android_server_am_BatteryStatsService.cpp",
"com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp",
- "com_android_server_BootReceiver.cpp",
"com_android_server_ConsumerIrService.cpp",
"com_android_server_companion_virtual_InputController.cpp",
"com_android_server_devicepolicy_CryptoTestHelper.cpp",
@@ -92,16 +91,6 @@ cc_library_static {
header_libs: [
"bionic_libc_platform_headers",
],
-
- static_libs: [
- "libunwindstack",
- ],
-
- whole_static_libs: [
- "libdebuggerd_tombstone_proto_to_text",
- ],
-
- runtime_libs: ["libdexfile"],
}
cc_defaults {
diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS
index 33d3686ee9ce..d4f6312d19d9 100644
--- a/services/core/jni/OWNERS
+++ b/services/core/jni/OWNERS
@@ -32,7 +32,3 @@ per-file com_android_server_companion_virtual_InputController.cpp = file:/servic
# Bug component : 158088 = per-file *AnrTimer*
per-file *AnrTimer* = file:/PERFORMANCE_OWNERS
-
-# Bug component : 158088 = per-file com_android_server_utils_AnrTimer*.java
-per-file com_android_server_utils_AnrTimer*.java = file:/PERFORMANCE_OWNERS
-per-file com_android_server_BootReceiver.cpp = file:/STABILITY_OWNERS
diff --git a/services/core/jni/com_android_server_BootReceiver.cpp b/services/core/jni/com_android_server_BootReceiver.cpp
deleted file mode 100644
index 3892d284dafb..000000000000
--- a/services/core/jni/com_android_server_BootReceiver.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2023 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.
- */
-
-#include <libdebuggerd/tombstone.h>
-#include <nativehelper/JNIHelp.h>
-
-#include <sstream>
-
-#include "jni.h"
-#include "tombstone.pb.h"
-
-namespace android {
-
-static void writeToString(std::stringstream& ss, const std::string& line, bool should_log) {
- ss << line << std::endl;
-}
-
-static jstring com_android_server_BootReceiver_getTombstoneText(JNIEnv* env, jobject,
- jbyteArray tombstoneBytes) {
- Tombstone tombstone;
- tombstone.ParseFromArray(env->GetByteArrayElements(tombstoneBytes, 0),
- env->GetArrayLength(tombstoneBytes));
-
- std::stringstream tombstoneString;
-
- tombstone_proto_to_text(tombstone,
- std::bind(&writeToString, std::ref(tombstoneString),
- std::placeholders::_1, std::placeholders::_2));
-
- return env->NewStringUTF(tombstoneString.str().c_str());
-}
-
-static const JNINativeMethod sMethods[] = {
- /* name, signature, funcPtr */
- {"getTombstoneText", "([B)Ljava/lang/String;",
- (jstring*)com_android_server_BootReceiver_getTombstoneText},
-};
-
-int register_com_android_server_BootReceiver(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "com/android/server/BootReceiver", sMethods,
- NELEM(sMethods));
-}
-
-} // namespace android
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index e7de081bd5f8..a87902fe03c5 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -63,7 +63,6 @@ int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env);
int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env);
int register_android_server_companion_virtual_InputController(JNIEnv* env);
int register_android_server_app_GameManagerService(JNIEnv* env);
-int register_com_android_server_BootReceiver(JNIEnv* env);
int register_com_android_server_wm_TaskFpsCallbackController(JNIEnv* env);
int register_com_android_server_display_DisplayControl(JNIEnv* env);
int register_com_android_server_SystemClockTime(JNIEnv* env);
@@ -123,7 +122,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_sensor_SensorService(vm, env);
register_android_server_companion_virtual_InputController(env);
register_android_server_app_GameManagerService(env);
- register_com_android_server_BootReceiver(env);
register_com_android_server_wm_TaskFpsCallbackController(env);
register_com_android_server_display_DisplayControl(env);
register_com_android_server_SystemClockTime(env);
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 37ca09d9fa27..b41568298dbc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
@@ -47,6 +47,10 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.SensorProperties;
+import android.hardware.face.FaceManager;
+import android.hardware.face.FaceSensorProperties;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -69,6 +73,7 @@ import android.view.WindowManagerGlobal;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -105,6 +110,8 @@ public class TrustManagerServiceTest {
private static final String URI_SCHEME_PACKAGE = "package";
private static final int TEST_USER_ID = 50;
+ private static final UserInfo TEST_USER =
+ new UserInfo(TEST_USER_ID, "user", UserInfo.FLAG_FULL);
private static final int PARENT_USER_ID = 60;
private static final int PROFILE_USER_ID = 70;
private static final long[] PARENT_BIOMETRIC_SIDS = new long[] { 600L, 601L };
@@ -117,6 +124,8 @@ public class TrustManagerServiceTest {
private @Mock ActivityManager mActivityManager;
private @Mock BiometricManager mBiometricManager;
private @Mock DevicePolicyManager mDevicePolicyManager;
+ private @Mock FaceManager mFaceManager;
+ private @Mock FingerprintManager mFingerprintManager;
private @Mock IKeystoreAuthorization mKeystoreAuthorization;
private @Mock LockPatternUtils mLockPatternUtils;
private @Mock PackageManager mPackageManager;
@@ -133,6 +142,9 @@ public class TrustManagerServiceTest {
when(mActivityManager.isUserRunning(TEST_USER_ID)).thenReturn(true);
doReturn(mock(IActivityManager.class)).when(() -> ActivityManager.getService());
+ when(mFaceManager.getSensorProperties()).thenReturn(List.of());
+ when(mFingerprintManager.getSensorProperties()).thenReturn(List.of());
+
doReturn(mKeystoreAuthorization).when(() -> Authorization.getService());
when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
@@ -161,13 +173,16 @@ public class TrustManagerServiceTest {
when(mPackageManager.checkPermission(any(), any())).thenReturn(
PackageManager.PERMISSION_GRANTED);
- when(mUserManager.getAliveUsers()).thenReturn(
- List.of(new UserInfo(TEST_USER_ID, "user", UserInfo.FLAG_FULL)));
+ when(mUserManager.getAliveUsers()).thenReturn(List.of(TEST_USER));
+ when(mUserManager.getEnabledProfileIds(TEST_USER_ID)).thenReturn(new int[0]);
+ when(mUserManager.getUserInfo(TEST_USER_ID)).thenReturn(TEST_USER);
when(mWindowManager.isKeyguardLocked()).thenReturn(true);
mMockContext.addMockSystemService(ActivityManager.class, mActivityManager);
mMockContext.addMockSystemService(BiometricManager.class, mBiometricManager);
+ mMockContext.addMockSystemService(FaceManager.class, mFaceManager);
+ mMockContext.addMockSystemService(FingerprintManager.class, mFingerprintManager);
mMockContext.setMockPackageManager(mPackageManager);
mMockContext.addMockSystemService(UserManager.class, mUserManager);
doReturn(mWindowManager).when(() -> WindowManagerGlobal.getWindowManagerService());
@@ -362,9 +377,9 @@ public class TrustManagerServiceTest {
when(mWindowManager.isKeyguardLocked()).thenReturn(true);
mTrustManager.reportKeyguardShowingChanged();
verify(mKeystoreAuthorization)
- .onDeviceLocked(eq(PARENT_USER_ID), eq(PARENT_BIOMETRIC_SIDS));
+ .onDeviceLocked(eq(PARENT_USER_ID), eq(PARENT_BIOMETRIC_SIDS), eq(false));
verify(mKeystoreAuthorization)
- .onDeviceLocked(eq(PROFILE_USER_ID), eq(PARENT_BIOMETRIC_SIDS));
+ .onDeviceLocked(eq(PROFILE_USER_ID), eq(PARENT_BIOMETRIC_SIDS), eq(false));
}
// Tests that when the device is locked for a managed profile with a *separate* challenge, the
@@ -381,7 +396,188 @@ public class TrustManagerServiceTest {
mTrustManager.setDeviceLockedForUser(PROFILE_USER_ID, true);
verify(mKeystoreAuthorization)
- .onDeviceLocked(eq(PROFILE_USER_ID), eq(PROFILE_BIOMETRIC_SIDS));
+ .onDeviceLocked(eq(PROFILE_USER_ID), eq(PROFILE_BIOMETRIC_SIDS), eq(false));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockEnabled_whenWeakFingerprintIsSetupAndAllowed()
+ throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFingerprint(SensorProperties.STRENGTH_WEAK);
+ verifyWeakUnlockEnabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockEnabled_whenWeakFaceIsSetupAndAllowed() throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFace(SensorProperties.STRENGTH_WEAK);
+ verifyWeakUnlockEnabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockEnabled_whenConvenienceFingerprintIsSetupAndAllowed()
+ throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFingerprint(SensorProperties.STRENGTH_CONVENIENCE);
+ verifyWeakUnlockEnabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockEnabled_whenConvenienceFaceIsSetupAndAllowed()
+ throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFace(SensorProperties.STRENGTH_CONVENIENCE);
+ verifyWeakUnlockEnabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockDisabled_whenStrongAuthRequired() throws Exception {
+ setupStrongAuthTracker(StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN, true);
+ setupFace(SensorProperties.STRENGTH_WEAK);
+ verifyWeakUnlockDisabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockDisabled_whenNonStrongBiometricNotAllowed() throws Exception {
+ setupStrongAuthTracker(StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED,
+ /* isNonStrongBiometricAllowed= */ false);
+ setupFace(SensorProperties.STRENGTH_WEAK);
+ verifyWeakUnlockDisabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockDisabled_whenWeakFingerprintSensorIsPresentButNotEnrolled()
+ throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFingerprint(SensorProperties.STRENGTH_WEAK, /* enrolled= */ false);
+ verifyWeakUnlockDisabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockDisabled_whenWeakFaceSensorIsPresentButNotEnrolled()
+ throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFace(SensorProperties.STRENGTH_WEAK, /* enrolled= */ false);
+ verifyWeakUnlockDisabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void
+ testKeystoreWeakUnlockDisabled_whenWeakFingerprintIsSetupButForbiddenByDevicePolicy()
+ throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFingerprint(SensorProperties.STRENGTH_WEAK);
+ when(mDevicePolicyManager.getKeyguardDisabledFeatures(null, TEST_USER_ID))
+ .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
+ verifyWeakUnlockDisabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockDisabled_whenWeakFaceIsSetupButForbiddenByDevicePolicy()
+ throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFace(SensorProperties.STRENGTH_WEAK);
+ when(mDevicePolicyManager.getKeyguardDisabledFeatures(null, TEST_USER_ID))
+ .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FACE);
+ verifyWeakUnlockDisabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockDisabled_whenOnlyStrongFingerprintIsSetup() throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFingerprint(SensorProperties.STRENGTH_STRONG);
+ verifyWeakUnlockDisabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockDisabled_whenOnlyStrongFaceIsSetup() throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ setupFace(SensorProperties.STRENGTH_STRONG);
+ verifyWeakUnlockDisabled();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2)
+ public void testKeystoreWeakUnlockDisabled_whenNoBiometricsAreSetup() throws Exception {
+ setupStrongAuthTrackerToAllowEverything();
+ verifyWeakUnlockDisabled();
+ }
+
+ private void setupStrongAuthTrackerToAllowEverything() throws Exception {
+ setupStrongAuthTracker(StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED, true);
+ }
+
+ private void setupStrongAuthTracker(int strongAuthFlags, boolean isNonStrongBiometricAllowed)
+ throws Exception {
+ bootService();
+ mService.onUserSwitching(null, new SystemService.TargetUser(TEST_USER));
+
+ ArgumentCaptor<StrongAuthTracker> strongAuthTracker =
+ ArgumentCaptor.forClass(StrongAuthTracker.class);
+ verify(mLockPatternUtils).registerStrongAuthTracker(strongAuthTracker.capture());
+ strongAuthTracker.getValue().getStub().onStrongAuthRequiredChanged(
+ strongAuthFlags, TEST_USER_ID);
+ strongAuthTracker.getValue().getStub().onIsNonStrongBiometricAllowedChanged(
+ isNonStrongBiometricAllowed, TEST_USER_ID);
+ mService.waitForIdle();
+ }
+
+ private void setupFingerprint(int strength) {
+ setupFingerprint(strength, /* enrolled= */ true);
+ }
+
+ private void setupFingerprint(int strength, boolean enrolled) {
+ int sensorId = 100;
+ List<SensorProperties.ComponentInfo> componentInfo = List.of();
+ SensorProperties sensor = new SensorProperties(sensorId, strength, componentInfo);
+ when(mFingerprintManager.getSensorProperties()).thenReturn(List.of(sensor));
+ when(mFingerprintManager.hasEnrolledTemplates(TEST_USER_ID)).thenReturn(enrolled);
+ }
+
+ private void setupFace(int strength) {
+ setupFace(strength, /* enrolled= */ true);
+ }
+
+ private void setupFace(int strength, boolean enrolled) {
+ int sensorId = 100;
+ List<SensorProperties.ComponentInfo> componentInfo = List.of();
+ FaceSensorProperties sensor = new FaceSensorProperties(
+ sensorId, strength, componentInfo, FaceSensorProperties.TYPE_RGB);
+ when(mFaceManager.getSensorProperties()).thenReturn(List.of(sensor));
+ when(mFaceManager.hasEnrolledTemplates(TEST_USER_ID)).thenReturn(enrolled);
+ }
+
+ private void verifyWeakUnlockEnabled() throws Exception {
+ verifyWeakUnlockValue(true);
+ }
+
+ private void verifyWeakUnlockDisabled() throws Exception {
+ verifyWeakUnlockValue(false);
+ }
+
+ // Simulates a device unlock and a device lock, then verifies that the expected
+ // weakUnlockEnabled flag was passed to Keystore's onDeviceLocked method.
+ private void verifyWeakUnlockValue(boolean expectedWeakUnlockEnabled) throws Exception {
+ when(mWindowManager.isKeyguardLocked()).thenReturn(false);
+ mTrustManager.reportKeyguardShowingChanged();
+ verify(mKeystoreAuthorization).onDeviceUnlocked(TEST_USER_ID, null);
+
+ when(mWindowManager.isKeyguardLocked()).thenReturn(true);
+ mTrustManager.reportKeyguardShowingChanged();
+ verify(mKeystoreAuthorization).onDeviceLocked(eq(TEST_USER_ID), any(),
+ eq(expectedWeakUnlockEnabled));
}
private void setupMocksForProfile(boolean unifiedChallenge) {
diff --git a/services/tests/servicestests/src/com/android/server/BootReceiverTest.java b/services/tests/servicestests/src/com/android/server/BootReceiverTest.java
deleted file mode 100644
index 523c5c060cf5..000000000000
--- a/services/tests/servicestests/src/com/android/server/BootReceiverTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.test.AndroidTestCase;
-
-import com.android.server.os.TombstoneProtos;
-import com.android.server.os.TombstoneProtos.Tombstone;
-
-public class BootReceiverTest extends AndroidTestCase {
- private static final String TAG = "BootReceiverTest";
-
- public void testRemoveMemoryFromTombstone() {
- Tombstone tombstoneBase = Tombstone.newBuilder()
- .setBuildFingerprint("build_fingerprint")
- .setRevision("revision")
- .setPid(123)
- .setTid(23)
- .setUid(34)
- .setSelinuxLabel("selinux_label")
- .addCommandLine("cmd1")
- .addCommandLine("cmd2")
- .addCommandLine("cmd3")
- .setProcessUptime(300)
- .setAbortMessage("abort")
- .addCauses(TombstoneProtos.Cause.newBuilder()
- .setHumanReadable("cause1")
- .setMemoryError(TombstoneProtos.MemoryError.newBuilder()
- .setTool(TombstoneProtos.MemoryError.Tool.SCUDO)
- .setType(TombstoneProtos.MemoryError.Type.DOUBLE_FREE)))
- .addLogBuffers(TombstoneProtos.LogBuffer.newBuilder().setName("name").addLogs(
- TombstoneProtos.LogMessage.newBuilder()
- .setTimestamp("123")
- .setMessage("message")))
- .addOpenFds(TombstoneProtos.FD.newBuilder().setFd(1).setPath("path"))
- .build();
-
- Tombstone tombstoneWithoutMemory = tombstoneBase.toBuilder()
- .putThreads(1, TombstoneProtos.Thread.newBuilder()
- .setId(1)
- .setName("thread1")
- .addRegisters(TombstoneProtos.Register.newBuilder().setName("r1").setU64(1))
- .addRegisters(TombstoneProtos.Register.newBuilder().setName("r2").setU64(2))
- .addBacktraceNote("backtracenote1")
- .addUnreadableElfFiles("files1")
- .setTaggedAddrCtrl(1)
- .setPacEnabledKeys(10)
- .build())
- .build();
-
- Tombstone tombstoneWithMemory = tombstoneBase.toBuilder()
- .addMemoryMappings(TombstoneProtos.MemoryMapping.newBuilder()
- .setBeginAddress(1)
- .setEndAddress(100)
- .setOffset(10)
- .setRead(true)
- .setWrite(true)
- .setExecute(false)
- .setMappingName("mapping")
- .setBuildId("build")
- .setLoadBias(70))
- .putThreads(1, TombstoneProtos.Thread.newBuilder()
- .setId(1)
- .setName("thread1")
- .addRegisters(TombstoneProtos.Register.newBuilder().setName("r1").setU64(1))
- .addRegisters(TombstoneProtos.Register.newBuilder().setName("r2").setU64(2))
- .addBacktraceNote("backtracenote1")
- .addUnreadableElfFiles("files1")
- .addMemoryDump(TombstoneProtos.MemoryDump.newBuilder()
- .setRegisterName("register1")
- .setMappingName("mapping")
- .setBeginAddress(10))
- .setTaggedAddrCtrl(1)
- .setPacEnabledKeys(10)
- .build())
- .build();
-
- assertThat(BootReceiver.removeMemoryFromTombstone(tombstoneWithMemory))
- .isEqualTo(tombstoneWithoutMemory);
- }
-}
diff --git a/services/usage/java/com/android/server/usage/BroadcastResponseStatsLogger.java b/services/usage/java/com/android/server/usage/BroadcastResponseStatsLogger.java
index 336bfdd0fb14..a8fd6f29f862 100644
--- a/services/usage/java/com/android/server/usage/BroadcastResponseStatsLogger.java
+++ b/services/usage/java/com/android/server/usage/BroadcastResponseStatsLogger.java
@@ -35,11 +35,13 @@ import android.util.Slog;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.Keep;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.RingBuffer;
import com.android.server.usage.BroadcastResponseStatsTracker.NotificationEventType;
+import java.util.function.IntFunction;
+import java.util.function.Supplier;
+
public class BroadcastResponseStatsLogger {
private static final int MAX_LOG_SIZE =
@@ -49,10 +51,10 @@ public class BroadcastResponseStatsLogger {
@GuardedBy("mLock")
private final LogBuffer mBroadcastEventsBuffer = new LogBuffer(
- BroadcastEvent.class, MAX_LOG_SIZE);
+ BroadcastEvent::new, BroadcastEvent[]::new, MAX_LOG_SIZE);
@GuardedBy("mLock")
private final LogBuffer mNotificationEventsBuffer = new LogBuffer(
- NotificationEvent.class, MAX_LOG_SIZE);
+ NotificationEvent::new, NotificationEvent[]::new, MAX_LOG_SIZE);
void logBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage,
UserHandle targetUser, long idForResponseEvent,
@@ -96,8 +98,8 @@ public class BroadcastResponseStatsLogger {
private static final class LogBuffer<T extends Data> extends RingBuffer<T> {
- LogBuffer(Class<T> classType, int capacity) {
- super(classType, capacity);
+ LogBuffer(Supplier<T> newItem, IntFunction<T[]> newBacking, int capacity) {
+ super(newItem, newBacking, capacity);
}
void logBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage,
@@ -179,8 +181,7 @@ public class BroadcastResponseStatsLogger {
}
}
- @Keep
- public static final class BroadcastEvent implements Data {
+ private static final class BroadcastEvent implements Data {
public int sourceUid;
public int targetUserId;
public int targetUidProcessState;
@@ -200,8 +201,7 @@ public class BroadcastResponseStatsLogger {
}
}
- @Keep
- public static final class NotificationEvent implements Data {
+ private static final class NotificationEvent implements Data {
public int type;
public String packageName;
public int userId;
@@ -218,7 +218,7 @@ public class BroadcastResponseStatsLogger {
}
}
- public interface Data {
+ private interface Data {
void reset();
}
}
diff --git a/test-base/Android.bp b/test-base/Android.bp
index 527159a78ebf..70a95400bd9e 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -120,12 +120,13 @@ filegroup {
path: "src",
}
-// Make the current.txt available for use by the cts/tests/signature tests.
+// Make the current.txt available for use by the cts/tests/signature and /vendor tests.
// ========================================================================
filegroup {
name: "android-test-base-current.txt",
visibility: [
"//cts/tests/signature/api",
+ "//vendor:__subpackages__",
],
srcs: [
"api/current.txt",
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 22320fd53631..7c4d12e338a5 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -54,12 +54,13 @@ java_sdk_library {
dist_group: "android",
}
-// Make the current.txt available for use by the cts/tests/signature tests.
+// Make the current.txt available for use by the cts/tests/signature and /vendor tests.
// ========================================================================
filegroup {
name: "android-test-mock-current.txt",
visibility: [
"//cts/tests/signature/api",
+ "//vendor:__subpackages__",
],
srcs: [
"api/current.txt",
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index 13a5dac9eb38..21e09d3221ce 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -79,12 +79,13 @@ java_library {
],
}
-// Make the current.txt available for use by the cts/tests/signature tests.
+// Make the current.txt available for use by the cts/tests/signature and /vendor tests.
// ========================================================================
filegroup {
name: "android-test-runner-current.txt",
visibility: [
"//cts/tests/signature/api",
+ "//vendor:__subpackages__",
],
srcs: [
"api/current.txt",