diff options
126 files changed, 971 insertions, 461 deletions
diff --git a/Android.bp b/Android.bp index 41d5f28a2680..cbc67d0e3e20 100644 --- a/Android.bp +++ b/Android.bp @@ -290,7 +290,6 @@ java_defaults { "core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl", "core/java/android/service/gatekeeper/IGateKeeperService.aidl", "core/java/android/service/intelligence/IIntelligenceService.aidl", - "core/java/android/service/notification/INotificationListener.aidl", "core/java/android/service/notification/IStatusBarNotificationHolder.aidl", "core/java/android/service/notification/IConditionListener.aidl", diff --git a/api/current.txt b/api/current.txt index 03e01604a483..3967896d76fe 100644 --- a/api/current.txt +++ b/api/current.txt @@ -37297,6 +37297,7 @@ package android.provider { method public static java.lang.String getVolumeName(android.net.Uri); method public static android.provider.MediaStore.PendingSession openPending(android.content.Context, android.net.Uri); method public static android.net.Uri setIncludePending(android.net.Uri); + method public static android.net.Uri setRequireOriginal(android.net.Uri); field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE"; field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE"; field public static final java.lang.String ACTION_REVIEW = "android.provider.action.REVIEW"; @@ -51966,8 +51967,8 @@ package android.view.inputmethod { package android.view.intelligence { - public final class IntelligenceManager { - method public android.content.ComponentName getIntelligenceServiceComponentName(); + public final class ContentCaptureManager { + method public android.content.ComponentName getServiceComponentName(); method public boolean isContentCaptureEnabled(); method public android.view.ViewStructure newVirtualViewStructure(android.view.autofill.AutofillId, int); method public void notifyViewAppeared(android.view.ViewStructure); diff --git a/api/system-current.txt b/api/system-current.txt index 62d446f7254e..7a2c233d8e3b 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -25,7 +25,6 @@ package android { field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH"; field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE"; field public static final java.lang.String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE"; - field public static final java.lang.String BIND_INTELLIGENCE_SERVICE = "android.permission.BIND_INTELLIGENCE_SERVICE"; field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET"; field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE"; field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"; @@ -34,6 +33,7 @@ package android { field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE"; field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE"; field public static final java.lang.String BIND_SETTINGS_SUGGESTIONS_SERVICE = "android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE"; + field public static final java.lang.String BIND_SMART_SUGGESTIONS_SERVICE = "android.permission.BIND_SMART_SUGGESTIONS_SERVICE"; field public static final java.lang.String BIND_SOUND_TRIGGER_DETECTION_SERVICE = "android.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE"; field public static final java.lang.String BIND_TELEPHONY_DATA_SERVICE = "android.permission.BIND_TELEPHONY_DATA_SERVICE"; field public static final java.lang.String BIND_TELEPHONY_NETWORK_SERVICE = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE"; @@ -4980,6 +4980,13 @@ package android.service.euicc { package android.service.intelligence { + public final class ContentCaptureEventsRequest implements android.os.Parcelable { + method public int describeContents(); + method public java.util.List<android.view.intelligence.ContentCaptureEvent> getEvents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.service.intelligence.ContentCaptureEventsRequest> CREATOR; + } + public final class FillCallback { method public void onSuccess(android.service.intelligence.FillResponse); } @@ -5014,16 +5021,6 @@ package android.service.intelligence { field public static final long FLAG_METADATA_ADDRESS = 1L; // 0x1L } - public abstract class IntelligenceService extends android.app.Service { - ctor public IntelligenceService(); - method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData); - method public abstract void onContentCaptureEvent(android.service.intelligence.InteractionSessionId, java.util.List<android.view.intelligence.ContentCaptureEvent>); - method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId); - method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId); - method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback); - field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.IntelligenceService"; - } - public final class InteractionContext implements android.os.Parcelable { method public int describeContents(); method public android.content.ComponentName getActivityComponent(); @@ -5059,6 +5056,21 @@ package android.service.intelligence { method public android.service.intelligence.PresentationParams.Area getSubArea(android.graphics.Rect); } + public abstract class SmartSuggestionsService extends android.app.Service { + ctor public SmartSuggestionsService(); + method public final java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities(); + method public final java.util.Set<java.lang.String> getContentCaptureDisabledPackages(); + method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData); + method public abstract void onContentCaptureEventsRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.ContentCaptureEventsRequest); + method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId); + method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId); + method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback); + method public final void setActivityContentCaptureEnabled(android.content.ComponentName, boolean); + method public final void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>); + method public final void setPackageContentCaptureEnabled(java.lang.String, boolean); + field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.SmartSuggestionsService"; + } + public final class SnapshotData implements android.os.Parcelable { method public int describeContents(); method public android.app.assist.AssistContent getAssistContent(); @@ -7243,14 +7255,6 @@ package android.view.intelligence { field public static final int TYPE_VIEW_TEXT_CHANGED = 7; // 0x7 } - public final class IntelligenceManager { - method public java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities(); - method public java.util.Set<java.lang.String> getContentCaptureDisabledPackages(); - method public void setActivityContentCaptureEnabled(android.content.ComponentName, boolean); - method public void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>); - method public void setPackageContentCaptureEnabled(java.lang.String, boolean); - } - public final class ViewNode extends android.app.assist.AssistStructure.ViewNode { method public android.view.autofill.AutofillId getParentAutofillId(); } diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java index 1597c8c9c2b2..52a2ab407f91 100644 --- a/cmds/content/src/com/android/commands/content/Content.java +++ b/cmds/content/src/com/android/commands/content/Content.java @@ -77,7 +77,7 @@ public class Content { + " <BINDING> binds a typed value to a column and is formatted:\n" + " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n" + " <TYPE> specifies data type such as:\n" - + " b - boolean, s - string, i - integer, l - long, f - float, d - double\n" + + " b - boolean, s - string, i - integer, l - long, f - float, d - double, n - null\n" + " Note: Omit the value for passing an empty string, e.g column:s:\n" + " Example:\n" + " # Add \"new_setting\" secure setting with value \"new_value\".\n" @@ -153,6 +153,7 @@ public class Content { private static final String TYPE_LONG = "l"; private static final String TYPE_FLOAT = "f"; private static final String TYPE_DOUBLE = "d"; + private static final String TYPE_NULL = "n"; private static final String COLON = ":"; private static final String ARGUMENT_PREFIX = "--"; @@ -410,6 +411,8 @@ public class Content { values.put(column, Long.parseLong(value)); } else if (TYPE_FLOAT.equalsIgnoreCase(type) || TYPE_DOUBLE.equalsIgnoreCase(type)) { values.put(column, Double.parseDouble(value)); + } else if (TYPE_NULL.equalsIgnoreCase(type)) { + values.putNull(column); } else { throw new IllegalArgumentException("Unsupported type: " + type); } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 05bb9a1c2139..f3f065a27e6f 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -122,7 +122,7 @@ import android.view.autofill.AutofillManager.AutofillClient; import android.view.autofill.AutofillPopupWindow; import android.view.autofill.IAutofillWindowPresenter; import android.view.intelligence.ContentCaptureEvent; -import android.view.intelligence.IntelligenceManager; +import android.view.intelligence.ContentCaptureManager; import android.widget.AdapterView; import android.widget.Toast; import android.widget.Toolbar; @@ -824,8 +824,8 @@ public class Activity extends ContextThemeWrapper /** The autofill manager. Always access via {@link #getAutofillManager()}. */ @Nullable private AutofillManager mAutofillManager; - /** The screen observation manager. Always access via {@link #getIntelligenceManager()}. */ - @Nullable private IntelligenceManager mIntelligenceManager; + /** The content capture manager. Always access via {@link #getContentCaptureManager()}. */ + @Nullable private ContentCaptureManager mContentCaptureManager; private final ArrayList<Application.ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = new ArrayList<Application.ActivityLifecycleCallbacks>(); @@ -1016,39 +1016,39 @@ public class Activity extends ContextThemeWrapper } /** - * (Creates, sets, and ) returns the intelligence manager + * (Creates, sets, and ) returns the content capture manager * - * @return The intelligence manager + * @return The content capture manager */ - @NonNull private IntelligenceManager getIntelligenceManager() { - if (mIntelligenceManager == null) { - mIntelligenceManager = getSystemService(IntelligenceManager.class); + @NonNull private ContentCaptureManager getContentCaptureManager() { + if (mContentCaptureManager == null) { + mContentCaptureManager = getSystemService(ContentCaptureManager.class); } - return mIntelligenceManager; + return mContentCaptureManager; } - private void notifyIntelligenceManagerIfNeeded(@ContentCaptureEvent.EventType int event) { - final IntelligenceManager im = getIntelligenceManager(); - if (im == null || !im.isContentCaptureEnabled()) { + private void notifyContentCaptureManagerIfNeeded(@ContentCaptureEvent.EventType int event) { + final ContentCaptureManager cm = getContentCaptureManager(); + if (cm == null || !cm.isContentCaptureEnabled()) { return; } switch (event) { case ContentCaptureEvent.TYPE_ACTIVITY_CREATED: //TODO(b/111276913): decide whether the InteractionSessionId should be // saved / restored in the activity bundle. - im.onActivityCreated(mToken, getComponentName()); + cm.onActivityCreated(mToken, getComponentName()); break; case ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED: - im.onActivityDestroyed(); + cm.onActivityDestroyed(); break; case ContentCaptureEvent.TYPE_ACTIVITY_STARTED: case ContentCaptureEvent.TYPE_ACTIVITY_RESUMED: case ContentCaptureEvent.TYPE_ACTIVITY_PAUSED: case ContentCaptureEvent.TYPE_ACTIVITY_STOPPED: - im.onActivityLifecycleEvent(event); + cm.onActivityLifecycleEvent(event); break; default: - Log.w(TAG, "notifyIntelligenceManagerIfNeeded(): invalid type " + event); + Log.w(TAG, "notifyContentCaptureManagerIfNeeded(): invalid type " + event); } } @@ -1057,6 +1057,7 @@ public class Activity extends ContextThemeWrapper super.attachBaseContext(newBase); if (newBase != null) { newBase.setAutofillClient(this); + newBase.setContentCaptureSupported(true); } } @@ -1066,6 +1067,12 @@ public class Activity extends ContextThemeWrapper return this; } + /** @hide */ + @Override + public boolean isContentCaptureSupported() { + return true; + } + /** * Register an {@link Application.ActivityLifecycleCallbacks} instance that receives * lifecycle callbacks for only this Activity. @@ -1410,7 +1417,7 @@ public class Activity extends ContextThemeWrapper mRestoredFromBundle = savedInstanceState != null; mCalled = true; - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED); } /** @@ -1644,7 +1651,7 @@ public class Activity extends ContextThemeWrapper if (mAutoFillResetNeeded) { getAutofillManager().onVisibleForAutofill(); } - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED); } /** @@ -1735,7 +1742,7 @@ public class Activity extends ContextThemeWrapper } } } - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED); mCalled = true; } @@ -2129,7 +2136,7 @@ public class Activity extends ContextThemeWrapper mAutoFillIgnoreFirstResumePause = false; } } - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED); mCalled = true; } @@ -2318,7 +2325,7 @@ public class Activity extends ContextThemeWrapper getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL, mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)); } - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED); } } @@ -2390,7 +2397,7 @@ public class Activity extends ContextThemeWrapper dispatchActivityDestroyed(); - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED); } @@ -6806,7 +6813,7 @@ public class Activity extends ContextThemeWrapper } void dumpIntelligenceManager(String prefix, PrintWriter writer) { - final IntelligenceManager im = getIntelligenceManager(); + final ContentCaptureManager im = getContentCaptureManager(); if (im != null) { im.dump(prefix, writer); } else { diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 28ecb27b53d2..6f0b6c8687db 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -217,6 +217,8 @@ class ContextImpl extends Context { private AutofillClient mAutofillClient = null; private boolean mIsAutofillCompatEnabled; + private boolean mIsContentCaptureSupported = false; + private final Object mSync = new Object(); @GuardedBy("mSync") @@ -2376,6 +2378,18 @@ class ContextImpl extends Context { mIsAutofillCompatEnabled = autofillCompatEnabled; } + /** @hide */ + @Override + public boolean isContentCaptureSupported() { + return mIsContentCaptureSupported; + } + + /** @hide */ + @Override + public void setContentCaptureSupported(boolean supported) { + mIsContentCaptureSupported = supported; + } + @UnsupportedAppUsage static ContextImpl createSystemContext(ActivityThread mainThread) { LoadedApk packageInfo = new LoadedApk(mainThread); diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 89ec19bbc6dd..25fa897f2a56 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1424,7 +1424,62 @@ public class NotificationManager { return other.priorityCategories == priorityCategories && other.priorityCallSenders == priorityCallSenders && other.priorityMessageSenders == priorityMessageSenders - && other.suppressedVisualEffects == suppressedVisualEffects; + && suppressedVisualEffectsEqual(suppressedVisualEffects, + other.suppressedVisualEffects); + } + + + private boolean suppressedVisualEffectsEqual(int suppressedEffects, + int otherSuppressedVisualEffects) { + if (suppressedEffects == otherSuppressedVisualEffects) { + return true; + } + + if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) { + suppressedEffects |= SUPPRESSED_EFFECT_PEEK; + } + if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) { + suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT; + suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS; + suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT; + } + + if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) { + otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK; + } + if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) { + otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT; + otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS; + otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT; + } + + if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) + != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) { + int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0 + ? otherSuppressedVisualEffects : suppressedEffects; + if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) { + return false; + } + } + + if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) + != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) { + int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0 + ? otherSuppressedVisualEffects : suppressedEffects; + if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0 + || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0 + || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) { + return false; + } + } + + int thisWithoutOldEffects = suppressedEffects + & ~SUPPRESSED_EFFECT_SCREEN_ON + & ~SUPPRESSED_EFFECT_SCREEN_OFF; + int otherWithoutOldEffects = otherSuppressedVisualEffects + & ~SUPPRESSED_EFFECT_SCREEN_ON + & ~SUPPRESSED_EFFECT_SCREEN_OFF; + return thisWithoutOldEffects == otherWithoutOldEffects; } @Override diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 0123551230b0..dfe371c3248e 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -165,8 +165,8 @@ import android.view.accessibility.CaptioningManager; import android.view.autofill.AutofillManager; import android.view.autofill.IAutoFillManager; import android.view.inputmethod.InputMethodManager; +import android.view.intelligence.ContentCaptureManager; import android.view.intelligence.IIntelligenceManager; -import android.view.intelligence.IntelligenceManager; import android.view.textclassifier.TextClassificationManager; import android.view.textservice.TextServicesManager; @@ -199,6 +199,7 @@ final class SystemServiceRegistry { private SystemServiceRegistry() { } static { + //CHECKSTYLE:OFF IndentationCheck registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class, new CachedServiceFetcher<AccessibilityManager>() { @Override @@ -1050,15 +1051,20 @@ final class SystemServiceRegistry { return new AutofillManager(ctx.getOuterContext(), service); }}); - registerService(Context.INTELLIGENCE_MANAGER_SERVICE, IntelligenceManager.class, - new CachedServiceFetcher<IntelligenceManager>() { + registerService(Context.CONTENT_CAPTURE_MANAGER_SERVICE, ContentCaptureManager.class, + new CachedServiceFetcher<ContentCaptureManager>() { @Override - public IntelligenceManager createService(ContextImpl ctx) + public ContentCaptureManager createService(ContextImpl ctx) throws ServiceNotFoundException { // Get the services without throwing as this is an optional feature - IBinder b = ServiceManager.getService(Context.INTELLIGENCE_MANAGER_SERVICE); - IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b); - return new IntelligenceManager(ctx.getOuterContext(), service); + Context outerContext = ctx.getOuterContext(); + if (outerContext.isContentCaptureSupported()) { + IBinder b = ServiceManager + .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE); + IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b); + return new ContentCaptureManager(outerContext, service); + } + return null; }}); registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() { @@ -1138,6 +1144,7 @@ final class SystemServiceRegistry { throws ServiceNotFoundException { return new RoleManager(ctx.getOuterContext()); }}); + //CHECKSTYLE:ON IndentationCheck } /** diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index ff57b0311d60..68aac642ecb0 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3933,12 +3933,13 @@ public abstract class Context { public static final String AUTOFILL_MANAGER_SERVICE = "autofill"; /** - * Official published name of the intelligence service. + * Official published name of the smart suggestions service. * * @hide * @see #getSystemService(String) */ - public static final String INTELLIGENCE_MANAGER_SERVICE = "intelligence"; + // TODO(b/111276913): rename string (will require SELinux change first) + public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "intelligence"; /** * Use with {@link #getSystemService(String)} to access the @@ -5223,6 +5224,25 @@ public abstract class Context { } /** + * Checks whether this context supports content capture. + * + * @hide + */ + // NOTE: for now we just need to check if it's supported so we can optimize calls that can be + // skipped when it isn't. Eventually, we might need a full + // ContentCaptureManager.ContentCaptureClient interface (as it's done with AutofillClient). + // + public boolean isContentCaptureSupported() { + return false; + } + + /** + * @hide + */ + public void setContentCaptureSupported(@SuppressWarnings("unused") boolean supported) { + } + + /** * Throws an exception if the Context is using system resources, * which are non-runtime-overlay-themable and may show inconsistent UI. * @hide diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 2db44b44fd6c..26ed3b736f80 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -1049,4 +1049,20 @@ public class ContextWrapper extends Context { mBase.setAutofillCompatibilityEnabled(autofillCompatEnabled); } } + + /** + * @hide + */ + @Override + public boolean isContentCaptureSupported() { + return mBase.isContentCaptureSupported(); + } + + /** + * @hide + */ + @Override + public void setContentCaptureSupported(boolean supported) { + mBase.setContentCaptureSupported(supported); + } } diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index 44b9e311dc0b..6de1ff4bc097 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -17,12 +17,6 @@ package android.os; import static android.system.OsConstants.AF_UNIX; -import static android.system.OsConstants.O_APPEND; -import static android.system.OsConstants.O_CREAT; -import static android.system.OsConstants.O_RDONLY; -import static android.system.OsConstants.O_RDWR; -import static android.system.OsConstants.O_TRUNC; -import static android.system.OsConstants.O_WRONLY; import static android.system.OsConstants.SEEK_SET; import static android.system.OsConstants.SOCK_SEQPACKET; import static android.system.OsConstants.SOCK_STREAM; @@ -254,8 +248,16 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { } /** {@hide} */ - public static ParcelFileDescriptor fromFd( - FileDescriptor fd, Handler handler, final OnCloseListener listener) throws IOException { + public static ParcelFileDescriptor fromPfd(ParcelFileDescriptor pfd, Handler handler, + final OnCloseListener listener) throws IOException { + final FileDescriptor original = new FileDescriptor(); + original.setInt$(pfd.detachFd()); + return fromFd(original, handler, listener); + } + + /** {@hide} */ + public static ParcelFileDescriptor fromFd(FileDescriptor fd, Handler handler, + final OnCloseListener listener) throws IOException { if (handler == null) { throw new IllegalArgumentException("Handler must not be null"); } diff --git a/core/java/android/os/RedactingFileDescriptor.java b/core/java/android/os/RedactingFileDescriptor.java index 60eb5c3c4a89..4e5eaac3442f 100644 --- a/core/java/android/os/RedactingFileDescriptor.java +++ b/core/java/android/os/RedactingFileDescriptor.java @@ -20,15 +20,18 @@ import android.content.Context; import android.os.storage.StorageManager; import android.system.ErrnoException; import android.system.Os; -import android.system.OsConstants; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; + import libcore.io.IoUtils; +import libcore.util.EmptyArray; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.InterruptedIOException; +import java.util.Arrays; /** * Variant of {@link FileDescriptor} that allows its creator to specify regions @@ -40,20 +43,21 @@ public class RedactingFileDescriptor { private static final String TAG = "RedactingFileDescriptor"; private static final boolean DEBUG = true; - private final long[] mRedactRanges; + private volatile long[] mRedactRanges; private FileDescriptor mInner = null; private ParcelFileDescriptor mOuter = null; - private RedactingFileDescriptor(Context context, File file, long[] redactRanges) + private RedactingFileDescriptor(Context context, File file, int mode, long[] redactRanges) throws IOException { mRedactRanges = checkRangesArgument(redactRanges); try { try { - mInner = Os.open(file.getAbsolutePath(), OsConstants.O_RDONLY, 0); + mInner = Os.open(file.getAbsolutePath(), + FileUtils.translateModePfdToPosix(mode), 0); mOuter = context.getSystemService(StorageManager.class) - .openProxyFileDescriptor(ParcelFileDescriptor.MODE_READ_ONLY, mCallback); + .openProxyFileDescriptor(mode, mCallback); } catch (ErrnoException e) { throw e.rethrowAsIOException(); } @@ -78,16 +82,61 @@ public class RedactingFileDescriptor { /** * Open the given {@link File} and returns a {@link ParcelFileDescriptor} - * that offers a redacted, read-only view of the underlying data. + * that offers a redacted view of the underlying data. If a redacted region + * is written to, the newly written data can be read back correctly instead + * of continuing to be redacted. * * @param file The underlying file to open. + * @param mode The {@link ParcelFileDescriptor} mode to open with. * @param redactRanges List of file offsets that should be redacted, stored * as {@code [start1, end1, start2, end2, ...]}. Start values are * inclusive and end values are exclusive. */ - public static ParcelFileDescriptor open(Context context, File file, long[] redactRanges) - throws IOException { - return new RedactingFileDescriptor(context, file, redactRanges).mOuter; + public static ParcelFileDescriptor open(Context context, File file, int mode, + long[] redactRanges) throws IOException { + return new RedactingFileDescriptor(context, file, mode, redactRanges).mOuter; + } + + /** + * Update the given ranges argument to remove any references to the given + * offset and length. This is typically used when a caller has written over + * a previously redacted region. + */ + @VisibleForTesting + public static long[] removeRange(long[] ranges, long start, long end) { + if (start == end) { + return ranges; + } else if (start > end) { + throw new IllegalArgumentException(); + } + + long[] res = EmptyArray.LONG; + for (int i = 0; i < ranges.length; i += 2) { + if (start <= ranges[i] && end >= ranges[i + 1]) { + // Range entirely covered; remove it + } else if (start >= ranges[i] && end <= ranges[i + 1]) { + // Range partially covered; punch a hole + res = Arrays.copyOf(res, res.length + 4); + res[res.length - 4] = ranges[i]; + res[res.length - 3] = start; + res[res.length - 2] = end; + res[res.length - 1] = ranges[i + 1]; + } else { + // Range might covered; adjust edges if needed + res = Arrays.copyOf(res, res.length + 2); + if (end >= ranges[i] && end <= ranges[i + 1]) { + res[res.length - 2] = Math.max(ranges[i], end); + } else { + res[res.length - 2] = ranges[i]; + } + if (start >= ranges[i] && start <= ranges[i + 1]) { + res[res.length - 1] = Math.min(ranges[i + 1], start); + } else { + res[res.length - 1] = ranges[i + 1]; + } + } + } + return res; } private final ProxyFileDescriptorCallback mCallback = new ProxyFileDescriptorCallback() { @@ -126,7 +175,24 @@ public class RedactingFileDescriptor { @Override public int onWrite(long offset, int size, byte[] data) throws ErrnoException { - throw new ErrnoException(TAG, OsConstants.EBADF); + int n = 0; + while (n < size) { + try { + final int res = Os.pwrite(mInner, data, n, size - n, offset + n); + if (res == 0) { + break; + } else { + n += res; + } + } catch (InterruptedIOException e) { + n += e.bytesTransferred; + } + } + + // Clear any relevant redaction ranges before returning, since the + // writer should have access to see the data they just overwrote + mRedactRanges = removeRange(mRedactRanges, offset, offset + n); + return n; } @Override diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index e0e4fe29f48a..ec8db1ca580e 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -121,6 +121,8 @@ public final class MediaStore { public static final String PARAM_INCLUDE_PENDING = "includePending"; /** {@hide} */ public static final String PARAM_PROGRESS = "progress"; + /** {@hide} */ + public static final String PARAM_REQUIRE_ORIGINAL = "requireOriginal"; /** * Activity Action: Launch a music player. @@ -478,6 +480,24 @@ public final class MediaStore { } /** + * Update the given {@link Uri} to indicate that the caller requires the + * original file contents when calling + * {@link ContentResolver#openFileDescriptor(Uri, String)}. + * <p> + * This can be useful when the caller wants to ensure they're backing up the + * exact bytes of the underlying media, without any Exif redaction being + * performed. + * <p> + * If the original file contents cannot be provided, a + * {@link UnsupportedOperationException} will be thrown when the returned + * {@link Uri} is used, such as when the caller doesn't hold + * {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}. + */ + public static @NonNull Uri setRequireOriginal(@NonNull Uri uri) { + return uri.buildUpon().appendQueryParameter(PARAM_REQUIRE_ORIGINAL, "1").build(); + } + + /** * Create a new pending media item using the given parameters. Pending items * are expected to have a short lifetime, and owners should either * {@link PendingSession#publish()} or {@link PendingSession#abandon()} a diff --git a/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl b/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl new file mode 100644 index 000000000000..23d607d9838c --- /dev/null +++ b/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.intelligence; + +parcelable ContentCaptureEventsRequest; diff --git a/core/java/android/service/intelligence/ContentCaptureEventsRequest.java b/core/java/android/service/intelligence/ContentCaptureEventsRequest.java new file mode 100644 index 000000000000..bc5b92bce999 --- /dev/null +++ b/core/java/android/service/intelligence/ContentCaptureEventsRequest.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.service.intelligence; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.intelligence.ContentCaptureEvent; + +import java.util.List; + +/** + * Batch of content capture events. + * + * @hide + */ +@SystemApi +public final class ContentCaptureEventsRequest implements Parcelable { + + private final List<ContentCaptureEvent> mEvents; + + /** @hide */ + public ContentCaptureEventsRequest(@NonNull List<ContentCaptureEvent> events) { + mEvents = events; + } + + /** + * Gets the events. + */ + @NonNull + public List<ContentCaptureEvent> getEvents() { + return mEvents; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) { + parcel.writeTypedList(mEvents, flags); + } + + public static final Parcelable.Creator<ContentCaptureEventsRequest> CREATOR = + new Parcelable.Creator<ContentCaptureEventsRequest>() { + + @Override + public ContentCaptureEventsRequest createFromParcel(Parcel parcel) { + return new ContentCaptureEventsRequest(parcel + .createTypedArrayList(ContentCaptureEvent.CREATOR)); + } + + @Override + public ContentCaptureEventsRequest[] newArray(int size) { + return new ContentCaptureEventsRequest[size]; + } + }; +} diff --git a/core/java/android/service/intelligence/FillController.java b/core/java/android/service/intelligence/FillController.java index c5e1242842bb..4a9c85de1fa2 100644 --- a/core/java/android/service/intelligence/FillController.java +++ b/core/java/android/service/intelligence/FillController.java @@ -15,12 +15,12 @@ */ package android.service.intelligence; -import static android.service.intelligence.IntelligenceService.DEBUG; +import static android.service.intelligence.SmartSuggestionsService.DEBUG; import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.RemoteException; -import android.service.intelligence.IntelligenceService.AutofillProxy; +import android.service.intelligence.SmartSuggestionsService.AutofillProxy; import android.util.Log; import android.util.Pair; import android.view.autofill.AutofillId; diff --git a/core/java/android/service/intelligence/FillRequest.java b/core/java/android/service/intelligence/FillRequest.java index 95e922487906..f68db9df6fe3 100644 --- a/core/java/android/service/intelligence/FillRequest.java +++ b/core/java/android/service/intelligence/FillRequest.java @@ -18,7 +18,7 @@ package android.service.intelligence; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.service.intelligence.IntelligenceService.AutofillProxy; +import android.service.intelligence.SmartSuggestionsService.AutofillProxy; import android.view.autofill.AutofillId; /** diff --git a/core/java/android/service/intelligence/FillWindow.java b/core/java/android/service/intelligence/FillWindow.java index 4ea07bfc86cf..309f6a1b6f1b 100644 --- a/core/java/android/service/intelligence/FillWindow.java +++ b/core/java/android/service/intelligence/FillWindow.java @@ -15,7 +15,7 @@ */ package android.service.intelligence; -import static android.service.intelligence.IntelligenceService.DEBUG; +import static android.service.intelligence.SmartSuggestionsService.DEBUG; import android.annotation.LongDef; import android.annotation.NonNull; diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl index e2260d7d3d76..d6b31079e34c 100644 --- a/core/java/android/service/intelligence/IIntelligenceService.aidl +++ b/core/java/android/service/intelligence/IIntelligenceService.aidl @@ -17,6 +17,7 @@ package android.service.intelligence; import android.os.IBinder; +import android.service.intelligence.ContentCaptureEventsRequest; import android.service.intelligence.InteractionSessionId; import android.service.intelligence.InteractionContext; import android.service.intelligence.SnapshotData; @@ -26,19 +27,19 @@ import android.view.intelligence.ContentCaptureEvent; import java.util.List; - /** * Interface from the system to an intelligence service. * * @hide */ + // TODO(b/111276913): rename / update javadoc (once the final name is defined) oneway interface IIntelligenceService { // Called when session is created (context not null) or destroyed (context null) void onSessionLifecycle(in InteractionContext context, in InteractionSessionId sessionId); - void onContentCaptureEvents(in InteractionSessionId sessionId, - in List<ContentCaptureEvent> events); + void onContentCaptureEventsRequest(in InteractionSessionId sessionId, + in ContentCaptureEventsRequest request); void onActivitySnapshot(in InteractionSessionId sessionId, in SnapshotData snapshotData); diff --git a/core/java/android/service/intelligence/InteractionContext.java b/core/java/android/service/intelligence/InteractionContext.java index 0cc377bb030b..7f4283db28d2 100644 --- a/core/java/android/service/intelligence/InteractionContext.java +++ b/core/java/android/service/intelligence/InteractionContext.java @@ -37,7 +37,7 @@ public final class InteractionContext implements Parcelable { /** * Flag used to indicate that the app explicitly disabled content capture for the activity * (using - * {@link android.view.intelligence.IntelligenceManager#setContentCaptureEnabled()}), + * {@link android.view.intelligence.ContentCaptureManager#setContentCaptureEnabled()}), * in which case the service will just receive activity-level events. */ public static final int FLAG_DISABLED_BY_APP = 0x1; diff --git a/core/java/android/service/intelligence/PresentationParams.java b/core/java/android/service/intelligence/PresentationParams.java index c59069bbb674..95303099793a 100644 --- a/core/java/android/service/intelligence/PresentationParams.java +++ b/core/java/android/service/intelligence/PresentationParams.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.graphics.Rect; -import android.service.intelligence.IntelligenceService.AutofillProxy; +import android.service.intelligence.SmartSuggestionsService.AutofillProxy; import android.util.DebugUtils; import android.view.View; diff --git a/core/java/android/service/intelligence/IntelligenceService.java b/core/java/android/service/intelligence/SmartSuggestionsService.java index 040e25e977e4..90f04ca66db7 100644 --- a/core/java/android/service/intelligence/IntelligenceService.java +++ b/core/java/android/service/intelligence/SmartSuggestionsService.java @@ -19,8 +19,10 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.annotation.CallSuper; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.Service; +import android.content.ComponentName; import android.content.Intent; import android.graphics.Rect; import android.os.CancellationSignal; @@ -43,19 +45,18 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.Set; /** - * A service used to capture the content of the screen. - * - * <p>The data collected by this service can be analyzed and combined with other sources to provide - * contextual data in other areas of the system such as Autofill. + * A service used to capture the content of the screen to provide contextual data in other areas of + * the system such as Autofill. * * @hide */ @SystemApi -public abstract class IntelligenceService extends Service { +public abstract class SmartSuggestionsService extends Service { - private static final String TAG = "IntelligenceService"; + private static final String TAG = "SmartSuggestionsService"; // TODO(b/111330312): STOPSHIP use dynamic value, or change to false static final boolean DEBUG = true; @@ -63,11 +64,11 @@ public abstract class IntelligenceService extends Service { /** * The {@link Intent} that must be declared as handled by the service. * To be supported, the service must also require the - * {@link android.Manifest.permission#BIND_INTELLIGENCE_SERVICE} permission so + * {@link android.Manifest.permission#BIND_SMART_SUGGESTIONS_SERVICE} permission so * that other applications can not abuse it. */ public static final String SERVICE_INTERFACE = - "android.service.intelligence.IntelligenceService"; + "android.service.intelligence.SmartSuggestionsService"; private Handler mHandler; @@ -80,21 +81,21 @@ public abstract class IntelligenceService extends Service { throws RemoteException { if (context != null) { mHandler.sendMessage( - obtainMessage(IntelligenceService::onCreateInteractionSession, - IntelligenceService.this, context, sessionId)); + obtainMessage(SmartSuggestionsService::onCreateInteractionSession, + SmartSuggestionsService.this, context, sessionId)); } else { mHandler.sendMessage( - obtainMessage(IntelligenceService::onDestroyInteractionSession, - IntelligenceService.this, sessionId)); + obtainMessage(SmartSuggestionsService::onDestroyInteractionSession, + SmartSuggestionsService.this, sessionId)); } } @Override - public void onContentCaptureEvents(InteractionSessionId sessionId, - List<ContentCaptureEvent> events) { + public void onContentCaptureEventsRequest(InteractionSessionId sessionId, + ContentCaptureEventsRequest request) { mHandler.sendMessage( - obtainMessage(IntelligenceService::onContentCaptureEvent, - IntelligenceService.this, sessionId, events)); + obtainMessage(SmartSuggestionsService::onContentCaptureEventsRequest, + SmartSuggestionsService.this, sessionId, request)); } @@ -102,22 +103,22 @@ public abstract class IntelligenceService extends Service { public void onActivitySnapshot(InteractionSessionId sessionId, SnapshotData snapshotData) { mHandler.sendMessage( - obtainMessage(IntelligenceService::onActivitySnapshot, - IntelligenceService.this, sessionId, snapshotData)); + obtainMessage(SmartSuggestionsService::onActivitySnapshot, + SmartSuggestionsService.this, sessionId, snapshotData)); } @Override public void onAutofillRequest(InteractionSessionId sessionId, IBinder client, int autofilSessionId, AutofillId focusedId) { - mHandler.sendMessage(obtainMessage(IntelligenceService::handleOnAutofillRequest, - IntelligenceService.this, sessionId, client, autofilSessionId, focusedId)); + mHandler.sendMessage(obtainMessage(SmartSuggestionsService::handleOnAutofillRequest, + SmartSuggestionsService.this, sessionId, client, autofilSessionId, focusedId)); } @Override public void onDestroyAutofillWindowsRequest(InteractionSessionId sessionId) { mHandler.sendMessage( - obtainMessage(IntelligenceService::handleOnDestroyAutofillWindowsRequest, - IntelligenceService.this, sessionId)); + obtainMessage(SmartSuggestionsService::handleOnDestroyAutofillWindowsRequest, + SmartSuggestionsService.this, sessionId)); } }; @@ -139,6 +140,69 @@ public abstract class IntelligenceService extends Service { } /** + * Explicitly limits content capture to the given packages and activities. + * + * <p>When the whitelist is set, it overrides the values passed to + * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)} + * and {@link #setPackageContentCaptureEnabled(String, boolean)}. + * + * <p>To reset the whitelist, call it passing {@code null} to both arguments. + * + * <p>Useful when the service wants to restrict content capture to a category of apps, like + * chat apps. For example, if the service wants to support view captures on all activities of + * app {@code ChatApp1} and just activities {@code act1} and {@code act2} of {@code ChatApp2}, + * it would call: {@code setContentCaptureWhitelist(Arrays.asList("ChatApp1"), + * Arrays.asList(new ComponentName("ChatApp2", "act1"), + * new ComponentName("ChatApp2", "act2")));} + */ + public final void setContentCaptureWhitelist(@Nullable List<String> packages, + @Nullable List<ComponentName> activities) { + //TODO(b/111276913): implement + } + + /** + * Defines whether content capture should be enabled for activities with such + * {@link android.content.ComponentName}. + * + * <p>Useful to blacklist a particular activity. + */ + public final void setActivityContentCaptureEnabled(@NonNull ComponentName activity, + boolean enabled) { + //TODO(b/111276913): implement + } + + /** + * Defines whether content capture should be enabled for activities of the app with such + * {@code packageName}. + * + * <p>Useful to blacklist any activity from a particular app. + */ + public final void setPackageContentCaptureEnabled(@NonNull String packageName, + boolean enabled) { + //TODO(b/111276913): implement + } + + /** + * Gets the activities where content capture was disabled by + * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}. + */ + @NonNull + public final Set<ComponentName> getContentCaptureDisabledActivities() { + //TODO(b/111276913): implement + return null; + } + + /** + * Gets the apps where content capture was disabled by + * {@link #setPackageContentCaptureEnabled(String, boolean)}. + */ + @NonNull + public final Set<String> getContentCaptureDisabledPackages() { + //TODO(b/111276913): implement + return null; + } + + /** * Creates a new interaction session. * * @param context interaction context @@ -152,12 +216,12 @@ public abstract class IntelligenceService extends Service { * session. * * @param sessionId the session's Id - * @param events the events + * @param request the events */ // TODO(b/111276913): rename to onContentCaptureEvents or something like that; also, pass a // Request object so it can be extended - public abstract void onContentCaptureEvent(@NonNull InteractionSessionId sessionId, - @NonNull List<ContentCaptureEvent> events); + public abstract void onContentCaptureEventsRequest(@NonNull InteractionSessionId sessionId, + @NonNull ContentCaptureEventsRequest request); private void handleOnAutofillRequest(@NonNull InteractionSessionId sessionId, @NonNull IBinder client, int autofillSessionId, @NonNull AutofillId focusedId) { @@ -242,8 +306,7 @@ public abstract class IntelligenceService extends Service { } /** - * Notifies the service of {@link IntelligenceSnapshotData snapshot data} associated with a - * session. + * Notifies the service of {@link SnapshotData snapshot data} associated with a session. * * @param sessionId the session's Id * @param snapshotData the data diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 8371c31b5ac5..0e2ae837a141 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -806,7 +806,7 @@ public class ZenModeConfig implements Parcelable { if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_CALLS, isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS, defaultPolicy))) { priorityCategories |= Policy.PRIORITY_CATEGORY_CALLS; - messageSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders()); + callSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders()); } if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS, diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java index 43ab8dc07000..194147c2c154 100644 --- a/core/java/android/service/notification/ZenPolicy.java +++ b/core/java/android/service/notification/ZenPolicy.java @@ -859,6 +859,27 @@ public final class ZenPolicy implements Parcelable { /** * @hide */ + public boolean areValuesSet() { + return getPriorityCategoryReminders() != STATE_UNSET + || getPriorityCategoryEvents() != STATE_UNSET + || getPriorityCategoryMessages() != STATE_UNSET + || getPriorityCategoryCalls() != STATE_UNSET + || getPriorityCategoryRepeatCallers() != STATE_UNSET + || getPriorityCategoryAlarms() != STATE_UNSET + || getPriorityCategoryMedia() != STATE_UNSET + || getPriorityCategorySystem() != STATE_UNSET + || getVisualEffectFullScreenIntent() != STATE_UNSET + || getVisualEffectLights() != STATE_UNSET + || getVisualEffectPeek() != STATE_UNSET + || getVisualEffectStatusBar() != STATE_UNSET + || getVisualEffectBadge() != STATE_UNSET + || getVisualEffectAmbient() != STATE_UNSET + || getVisualEffectNotificationList() != STATE_UNSET; + } + + /** + * @hide + */ public void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index c5d03741dbba..401e75c95a38 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -112,7 +112,7 @@ import android.view.autofill.AutofillValue; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; -import android.view.intelligence.IntelligenceManager; +import android.view.intelligence.ContentCaptureManager; import android.widget.Checkable; import android.widget.FrameLayout; import android.widget.ScrollBarDrawable; @@ -8138,7 +8138,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * is visible. * * <p>The populated structure is then passed to the service through - * {@link IntelligenceManager#notifyViewAppeared(ViewStructure)}. + * {@link ContentCaptureManager#notifyViewAppeared(ViewStructure)}. * * <p><b>Note: </b>the following methods of the {@code structure} will be ignored: * <ul> @@ -8915,7 +8915,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Helper used to notify the {@link IntelligenceManager} when the view is removed or + * Helper used to notify the {@link ContentCaptureManager} when the view is removed or * added, based on whether it's laid out and visible, and without knowing if the parent removed * it from the view hierarchy. * @@ -8931,11 +8931,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * </ol> */ private void notifyAppearedOrDisappearedForContentCaptureIfNeeded(boolean appeared) { + // First check if context has client, so it saves a service lookup when it doesn't + if (!mContext.isContentCaptureSupported()) return; - final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class); - if (im == null || !im.isContentCaptureEnabled()) return; + // Then check if it's enabled in the context... + final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class); + if (cm == null || !cm.isContentCaptureEnabled()) return; - // NOTE: isImportantForContentCapture() is more expensive than im.isContentCaptureEnabled() + // ... and finally at the view level + // NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled() if (!isImportantForContentCapture()) return; if (appeared) { @@ -8950,9 +8954,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return; } // All good: notify the manager... - final ViewStructure structure = im.newViewStructure(this); + final ViewStructure structure = cm.newViewStructure(this); onProvideContentCaptureStructure(structure, /* flags= */ 0); - im.notifyViewAppeared(structure); + cm.notifyViewAppeared(structure); // ...and set the flags mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED; mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED; @@ -8969,7 +8973,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return; } // All good: notify the manager... - im.notifyViewDisappeared(getAutofillId()); + cm.notifyViewDisappeared(getAutofillId()); // ...and set the flags mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED; mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED; diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java index befcb55b1f73..f63628105cba 100644 --- a/core/java/android/view/intelligence/ContentCaptureEvent.java +++ b/core/java/android/view/intelligence/ContentCaptureEvent.java @@ -163,7 +163,7 @@ public final class ContentCaptureEvent implements Parcelable { * Gets optional flags associated with the event. * * @return either {@code 0} or - * {@link android.view.intelligence.IntelligenceManager#FLAG_USER_INPUT}. + * {@link android.view.intelligence.ContentCaptureManager#FLAG_USER_INPUT}. */ public int getFlags() { return mFlags; diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/ContentCaptureManager.java index 2f3b4ef56aa1..9023cd08159a 100644 --- a/core/java/android/view/intelligence/IntelligenceManager.java +++ b/core/java/android/view/intelligence/ContentCaptureManager.java @@ -23,7 +23,6 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.ComponentName; import android.content.Context; @@ -44,13 +43,8 @@ import com.android.internal.util.Preconditions; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.List; -import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -/** - * TODO(b/111276913): add javadocs / implement - */ /* * NOTE: all methods in this class should return right away, or do the real work in a handler * thread. @@ -58,10 +52,13 @@ import java.util.concurrent.atomic.AtomicBoolean; * Hence, the only field that must be thread-safe is mEnabled, which is called at the beginning * of every method. */ -@SystemService(Context.INTELLIGENCE_MANAGER_SERVICE) -public final class IntelligenceManager { +/** + * TODO(b/111276913): add javadocs / implement + */ +@SystemService(Context.CONTENT_CAPTURE_MANAGER_SERVICE) +public final class ContentCaptureManager { - private static final String TAG = "IntelligenceManager"; + private static final String TAG = "ContentCaptureManager"; // TODO(b/111276913): define a way to dynamically set them(for example, using settings?) private static final boolean VERBOSE = false; @@ -140,7 +137,7 @@ public final class IntelligenceManager { private final Handler mHandler; /** @hide */ - public IntelligenceManager(@NonNull Context context, @Nullable IIntelligenceManager service) { + public ContentCaptureManager(@NonNull Context context, @Nullable IIntelligenceManager service) { mContext = Preconditions.checkNotNull(context, "context cannot be null"); if (VERBOSE) { Log.v(TAG, "Constructor for " + context.getPackageName()); @@ -156,7 +153,7 @@ public final class IntelligenceManager { public void onActivityCreated(@NonNull IBinder token, @NonNull ComponentName componentName) { if (!isContentCaptureEnabled()) return; - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleStartSession, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleStartSession, this, token, componentName)); } @@ -264,7 +261,7 @@ public final class IntelligenceManager { Log.v(TAG, "onActivityLifecycleEvent() for " + getActivityDebugName() + ": " + ContentCaptureEvent.getTypeAsString(type)); } - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this, new ContentCaptureEvent(type), /* forceFlush= */ true)); } @@ -279,7 +276,7 @@ public final class IntelligenceManager { + ", mId=" + mId); } - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleFinishSession, this)); + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleFinishSession, this)); } private void handleFinishSession() { @@ -328,7 +325,7 @@ public final class IntelligenceManager { throw new IllegalArgumentException("Invalid node class: " + node.getClass()); } - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this, new ContentCaptureEvent(TYPE_VIEW_APPEARED) .setViewNode(((ViewNode.ViewStructureImpl) node).mNode), /* forceFlush= */ false)); @@ -346,7 +343,7 @@ public final class IntelligenceManager { Preconditions.checkNotNull(id); if (!isContentCaptureEnabled()) return; - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this, new ContentCaptureEvent(TYPE_VIEW_DISAPPEARED).setAutofillId(id), /* forceFlush= */ false)); } @@ -365,7 +362,7 @@ public final class IntelligenceManager { if (!isContentCaptureEnabled()) return; - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this, new ContentCaptureEvent(TYPE_VIEW_TEXT_CHANGED, flags).setAutofillId(id) .setText(text), /* forceFlush= */ false)); } @@ -396,11 +393,11 @@ public final class IntelligenceManager { } /** - * Returns the component name of the {@code android.service.intelligence.IntelligenceService} - * that is enabled for the current user. + * Returns the component name of the system service that is consuming the captured events for + * the current user. */ @Nullable - public ComponentName getIntelligenceServiceComponentName() { + public ComponentName getServiceComponentName() { //TODO(b/111276913): implement return null; } @@ -422,106 +419,6 @@ public final class IntelligenceManager { //TODO(b/111276913): implement } - /** - * Called by the the service {@link android.service.intelligence.IntelligenceService} - * to define whether content capture should be enabled for activities with such - * {@link android.content.ComponentName}. - * - * <p>Useful to blacklist a particular activity. - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - public void setActivityContentCaptureEnabled(@NonNull ComponentName activity, - boolean enabled) { - //TODO(b/111276913): implement - } - - /** - * Called by the the service {@link android.service.intelligence.IntelligenceService} - * to explicitly limit content capture to the given packages and activities. - * - * <p>When the whitelist is set, it overrides the values passed to - * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)} - * and {@link #setPackageContentCaptureEnabled(String, boolean)}. - * - * <p>To reset the whitelist, call it passing {@code null} to both arguments. - * - * <p>Useful when the service wants to restrict content capture to a category of apps, like - * chat apps. For example, if the service wants to support view captures on all activities of - * app {@code ChatApp1} and just activities {@code act1} and {@code act2} of {@code ChatApp2}, - * it would call: {@code setContentCaptureWhitelist(Arrays.asList("ChatApp1"), - * Arrays.asList(new ComponentName("ChatApp2", "act1"), - * new ComponentName("ChatApp2", "act2")));} - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - public void setContentCaptureWhitelist(@Nullable List<String> packages, - @Nullable List<ComponentName> activities) { - //TODO(b/111276913): implement - } - - /** - * Called by the the service {@link android.service.intelligence.IntelligenceService} - * to define whether content capture should be enabled for activities of the app with such - * {@code packageName}. - * - * <p>Useful to blacklist any activity from a particular app. - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - public void setPackageContentCaptureEnabled(@NonNull String packageName, boolean enabled) { - //TODO(b/111276913): implement - } - - /** - * Gets the activities where content capture was disabled by - * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}. - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - @NonNull - public Set<ComponentName> getContentCaptureDisabledActivities() { - //TODO(b/111276913): implement - return null; - } - - /** - * Gets the apps where content capture was disabled by - * {@link #setPackageContentCaptureEnabled(String, boolean)}. - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - @NonNull - public Set<String> getContentCaptureDisabledPackages() { - //TODO(b/111276913): implement - return null; - } - /** @hide */ public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.println("IntelligenceManager"); @@ -547,7 +444,7 @@ public final class IntelligenceManager { } if (mEvents != null) { final int numberEvents = mEvents.size(); - pw.print(prefix2); pw.print("batched events: "); pw.print(numberEvents); + pw.print(prefix2); pw.print("buffered events: "); pw.print(numberEvents); pw.print('/'); pw.println(MAX_BUFFER_SIZE); if (VERBOSE && numberEvents > 0) { final String prefix3 = prefix2 + " "; diff --git a/core/java/android/view/intelligence/IIntelligenceManager.aidl b/core/java/android/view/intelligence/IIntelligenceManager.aidl index 7518ff53b638..882fb2674bf1 100644 --- a/core/java/android/view/intelligence/IIntelligenceManager.aidl +++ b/core/java/android/view/intelligence/IIntelligenceManager.aidl @@ -28,6 +28,7 @@ import java.util.List; /** * {@hide} */ +// TODO(b/111276913): rename once the final name is defined oneway interface IIntelligenceManager { /** * Starts a session, sending the "remote" sessionId to the receiver. diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 1deee8af3d75..085f8f1d678f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -166,7 +166,7 @@ import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; -import android.view.intelligence.IntelligenceManager; +import android.view.intelligence.ContentCaptureManager; import android.view.textclassifier.TextClassification; import android.view.textclassifier.TextClassificationContext; import android.view.textclassifier.TextClassificationManager; @@ -10135,7 +10135,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * Notify managers (such as {@link AutofillManager} and {@link IntelligenceManager}) that are + * Notify managers (such as {@link AutofillManager} and {@link ContentCaptureManager}) that are * interested on text changes. */ private void notifyListeningManagersAfterTextChanged() { @@ -10155,10 +10155,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // ContentCapture if (isImportantForContentCapture() && isTextEditable()) { - final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class); - if (im != null && im.isContentCaptureEnabled()) { + final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class); + if (cm != null && cm.isContentCaptureEnabled()) { // TODO(b/111276913): pass flags when edited by user / add CTS test - im.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0); + cm.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0); } } } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index bdd5f83aa4ea..31bb1d57d702 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -34,7 +34,6 @@ cc_library_shared { ], cppflags: ["-Wno-conversion-null"], - cpp_std: "c++17", srcs: [ "AndroidRuntime.cpp", diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index b465fb4f7eba..0e052fe8d4b1 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -234,10 +234,14 @@ message SecureSettingsProto { } optional Location location = 31; + // How frequently will the user be reminded about location permission grants message LocationAccessCheck { option (android.msg_privacy).dest = DEST_EXPLICIT; + // Time in between periodic checks optional SettingProto interval_millis = 1 [ (android.privacy).dest = DEST_AUTOMATIC ]; + + // Time in between the user granting a location permission and a check optional SettingProto delay_millis = 2 [ (android.privacy).dest = DEST_AUTOMATIC ]; } optional LocationAccessCheck location_access_check = 73; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index b4d5f67e945e..91b98694a623 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3047,12 +3047,12 @@ <permission android:name="android.permission.BIND_TEXTCLASSIFIER_SERVICE" android:protectionLevel="signature" /> - <!-- Must be required by a android.service.intelligence.IntelligenceService, + <!-- Must be required by a android.service.intelligence.SmartSuggestionsService, to ensure that only the system can bind to it. @SystemApi @hide This is not a third-party API (intended for OEMs and system apps). <p>Protection level: signature --> - <permission android:name="android.permission.BIND_INTELLIGENCE_SERVICE" + <permission android:name="android.permission.BIND_SMART_SUGGESTIONS_SERVICE" android:protectionLevel="signature" /> <!-- Must be required by hotword enrollment application, diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 244728954aa0..f55e48e5b140 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1915,6 +1915,9 @@ <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" /> <enum name="KEYCODE_ALL_APPS" value="284" /> <enum name="KEYCODE_REFRESH" value="285" /> + <enum name="KEYCODE_THUMBS_UP" value="286" /> + <enum name="KEYCODE_THUMBS_DOWN" value="287" /> + <enum name="KEYCODE_PROFILE_SWITCH" value="288" /> </attr> <!-- ***************************************************************** --> diff --git a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java index c8bc35c976a2..9e1523165925 100644 --- a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java +++ b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java @@ -16,6 +16,10 @@ package android.os; +import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; +import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; +import static android.os.RedactingFileDescriptor.removeRange; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -58,8 +62,8 @@ public class RedactingFileDescriptorTest { @Test public void testSingleByte() throws Exception { - final FileDescriptor fd = RedactingFileDescriptor - .open(mContext, mFile, new long[] { 10, 11 }).getFileDescriptor(); + final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY, + new long[] { 10, 11 }).getFileDescriptor(); final byte[] buf = new byte[1_000]; assertEquals(buf.length, Os.read(fd, buf, 0, buf.length)); @@ -74,8 +78,8 @@ public class RedactingFileDescriptorTest { @Test public void testRanges() throws Exception { - final FileDescriptor fd = RedactingFileDescriptor - .open(mContext, mFile, new long[] { 100, 200, 300, 400 }).getFileDescriptor(); + final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY, + new long[] { 100, 200, 300, 400 }).getFileDescriptor(); final byte[] buf = new byte[10]; assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 90)); @@ -96,8 +100,8 @@ public class RedactingFileDescriptorTest { @Test public void testEntireFile() throws Exception { - final FileDescriptor fd = RedactingFileDescriptor - .open(mContext, mFile, new long[] { 0, 5_000_000 }).getFileDescriptor(); + final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY, + new long[] { 0, 5_000_000 }).getFileDescriptor(); try (FileInputStream in = new FileInputStream(fd)) { int val; @@ -106,4 +110,61 @@ public class RedactingFileDescriptorTest { } } } + + @Test + public void testReadWrite() throws Exception { + final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE, + new long[] { 100, 200, 300, 400 }).getFileDescriptor(); + + // Redacted at first + final byte[] buf = new byte[10]; + assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 95)); + assertArrayEquals(new byte[] { 64, 64, 64, 64, 64, 0, 0, 0, 0, 0 }, buf); + + // But we can see data that we've written + Os.pwrite(fd, new byte[] { 32, 32 }, 0, 2, 102); + assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 95)); + assertArrayEquals(new byte[] { 64, 64, 64, 64, 64, 0, 0, 32, 32, 0 }, buf); + } + + @Test + public void testRemoveRange() throws Exception { + // Removing outside ranges should have no changes + assertArrayEquals(new long[] { 100, 200, 300, 400 }, + removeRange(new long[] { 100, 200, 300, 400 }, 0, 100)); + assertArrayEquals(new long[] { 100, 200, 300, 400 }, + removeRange(new long[] { 100, 200, 300, 400 }, 200, 300)); + assertArrayEquals(new long[] { 100, 200, 300, 400 }, + removeRange(new long[] { 100, 200, 300, 400 }, 400, 500)); + + // Removing full regions + assertArrayEquals(new long[] { 100, 200 }, + removeRange(new long[] { 100, 200, 300, 400 }, 300, 400)); + assertArrayEquals(new long[] { 100, 200 }, + removeRange(new long[] { 100, 200, 300, 400 }, 250, 450)); + assertArrayEquals(new long[] { 300, 400 }, + removeRange(new long[] { 100, 200, 300, 400 }, 50, 250)); + assertArrayEquals(new long[] { }, + removeRange(new long[] { 100, 200, 300, 400 }, 0, 5_000_000)); + } + + @Test + public void testRemoveRange_Partial() throws Exception { + assertArrayEquals(new long[] { 150, 200, 300, 400 }, + removeRange(new long[] { 100, 200, 300, 400 }, 50, 150)); + assertArrayEquals(new long[] { 100, 150, 300, 400 }, + removeRange(new long[] { 100, 200, 300, 400 }, 150, 250)); + assertArrayEquals(new long[] { 100, 150, 350, 400 }, + removeRange(new long[] { 100, 200, 300, 400 }, 150, 350)); + assertArrayEquals(new long[] { 100, 150 }, + removeRange(new long[] { 100, 200, 300, 400 }, 150, 500)); + } + + @Test + public void testRemoveRange_Hole() throws Exception { + assertArrayEquals(new long[] { 100, 125, 175, 200, 300, 400 }, + removeRange(new long[] { 100, 200, 300, 400 }, 125, 175)); + assertArrayEquals(new long[] { 100, 200 }, + removeRange(new long[] { 100, 200 }, 150, 150)); + } } diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 4a5b61a2d6cd..da77b99e6e53 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -9,8 +9,6 @@ cc_defaults { "hwui_lto", ], - cpp_std: "c++17", - cflags: [ "-DEGL_EGLEXT_PROTOTYPES", "-DGL_GLEXT_PROTOTYPES", diff --git a/libs/hwui/CanvasTransform.cpp b/libs/hwui/CanvasTransform.cpp index 06e937ab66f4..0cfaa8c61279 100644 --- a/libs/hwui/CanvasTransform.cpp +++ b/libs/hwui/CanvasTransform.cpp @@ -146,4 +146,4 @@ bool transformPaint(ColorTransform transform, SkPaint* paint, BitmapPalette pale return shouldInvert; } -}; // namespace android::uirenderer
\ No newline at end of file +} // namespace android::uirenderer diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index a952cc23e1ef..dc63e5db4a70 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -31,5 +31,5 @@ typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; */ using DisplayList = skiapipeline::SkiaDisplayList; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/FrameMetricsObserver.h b/libs/hwui/FrameMetricsObserver.h index ba72e937095f..237fc622dd2e 100644 --- a/libs/hwui/FrameMetricsObserver.h +++ b/libs/hwui/FrameMetricsObserver.h @@ -26,5 +26,5 @@ public: virtual void notify(const int64_t* buffer); }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/FrameMetricsReporter.h b/libs/hwui/FrameMetricsReporter.h index d920a99f5ee3..75b8038c5040 100644 --- a/libs/hwui/FrameMetricsReporter.h +++ b/libs/hwui/FrameMetricsReporter.h @@ -56,5 +56,5 @@ private: std::vector<sp<FrameMetricsObserver> > mObservers; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/GlFunctorLifecycleListener.h b/libs/hwui/GlFunctorLifecycleListener.h index 5d07b46919d4..5adc46961c8b 100644 --- a/libs/hwui/GlFunctorLifecycleListener.h +++ b/libs/hwui/GlFunctorLifecycleListener.h @@ -28,5 +28,5 @@ public: virtual void onGlFunctorReleased(Functor* functor) = 0; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp index 165fc4860fb2..a97c12cad9fd 100644 --- a/libs/hwui/HardwareBitmapUploader.cpp +++ b/libs/hwui/HardwareBitmapUploader.cpp @@ -256,4 +256,4 @@ sk_sp<Bitmap> HardwareBitmapUploader::allocateHardwareBitmap(const SkBitmap& sou return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info(), Bitmap::computePalette(bitmap))); } -}; // namespace android::uirenderer +} // namespace android::uirenderer diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h index c0113d81fefb..6298013bd263 100644 --- a/libs/hwui/HardwareBitmapUploader.h +++ b/libs/hwui/HardwareBitmapUploader.h @@ -25,4 +25,4 @@ public: static sk_sp<Bitmap> allocateHardwareBitmap(const SkBitmap& sourceBitmap); }; -}; // namespace android::uirenderer +} // namespace android::uirenderer diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index d0df200d2fa6..a15ff2235db2 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -54,5 +54,5 @@ SkBlendMode Layer::getMode() const { } } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 98600dbf1eea..ea3bfc9e80cb 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -144,5 +144,5 @@ private: }; // struct Layer -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/LayerUpdateQueue.h b/libs/hwui/LayerUpdateQueue.h index 6857999500f0..2c63af6aaab4 100644 --- a/libs/hwui/LayerUpdateQueue.h +++ b/libs/hwui/LayerUpdateQueue.h @@ -50,7 +50,7 @@ private: std::vector<Entry> mEntries; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_LAYER_UPDATE_QUEUE_H diff --git a/libs/hwui/Lighting.h b/libs/hwui/Lighting.h index d972c2181aea..ccfbb93b00ef 100644 --- a/libs/hwui/Lighting.h +++ b/libs/hwui/Lighting.h @@ -34,5 +34,5 @@ struct LightInfo { uint8_t spotShadowAlpha; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp index d84ed321a4cb..d0dbff031e99 100644 --- a/libs/hwui/Matrix.cpp +++ b/libs/hwui/Matrix.cpp @@ -526,5 +526,5 @@ void Matrix4::dump(const char* label) const { ALOGD("]"); } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h index 1b5cb60ca4bd..b33cfe2ec511 100644 --- a/libs/hwui/Matrix.h +++ b/libs/hwui/Matrix.h @@ -245,5 +245,5 @@ private: typedef Matrix4 mat4; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/NinePatchUtils.h b/libs/hwui/NinePatchUtils.h index 082e95fb1440..86d3cb9a5b11 100644 --- a/libs/hwui/NinePatchUtils.h +++ b/libs/hwui/NinePatchUtils.h @@ -103,5 +103,5 @@ static inline void SetLatticeFlags(SkCanvas::Lattice* lattice, SkCanvas::Lattice } } -}; // namespace NinePatchUtils -}; // namespace android +} // namespace NinePatchUtils +} // namespace android diff --git a/libs/hwui/PathParser.cpp b/libs/hwui/PathParser.cpp index ad599e9ec316..808921d344da 100644 --- a/libs/hwui/PathParser.cpp +++ b/libs/hwui/PathParser.cpp @@ -304,5 +304,5 @@ void PathParser::parseAsciiStringForSkPath(SkPath* skPath, ParseResult* result, return; } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/PathParser.h b/libs/hwui/PathParser.h index 474eb97b53c6..f5bebce605fb 100644 --- a/libs/hwui/PathParser.h +++ b/libs/hwui/PathParser.h @@ -46,6 +46,6 @@ public: static void validateVerbAndPoints(char verb, size_t points, ParseResult* result); }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_PATHPARSER_H diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 3f2c616eb8ff..4a3e10c54cef 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -223,5 +223,5 @@ void Properties::overrideRenderPipelineType(RenderPipelineType type) { sRenderPipelineType = type; } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 542bc71f7c72..da53f6657ff7 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -289,7 +289,7 @@ private: static RenderPipelineType sRenderPipelineType; }; // class Caches -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_PROPERTIES_H diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index f928de9b92a6..c63e449319dd 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -1028,5 +1028,5 @@ void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { fDL->drawVectorDrawable(tree); } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index 099e0be433ea..08cfc6266f56 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -216,5 +216,5 @@ private: DisplayListData* fDL; }; -}; // namespace uirenderer -}; // namespace android
\ No newline at end of file +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h index 0715187e19ea..d6362ef10aad 100644 --- a/libs/hwui/Rect.h +++ b/libs/hwui/Rect.h @@ -262,5 +262,5 @@ public: } }; // class Rect -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/UvMapper.h b/libs/hwui/UvMapper.h index b495e3394bc9..833ca4a79ce5 100644 --- a/libs/hwui/UvMapper.h +++ b/libs/hwui/UvMapper.h @@ -124,7 +124,7 @@ private: float mMaxV; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_UV_MAPPER_H diff --git a/libs/hwui/Vector.h b/libs/hwui/Vector.h index d2c15ad872a5..e6eea1c5c0ca 100644 --- a/libs/hwui/Vector.h +++ b/libs/hwui/Vector.h @@ -113,7 +113,7 @@ public: } }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_VECTOR_H diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp index 6cf04bf5f811..dd62bbbdc84f 100644 --- a/libs/hwui/VectorDrawable.cpp +++ b/libs/hwui/VectorDrawable.cpp @@ -691,7 +691,7 @@ BitmapPalette Tree::computePalette() { return BitmapPalette::Unknown; } -}; // namespace VectorDrawable +} // namespace VectorDrawable -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h index f0912777e3d8..28cabb9be0f1 100644 --- a/libs/hwui/Vertex.h +++ b/libs/hwui/Vertex.h @@ -73,7 +73,7 @@ struct TextureVertex { REQUIRE_COMPATIBLE_LAYOUT(TextureVertex); -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_VERTEX_H diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h index 613cf4af64b2..6543a2251f7a 100644 --- a/libs/hwui/VertexBuffer.h +++ b/libs/hwui/VertexBuffer.h @@ -174,7 +174,7 @@ private: void (*mCleanupIndexMethod)(void*); }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_VERTEX_BUFFER_H diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index e99742bc2eba..a5f21d8e6d73 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -76,8 +76,8 @@ typedef uint32_t Flags; namespace uirenderer { namespace VectorDrawable { class Tree; -}; -}; +} +} typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; typedef std::function<void(uint16_t* text, float* positions)> ReadGlyphFunc; @@ -318,4 +318,4 @@ protected: friend class DrawTextOnPathFunctor; }; -}; // namespace android +} // namespace android diff --git a/libs/hwui/pipeline/skia/AnimatedDrawables.h b/libs/hwui/pipeline/skia/AnimatedDrawables.h index efef6de2a9e1..bf19655825b3 100644 --- a/libs/hwui/pipeline/skia/AnimatedDrawables.h +++ b/libs/hwui/pipeline/skia/AnimatedDrawables.h @@ -79,6 +79,6 @@ private: sp<uirenderer::CanvasPropertyPaint> mPaint; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h index e4ba13da709c..206219426bb0 100644 --- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h +++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h @@ -172,6 +172,6 @@ private: std::string mIdent; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/FunctorDrawable.h b/libs/hwui/pipeline/skia/FunctorDrawable.h index 162d13762e1a..af3a056864a7 100644 --- a/libs/hwui/pipeline/skia/FunctorDrawable.h +++ b/libs/hwui/pipeline/skia/FunctorDrawable.h @@ -48,6 +48,6 @@ protected: const SkRect mBounds; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp index 90d5e715f8cd..4a87e7502c6f 100644 --- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp @@ -216,6 +216,6 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { } } -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.h b/libs/hwui/pipeline/skia/GLFunctorDrawable.h index b06f7f029f23..215979cba2e3 100644 --- a/libs/hwui/pipeline/skia/GLFunctorDrawable.h +++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.h @@ -41,6 +41,6 @@ protected: void onDraw(SkCanvas* canvas) override; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp index 9b408fbc95ca..f08ac17e4082 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.cpp +++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp @@ -145,6 +145,6 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer return layerImage != nullptr; } -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h index 5c125908ffb2..95dc6d0cf096 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.h +++ b/libs/hwui/pipeline/skia/LayerDrawable.h @@ -45,6 +45,6 @@ private: sp<DeferredLayerUpdater> mLayerUpdater; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp index d80cb6d1ab70..4494cb05df10 100644 --- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp +++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp @@ -332,6 +332,6 @@ void RenderNodeDrawable::setViewProperties(const RenderProperties& properties, S } } -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h index d746978b0a61..6ba8e599818c 100644 --- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h +++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h @@ -150,6 +150,6 @@ private: SkiaDisplayList* mProjectedDisplayList = nullptr; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp index dba97fe5ef9f..0a3c8f4347eb 100644 --- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp +++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp @@ -211,6 +211,6 @@ void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0); } -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h index 26cfa908228c..cfc0f9b258da 100644 --- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h +++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h @@ -74,6 +74,6 @@ private: StartReorderBarrierDrawable* mStartBarrier; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp index 38905138e332..ac6f6a3f776d 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp @@ -141,6 +141,6 @@ void SkiaDisplayList::output(std::ostream& output, uint32_t level) { mDisplayList.draw(&canvas); } -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h index ac7bb7b0950c..d7879e722a29 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.h +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h @@ -36,7 +36,7 @@ class Outline; namespace VectorDrawable { class Tree; -}; +} typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; namespace skiapipeline { @@ -179,6 +179,6 @@ public: SkMatrix mParentMatrix; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index f5de1c8adfaf..b682ab0256dd 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -259,6 +259,6 @@ double SkiaRecordingCanvas::drawAnimatedImage(AnimatedImageDrawable* animatedIma return 0; } -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h index 988728dfe23e..d6107a9d9969 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h @@ -92,6 +92,6 @@ private: PaintCoW&& filterBitmap(PaintCoW&& paint, sk_sp<SkColorFilter> colorSpaceFilter); }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp index a594206a2dd9..004a558dd9d0 100644 --- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp @@ -219,6 +219,6 @@ void VkInteropFunctorDrawable::syncFunctor() const { }); } -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h index 3269cfbb8fe3..8fe52c5ef700 100644 --- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h +++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h @@ -51,6 +51,6 @@ private: SkImageInfo mFBInfo; }; -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/private/hwui/DrawGlInfo.h b/libs/hwui/private/hwui/DrawGlInfo.h index efa9da27199d..9e1bb8e8e548 100644 --- a/libs/hwui/private/hwui/DrawGlInfo.h +++ b/libs/hwui/private/hwui/DrawGlInfo.h @@ -83,7 +83,7 @@ struct DrawGlInfo { }; }; // struct DrawGlInfo -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_DRAW_GL_INFO_H diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 6668c5840c3e..d9b789f28f8d 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -49,7 +49,7 @@ enum { Reset = 1 << 1, JankStats = 1 << 2, }; -}; +} /* * RenderProxy is strictly single threaded. All methods must be invoked on the owning diff --git a/libs/hwui/surfacetexture/EGLConsumer.cpp b/libs/hwui/surfacetexture/EGLConsumer.cpp index c8220c6cb0d4..85b3917809fa 100644 --- a/libs/hwui/surfacetexture/EGLConsumer.cpp +++ b/libs/hwui/surfacetexture/EGLConsumer.cpp @@ -672,4 +672,4 @@ EGLImageKHR EGLConsumer::EglImage::createImage(EGLDisplay dpy, return image; } -}; // namespace android +} // namespace android diff --git a/libs/hwui/surfacetexture/EGLConsumer.h b/libs/hwui/surfacetexture/EGLConsumer.h index eccb08298f6f..7dac3ef0f44a 100644 --- a/libs/hwui/surfacetexture/EGLConsumer.h +++ b/libs/hwui/surfacetexture/EGLConsumer.h @@ -308,4 +308,4 @@ protected: sp<EglImage> mReleasedTexImage; }; -}; // namespace android +} // namespace android diff --git a/libs/hwui/surfacetexture/ImageConsumer.h b/libs/hwui/surfacetexture/ImageConsumer.h index 5bab0ef58a9a..f0e55bbf19f8 100644 --- a/libs/hwui/surfacetexture/ImageConsumer.h +++ b/libs/hwui/surfacetexture/ImageConsumer.h @@ -97,4 +97,4 @@ private: ImageSlot mImageSlots[BufferQueueDefs::NUM_BUFFER_SLOTS]; }; -}; /* namespace android */ +} /* namespace android */ diff --git a/libs/hwui/surfacetexture/SurfaceTexture.cpp b/libs/hwui/surfacetexture/SurfaceTexture.cpp index 90f891265572..da094442684d 100644 --- a/libs/hwui/surfacetexture/SurfaceTexture.cpp +++ b/libs/hwui/surfacetexture/SurfaceTexture.cpp @@ -491,4 +491,4 @@ sk_sp<SkImage> SurfaceTexture::dequeueImage(SkMatrix& transformMatrix, bool* que return image; } -}; // namespace android +} // namespace android diff --git a/libs/hwui/surfacetexture/SurfaceTexture.h b/libs/hwui/surfacetexture/SurfaceTexture.h index 96afd82b0d40..b5d136ff3058 100644 --- a/libs/hwui/surfacetexture/SurfaceTexture.h +++ b/libs/hwui/surfacetexture/SurfaceTexture.h @@ -449,4 +449,4 @@ protected: }; // ---------------------------------------------------------------------------- -}; // namespace android +} // namespace android diff --git a/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp b/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp index 217d63f9c2e1..41714ebd84b1 100644 --- a/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp +++ b/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp @@ -81,5 +81,5 @@ TEST(LayerUpdateQueue, clear) { EXPECT_TRUE(queue.entries().empty()); } -}; -}; +} +} diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp index 02f740cee096..ee6beba847a0 100644 --- a/libs/hwui/tests/unit/VectorDrawableTests.cpp +++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp @@ -406,5 +406,5 @@ TEST(VectorDrawable, drawPathWithoutIncrementingShaderRefCount) { EXPECT_TRUE(shader->unique()); } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/thread/Barrier.h b/libs/hwui/thread/Barrier.h index 8faeee6b391a..bb750ca0fa88 100644 --- a/libs/hwui/thread/Barrier.h +++ b/libs/hwui/thread/Barrier.h @@ -48,7 +48,7 @@ private: mutable Condition mCondition; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_BARRIER_H diff --git a/libs/hwui/thread/Future.h b/libs/hwui/thread/Future.h index 45f3102492e3..df53348e58fb 100644 --- a/libs/hwui/thread/Future.h +++ b/libs/hwui/thread/Future.h @@ -53,7 +53,7 @@ private: T mResult; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_FUTURE_H diff --git a/libs/hwui/thread/Signal.h b/libs/hwui/thread/Signal.h index ffcd4b675a85..6d33ac473ac4 100644 --- a/libs/hwui/thread/Signal.h +++ b/libs/hwui/thread/Signal.h @@ -53,7 +53,7 @@ private: mutable Condition mCondition; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_SIGNAL_H diff --git a/libs/hwui/thread/Task.h b/libs/hwui/thread/Task.h index 276a22f941fe..228ce19a2fd5 100644 --- a/libs/hwui/thread/Task.h +++ b/libs/hwui/thread/Task.h @@ -48,7 +48,7 @@ private: sp<Future<T> > mFuture; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_TASK_H diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp index 54b55e472095..26ff6ebad3b4 100644 --- a/libs/hwui/thread/TaskManager.cpp +++ b/libs/hwui/thread/TaskManager.cpp @@ -129,5 +129,5 @@ void TaskManager::WorkerThread::exit() { mSignal.signal(); } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h index 29b4fcdbfde9..c4c1291e755c 100644 --- a/libs/hwui/thread/TaskManager.h +++ b/libs/hwui/thread/TaskManager.h @@ -101,7 +101,7 @@ private: std::vector<sp<WorkerThread> > mThreads; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_TASK_MANAGER_H diff --git a/libs/hwui/utils/Blur.cpp b/libs/hwui/utils/Blur.cpp index 1bc5646993c9..763d1aa177b7 100644 --- a/libs/hwui/utils/Blur.cpp +++ b/libs/hwui/utils/Blur.cpp @@ -178,5 +178,5 @@ void Blur::vertical(float* weights, int32_t radius, const uint8_t* source, uint8 } } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/utils/Blur.h b/libs/hwui/utils/Blur.h index bec3837106e8..d6b41b83def8 100644 --- a/libs/hwui/utils/Blur.h +++ b/libs/hwui/utils/Blur.h @@ -41,7 +41,7 @@ public: int32_t width, int32_t height); }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_HWUI_BLUR_H diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp index 3fb6a31a7d97..dc347f615d98 100644 --- a/libs/hwui/utils/Color.cpp +++ b/libs/hwui/utils/Color.cpp @@ -221,5 +221,5 @@ SkColor LabToSRGB(const Lab& lab, SkAlpha alpha) { static_cast<uint8_t>(rgb.b * 255)); } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/utils/FatVector.h b/libs/hwui/utils/FatVector.h index eafe2f13c16d..8cc4d1010ab6 100644 --- a/libs/hwui/utils/FatVector.h +++ b/libs/hwui/utils/FatVector.h @@ -99,7 +99,7 @@ private: typename InlineStdAllocator<T, SIZE>::Allocation mAllocation; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_FAT_VECTOR_H diff --git a/libs/hwui/utils/GLUtils.cpp b/libs/hwui/utils/GLUtils.cpp index fcd036c451e9..c694e93f7e21 100644 --- a/libs/hwui/utils/GLUtils.cpp +++ b/libs/hwui/utils/GLUtils.cpp @@ -76,5 +76,5 @@ const char* GLUtils::getGLFramebufferError() { } } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp index 3e5021cd45d4..8baa4b770f85 100644 --- a/libs/hwui/utils/LinearAllocator.cpp +++ b/libs/hwui/utils/LinearAllocator.cpp @@ -249,5 +249,5 @@ void LinearAllocator::dumpMemoryStats(const char* prefix) { ALOGD("%sPages %zu (dedicated %zu)", prefix, mPageCount, mDedicatedPageCount); } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/utils/LinearAllocator.h b/libs/hwui/utils/LinearAllocator.h index 03f685e8aca8..b401fcf58f76 100644 --- a/libs/hwui/utils/LinearAllocator.h +++ b/libs/hwui/utils/LinearAllocator.h @@ -201,7 +201,7 @@ public: : std::vector<T, LinearStdAllocator<T>>(allocator) {} }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif // ANDROID_LINEARALLOCATOR_H diff --git a/libs/hwui/utils/Pair.h b/libs/hwui/utils/Pair.h index 4bcd57629e0c..76f93cbfeb92 100644 --- a/libs/hwui/utils/Pair.h +++ b/libs/hwui/utils/Pair.h @@ -36,7 +36,7 @@ struct Pair { inline const S& getSecond() const { return second; } }; -}; // namespace uirenderer +} // namespace uirenderer template <typename F, typename S> struct trait_trivial_ctor<uirenderer::Pair<F, S> > { @@ -55,6 +55,6 @@ struct trait_trivial_move<uirenderer::Pair<F, S> > { enum { value = aggregate_traits<F, S>::has_trivial_move }; }; -}; // namespace android +} // namespace android #endif // ANDROID_HWUI_PAIR_H diff --git a/libs/hwui/utils/Result.h b/libs/hwui/utils/Result.h index 7f33f2e3424d..bd20ba66d8a7 100644 --- a/libs/hwui/utils/Result.h +++ b/libs/hwui/utils/Result.h @@ -51,4 +51,4 @@ private: std::variant<R, Error<E>> result; }; -}; // namespace android::uirenderer +} // namespace android::uirenderer diff --git a/libs/hwui/utils/RingBuffer.h b/libs/hwui/utils/RingBuffer.h index b3e893139cf8..081386a7f671 100644 --- a/libs/hwui/utils/RingBuffer.h +++ b/libs/hwui/utils/RingBuffer.h @@ -61,7 +61,7 @@ private: size_t mCount = 0; }; -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android #endif /* RINGBUFFER_H_ */ diff --git a/libs/hwui/utils/StringUtils.cpp b/libs/hwui/utils/StringUtils.cpp index 5304b762f3dc..304982e8e493 100644 --- a/libs/hwui/utils/StringUtils.cpp +++ b/libs/hwui/utils/StringUtils.cpp @@ -34,5 +34,5 @@ unordered_string_set StringUtils::split(const char* spacedList) { return set; } -}; // namespace uirenderer -}; // namespace android +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/utils/TypeLogic.h b/libs/hwui/utils/TypeLogic.h index dbdad33d8335..1689ccecd6b1 100644 --- a/libs/hwui/utils/TypeLogic.h +++ b/libs/hwui/utils/TypeLogic.h @@ -37,4 +37,4 @@ template <typename D, typename S> struct copy_cv { template <typename D, typename S> using same_cv = copy_cv<std::remove_cv_t<D>, S>; template <typename D, typename S> using same_cv_t = typename same_cv<D, S>::type; -}; // namespace android::uirenderer
\ No newline at end of file +} // namespace android::uirenderer diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index c226d49c6af7..71736dd38e91 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -2620,7 +2620,8 @@ public class AudioTrack extends PlayerBase * to the audio sink. * <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after * queuing as much audio data for playback as possible without blocking. - * @param timestamp The timestamp of the first decodable audio frame in the provided audioData. + * @param timestamp The timestamp, in nanoseconds, of the first decodable audio frame in the + * provided audioData. * @return zero or the positive number of bytes that were written, or one of the following * error codes. * <ul> diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 01a0cb619bf0..32c4643adad0 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -2635,13 +2635,18 @@ public class ExifInterface { if (size == 0) { return 0; } - // We don't allow read positions after the available bytes, - // the input stream won't be able to seek back then. - if (position < 0 || position >= in.available()) { + if (position < 0) { return -1; } try { if (mPosition != position) { + // We don't allow seek to positions after the available bytes, + // the input stream won't be able to seek back then. + // However, if we hit an exception before (mPosition set to -1), + // let it try the seek in hope it might recover. + if (mPosition >= 0 && position >= mPosition + in.available()) { + return -1; + } in.seek(position); mPosition = position; } @@ -2649,8 +2654,8 @@ public class ExifInterface { // If the read will cause us to go over the available bytes, // reduce the size so that we stay in the available range. // Otherwise the input stream may not be able to seek back. - if (mPosition + size > in.available()) { - size = in.available() - (int)mPosition; + if (size > in.available()) { + size = in.available(); } int bytesRead = in.read(buffer, offset, size); diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml index 91e23ddeaedf..03eafc4ab836 100644 --- a/packages/PrintSpooler/AndroidManifest.xml +++ b/packages/PrintSpooler/AndroidManifest.xml @@ -34,15 +34,23 @@ <uses-permission android:name="com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"/> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.READ_PRINT_SERVICES" /> <uses-permission android:name="android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" + android:dataSentOffDevice="no" + android:dataSharedWithThirdParty="no" + android:dataUsedForMonetization="no" + android:dataRetentionTime="unlimited"/> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" + android:dataSentOffDevice="no" + android:dataSharedWithThirdParty="no" + android:dataUsedForMonetization="no" + android:dataRetentionTime="unlimited"/> + <application android:allowClearUserData="true" android:label="@string/app_label" - android:allowBackup= "false" android:supportsRtl="true"> <service diff --git a/packages/SettingsLib/res/layout/preference_checkable_two_target.xml b/packages/SettingsLib/res/layout/preference_checkable_two_target.xml new file mode 100644 index 000000000000..1a47afc81d55 --- /dev/null +++ b/packages/SettingsLib/res/layout/preference_checkable_two_target.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<!-- Based off preference_material_settings.xml except that ripple on only on the left side. --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:settings="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:gravity="center_vertical" + android:background="@android:color/transparent" + android:clipToPadding="false"> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="?android:attr/selectableItemBackground" + android:gravity="start|center_vertical" + android:clipToPadding="false" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> + + <LinearLayout + android:id="@+id/checkbox_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="start|center_vertical" + android:minWidth="56dp" + android:orientation="horizontal" + android:clipToPadding="false" + android:paddingTop="4dp" + android:paddingBottom="4dp"> + <include layout="@layout/preference_widget_checkbox" /> + </LinearLayout> + + <RelativeLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:paddingTop="16dp" + android:paddingBottom="16dp"> + + <TextView + android:id="@android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceListItem" + android:ellipsize="marquee" /> + + <TextView + android:id="@android:id/summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@android:id/title" + android:layout_alignStart="@android:id/title" + android:textAppearance="?android:attr/textAppearanceListItemSecondary" + android:textColor="?android:attr/textColorSecondary" + android:maxLines="10" /> + + </RelativeLayout> + + </LinearLayout> + + <include layout="@layout/preference_two_target_divider" /> + + <!-- Preference should place its actual preference widget here. --> + <LinearLayout + android:id="@android:id/widget_frame" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:minWidth="64dp" + android:gravity="center" + android:orientation="vertical" /> + +</LinearLayout>
\ No newline at end of file diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java index 92fd86894d56..12b8efb1461c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java @@ -53,6 +53,8 @@ public final class CategoryKey { "com.android.settings.category.ia.night_display"; public static final String CATEGORY_PRIVACY = "com.android.settings.category.ia.privacy"; + public static final String CATEGORY_ENTERPRISE_PRIVACY = + "com.android.settings.category.ia.enterprise_privacy"; public static final Map<String, String> KEY_COMPAT_MAP; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java index a5e7f04be281..8821679aadf1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java @@ -33,7 +33,7 @@ import com.android.systemui.statusbar.notification.row.NotificationInflater.Infl * dozing and/or in AOD. The pulse uses the notification's ambient view and pops in briefly * before automatically dismissing the alert. */ -public final class AmbientPulseManager extends AlertingNotificationManager { +public class AmbientPulseManager extends AlertingNotificationManager { protected final ArraySet<OnAmbientChangedListener> mListeners = new ArraySet<>(); @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 626e68850c12..5d640e0216e0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -18,6 +18,8 @@ package com.android.systemui.statusbar.notification.stack; import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator .ExpandAnimationParameters; +import static com.android.systemui.statusbar.notification.stack.StackStateAnimator + .ANIMATION_DURATION_SWIPE; import static com.android.systemui.statusbar.phone.NotificationIconAreaController.LOW_PRIORITY; import android.animation.Animator; @@ -5093,7 +5095,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd if (i == 0) { endRunnable = animationFinishAction; } - dismissViewAnimated(view, endRunnable, totalDelay, 260); + dismissViewAnimated(view, endRunnable, totalDelay, ANIMATION_DURATION_SWIPE); currentDelay = Math.max(50, currentDelay - rowDelayDecrement); totalDelay += currentDelay; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java index fef28cf1393e..d6905478a043 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java @@ -44,6 +44,7 @@ public class StackStateAnimator { public static final int ANIMATION_DURATION_WAKEUP = 500; public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448; public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464; + public static final int ANIMATION_DURATION_SWIPE = 260; public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220; public static final int ANIMATION_DURATION_CLOSE_REMOTE_INPUT = 150; public static final int ANIMATION_DURATION_HEADS_UP_APPEAR = 550; diff --git a/services/core/java/com/android/server/AbstractPerUserSystemService.java b/services/core/java/com/android/server/AbstractPerUserSystemService.java index 71d261c7f5b5..001d85f1b798 100644 --- a/services/core/java/com/android/server/AbstractPerUserSystemService.java +++ b/services/core/java/com/android/server/AbstractPerUserSystemService.java @@ -108,7 +108,8 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst * <p>Typically called when the service {@link Settings} property or {@link UserManager} * restriction changed, which includes the initial creation of the service. * - * <p>Subclasses can extend this method to provide extra initialization. + * <p>Subclasses can extend this method to provide extra initialization, like clearing up + * previous state. * * @param disabled whether the service is disabled (due to {@link UserManager} restrictions). * diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index f0b472be1472..a2cbfaa02bfb 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -47,6 +47,7 @@ import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.telephony.emergency.EmergencyNumber; import android.util.LocalLog; import android.util.StatsLog; @@ -1664,6 +1665,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override + public void notifyEmergencyNumberList(List<EmergencyNumber> emergencyNumberList) { + // TODO checkPermission, modify Listener constent documentation + // TODO implement multisim emergency number list update in listener + // TODO implement PhoneStateListenerTest + } + + + @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index c2f4406c615d..bf95210195b7 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -313,6 +313,7 @@ public class NetworkMonitor extends StateMachine { private final State mCaptivePortalState = new CaptivePortalState(); private final State mEvaluatingPrivateDnsState = new EvaluatingPrivateDnsState(); private final State mProbingState = new ProbingState(); + private final State mWaitingForNextProbeState = new WaitingForNextProbeState(); private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null; @@ -368,6 +369,7 @@ public class NetworkMonitor extends StateMachine { addState(mMaybeNotifyState, mDefaultState); addState(mEvaluatingState, mMaybeNotifyState); addState(mProbingState, mEvaluatingState); + addState(mWaitingForNextProbeState, mEvaluatingState); addState(mCaptivePortalState, mMaybeNotifyState); addState(mEvaluatingPrivateDnsState, mDefaultState); addState(mValidatedState, mDefaultState); @@ -877,6 +879,11 @@ public class NetworkMonitor extends StateMachine { @Override public void enter() { + if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) { + //Don't continue to blame UID forever. + TrafficStats.clearThreadStatsUid(); + } + final int token = ++mProbeToken; mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0, isCaptivePortal()))); @@ -904,29 +911,16 @@ public class NetworkMonitor extends StateMachine { mLastPortalProbeResult = probeResult; transitionTo(mCaptivePortalState); } else { - final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0); - sendMessageDelayed(msg, mReevaluateDelayMs); logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED); notifyNetworkTestResultInvalid(probeResult.redirectUrl); - if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) { - // Don't continue to blame UID forever. - TrafficStats.clearThreadStatsUid(); - } - mReevaluateDelayMs *= 2; - if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) { - mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS; - } + transitionTo(mWaitingForNextProbeState); } return HANDLED; - case CMD_REEVALUATE: - // Leave the event to EvaluatingState. Defer this message will result in reset - // of mReevaluateDelayMs and mEvaluateAttempts. - case CMD_NETWORK_DISCONNECTED: case EVENT_DNS_NOTIFICATION: + // Leave the event to DefaultState to record correct dns timestamp. return NOT_HANDLED; default: - // TODO: Some events may able to handle in this state, instead of deferring to - // next state. + // Wait for probe result and defer events to next state by default. deferMessage(message); return HANDLED; } @@ -941,6 +935,29 @@ public class NetworkMonitor extends StateMachine { } } + // Being in the WaitingForNextProbeState indicates that evaluating probes failed and state is + // transited from ProbingState. This ensures that the state machine is only in ProbingState + // while a probe is in progress, not while waiting to perform the next probe. That allows + // ProbingState to defer most messages until the probe is complete, which keeps the code simple + // and matches the pre-Q behaviour where probes were a blocking operation performed on the state + // machine thread. + private class WaitingForNextProbeState extends State { + @Override + public void enter() { + final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0); + sendMessageDelayed(msg, mReevaluateDelayMs); + mReevaluateDelayMs *= 2; + if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) { + mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS; + } + } + + @Override + public boolean processMessage(Message message) { + return NOT_HANDLED; + } + } + // Limits the list of IP addresses returned by getAllByName or tried by openConnection to at // most one per address family. This ensures we only wait up to 20 seconds for TCP connections // to complete, regardless of how many IP addresses a host has. diff --git a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java index 6fe632459eaa..d5be26ac3389 100644 --- a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java +++ b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java @@ -27,12 +27,13 @@ import android.view.autofill.IAutoFillManagerClient; * * @hide Only for use within the system server. */ +//TODO(b/111276913): rename once the final name is defined public abstract class IntelligenceManagerInternal { /** * Checks whether the given {@code uid} owns the - * {@link android.service.intelligence.IntelligenceService} implementation associated with the - * given {@code userId}. + * {@link android.service.intelligence.SmartSuggestionsService} implementation associated with + * the given {@code userId}. */ public abstract boolean isIntelligenceServiceForUser(int uid, @UserIdInt int userId); diff --git a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java index 08fbf5549a87..108f91c7fe4c 100644 --- a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java +++ b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java @@ -19,9 +19,9 @@ import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.os.IBinder; -import android.service.intelligence.IntelligenceService; import android.service.intelligence.InteractionContext; import android.service.intelligence.InteractionSessionId; +import android.service.intelligence.SmartSuggestionsService; import android.service.intelligence.SnapshotData; import android.util.Slog; import android.view.autofill.AutofillId; @@ -59,7 +59,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks mService = service; mId = Preconditions.checkNotNull(sessionId); mRemoteService = new RemoteIntelligenceService(context, - IntelligenceService.SERVICE_INTERFACE, serviceComponentName, userId, this, + SmartSuggestionsService.SERVICE_INTERFACE, serviceComponentName, userId, this, bindInstantServiceAllowed, verbose); mInterationContext = new InteractionContext(appComponentName, taskId, displayId, flags); } @@ -72,7 +72,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks } /** - * Notifies the {@link IntelligenceService} that the service started. + * Notifies the {@link SmartSuggestionsService} that the service started. */ @GuardedBy("mLock") public void notifySessionStartedLocked() { @@ -80,14 +80,14 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks } /** - * Notifies the {@link IntelligenceService} of a batch of events. + * Notifies the {@link SmartSuggestionsService} of a batch of events. */ public void sendEventsLocked(@NonNull List<ContentCaptureEvent> events) { mRemoteService.onContentCaptureEventsRequest(mId, events); } /** - * Notifies the {@link IntelligenceService} of a snapshot of an activity. + * Notifies the {@link SmartSuggestionsService} of a snapshot of an activity. */ @GuardedBy("mLock") public void sendActivitySnapshotLocked(@NonNull SnapshotData snapshotData) { @@ -110,7 +110,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks * Cleans up the session and removes it from the service. * * @param notifyRemoteService whether it should trigger a {@link - * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)} + * SmartSuggestionsService#onDestroyInteractionSession(InteractionSessionId)} * request. */ @GuardedBy("mLock") @@ -126,7 +126,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks * Cleans up the session, but not removes it from the service. * * @param notifyRemoteService whether it should trigger a {@link - * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)} + * SmartSuggestionsService#onDestroyInteractionSession(InteractionSessionId)} * request. */ @GuardedBy("mLock") diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java index 9fd797d1e549..e0d47d2c8802 100644 --- a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java +++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java @@ -16,7 +16,7 @@ package com.android.server.intelligence; -import static android.content.Context.INTELLIGENCE_MANAGER_SERVICE; +import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE; import android.annotation.NonNull; import android.annotation.Nullable; @@ -50,6 +50,7 @@ import java.util.List; * <p>The data collected by this service can be analyzed and combined with other sources to provide * contextual data in other areas of the system such as Autofill. */ +//TODO(b/111276913): rename once the final name is defined public final class IntelligenceManagerService extends AbstractMasterSystemService<IntelligenceManagerService, IntelligencePerUserService> { @@ -67,7 +68,7 @@ public final class IntelligenceManagerService extends @Override // from AbstractMasterSystemService protected String getServiceSettingsProperty() { // TODO(b/111276913): STOPSHIP temporary settings, until it's set by resourcs + cmd - return "intel_service"; + return "smart_suggestions_service"; } @Override // from AbstractMasterSystemService @@ -78,7 +79,7 @@ public final class IntelligenceManagerService extends @Override // from SystemService public void onStart() { - publishBinderService(INTELLIGENCE_MANAGER_SERVICE, + publishBinderService(CONTENT_CAPTURE_MANAGER_SERVICE, new IntelligenceManagerServiceStub()); publishLocalService(IntelligenceManagerInternal.class, mLocalService); } diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java index 9ab7e58feb9b..84e06b04768c 100644 --- a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java +++ b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java @@ -41,7 +41,7 @@ import android.util.Slog; import android.view.autofill.AutofillId; import android.view.autofill.IAutoFillManagerClient; import android.view.intelligence.ContentCaptureEvent; -import android.view.intelligence.IntelligenceManager; +import android.view.intelligence.ContentCaptureManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.IResultReceiver; @@ -54,6 +54,7 @@ import java.util.List; /** * Per-user instance of {@link IntelligenceManagerService}. */ +//TODO(b/111276913): rename once the final name is defined final class IntelligencePerUserService extends AbstractPerUserSystemService<IntelligencePerUserService, IntelligenceManagerService> { @@ -86,16 +87,23 @@ final class IntelligencePerUserService Slog.w(TAG, "Could not get service for " + serviceComponent + ": " + e); return null; } - if (!Manifest.permission.BIND_INTELLIGENCE_SERVICE.equals(si.permission)) { - Slog.w(TAG, "IntelligenceService from '" + si.packageName + if (!Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE.equals(si.permission)) { + Slog.w(TAG, "SmartSuggestionsService from '" + si.packageName + "' does not require permission " - + Manifest.permission.BIND_INTELLIGENCE_SERVICE); + + Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE); throw new SecurityException("Service does not require permission " - + Manifest.permission.BIND_INTELLIGENCE_SERVICE); + + Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE); } return si; } + @Override // from PerUserSystemService + @GuardedBy("mLock") + protected boolean updateLocked(boolean disabled) { + destroyLocked(); + return super.updateLocked(disabled); + } + // TODO(b/111276913): log metrics @GuardedBy("mLock") public void startSessionLocked(@NonNull IBinder activityToken, @@ -103,7 +111,7 @@ final class IntelligencePerUserService @NonNull InteractionSessionId sessionId, int flags, @NonNull IResultReceiver resultReceiver) { if (!isEnabledLocked()) { - sendToClient(resultReceiver, IntelligenceManager.STATE_DISABLED); + sendToClient(resultReceiver, ContentCaptureManager.STATE_DISABLED); return; } final ComponentName serviceComponentName = getServiceComponentName(); @@ -126,7 +134,7 @@ final class IntelligencePerUserService // TODO(b/111276913): check if local ids match and decide what to do if they don't // TODO(b/111276913): should we call session.notifySessionStartedLocked() again?? // if not, move notifySessionStartedLocked() into session constructor - sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE); + sendToClient(resultReceiver, ContentCaptureManager.STATE_ACTIVE); return; } @@ -142,7 +150,7 @@ final class IntelligencePerUserService } mSessions.put(sessionId, session); session.notifySessionStartedLocked(); - sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE); + sendToClient(resultReceiver, ContentCaptureManager.STATE_ACTIVE); } // TODO(b/111276913): log metrics diff --git a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java index 00c5b6a1d67b..5ebb99eeddcf 100644 --- a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java +++ b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java @@ -23,6 +23,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.IInterface; import android.os.RemoteException; +import android.service.intelligence.ContentCaptureEventsRequest; import android.service.intelligence.IIntelligenceService; import android.service.intelligence.InteractionContext; import android.service.intelligence.InteractionSessionId; @@ -39,6 +40,7 @@ import com.android.server.AbstractRemoteService; import java.util.List; +//TODO(b/111276913): rename once the final name is defined final class RemoteIntelligenceService extends AbstractRemoteService { private static final String TAG = "RemoteIntelligenceService"; @@ -194,7 +196,8 @@ final class RemoteIntelligenceService extends AbstractRemoteService { @Override // from MyPendingRequest public void myRun(@NonNull RemoteIntelligenceService remoteService) throws RemoteException { - remoteService.mService.onContentCaptureEvents(mSessionId, mEvents); + remoteService.mService.onContentCaptureEventsRequest(mSessionId, + new ContentCaptureEventsRequest(mEvents)); } } diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp index 0c40a6b5fa84..de40e0df48e7 100644 --- a/startop/view_compiler/Android.bp +++ b/startop/view_compiler/Android.bp @@ -24,7 +24,6 @@ cc_defaults { "libdexfile", "slicer", ], - cppflags: ["-std=c++17"], } cc_library_host_static { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index d54da0905e18..7a6647c040da 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -5372,7 +5372,7 @@ public class TelephonyManager { /** * Rollback modem configurations to factory default except some config which are in whitelist. - * Used for device configuration by some CDMA operators. + * Used for device configuration by some carriers. * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling @@ -5399,7 +5399,7 @@ public class TelephonyManager { } /** - * Generate a radio modem reset. Used for device configuration by some CDMA operators. + * Generate a radio modem reset. Used for device configuration by some carriers. * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 923ab066ef0f..76e7509c1094 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -25,6 +25,7 @@ import android.telephony.PhoneCapability; import android.telephony.PhysicalChannelConfig; import android.telephony.ServiceState; import android.telephony.SignalStrength; +import android.telephony.emergency.EmergencyNumber; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.IOnSubscriptionsChangedListener; @@ -80,4 +81,5 @@ interface ITelephonyRegistry { void notifyPhoneCapabilityChanged(in PhoneCapability capability); void notifyPreferredDataSubIdChanged(int preferredSubId); void notifyRadioPowerStateChanged(in int state); + void notifyEmergencyNumberList(in List<EmergencyNumber> emergencyNumberList); } diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh index e50c70d0656a..f25fcdcb7479 100755 --- a/tools/aosp/aosp_sha.sh +++ b/tools/aosp/aosp_sha.sh @@ -19,6 +19,6 @@ else echo "If your change contains no confidential details (such as security fixes), please" echo "upload and merge this change at https://android-review.googlesource.com/." echo - exit 77 + exit 1 fi fi |