Loading core/java/android/content/ContentCaptureOptions.java +189 −36 Original line number Diff line number Diff line Loading @@ -75,6 +75,20 @@ public final class ContentCaptureOptions implements Parcelable { */ public final boolean disableFlushForViewTreeAppearing; /** * Is the content capture receiver enabled. * * @hide */ public final boolean enableReceiver; /** * Options for the content protection flow. * * @hide */ @NonNull public final ContentProtectionOptions contentProtectionOptions; /** * List of activities explicitly allowlisted for content capture (or {@code null} if allowlisted * for all acitivites in the package). Loading @@ -94,52 +108,99 @@ public final class ContentCaptureOptions implements Parcelable { * for contexts belonging to the content capture service app. */ public ContentCaptureOptions(int loggingLevel) { this(/* lite= */ true, loggingLevel, /* maxBufferSize= */ 0, /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0, /* logHistorySize= */ 0, /* disableFlushForViewTreeAppearing= */ false, this( /* lite= */ true, loggingLevel, /* maxBufferSize= */ 0, /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0, /* logHistorySize= */ 0, /* disableFlushForViewTreeAppearing= */ false, /* enableReceiver= */ false, new ContentProtectionOptions( /* enableReceiver= */ false, /* bufferSize= */ 0), /* whitelistedComponents= */ null); } /** * Default constructor. */ public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, /** Default constructor. */ public ContentCaptureOptions( int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this( /* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, ContentCaptureManager.DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING, ContentCaptureManager.DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER, new ContentProtectionOptions( ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER, ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE), whitelistedComponents); } /** @hide */ public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, public ContentCaptureOptions( int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, boolean disableFlushForViewTreeAppearing, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing, boolean enableReceiver, @NonNull ContentProtectionOptions contentProtectionOptions, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this( /* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing, enableReceiver, contentProtectionOptions, whitelistedComponents); } /** @hide */ @VisibleForTesting public ContentCaptureOptions(@Nullable ArraySet<ComponentName> whitelistedComponents) { this(ContentCaptureManager.LOGGING_LEVEL_VERBOSE, this( ContentCaptureManager.LOGGING_LEVEL_VERBOSE, ContentCaptureManager.DEFAULT_MAX_BUFFER_SIZE, ContentCaptureManager.DEFAULT_IDLE_FLUSHING_FREQUENCY_MS, ContentCaptureManager.DEFAULT_TEXT_CHANGE_FLUSHING_FREQUENCY_MS, ContentCaptureManager.DEFAULT_LOG_HISTORY_SIZE, ContentCaptureManager.DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING, ContentCaptureManager.DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER, new ContentProtectionOptions( ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER, ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE), whitelistedComponents); } private ContentCaptureOptions(boolean lite, int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, private ContentCaptureOptions( boolean lite, int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, boolean disableFlushForViewTreeAppearing, @Nullable ArraySet<ComponentName> whitelistedComponents) { boolean enableReceiver, @NonNull ContentProtectionOptions contentProtectionOptions, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this.lite = lite; this.loggingLevel = loggingLevel; this.maxBufferSize = maxBufferSize; Loading @@ -147,6 +208,8 @@ public final class ContentCaptureOptions implements Parcelable { this.textChangeFlushingFrequencyMs = textChangeFlushingFrequencyMs; this.logHistorySize = logHistorySize; this.disableFlushForViewTreeAppearing = disableFlushForViewTreeAppearing; this.enableReceiver = enableReceiver; this.contentProtectionOptions = contentProtectionOptions; this.whitelistedComponents = whitelistedComponents; } Loading Loading @@ -191,12 +254,22 @@ public final class ContentCaptureOptions implements Parcelable { return "ContentCaptureOptions [loggingLevel=" + loggingLevel + " (lite)]"; } final StringBuilder string = new StringBuilder("ContentCaptureOptions ["); string.append("loggingLevel=").append(loggingLevel) .append(", maxBufferSize=").append(maxBufferSize) .append(", idleFlushingFrequencyMs=").append(idleFlushingFrequencyMs) .append(", textChangeFlushingFrequencyMs=").append(textChangeFlushingFrequencyMs) .append(", logHistorySize=").append(logHistorySize) .append(", disableFlushForViewTreeAppearing=").append(disableFlushForViewTreeAppearing); string.append("loggingLevel=") .append(loggingLevel) .append(", maxBufferSize=") .append(maxBufferSize) .append(", idleFlushingFrequencyMs=") .append(idleFlushingFrequencyMs) .append(", textChangeFlushingFrequencyMs=") .append(textChangeFlushingFrequencyMs) .append(", logHistorySize=") .append(logHistorySize) .append(", disableFlushForViewTreeAppearing=") .append(disableFlushForViewTreeAppearing) .append(", enableReceiver=") .append(enableReceiver) .append(", contentProtectionOptions=") .append(contentProtectionOptions); if (whitelistedComponents != null) { string.append(", whitelisted=").append(whitelistedComponents); } Loading @@ -210,11 +283,21 @@ public final class ContentCaptureOptions implements Parcelable { pw.print(", lite"); return; } pw.print(", bufferSize="); pw.print(maxBufferSize); pw.print(", idle="); pw.print(idleFlushingFrequencyMs); pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs); pw.print(", logSize="); pw.print(logHistorySize); pw.print(", disableFlushForViewTreeAppearing="); pw.print(disableFlushForViewTreeAppearing); pw.print(", bufferSize="); pw.print(maxBufferSize); pw.print(", idle="); pw.print(idleFlushingFrequencyMs); pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs); pw.print(", logSize="); pw.print(logHistorySize); pw.print(", disableFlushForViewTreeAppearing="); pw.print(disableFlushForViewTreeAppearing); pw.print(", enableReceiver="); pw.print(enableReceiver); pw.print(", contentProtectionOptions=["); contentProtectionOptions.dumpShort(pw); pw.print("]"); if (whitelistedComponents != null) { pw.print(", whitelisted="); pw.print(whitelistedComponents); } Loading @@ -236,6 +319,8 @@ public final class ContentCaptureOptions implements Parcelable { parcel.writeInt(textChangeFlushingFrequencyMs); parcel.writeInt(logHistorySize); parcel.writeBoolean(disableFlushForViewTreeAppearing); parcel.writeBoolean(enableReceiver); contentProtectionOptions.writeToParcel(parcel); parcel.writeArraySet(whitelistedComponents); } Loading @@ -254,12 +339,22 @@ public final class ContentCaptureOptions implements Parcelable { final int textChangeFlushingFrequencyMs = parcel.readInt(); final int logHistorySize = parcel.readInt(); final boolean disableFlushForViewTreeAppearing = parcel.readBoolean(); final boolean enableReceiver = parcel.readBoolean(); final ContentProtectionOptions contentProtectionOptions = ContentProtectionOptions.createFromParcel(parcel); @SuppressWarnings("unchecked") final ArraySet<ComponentName> whitelistedComponents = (ArraySet<ComponentName>) parcel.readArraySet(null); return new ContentCaptureOptions(loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing, whitelistedComponents); return new ContentCaptureOptions( loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing, enableReceiver, contentProtectionOptions, whitelistedComponents); } @Override Loading @@ -267,4 +362,62 @@ public final class ContentCaptureOptions implements Parcelable { return new ContentCaptureOptions[size]; } }; /** * Content protection options for a given package. * * <p>Does not implement {@code Parcelable} since it is an inner class without a matching AIDL. * * @hide */ public static class ContentProtectionOptions { /** * Is the content protection receiver enabled. * * @hide */ public final boolean enableReceiver; /** * Size of the in-memory ring buffer for the content protection flow. * * @hide */ public final int bufferSize; public ContentProtectionOptions(boolean enableReceiver, int bufferSize) { this.enableReceiver = enableReceiver; this.bufferSize = bufferSize; } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder("ContentProtectionOptions ["); stringBuilder .append("enableReceiver=") .append(enableReceiver) .append(", bufferSize=") .append(bufferSize); return stringBuilder.append(']').toString(); } private void dumpShort(@NonNull PrintWriter pw) { pw.print("enableReceiver="); pw.print(enableReceiver); pw.print(", bufferSize="); pw.print(bufferSize); } private void writeToParcel(Parcel parcel) { parcel.writeBoolean(enableReceiver); parcel.writeInt(bufferSize); } private static ContentProtectionOptions createFromParcel(Parcel parcel) { boolean enableReceiver = parcel.readBoolean(); int bufferSize = parcel.readInt(); return new ContentProtectionOptions(enableReceiver, bufferSize); } } } core/java/android/service/wallpaper/WallpaperService.java +1 −1 Original line number Diff line number Diff line Loading @@ -1391,7 +1391,7 @@ public abstract class WallpaperService extends Service { Trace.endSection(); } if (redrawNeeded) { if (redrawNeeded || sizeChanged) { Trace.beginSection("WPMS.Engine.onSurfaceRedrawNeeded"); onSurfaceRedrawNeeded(mSurfaceHolder); Trace.endSection(); Loading core/java/android/view/contentcapture/ContentCaptureManager.java +36 −3 Original line number Diff line number Diff line Loading @@ -352,6 +352,30 @@ public final class ContentCaptureManager { public static final String DEVICE_CONFIG_PROPERTY_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING = "disable_flush_for_view_tree_appearing"; /** * Enables the content protection receiver. * * @hide */ public static final String DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER = "enable_content_protection_receiver"; /** * Sets the size of the app blocklist for the content protection flow. * * @hide */ public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = "content_protection_apps_blocklist_size"; /** * Sets the size of the in-memory ring buffer for the content protection flow. * * @hide */ public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE = "content_protection_buffer_size"; /** @hide */ @TestApi public static final int LOGGING_LEVEL_OFF = 0; Loading Loading @@ -384,6 +408,14 @@ public final class ContentCaptureManager { public static final int DEFAULT_LOG_HISTORY_SIZE = 10; /** @hide */ public static final boolean DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING = false; /** @hide */ public static final boolean DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER = true; /** @hide */ public static final boolean DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER = false; /** @hide */ public static final int DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = 1000; /** @hide */ public static final int DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE = 150; private final Object mLock = new Object(); Loading Loading @@ -425,11 +457,11 @@ public final class ContentCaptureManager { /** @hide */ static class StrippedContext { final String mPackageName; final String mContext; @NonNull final String mPackageName; @NonNull final String mContext; final @UserIdInt int mUserId; private StrippedContext(Context context) { private StrippedContext(@NonNull Context context) { mPackageName = context.getPackageName(); mContext = context.toString(); mUserId = context.getUserId(); Loading @@ -440,6 +472,7 @@ public final class ContentCaptureManager { return mContext; } @NonNull public String getPackageName() { return mPackageName; } Loading core/java/android/view/contentprotection/ContentProtectionUtils.java 0 → 100644 +60 −0 Original line number Diff line number Diff line /* * 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 android.view.contentprotection; import android.annotation.NonNull; import android.annotation.Nullable; import android.view.contentcapture.ContentCaptureEvent; import android.view.contentcapture.ViewNode; /** * Utilities for reading data from {@link ContentCaptureEvent} and {@link ViewNode}. * * @hide */ public final class ContentProtectionUtils { /** Returns the text extracted directly from the {@link ContentCaptureEvent}, if set. */ @Nullable public static String getEventText(@NonNull ContentCaptureEvent event) { CharSequence text = event.getText(); if (text == null) { return null; } return text.toString(); } /** Returns the text extracted from the event's {@link ViewNode}, if set. */ @Nullable public static String getViewNodeText(@NonNull ContentCaptureEvent event) { ViewNode viewNode = event.getViewNode(); if (viewNode == null) { return null; } return getViewNodeText(viewNode); } /** Returns the text extracted directly from the {@link ViewNode}, if set. */ @Nullable public static String getViewNodeText(@NonNull ViewNode viewNode) { CharSequence text = viewNode.getText(); if (text == null) { return null; } return text.toString(); } } core/java/android/window/SnapshotDrawerUtils.java +27 −6 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_AT import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES; import static com.android.internal.policy.DecorView.getNavigationBarRect; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityThread; Loading Loading @@ -183,7 +184,7 @@ public class SnapshotDrawerUtils { // We consider nearly matched dimensions as there can be rounding errors and the user // won't notice very minute differences from scaling one dimension more than the other final boolean aspectRatioMismatch = !isAspectRatioMatch(mFrame, mSnapshot); boolean aspectRatioMismatch = !isAspectRatioMatch(mFrame, mSnapshot); // Keep a reference to it such that it doesn't get destroyed when finalized. SurfaceControl childSurfaceControl = new SurfaceControl.Builder(session) Loading @@ -198,9 +199,21 @@ public class SnapshotDrawerUtils { // We can just show the surface here as it will still be hidden as the parent is // still hidden. mTransaction.show(childSurfaceControl); if (aspectRatioMismatch) { Rect crop = null; final Rect letterboxInsets = mSnapshot.getLetterboxInsets(); if (letterboxInsets.left != 0 || letterboxInsets.top != 0 || letterboxInsets.right != 0 || letterboxInsets.bottom != 0) { // Clip off letterbox. crop = calculateSnapshotCrop(letterboxInsets); // If the snapshot can cover the frame, then no need to draw background. aspectRatioMismatch = !isAspectRatioMatch(mFrame, crop); } // if letterbox doesn't match window frame, try crop by content insets if (aspectRatioMismatch) { // Clip off ugly navigation bar. final Rect crop = calculateSnapshotCrop(); crop = calculateSnapshotCrop(mSnapshot.getContentInsets()); } frame = calculateSnapshotFrame(crop); mTransaction.setWindowCrop(childSurfaceControl, crop); mTransaction.setPosition(childSurfaceControl, frame.left, frame.top); Loading Loading @@ -242,14 +255,13 @@ public class SnapshotDrawerUtils { /** * Calculates the snapshot crop in snapshot coordinate space. * * @param insets Content insets or Letterbox insets * @return crop rect in snapshot coordinate space. */ Rect calculateSnapshotCrop() { Rect calculateSnapshotCrop(@NonNull Rect insets) { final Rect rect = new Rect(); final HardwareBuffer snapshot = mSnapshot.getHardwareBuffer(); rect.set(0, 0, snapshot.getWidth(), snapshot.getHeight()); final Rect insets = mSnapshot.getContentInsets(); final float scaleX = (float) snapshot.getWidth() / mSnapshot.getTaskSize().x; final float scaleY = (float) snapshot.getHeight() / mSnapshot.getTaskSize().y; Loading Loading @@ -334,6 +346,15 @@ public class SnapshotDrawerUtils { - ((float) frame.width() / frame.height())) <= 0.01f; } private static boolean isAspectRatioMatch(Rect frame1, Rect frame2) { if (frame1.isEmpty() || frame2.isEmpty()) { return false; } return Math.abs( ((float) frame2.width() / frame2.height()) - ((float) frame1.width() / frame1.height())) <= 0.01f; } /** * Get or create a TaskDescription from a RunningTaskInfo. */ Loading Loading
core/java/android/content/ContentCaptureOptions.java +189 −36 Original line number Diff line number Diff line Loading @@ -75,6 +75,20 @@ public final class ContentCaptureOptions implements Parcelable { */ public final boolean disableFlushForViewTreeAppearing; /** * Is the content capture receiver enabled. * * @hide */ public final boolean enableReceiver; /** * Options for the content protection flow. * * @hide */ @NonNull public final ContentProtectionOptions contentProtectionOptions; /** * List of activities explicitly allowlisted for content capture (or {@code null} if allowlisted * for all acitivites in the package). Loading @@ -94,52 +108,99 @@ public final class ContentCaptureOptions implements Parcelable { * for contexts belonging to the content capture service app. */ public ContentCaptureOptions(int loggingLevel) { this(/* lite= */ true, loggingLevel, /* maxBufferSize= */ 0, /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0, /* logHistorySize= */ 0, /* disableFlushForViewTreeAppearing= */ false, this( /* lite= */ true, loggingLevel, /* maxBufferSize= */ 0, /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0, /* logHistorySize= */ 0, /* disableFlushForViewTreeAppearing= */ false, /* enableReceiver= */ false, new ContentProtectionOptions( /* enableReceiver= */ false, /* bufferSize= */ 0), /* whitelistedComponents= */ null); } /** * Default constructor. */ public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, /** Default constructor. */ public ContentCaptureOptions( int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this( /* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, ContentCaptureManager.DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING, ContentCaptureManager.DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER, new ContentProtectionOptions( ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER, ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE), whitelistedComponents); } /** @hide */ public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, public ContentCaptureOptions( int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, boolean disableFlushForViewTreeAppearing, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing, boolean enableReceiver, @NonNull ContentProtectionOptions contentProtectionOptions, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this( /* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing, enableReceiver, contentProtectionOptions, whitelistedComponents); } /** @hide */ @VisibleForTesting public ContentCaptureOptions(@Nullable ArraySet<ComponentName> whitelistedComponents) { this(ContentCaptureManager.LOGGING_LEVEL_VERBOSE, this( ContentCaptureManager.LOGGING_LEVEL_VERBOSE, ContentCaptureManager.DEFAULT_MAX_BUFFER_SIZE, ContentCaptureManager.DEFAULT_IDLE_FLUSHING_FREQUENCY_MS, ContentCaptureManager.DEFAULT_TEXT_CHANGE_FLUSHING_FREQUENCY_MS, ContentCaptureManager.DEFAULT_LOG_HISTORY_SIZE, ContentCaptureManager.DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING, ContentCaptureManager.DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER, new ContentProtectionOptions( ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER, ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE), whitelistedComponents); } private ContentCaptureOptions(boolean lite, int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, private ContentCaptureOptions( boolean lite, int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, boolean disableFlushForViewTreeAppearing, @Nullable ArraySet<ComponentName> whitelistedComponents) { boolean enableReceiver, @NonNull ContentProtectionOptions contentProtectionOptions, @SuppressLint({"ConcreteCollection", "NullableCollection"}) @Nullable ArraySet<ComponentName> whitelistedComponents) { this.lite = lite; this.loggingLevel = loggingLevel; this.maxBufferSize = maxBufferSize; Loading @@ -147,6 +208,8 @@ public final class ContentCaptureOptions implements Parcelable { this.textChangeFlushingFrequencyMs = textChangeFlushingFrequencyMs; this.logHistorySize = logHistorySize; this.disableFlushForViewTreeAppearing = disableFlushForViewTreeAppearing; this.enableReceiver = enableReceiver; this.contentProtectionOptions = contentProtectionOptions; this.whitelistedComponents = whitelistedComponents; } Loading Loading @@ -191,12 +254,22 @@ public final class ContentCaptureOptions implements Parcelable { return "ContentCaptureOptions [loggingLevel=" + loggingLevel + " (lite)]"; } final StringBuilder string = new StringBuilder("ContentCaptureOptions ["); string.append("loggingLevel=").append(loggingLevel) .append(", maxBufferSize=").append(maxBufferSize) .append(", idleFlushingFrequencyMs=").append(idleFlushingFrequencyMs) .append(", textChangeFlushingFrequencyMs=").append(textChangeFlushingFrequencyMs) .append(", logHistorySize=").append(logHistorySize) .append(", disableFlushForViewTreeAppearing=").append(disableFlushForViewTreeAppearing); string.append("loggingLevel=") .append(loggingLevel) .append(", maxBufferSize=") .append(maxBufferSize) .append(", idleFlushingFrequencyMs=") .append(idleFlushingFrequencyMs) .append(", textChangeFlushingFrequencyMs=") .append(textChangeFlushingFrequencyMs) .append(", logHistorySize=") .append(logHistorySize) .append(", disableFlushForViewTreeAppearing=") .append(disableFlushForViewTreeAppearing) .append(", enableReceiver=") .append(enableReceiver) .append(", contentProtectionOptions=") .append(contentProtectionOptions); if (whitelistedComponents != null) { string.append(", whitelisted=").append(whitelistedComponents); } Loading @@ -210,11 +283,21 @@ public final class ContentCaptureOptions implements Parcelable { pw.print(", lite"); return; } pw.print(", bufferSize="); pw.print(maxBufferSize); pw.print(", idle="); pw.print(idleFlushingFrequencyMs); pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs); pw.print(", logSize="); pw.print(logHistorySize); pw.print(", disableFlushForViewTreeAppearing="); pw.print(disableFlushForViewTreeAppearing); pw.print(", bufferSize="); pw.print(maxBufferSize); pw.print(", idle="); pw.print(idleFlushingFrequencyMs); pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs); pw.print(", logSize="); pw.print(logHistorySize); pw.print(", disableFlushForViewTreeAppearing="); pw.print(disableFlushForViewTreeAppearing); pw.print(", enableReceiver="); pw.print(enableReceiver); pw.print(", contentProtectionOptions=["); contentProtectionOptions.dumpShort(pw); pw.print("]"); if (whitelistedComponents != null) { pw.print(", whitelisted="); pw.print(whitelistedComponents); } Loading @@ -236,6 +319,8 @@ public final class ContentCaptureOptions implements Parcelable { parcel.writeInt(textChangeFlushingFrequencyMs); parcel.writeInt(logHistorySize); parcel.writeBoolean(disableFlushForViewTreeAppearing); parcel.writeBoolean(enableReceiver); contentProtectionOptions.writeToParcel(parcel); parcel.writeArraySet(whitelistedComponents); } Loading @@ -254,12 +339,22 @@ public final class ContentCaptureOptions implements Parcelable { final int textChangeFlushingFrequencyMs = parcel.readInt(); final int logHistorySize = parcel.readInt(); final boolean disableFlushForViewTreeAppearing = parcel.readBoolean(); final boolean enableReceiver = parcel.readBoolean(); final ContentProtectionOptions contentProtectionOptions = ContentProtectionOptions.createFromParcel(parcel); @SuppressWarnings("unchecked") final ArraySet<ComponentName> whitelistedComponents = (ArraySet<ComponentName>) parcel.readArraySet(null); return new ContentCaptureOptions(loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing, whitelistedComponents); return new ContentCaptureOptions( loggingLevel, maxBufferSize, idleFlushingFrequencyMs, textChangeFlushingFrequencyMs, logHistorySize, disableFlushForViewTreeAppearing, enableReceiver, contentProtectionOptions, whitelistedComponents); } @Override Loading @@ -267,4 +362,62 @@ public final class ContentCaptureOptions implements Parcelable { return new ContentCaptureOptions[size]; } }; /** * Content protection options for a given package. * * <p>Does not implement {@code Parcelable} since it is an inner class without a matching AIDL. * * @hide */ public static class ContentProtectionOptions { /** * Is the content protection receiver enabled. * * @hide */ public final boolean enableReceiver; /** * Size of the in-memory ring buffer for the content protection flow. * * @hide */ public final int bufferSize; public ContentProtectionOptions(boolean enableReceiver, int bufferSize) { this.enableReceiver = enableReceiver; this.bufferSize = bufferSize; } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder("ContentProtectionOptions ["); stringBuilder .append("enableReceiver=") .append(enableReceiver) .append(", bufferSize=") .append(bufferSize); return stringBuilder.append(']').toString(); } private void dumpShort(@NonNull PrintWriter pw) { pw.print("enableReceiver="); pw.print(enableReceiver); pw.print(", bufferSize="); pw.print(bufferSize); } private void writeToParcel(Parcel parcel) { parcel.writeBoolean(enableReceiver); parcel.writeInt(bufferSize); } private static ContentProtectionOptions createFromParcel(Parcel parcel) { boolean enableReceiver = parcel.readBoolean(); int bufferSize = parcel.readInt(); return new ContentProtectionOptions(enableReceiver, bufferSize); } } }
core/java/android/service/wallpaper/WallpaperService.java +1 −1 Original line number Diff line number Diff line Loading @@ -1391,7 +1391,7 @@ public abstract class WallpaperService extends Service { Trace.endSection(); } if (redrawNeeded) { if (redrawNeeded || sizeChanged) { Trace.beginSection("WPMS.Engine.onSurfaceRedrawNeeded"); onSurfaceRedrawNeeded(mSurfaceHolder); Trace.endSection(); Loading
core/java/android/view/contentcapture/ContentCaptureManager.java +36 −3 Original line number Diff line number Diff line Loading @@ -352,6 +352,30 @@ public final class ContentCaptureManager { public static final String DEVICE_CONFIG_PROPERTY_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING = "disable_flush_for_view_tree_appearing"; /** * Enables the content protection receiver. * * @hide */ public static final String DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER = "enable_content_protection_receiver"; /** * Sets the size of the app blocklist for the content protection flow. * * @hide */ public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = "content_protection_apps_blocklist_size"; /** * Sets the size of the in-memory ring buffer for the content protection flow. * * @hide */ public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE = "content_protection_buffer_size"; /** @hide */ @TestApi public static final int LOGGING_LEVEL_OFF = 0; Loading Loading @@ -384,6 +408,14 @@ public final class ContentCaptureManager { public static final int DEFAULT_LOG_HISTORY_SIZE = 10; /** @hide */ public static final boolean DEFAULT_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING = false; /** @hide */ public static final boolean DEFAULT_ENABLE_CONTENT_CAPTURE_RECEIVER = true; /** @hide */ public static final boolean DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER = false; /** @hide */ public static final int DEFAULT_CONTENT_PROTECTION_APPS_BLOCKLIST_SIZE = 1000; /** @hide */ public static final int DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE = 150; private final Object mLock = new Object(); Loading Loading @@ -425,11 +457,11 @@ public final class ContentCaptureManager { /** @hide */ static class StrippedContext { final String mPackageName; final String mContext; @NonNull final String mPackageName; @NonNull final String mContext; final @UserIdInt int mUserId; private StrippedContext(Context context) { private StrippedContext(@NonNull Context context) { mPackageName = context.getPackageName(); mContext = context.toString(); mUserId = context.getUserId(); Loading @@ -440,6 +472,7 @@ public final class ContentCaptureManager { return mContext; } @NonNull public String getPackageName() { return mPackageName; } Loading
core/java/android/view/contentprotection/ContentProtectionUtils.java 0 → 100644 +60 −0 Original line number Diff line number Diff line /* * 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 android.view.contentprotection; import android.annotation.NonNull; import android.annotation.Nullable; import android.view.contentcapture.ContentCaptureEvent; import android.view.contentcapture.ViewNode; /** * Utilities for reading data from {@link ContentCaptureEvent} and {@link ViewNode}. * * @hide */ public final class ContentProtectionUtils { /** Returns the text extracted directly from the {@link ContentCaptureEvent}, if set. */ @Nullable public static String getEventText(@NonNull ContentCaptureEvent event) { CharSequence text = event.getText(); if (text == null) { return null; } return text.toString(); } /** Returns the text extracted from the event's {@link ViewNode}, if set. */ @Nullable public static String getViewNodeText(@NonNull ContentCaptureEvent event) { ViewNode viewNode = event.getViewNode(); if (viewNode == null) { return null; } return getViewNodeText(viewNode); } /** Returns the text extracted directly from the {@link ViewNode}, if set. */ @Nullable public static String getViewNodeText(@NonNull ViewNode viewNode) { CharSequence text = viewNode.getText(); if (text == null) { return null; } return text.toString(); } }
core/java/android/window/SnapshotDrawerUtils.java +27 −6 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_AT import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES; import static com.android.internal.policy.DecorView.getNavigationBarRect; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityThread; Loading Loading @@ -183,7 +184,7 @@ public class SnapshotDrawerUtils { // We consider nearly matched dimensions as there can be rounding errors and the user // won't notice very minute differences from scaling one dimension more than the other final boolean aspectRatioMismatch = !isAspectRatioMatch(mFrame, mSnapshot); boolean aspectRatioMismatch = !isAspectRatioMatch(mFrame, mSnapshot); // Keep a reference to it such that it doesn't get destroyed when finalized. SurfaceControl childSurfaceControl = new SurfaceControl.Builder(session) Loading @@ -198,9 +199,21 @@ public class SnapshotDrawerUtils { // We can just show the surface here as it will still be hidden as the parent is // still hidden. mTransaction.show(childSurfaceControl); if (aspectRatioMismatch) { Rect crop = null; final Rect letterboxInsets = mSnapshot.getLetterboxInsets(); if (letterboxInsets.left != 0 || letterboxInsets.top != 0 || letterboxInsets.right != 0 || letterboxInsets.bottom != 0) { // Clip off letterbox. crop = calculateSnapshotCrop(letterboxInsets); // If the snapshot can cover the frame, then no need to draw background. aspectRatioMismatch = !isAspectRatioMatch(mFrame, crop); } // if letterbox doesn't match window frame, try crop by content insets if (aspectRatioMismatch) { // Clip off ugly navigation bar. final Rect crop = calculateSnapshotCrop(); crop = calculateSnapshotCrop(mSnapshot.getContentInsets()); } frame = calculateSnapshotFrame(crop); mTransaction.setWindowCrop(childSurfaceControl, crop); mTransaction.setPosition(childSurfaceControl, frame.left, frame.top); Loading Loading @@ -242,14 +255,13 @@ public class SnapshotDrawerUtils { /** * Calculates the snapshot crop in snapshot coordinate space. * * @param insets Content insets or Letterbox insets * @return crop rect in snapshot coordinate space. */ Rect calculateSnapshotCrop() { Rect calculateSnapshotCrop(@NonNull Rect insets) { final Rect rect = new Rect(); final HardwareBuffer snapshot = mSnapshot.getHardwareBuffer(); rect.set(0, 0, snapshot.getWidth(), snapshot.getHeight()); final Rect insets = mSnapshot.getContentInsets(); final float scaleX = (float) snapshot.getWidth() / mSnapshot.getTaskSize().x; final float scaleY = (float) snapshot.getHeight() / mSnapshot.getTaskSize().y; Loading Loading @@ -334,6 +346,15 @@ public class SnapshotDrawerUtils { - ((float) frame.width() / frame.height())) <= 0.01f; } private static boolean isAspectRatioMatch(Rect frame1, Rect frame2) { if (frame1.isEmpty() || frame2.isEmpty()) { return false; } return Math.abs( ((float) frame2.width() / frame2.height()) - ((float) frame1.width() / frame1.height())) <= 0.01f; } /** * Get or create a TaskDescription from a RunningTaskInfo. */ Loading