diff options
47 files changed, 721 insertions, 269 deletions
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java index 9ea6f7946fcf..01f31e43989e 100644 --- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java +++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java @@ -19,6 +19,7 @@ package android.app; import android.Manifest; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SystemApi; @@ -591,8 +592,8 @@ public class AlarmManager { * in milliseconds. The alarm will be delivered no later than this many * milliseconds after {@code windowStartMillis}. Note that this parameter * is a <i>duration,</i> not the timestamp of the end of the window. - * @param tag string describing the alarm, used for logging and battery-use - * attribution + * @param tag Optional. A string describing the alarm, used for logging and battery-use + * attribution. * @param listener {@link OnAlarmListener} instance whose * {@link OnAlarmListener#onAlarm() onAlarm()} method will be * called when the alarm time is reached. A given OnAlarmListener instance can @@ -605,9 +606,8 @@ public class AlarmManager { @SystemApi @RequiresPermission(Manifest.permission.SCHEDULE_PRIORITIZED_ALARM) public void setPrioritized(@AlarmType int type, long windowStartMillis, long windowLengthMillis, - @NonNull String tag, @NonNull Executor executor, @NonNull OnAlarmListener listener) { + @Nullable String tag, @NonNull Executor executor, @NonNull OnAlarmListener listener) { Objects.requireNonNull(executor); - Objects.requireNonNull(tag); Objects.requireNonNull(listener); setImpl(type, windowStartMillis, windowLengthMillis, 0, FLAG_PRIORITIZE, null, listener, tag, executor, null, null); @@ -782,6 +782,50 @@ public class AlarmManager { targetHandler, workSource, null); } + /** + * Exact version of {@link #set(int, long, long, long, OnAlarmListener, Handler, WorkSource)}. + * This equivalent to calling the aforementioned API with {@code windowMillis} and + * {@code intervalMillis} set to 0. + * One subtle difference is that this API requires {@code workSource} to be non-null. If you + * don't want to attribute this alarm to another app for battery consumption, you should use + * {@link #setExact(int, long, String, OnAlarmListener, Handler)} instead. + * + * <p> + * Note that using this API requires you to hold + * {@link Manifest.permission#SCHEDULE_EXACT_ALARM}, unless you are on the system's power + * allowlist. This can be set, for example, by marking the app as {@code <allow-in-power-save>} + * within the system config. + * + * @param type type of alarm + * @param triggerAtMillis The exact time in milliseconds, that the alarm should be delivered, + * expressed in the appropriate clock's units (depending on the alarm + * type). + * @param listener {@link OnAlarmListener} instance whose + * {@link OnAlarmListener#onAlarm() onAlarm()} method will be called when + * the alarm time is reached. + * @param executor The {@link Executor} on which to execute the listener's onAlarm() + * callback. + * @param tag Optional. A string tag used to identify this alarm in logs and + * battery-attribution. + * @param workSource A {@link WorkSource} object to attribute this alarm to the app that + * requested this work. + * @hide + */ + @SystemApi + @RequiresPermission(allOf = { + Manifest.permission.UPDATE_DEVICE_STATS, + Manifest.permission.SCHEDULE_EXACT_ALARM}, conditional = true) + public void setExact(@AlarmType int type, long triggerAtMillis, @Nullable String tag, + @NonNull Executor executor, @NonNull WorkSource workSource, + @NonNull OnAlarmListener listener) { + Objects.requireNonNull(executor); + Objects.requireNonNull(workSource); + Objects.requireNonNull(listener); + setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, null, listener, tag, executor, + workSource, null); + } + + private void setImpl(@AlarmType int type, long triggerAtMillis, long windowMillis, long intervalMillis, int flags, PendingIntent operation, final OnAlarmListener listener, String listenerTag, Handler targetHandler, WorkSource workSource, diff --git a/apex/jobscheduler/service/jni/Android.bp b/apex/jobscheduler/service/jni/Android.bp index 333da74400e0..34a1fa2ebc13 100644 --- a/apex/jobscheduler/service/jni/Android.bp +++ b/apex/jobscheduler/service/jni/Android.bp @@ -29,14 +29,3 @@ cc_library_shared { "libbase", ], } - -filegroup { - name: "lib_alarmManagerService_native", - srcs: [ - "com_android_server_alarm_AlarmManagerService.cpp", - ], - visibility: [ - // TODO: remove this - "//vendor:__subpackages__", - ], -} diff --git a/core/api/current.txt b/core/api/current.txt index 73d89176bb98..3dfab41e7d07 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -24614,7 +24614,6 @@ package android.media.effect { package android.media.metrics { public abstract class Event { - ctor protected Event(long); method @NonNull public android.os.Bundle getMetricsBundle(); method @IntRange(from=0xffffffff) public long getTimeSinceCreatedMillis(); } @@ -24624,7 +24623,7 @@ package android.media.metrics { field @NonNull public static final android.media.metrics.LogSessionId LOG_SESSION_ID_NONE; } - public class MediaMetricsManager { + public final class MediaMetricsManager { method @NonNull public android.media.metrics.PlaybackSession createPlaybackSession(); method @NonNull public android.media.metrics.RecordingSession createRecordingSession(); field public static final long INVALID_TIMESTAMP = -1L; // 0xffffffffffffffffL @@ -52671,6 +52670,22 @@ package android.view.textservice { method public void onGetSuggestions(android.view.textservice.SuggestionsInfo[]); } + public static class SpellCheckerSession.SpellCheckerSessionParams { + method @NonNull public android.os.Bundle getExtras(); + method @Nullable public java.util.Locale getLocale(); + method public int getSupportedAttributes(); + method public boolean shouldReferToSpellCheckerLanguageSettings(); + } + + public static final class SpellCheckerSession.SpellCheckerSessionParams.Builder { + ctor public SpellCheckerSession.SpellCheckerSessionParams.Builder(); + method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams build(); + method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams.Builder setExtras(@NonNull android.os.Bundle); + method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams.Builder setLocale(@Nullable java.util.Locale); + method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams.Builder setShouldReferToSpellCheckerLanguageSettings(boolean); + method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams.Builder setSupportedAttributes(int); + } + public final class SpellCheckerSubtype implements android.os.Parcelable { ctor @Deprecated public SpellCheckerSubtype(int, String, String); method public boolean containsExtraValueKey(String); @@ -52724,7 +52739,7 @@ package android.view.textservice { method @NonNull public java.util.List<android.view.textservice.SpellCheckerInfo> getEnabledSpellCheckerInfos(); method public boolean isSpellCheckerEnabled(); method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@Nullable android.os.Bundle, @Nullable java.util.Locale, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean); - method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@Nullable java.util.Locale, boolean, int, @Nullable android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener); + method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams, @NonNull java.util.concurrent.Executor, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener); } } diff --git a/core/api/system-current.txt b/core/api/system-current.txt index fb6c457ecbd6..adbf18fb54c8 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -438,7 +438,8 @@ package android.app { public class AlarmManager { method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, android.app.PendingIntent, android.os.WorkSource); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, android.app.AlarmManager.OnAlarmListener, android.os.Handler, android.os.WorkSource); - method @RequiresPermission(android.Manifest.permission.SCHEDULE_PRIORITIZED_ALARM) public void setPrioritized(int, long, long, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.app.AlarmManager.OnAlarmListener); + method @RequiresPermission(allOf={android.Manifest.permission.UPDATE_DEVICE_STATS, android.Manifest.permission.SCHEDULE_EXACT_ALARM}, conditional=true) public void setExact(int, long, @Nullable String, @NonNull java.util.concurrent.Executor, @NonNull android.os.WorkSource, @NonNull android.app.AlarmManager.OnAlarmListener); + method @RequiresPermission(android.Manifest.permission.SCHEDULE_PRIORITIZED_ALARM) public void setPrioritized(int, long, long, @Nullable String, @NonNull java.util.concurrent.Executor, @NonNull android.app.AlarmManager.OnAlarmListener); } public class AppOpsManager { @@ -11108,10 +11109,6 @@ package android.telephony { field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool"; } - public static final class CarrierConfigManager.Ims { - field public static final String KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY = "ims.publish_service_desc_feature_tag_map_override_string_array"; - } - public static final class CarrierConfigManager.Wifi { field public static final String KEY_AVOID_5GHZ_SOFTAP_FOR_LAA_BOOL = "wifi.avoid_5ghz_softap_for_laa_bool"; field public static final String KEY_AVOID_5GHZ_WIFI_DIRECT_FOR_LAA_BOOL = "wifi.avoid_5ghz_wifi_direct_for_laa_bool"; diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 45120b694b62..77f0cf8578d4 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -8792,11 +8792,11 @@ public class Activity extends ContextThemeWrapper * @hide */ public void updateUiTranslationState(int state, TranslationSpec sourceSpec, - TranslationSpec destSpec, List<AutofillId> viewIds) { + TranslationSpec targetSpec, List<AutofillId> viewIds) { if (mUiTranslationController == null) { mUiTranslationController = new UiTranslationController(this, getApplicationContext()); } - mUiTranslationController.updateUiTranslationState(state, sourceSpec, destSpec, viewIds); + mUiTranslationController.updateUiTranslationState(state, sourceSpec, targetSpec, viewIds); } class HostCallbacks extends FragmentHostCallback<Activity> { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 98fee9cf90cf..0acc4b3b6110 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1835,12 +1835,12 @@ public final class ActivityThread extends ClientTransactionHandler @Override public void updateUiTranslationState(IBinder activityToken, int state, - TranslationSpec sourceSpec, TranslationSpec destSpec, List<AutofillId> viewIds) { + TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds) { SomeArgs args = SomeArgs.obtain(); args.arg1 = activityToken; args.arg2 = state; args.arg3 = sourceSpec; - args.arg4 = destSpec; + args.arg4 = targetSpec; args.arg5 = viewIds; sendMessage(H.UPDATE_UI_TRANSLATION_STATE, args); } @@ -4169,13 +4169,13 @@ public final class ActivityThread extends ClientTransactionHandler } private void updateUiTranslationState(IBinder activityToken, int state, - TranslationSpec sourceSpec, TranslationSpec destSpec, List<AutofillId> viewIds) { + TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds) { final ActivityClientRecord r = mActivities.get(activityToken); if (r == null) { Log.w(TAG, "updateUiTranslationState(): no activity for " + activityToken); return; } - r.activity.updateUiTranslationState(state, sourceSpec, destSpec, viewIds); + r.activity.updateUiTranslationState(state, sourceSpec, targetSpec, viewIds); } private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl index 78e7ce8c594e..918309e8e735 100644 --- a/core/java/android/app/IApplicationThread.aidl +++ b/core/java/android/app/IApplicationThread.aidl @@ -160,5 +160,5 @@ oneway interface IApplicationThread { IUiAutomationConnection instrumentationUiConnection, in ApplicationInfo targetInfo); void updateUiTranslationState(IBinder activityToken, int state, in TranslationSpec sourceSpec, - in TranslationSpec destSpec, in List<AutofillId> viewIds); + in TranslationSpec targetSpec, in List<AutofillId> viewIds); } diff --git a/core/java/android/os/CountDownTimer.java b/core/java/android/os/CountDownTimer.java index c7bf0fd6ba49..51faa855727e 100644 --- a/core/java/android/os/CountDownTimer.java +++ b/core/java/android/os/CountDownTimer.java @@ -22,7 +22,22 @@ package android.os; * * Example of showing a 30 second countdown in a text field: * - * <pre class="prettyprint"> + * <div> + * <div class="ds-selector-tabs"><section><h3 id="kotlin">Kotlin</h3> + * <pre class="prettyprint lang-kotlin"> + * object : CountDownTimer(30000, 1000) { + * + * override fun onTick(millisUntilFinished: Long) { + * mTextField.setText("seconds remaining: " + millisUntilFinished / 1000) + * } + * + * override fun onFinish() { + * mTextField.setText("done!") + * } + * }.start() + * </pre> + * </section><section><h3 id="java">Java</h3> + * <pre class="prettyprint lang-java"> * new CountDownTimer(30000, 1000) { * * public void onTick(long millisUntilFinished) { @@ -32,8 +47,8 @@ package android.os; * public void onFinish() { * mTextField.setText("done!"); * } - * }.start(); - * </pre> + * }.start(); + * </pre></section></div></div> * * The calls to {@link #onTick(long)} are synchronized to this object so that * one call to {@link #onTick(long)} won't ever occur before the previous diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index e3b13f4f9f17..b8bb353a1c2f 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -623,7 +623,7 @@ public final class Debug * </tr> * <tr> * <td>summary.total-pss</td> - * <td>Total PPS memory usage in kB.</td> + * <td>Total PSS memory usage in kB.</td> * <td>{@code 1442}</td> * <td>23</td> * </tr> diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java index 7a624e1da26c..a537c98fc497 100644 --- a/core/java/android/os/Parcelable.java +++ b/core/java/android/os/Parcelable.java @@ -27,10 +27,39 @@ import java.lang.annotation.RetentionPolicy; * and restored from a {@link Parcel}. Classes implementing the Parcelable * interface must also have a non-null static field called <code>CREATOR</code> * of a type that implements the {@link Parcelable.Creator} interface. - * + * * <p>A typical implementation of Parcelable is:</p> - * - * <pre> + * + * <div> + * <div class="ds-selector-tabs"><section><h3 id="kotlin">Kotlin</h3> + * <pre class="prettyprint lang-kotlin"> + * class MyParcelable private constructor(`in`: Parcel) : Parcelable { + * private val mData: Int = `in`.readInt() + * + * override fun describeContents(): Int { + * return 0 + * } + * + * override fun writeToParcel(out: Parcel, flags: Int) { + * out.writeInt(mData) + * } + * + * companion object { + * val CREATOR: Parcelable.Creator<MyParcelable?> + * = object : Parcelable.Creator<MyParcelable?> { + * override fun createFromParcel(`in`: Parcel): MyParcelable? { + * return MyParcelable(`in`) + * } + * + * override fun newArray(size: Int): Array<MyParcelable?> { + * return arrayOfNulls(size) + * } + * } + * } + * } + * </pre> + * </section><section><h3 id="java">Java</h3> + * <pre class="prettyprint lang-java"> * public class MyParcelable implements Parcelable { * private int mData; * @@ -52,11 +81,11 @@ import java.lang.annotation.RetentionPolicy; * return new MyParcelable[size]; * } * }; - * + * * private MyParcelable(Parcel in) { * mData = in.readInt(); * } - * }</pre> + * }</pre></section></div></div> */ public interface Parcelable { /** @hide */ diff --git a/core/java/android/service/translation/TranslationService.java b/core/java/android/service/translation/TranslationService.java index a3bbdb9af475..b79e69201fc6 100644 --- a/core/java/android/service/translation/TranslationService.java +++ b/core/java/android/service/translation/TranslationService.java @@ -283,6 +283,5 @@ public abstract class TranslationService extends Service { resultReceiver.send(TranslationManager.STATUS_SYNC_CALL_SUCCESS, bundle); } }); - } } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 4977a6e59ede..83669fa96a9b 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -34,6 +34,7 @@ import android.annotation.Size; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; +import android.graphics.BLASTBufferQueue; import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; import android.graphics.Matrix; @@ -95,6 +96,7 @@ public final class SurfaceControl implements Parcelable { private static native void nativeWriteToParcel(long nativeObject, Parcel out); private static native void nativeRelease(long nativeObject); private static native void nativeDisconnect(long nativeObject); + private static native void nativeUpdateDefaultBufferSize(long nativeObject, int width, int height); private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs, ScreenCaptureListener captureListener); private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs, @@ -1083,6 +1085,11 @@ public final class SurfaceControl implements Parcelable { throw new IllegalStateException( "Only buffer layers can set a valid buffer size."); } + boolean isBqLayer = isBufferQueueLayer(); + if (isBqLayer) { + setBLASTLayer(); + } + return new SurfaceControl( mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata, mLocalOwnerView, mCallsite); @@ -1139,9 +1146,6 @@ public final class SurfaceControl implements Parcelable { return setFlags(FX_SURFACE_NORMAL, FX_SURFACE_MASK); } - /** - * Set the initial size of the controlled surface's buffers in pixels. - */ private void unsetBufferSize() { mWidth = 0; mHeight = 0; @@ -1306,11 +1310,14 @@ public final class SurfaceControl implements Parcelable { return (mFlags & FX_SURFACE_EFFECT) == FX_SURFACE_EFFECT; } + private boolean isBufferQueueLayer() { + return (mFlags & FX_SURFACE_NORMAL) == FX_SURFACE_NORMAL; + } + /** * @hide */ public Builder setBLASTLayer() { - unsetBufferSize(); return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK); } @@ -2659,8 +2666,7 @@ public final class SurfaceControl implements Parcelable { final Point size = mResizedSurfaces.valueAt(i); final SurfaceControl surfaceControl = mResizedSurfaces.keyAt(i); synchronized (surfaceControl.mLock) { - surfaceControl.mWidth = size.x; - surfaceControl.mHeight = size.y; + surfaceControl.resize(size.x, size.y); } } mResizedSurfaces.clear(); @@ -3576,4 +3582,13 @@ public final class SurfaceControl implements Parcelable { public static Transaction getGlobalTransaction() { return sGlobalTransaction; } + + /** + * @hide + */ + public void resize(int w, int h) { + mWidth = w; + mHeight = h; + nativeUpdateDefaultBufferSize(mNativeObject, w, h); + } } diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java index a449cf1876e1..6cfb9381f130 100644 --- a/core/java/android/view/textservice/SpellCheckerSession.java +++ b/core/java/android/view/textservice/SpellCheckerSession.java @@ -17,10 +17,13 @@ package android.view.textservice; import android.annotation.BinderThread; +import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; import android.os.Binder; import android.os.Build; +import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -37,6 +40,7 @@ import com.android.internal.textservice.ITextServicesSessionListener; import dalvik.system.CloseGuard; import java.util.LinkedList; +import java.util.Locale; import java.util.Queue; import java.util.concurrent.Executor; @@ -525,6 +529,161 @@ public class SpellCheckerSession { } } + /** Parameters used to create a {@link SpellCheckerSession}. */ + public static class SpellCheckerSessionParams { + @Nullable + private final Locale mLocale; + private final boolean mShouldReferToSpellCheckerLanguageSettings; + private final @SuggestionsInfo.ResultAttrs int mSupportedAttributes; + private final Bundle mExtras; + + private SpellCheckerSessionParams(Locale locale, + boolean referToSpellCheckerLanguageSettings, int supportedAttributes, + Bundle extras) { + mLocale = locale; + mShouldReferToSpellCheckerLanguageSettings = referToSpellCheckerLanguageSettings; + mSupportedAttributes = supportedAttributes; + mExtras = extras; + } + + /** + * Returns the locale in which the spell checker should operate. + * + * @see android.service.textservice.SpellCheckerService.Session#getLocale() + */ + @SuppressLint("UseIcu") + @Nullable + public Locale getLocale() { + return mLocale; + } + + /** + * Returns true if the user's spell checker language settings should be used to determine + * the spell checker locale. + */ + public boolean shouldReferToSpellCheckerLanguageSettings() { + return mShouldReferToSpellCheckerLanguageSettings; + } + + /** + * Returns a bitmask of {@link SuggestionsInfo} attributes that the spell checker can set + * in {@link SuggestionsInfo} it returns. + * + * @see android.service.textservice.SpellCheckerService.Session#getSupportedAttributes() + */ + public @SuggestionsInfo.ResultAttrs int getSupportedAttributes() { + return mSupportedAttributes; + } + + /** + * Returns a bundle containing extra parameters for the spell checker. + * + * <p>This bundle can be used to pass implementation-specific parameters to the + * {@link android.service.textservice.SpellCheckerService} implementation. + * + * @see android.service.textservice.SpellCheckerService.Session#getBundle() + */ + @NonNull + public Bundle getExtras() { + return mExtras; + } + + /** Builder of {@link SpellCheckerSessionParams}. */ + public static final class Builder { + @Nullable + private Locale mLocale; + private boolean mShouldReferToSpellCheckerLanguageSettings = false; + private @SuggestionsInfo.ResultAttrs int mSupportedAttributes = 0; + private Bundle mExtras = Bundle.EMPTY; + + /** Constructs a {@code Builder}. */ + public Builder() { + } + + /** + * Returns constructed {@link SpellCheckerSession} instance. + * + * <p>Before calling this method, either {@link #setLocale(Locale)} should be called + * with a non-null locale or + * {@link #setShouldReferToSpellCheckerLanguageSettings(boolean)} should be called with + * {@code true}. + */ + @NonNull + public SpellCheckerSessionParams build() { + if (mLocale == null && !mShouldReferToSpellCheckerLanguageSettings) { + throw new IllegalArgumentException("mLocale should not be null if " + + " mShouldReferToSpellCheckerLanguageSettings is false."); + } + return new SpellCheckerSessionParams(mLocale, + mShouldReferToSpellCheckerLanguageSettings, mSupportedAttributes, mExtras); + } + + /** + * Sets the locale in which the spell checker should operate. + * + * @see android.service.textservice.SpellCheckerService.Session#getLocale() + */ + @NonNull + public Builder setLocale(@SuppressLint("UseIcu") @Nullable Locale locale) { + mLocale = locale; + return this; + } + + /** + * Sets whether or not the user's spell checker language settings should be used to + * determine spell checker locale. + * + * <p>If {@code shouldReferToSpellCheckerLanguageSettings} is true, the exact way of + * determining spell checker locale differs based on {@code locale} specified in + * {@link #setLocale(Locale)}. + * If {@code shouldReferToSpellCheckerLanguageSettings} is true and {@code locale} is + * null, the locale specified in Settings will be used. If + * {@code shouldReferToSpellCheckerLanguageSettings} is true and {@code locale} is not + * null, {@link SpellCheckerSession} can be created only when the locale specified in + * Settings is the same as {@code locale}. Exceptionally, if + * {@code shouldReferToSpellCheckerLanguageSettings} is true and {@code locale} is + * language only (e.g. "en"), the specified locale in Settings (e.g. "en_US") will be + * used. + * + * @see #setLocale(Locale) + */ + @NonNull + public Builder setShouldReferToSpellCheckerLanguageSettings( + boolean shouldReferToSpellCheckerLanguageSettings) { + mShouldReferToSpellCheckerLanguageSettings = + shouldReferToSpellCheckerLanguageSettings; + return this; + } + + /** + * Sets a bitmask of {@link SuggestionsInfo} attributes that the spell checker can set + * in {@link SuggestionsInfo} it returns. + * + * @see android.service.textservice.SpellCheckerService.Session#getSupportedAttributes() + */ + @NonNull + public Builder setSupportedAttributes( + @SuggestionsInfo.ResultAttrs int supportedAttributes) { + mSupportedAttributes = supportedAttributes; + return this; + } + + /** + * Sets a bundle containing extra parameters for the spell checker. + * + * <p>This bundle can be used to pass implementation-specific parameters to the + * {@link android.service.textservice.SpellCheckerService} implementation. + * + * @see android.service.textservice.SpellCheckerService.Session#getBundle() + */ + @NonNull + public Builder setExtras(@NonNull Bundle extras) { + mExtras = extras; + return this; + } + } + } + /** * Callback for getting results from text services */ diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java index bf91cca85522..ae927cf60565 100644 --- a/core/java/android/view/textservice/TextServicesManager.java +++ b/core/java/android/view/textservice/TextServicesManager.java @@ -19,7 +19,6 @@ package android.view.textservice; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SuppressLint; import android.annotation.SystemService; import android.annotation.UserIdInt; import android.compat.annotation.UnsupportedAppUsage; @@ -35,6 +34,7 @@ import android.os.UserHandle; import android.util.Log; import android.view.inputmethod.InputMethodManager; import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener; +import android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams; import com.android.internal.textservice.ISpellCheckerSessionListener; import com.android.internal.textservice.ITextServicesManager; @@ -166,15 +166,17 @@ public final class TextServicesManager { * {@link SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS} will be passed to the spell * checker as supported attributes. * - * @see #newSpellCheckerSession(Locale, boolean, int, Bundle, Executor, - * SpellCheckerSessionListener) - * @param bundle A bundle to pass to the spell checker. - * @param locale The locale for the spell checker. - * @param listener A spell checker session lister for getting results from the spell checker. - * The listener will be called on the calling thread. - * @param referToSpellCheckerLanguageSettings If true, the session for one of enabled - * languages in settings will be used. - * @return A spell checker session from the spell checker. + * @param locale the locale for the spell checker. If {@code locale} is null and + * referToSpellCheckerLanguageSettings is true, the locale specified in Settings will be + * returned. If {@code locale} is not null and referToSpellCheckerLanguageSettings is true, + * the locale specified in Settings will be returned only when it is same as {@code locale}. + * Exceptionally, when referToSpellCheckerLanguageSettings is true and {@code locale} is + * only language (e.g. "en"), the specified locale in Settings (e.g. "en_US") will be + * selected. + * @param listener a spell checker session lister for getting results from the spell checker. + * @param referToSpellCheckerLanguageSettings if true, the session for one of enabled + * languages in settings will be returned. + * @return a spell checker session of the spell checker */ @Nullable public SpellCheckerSession newSpellCheckerSession(@Nullable Bundle bundle, @@ -186,51 +188,40 @@ public final class TextServicesManager { int supportedAttributes = SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO | SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS; + SpellCheckerSessionParams.Builder paramsBuilder = new SpellCheckerSessionParams.Builder() + .setLocale(locale) + .setShouldReferToSpellCheckerLanguageSettings(referToSpellCheckerLanguageSettings) + .setSupportedAttributes(supportedAttributes); + if (bundle != null) { + paramsBuilder.setExtras(bundle); + } // Using the implicit looper to preserve the old behavior. Executor executor = new HandlerExecutor(new Handler()); - return newSpellCheckerSession(locale, referToSpellCheckerLanguageSettings, - supportedAttributes, bundle, executor, listener); + return newSpellCheckerSession(paramsBuilder.build(), executor, listener); } /** * Get a spell checker session from the spell checker. * - * <p>If {@code locale} is null and {@code referToSpellCheckerLanguageSettings} is true, the - * locale specified in Settings will be used. If {@code locale} is not null and - * {@code referToSpellCheckerLanguageSettings} is true, the locale specified in Settings will be - * returned only when it is same as {@code locale}. - * Exceptionally, when {@code referToSpellCheckerLanguageSettings} is true and {@code locale} is - * language only (e.g. "en"), the specified locale in Settings (e.g. "en_US") will be - * selected. - * - * @param locale The locale for the spell checker. - * @param referToSpellCheckerLanguageSettings If true, the session for one of enabled - * languages in settings will be used. - * @param supportedAttributes A union of {@link SuggestionsInfo} attributes that the spell - * checker can set in the spell checking results. - * @param bundle A bundle for passing implementation-specific extra parameters for the spell - * checker. You can check the current spell checker package by - * {@link #getCurrentSpellCheckerInfo()}. - * @param executor An executor to call the listener on. - * @param listener A spell checker session lister for getting results from a spell checker. + * @param params The parameters passed to the spell checker. + * @param executor The executor on which {@code listener} will be called back. + * @param listener a spell checker session lister for getting results from the spell checker. * @return The spell checker session of the spell checker. */ @Nullable public SpellCheckerSession newSpellCheckerSession( - @SuppressLint("UseIcu") @Nullable Locale locale, - boolean referToSpellCheckerLanguageSettings, - @SuggestionsInfo.ResultAttrs int supportedAttributes, - @Nullable Bundle bundle, + @NonNull SpellCheckerSessionParams params, @NonNull @CallbackExecutor Executor executor, @NonNull SpellCheckerSessionListener listener) { Objects.requireNonNull(executor); Objects.requireNonNull(listener); - if (!referToSpellCheckerLanguageSettings && locale == null) { + Locale locale = params.getLocale(); + if (!params.shouldReferToSpellCheckerLanguageSettings() && locale == null) { throw new IllegalArgumentException("Locale should not be null if you don't refer" + " settings."); } - if (referToSpellCheckerLanguageSettings && !isSpellCheckerEnabled()) { + if (params.shouldReferToSpellCheckerLanguageSettings() && !isSpellCheckerEnabled()) { return null; } @@ -244,7 +235,7 @@ public final class TextServicesManager { return null; } SpellCheckerSubtype subtypeInUse = null; - if (referToSpellCheckerLanguageSettings) { + if (params.shouldReferToSpellCheckerLanguageSettings()) { subtypeInUse = getCurrentSpellCheckerSubtype(true); if (subtypeInUse == null) { return null; @@ -278,7 +269,8 @@ public final class TextServicesManager { try { mService.getSpellCheckerService(mUserId, sci.getId(), subtypeInUse.getLocale(), session.getTextServicesSessionListener(), - session.getSpellCheckerSessionListener(), bundle, supportedAttributes); + session.getSpellCheckerSessionListener(), + params.getExtras(), params.getSupportedAttributes()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/view/translation/TranslationResponse.java b/core/java/android/view/translation/TranslationResponse.java index f9b7012b8f03..eef283d7a6db 100644 --- a/core/java/android/view/translation/TranslationResponse.java +++ b/core/java/android/view/translation/TranslationResponse.java @@ -87,7 +87,7 @@ public final class TranslationResponse implements Parcelable { /** * Adds {@link TranslationResponseValue} to be translated. The input * TranslationResponseValue format should match those provided by the - * {@link android.view.translation.Translator}'s destSpec. + * {@link android.view.translation.Translator}'s targetSpec. * * @param value the translated value. * @return this Builder. @@ -109,7 +109,7 @@ public final class TranslationResponse implements Parcelable { /** * Sets the list of {@link ViewTranslationResponse} to be translated. The input * ViewTranslationResponse contains {@link TranslationResponseValue}s whose format should - * match those provided by the {@link android.view.translation.Translator}'s destSpec. + * match those provided by the {@link android.view.translation.Translator}'s targetSpec. * * @param response the translated response. * @return this Builder. diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java index 00aeede2b242..b6d3d0953d71 100644 --- a/core/java/android/view/translation/UiTranslationController.java +++ b/core/java/android/view/translation/UiTranslationController.java @@ -100,7 +100,7 @@ public class UiTranslationController { * Update the Ui translation state. */ public void updateUiTranslationState(@UiTranslationState int state, TranslationSpec sourceSpec, - TranslationSpec destSpec, List<AutofillId> views) { + TranslationSpec targetSpec, List<AutofillId> views) { if (!mActivity.isResumed() && (state == STATE_UI_TRANSLATION_STARTED || state == STATE_UI_TRANSLATION_RESUMED)) { return; @@ -113,11 +113,11 @@ public class UiTranslationController { switch (state) { case STATE_UI_TRANSLATION_STARTED: final Pair<TranslationSpec, TranslationSpec> specs = - new Pair<>(sourceSpec, destSpec); + new Pair<>(sourceSpec, targetSpec); if (!mTranslators.containsKey(specs)) { mWorkerHandler.sendMessage(PooledLambda.obtainMessage( UiTranslationController::createTranslatorAndStart, - UiTranslationController.this, sourceSpec, destSpec, views)); + UiTranslationController.this, sourceSpec, targetSpec, views)); } else { onUiTranslationStarted(mTranslators.get(specs), views); } @@ -386,12 +386,13 @@ public class UiTranslationController { * translation when the Translator is created successfully. */ @WorkerThread - private void createTranslatorAndStart(TranslationSpec sourceSpec, TranslationSpec destSpec, + private void createTranslatorAndStart(TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> views) { - final Translator translator = createTranslatorIfNeeded(sourceSpec, destSpec); + // Create Translator + final Translator translator = createTranslatorIfNeeded(sourceSpec, targetSpec); if (translator == null) { - Log.w(TAG, "Can not create Translator for sourceSpec:" + sourceSpec + " destSpec:" - + destSpec); + Log.w(TAG, "Can not create Translator for sourceSpec:" + sourceSpec + " targetSpec:" + + targetSpec); return; } onUiTranslationStarted(translator, views); diff --git a/core/java/android/view/translation/UiTranslationManager.java b/core/java/android/view/translation/UiTranslationManager.java index 62868acac756..130e07889d84 100644 --- a/core/java/android/view/translation/UiTranslationManager.java +++ b/core/java/android/view/translation/UiTranslationManager.java @@ -124,7 +124,7 @@ public final class UiTranslationManager { * ActivityId)} instead. * * @param sourceSpec {@link TranslationSpec} for the data to be translated. - * @param destSpec {@link TranslationSpec} for the translated data. + * @param targetSpec {@link TranslationSpec} for the translated data. * @param viewIds A list of the {@link View}'s {@link AutofillId} which needs to be translated * @param taskId the Activity Task id which needs ui translation * @deprecated Use {@code startTranslation(TranslationSpec, TranslationSpec, List<AutofillId>, @@ -137,17 +137,17 @@ public final class UiTranslationManager { @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) @SystemApi public void startTranslation(@NonNull TranslationSpec sourceSpec, - @NonNull TranslationSpec destSpec, @NonNull List<AutofillId> viewIds, + @NonNull TranslationSpec targetSpec, @NonNull List<AutofillId> viewIds, int taskId) { Objects.requireNonNull(sourceSpec); - Objects.requireNonNull(destSpec); + Objects.requireNonNull(targetSpec); Objects.requireNonNull(viewIds); if (viewIds.size() == 0) { throw new IllegalArgumentException("Invalid empty views: " + viewIds); } try { mService.updateUiTranslationStateByTaskId(STATE_UI_TRANSLATION_STARTED, sourceSpec, - destSpec, viewIds, taskId, mContext.getUserId()); + targetSpec, viewIds, taskId, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -157,11 +157,11 @@ public final class UiTranslationManager { * Request ui translation for a given Views. * * @param sourceSpec {@link TranslationSpec} for the data to be translated. - * @param destSpec {@link TranslationSpec} for the translated data. + * @param targetSpec {@link TranslationSpec} for the translated data. * @param viewIds A list of the {@link View}'s {@link AutofillId} which needs to be translated * @param activityId the identifier for the Activity which needs ui translation * @throws IllegalArgumentException if the no {@link View}'s {@link AutofillId} in the list - * @throws NullPointerException the sourceSpec, destSpec, viewIds, activityId or + * @throws NullPointerException the sourceSpec, targetSpec, viewIds, activityId or * {@link android.app.assist.ActivityId#getToken()} is {@code null} * * @hide @@ -169,11 +169,11 @@ public final class UiTranslationManager { @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) @SystemApi public void startTranslation(@NonNull TranslationSpec sourceSpec, - @NonNull TranslationSpec destSpec, @NonNull List<AutofillId> viewIds, + @NonNull TranslationSpec targetSpec, @NonNull List<AutofillId> viewIds, @NonNull ActivityId activityId) { // TODO(b/177789967): Return result code or find a way to notify the status. Objects.requireNonNull(sourceSpec); - Objects.requireNonNull(destSpec); + Objects.requireNonNull(targetSpec); Objects.requireNonNull(viewIds); Objects.requireNonNull(activityId); Objects.requireNonNull(activityId.getToken()); @@ -182,7 +182,7 @@ public final class UiTranslationManager { } try { mService.updateUiTranslationState(STATE_UI_TRANSLATION_STARTED, sourceSpec, - destSpec, viewIds, activityId.getToken(), activityId.getTaskId(), + targetSpec, viewIds, activityId.getToken(), activityId.getTaskId(), mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -208,7 +208,7 @@ public final class UiTranslationManager { public void finishTranslation(int taskId) { try { mService.updateUiTranslationStateByTaskId(STATE_UI_TRANSLATION_FINISHED, - null /* sourceSpec */, null /* destSpec*/, null /* viewIds */, taskId, + null /* sourceSpec */, null /* targetSpec */, null /* viewIds */, taskId, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -232,7 +232,7 @@ public final class UiTranslationManager { Objects.requireNonNull(activityId); Objects.requireNonNull(activityId.getToken()); mService.updateUiTranslationState(STATE_UI_TRANSLATION_FINISHED, - null /* sourceSpec */, null /* destSpec*/, null /* viewIds */, + null /* sourceSpec */, null /* targetSpec */, null /* viewIds */, activityId.getToken(), activityId.getTaskId(), mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -257,7 +257,7 @@ public final class UiTranslationManager { public void pauseTranslation(int taskId) { try { mService.updateUiTranslationStateByTaskId(STATE_UI_TRANSLATION_PAUSED, - null /* sourceSpec */, null /* destSpec*/, null /* viewIds */, taskId, + null /* sourceSpec */, null /* targetSpec */, null /* viewIds */, taskId, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -281,7 +281,7 @@ public final class UiTranslationManager { Objects.requireNonNull(activityId); Objects.requireNonNull(activityId.getToken()); mService.updateUiTranslationState(STATE_UI_TRANSLATION_PAUSED, - null /* sourceSpec */, null /* destSpec*/, null /* viewIds */, + null /* sourceSpec */, null /* targetSpec */, null /* viewIds */, activityId.getToken(), activityId.getTaskId(), mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -306,7 +306,7 @@ public final class UiTranslationManager { public void resumeTranslation(int taskId) { try { mService.updateUiTranslationStateByTaskId(STATE_UI_TRANSLATION_RESUMED, - null /* sourceSpec */, null /* destSpec*/, null /* viewIds */, + null /* sourceSpec */, null /* targetSpec */, null /* viewIds */, taskId, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -330,7 +330,7 @@ public final class UiTranslationManager { Objects.requireNonNull(activityId); Objects.requireNonNull(activityId.getToken()); mService.updateUiTranslationState(STATE_UI_TRANSLATION_RESUMED, - null /* sourceSpec */, null /* destSpec*/, null /* viewIds */, + null /* sourceSpec */, null /* targetSpec */, null /* viewIds */, activityId.getToken(), activityId.getTaskId(), mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java index 287c18275a96..a16c1519e4d0 100644 --- a/core/java/android/widget/SpellChecker.java +++ b/core/java/android/widget/SpellChecker.java @@ -28,6 +28,7 @@ import android.util.Range; import android.view.textservice.SentenceSuggestionsInfo; import android.view.textservice.SpellCheckerSession; import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener; +import android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams; import android.view.textservice.SuggestionsInfo; import android.view.textservice.TextInfo; import android.view.textservice.TextServicesManager; @@ -124,10 +125,12 @@ public class SpellChecker implements SpellCheckerSessionListener { | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_GRAMMAR_ERROR | SuggestionsInfo.RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS; + SpellCheckerSessionParams params = new SpellCheckerSessionParams.Builder() + .setLocale(mCurrentLocale) + .setSupportedAttributes(supportedAttributes) + .build(); mSpellCheckerSession = mTextServicesManager.newSpellCheckerSession( - mCurrentLocale, false, supportedAttributes, - null /* Bundle not currently used by the textServicesManager */, - mTextView.getContext().getMainExecutor(), this); + params, mTextView.getContext().getMainExecutor(), this); } // Restore SpellCheckSpans in pool diff --git a/core/java/com/android/internal/app/IAppOpsCallback.aidl b/core/java/com/android/internal/app/IAppOpsCallback.aidl index 15221b1f0fa7..024ff66a67f6 100644 --- a/core/java/com/android/internal/app/IAppOpsCallback.aidl +++ b/core/java/com/android/internal/app/IAppOpsCallback.aidl @@ -17,7 +17,7 @@ package com.android.internal.app; // This interface is also used by native code, so must -// be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsCallback.h +// be kept in sync with frameworks/native/libs/permission/include/binder/IAppOpsCallback.h oneway interface IAppOpsCallback { void opChanged(int op, int uid, String packageName); } diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index 8a6856e3b51b..281702eebc2b 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -33,7 +33,7 @@ import com.android.internal.app.MessageSamplingConfig; interface IAppOpsService { // These methods are also called by native code, so must - // be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsService.h + // be kept in sync with frameworks/native/libs/permission/include/binder/IAppOpsService.h // and not be reordered int checkOperation(int code, int uid, String packageName); SyncNotedAppOp noteOperation(int code, int uid, String packageName, @nullable String attributionTag, diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 1673362028f9..993e4e7b4b3d 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -149,8 +149,11 @@ class ZygoteConnection { return null; } - if (parsedArgs.mUsapPoolStatusSpecified) { - // Handle this once we've released the argBuffer, to avoid opening a second one. + if (parsedArgs.mUsapPoolStatusSpecified + || parsedArgs.mApiDenylistExemptions != null + || parsedArgs.mHiddenApiAccessLogSampleRate != -1 + || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) { + // Handle these once we've released argBuffer, to avoid opening a second one. break; } @@ -183,18 +186,6 @@ class ZygoteConnection { return null; } - if (parsedArgs.mApiDenylistExemptions != null) { - return handleApiDenylistExemptions(zygoteServer, - parsedArgs.mApiDenylistExemptions); - } - - if (parsedArgs.mHiddenApiAccessLogSampleRate != -1 - || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) { - return handleHiddenApiAccessLogSampleRate(zygoteServer, - parsedArgs.mHiddenApiAccessLogSampleRate, - parsedArgs.mHiddenApiAccessStatslogSampleRate); - } - if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) { throw new ZygoteSecurityException("Client may not specify capabilities: " @@ -311,10 +302,20 @@ class ZygoteConnection { } } } + // Handle anything that may need a ZygoteCommandBuffer after we've released ours. if (parsedArgs.mUsapPoolStatusSpecified) { - // Now that we've released argBuffer: return handleUsapPoolStatusChange(zygoteServer, parsedArgs.mUsapPoolEnabled); } + if (parsedArgs.mApiDenylistExemptions != null) { + return handleApiDenylistExemptions(zygoteServer, + parsedArgs.mApiDenylistExemptions); + } + if (parsedArgs.mHiddenApiAccessLogSampleRate != -1 + || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) { + return handleHiddenApiAccessLogSampleRate(zygoteServer, + parsedArgs.mHiddenApiAccessLogSampleRate, + parsedArgs.mHiddenApiAccessStatslogSampleRate); + } throw new AssertionError("Shouldn't get here"); } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 4194acbfe015..27f82f1b52dd 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -394,6 +394,14 @@ static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) { } } +static void nativeSetDefaultBufferSize(JNIEnv* env, jclass clazz, jlong nativeObject, + jint width, jint height) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + if (ctrl != NULL) { + ctrl->updateDefaultBufferSize(width, height); + } +} + static Rect rectFromObj(JNIEnv* env, jobject rectObj) { int left = env->GetIntField(rectObj, gRectClassInfo.left); int top = env->GetIntField(rectObj, gRectClassInfo.top); @@ -1771,6 +1779,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeRelease }, {"nativeDisconnect", "(J)V", (void*)nativeDisconnect }, + {"nativeUpdateDefaultBufferSize", "(JII)V", + (void*)nativeSetDefaultBufferSize}, {"nativeCreateTransaction", "()J", (void*)nativeCreateTransaction }, {"nativeApplyTransaction", "(JZ)V", diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java index 4dbdc606497e..281ce2bd3ab6 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java @@ -693,7 +693,7 @@ public class TransactionParcelTests { @Override public void updateUiTranslationState(IBinder activityToken, int state, - TranslationSpec sourceSpec, TranslationSpec destSpec, List<AutofillId> viewIds) { + TranslationSpec sourceSpec, TranslationSpec targetSpec, List<AutofillId> viewIds) { } } diff --git a/media/java/android/media/metrics/Event.java b/media/java/android/media/metrics/Event.java index 17218f09b5d6..4a69ac5b9bf9 100644 --- a/media/java/android/media/metrics/Event.java +++ b/media/java/android/media/metrics/Event.java @@ -32,19 +32,17 @@ public abstract class Event { mTimeSinceCreatedMillis = MediaMetricsManager.INVALID_TIMESTAMP; } - // TODO: remove - protected Event(long timeSinceCreatedMillis) { - mTimeSinceCreatedMillis = timeSinceCreatedMillis; - } - /* package */ Event(long timeSinceCreatedMillis, Bundle extras) { mTimeSinceCreatedMillis = timeSinceCreatedMillis; mMetricsBundle = extras; } /** - * Gets time since the corresponding instance is created in millisecond. + * Gets time since the corresponding log session is created in millisecond. * @return the timestamp since the instance is created, or -1 if unknown. + * @see LogSessionId + * @see PlaybackSession + * @see RecordingSession */ @IntRange(from = -1) public long getTimeSinceCreatedMillis() { diff --git a/media/java/android/media/metrics/MediaMetricsManager.java b/media/java/android/media/metrics/MediaMetricsManager.java index b4a74a33197a..23b697ff7512 100644 --- a/media/java/android/media/metrics/MediaMetricsManager.java +++ b/media/java/android/media/metrics/MediaMetricsManager.java @@ -25,7 +25,7 @@ import android.os.RemoteException; * This class gives information about, and interacts with media metrics. */ @SystemService(Context.MEDIA_METRICS_SERVICE) -public class MediaMetricsManager { +public final class MediaMetricsManager { public static final long INVALID_TIMESTAMP = -1; private static final String TAG = "MediaMetricsManager"; diff --git a/media/java/android/media/metrics/NetworkEvent.java b/media/java/android/media/metrics/NetworkEvent.java index 0e805439e603..7471d1d469ce 100644 --- a/media/java/android/media/metrics/NetworkEvent.java +++ b/media/java/android/media/metrics/NetworkEvent.java @@ -105,10 +105,8 @@ public final class NetworkEvent extends Event implements Parcelable { /** * Creates a new NetworkEvent. - * - * @hide */ - public NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis, + private NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis, @NonNull Bundle extras) { this.mNetworkType = type; this.mTimeSinceCreatedMillis = timeSinceCreatedMillis; @@ -124,8 +122,11 @@ public final class NetworkEvent extends Event implements Parcelable { } /** - * Gets timestamp since the creation in milliseconds. + * Gets timestamp since the creation of the log session in milliseconds. * @return the timestamp since the creation in milliseconds, or -1 if unknown. + * @see LogSessionId + * @see PlaybackSession + * @see RecordingSession */ @Override @IntRange(from = -1) @@ -177,8 +178,7 @@ public final class NetworkEvent extends Event implements Parcelable { return 0; } - /** @hide */ - /* package-private */ NetworkEvent(@NonNull android.os.Parcel in) { + private NetworkEvent(@NonNull android.os.Parcel in) { int type = in.readInt(); long timeSinceCreatedMillis = in.readLong(); Bundle extras = in.readBundle(); @@ -230,6 +230,7 @@ public final class NetworkEvent extends Event implements Parcelable { * Sets timestamp since the creation in milliseconds. * @param value the timestamp since the creation in milliseconds. * -1 indicates the value is unknown. + * @see #getTimeSinceCreatedMillis() */ public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) { mTimeSinceCreatedMillis = value; diff --git a/media/java/android/media/metrics/PlaybackErrorEvent.java b/media/java/android/media/metrics/PlaybackErrorEvent.java index f36c04e77521..d155576c9b47 100644 --- a/media/java/android/media/metrics/PlaybackErrorEvent.java +++ b/media/java/android/media/metrics/PlaybackErrorEvent.java @@ -150,10 +150,8 @@ public final class PlaybackErrorEvent extends Event implements Parcelable { /** * Creates a new PlaybackErrorEvent. - * - * @hide */ - public PlaybackErrorEvent( + private PlaybackErrorEvent( @Nullable String exceptionStack, int errorCode, int subErrorCode, @@ -191,8 +189,10 @@ public final class PlaybackErrorEvent extends Event implements Parcelable { } /** - * Gets the timestamp since creation in milliseconds. + * Gets the timestamp since creation of the playback session in milliseconds. * @return the timestamp since the playback is created, or -1 if unknown. + * @see LogSessionId + * @see PlaybackSession */ @Override @IntRange(from = -1) @@ -254,8 +254,7 @@ public final class PlaybackErrorEvent extends Event implements Parcelable { return 0; } - /** @hide */ - /* package-private */ PlaybackErrorEvent(@NonNull Parcel in) { + private PlaybackErrorEvent(@NonNull Parcel in) { byte flg = in.readByte(); String exceptionStack = (flg & 0x1) == 0 ? null : in.readString(); int errorCode = in.readInt(); @@ -330,6 +329,7 @@ public final class PlaybackErrorEvent extends Event implements Parcelable { * Set the timestamp since creation in milliseconds. * @param value the timestamp since the creation in milliseconds. * -1 indicates the value is unknown. + * @see #getTimeSinceCreatedMillis() */ public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) { mTimeSinceCreatedMillis = value; diff --git a/media/java/android/media/metrics/PlaybackMetrics.java b/media/java/android/media/metrics/PlaybackMetrics.java index 5f606a0a8ed0..bbcc48480e68 100644 --- a/media/java/android/media/metrics/PlaybackMetrics.java +++ b/media/java/android/media/metrics/PlaybackMetrics.java @@ -213,6 +213,7 @@ public final class PlaybackMetrics implements Parcelable { /** * Gets the media duration in milliseconds. + * <p>Media duration is the length of the media. * @return the media duration in milliseconds, or -1 if unknown. */ @IntRange(from = -1) @@ -328,6 +329,8 @@ public final class PlaybackMetrics implements Parcelable { /** * Gets network transfer duration in milliseconds. + * <p>Total transfer time spent reading from the network in ms. For parallel requests, the + * overlapping time intervals are counted only once. */ @IntRange(from = -1) public long getNetworkTransferDurationMillis() { @@ -523,6 +526,7 @@ public final class PlaybackMetrics implements Parcelable { /** * Sets the media duration in milliseconds. * @param value the media duration in milliseconds. -1 indicates the value is unknown. + * @see #getMediaDurationMillis() */ public @NonNull Builder setMediaDurationMillis(@IntRange(from = -1) long value) { mMediaDurationMillis = value; @@ -645,6 +649,7 @@ public final class PlaybackMetrics implements Parcelable { * Sets the network transfer duration in milliseconds. * @param value the network transfer duration in milliseconds. * -1 indicates the value is unknown. + * @see #getNetworkTransferDurationMillis() */ public @NonNull Builder setNetworkTransferDurationMillis(@IntRange(from = -1) long value) { mNetworkTransferDurationMillis = value; diff --git a/media/java/android/media/metrics/PlaybackStateEvent.java b/media/java/android/media/metrics/PlaybackStateEvent.java index 449abe952038..8e7482534677 100644 --- a/media/java/android/media/metrics/PlaybackStateEvent.java +++ b/media/java/android/media/metrics/PlaybackStateEvent.java @@ -132,10 +132,8 @@ public final class PlaybackStateEvent extends Event implements Parcelable { /** * Creates a new PlaybackStateEvent. - * - * @hide */ - public PlaybackStateEvent( + private PlaybackStateEvent( int state, long timeSinceCreatedMillis, @NonNull Bundle extras) { @@ -147,13 +145,16 @@ public final class PlaybackStateEvent extends Event implements Parcelable { /** * Gets playback state. */ + @State public int getState() { return mState; } /** - * Gets time since the corresponding playback is created in millisecond. + * Gets time since the corresponding playback session is created in millisecond. * @return the timestamp since the playback is created, or -1 if unknown. + * @see LogSessionId + * @see PlaybackSession */ @Override @IntRange(from = -1) @@ -197,8 +198,7 @@ public final class PlaybackStateEvent extends Event implements Parcelable { return 0; } - /** @hide */ - /* package-private */ PlaybackStateEvent(@NonNull Parcel in) { + private PlaybackStateEvent(@NonNull Parcel in) { int state = in.readInt(); long timeSinceCreatedMillis = in.readLong(); Bundle extras = in.readBundle(); @@ -247,6 +247,7 @@ public final class PlaybackStateEvent extends Event implements Parcelable { * Sets timestamp since the creation in milliseconds. * @param value the timestamp since the creation in milliseconds. * -1 indicates the value is unknown. + * @see #getTimeSinceCreatedMillis() */ public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) { mTimeSinceCreatedMillis = value; diff --git a/media/java/android/media/metrics/TrackChangeEvent.java b/media/java/android/media/metrics/TrackChangeEvent.java index c36702695095..65d011cf6758 100644 --- a/media/java/android/media/metrics/TrackChangeEvent.java +++ b/media/java/android/media/metrics/TrackChangeEvent.java @@ -184,8 +184,11 @@ public final class TrackChangeEvent extends Event implements Parcelable { } /** - * Gets timestamp since the creation in milliseconds. + * Gets timestamp since the creation of the log session in milliseconds. * @return the timestamp since the creation in milliseconds, or -1 if unknown. + * @see LogSessionId + * @see PlaybackSession + * @see RecordingSession */ @Override @IntRange(from = -1) @@ -193,6 +196,11 @@ public final class TrackChangeEvent extends Event implements Parcelable { return mTimeSinceCreatedMillis; } + /** + * Gets the track type. + * <p>The track type must be one of {@link #TRACK_TYPE_AUDIO}, {@link #TRACK_TYPE_VIDEO}, + * {@link #TRACK_TYPE_TEXT}. + */ @TrackType public int getTrackType() { return mType; @@ -302,8 +310,7 @@ public final class TrackChangeEvent extends Event implements Parcelable { return 0; } - /** @hide */ - /* package-private */ TrackChangeEvent(@NonNull Parcel in) { + private TrackChangeEvent(@NonNull Parcel in) { int flg = in.readInt(); int state = in.readInt(); int reason = in.readInt(); @@ -429,8 +436,14 @@ public final class TrackChangeEvent extends Event implements Parcelable { /** * Creates a new Builder. + * @param type the track type. It must be one of {@link #TRACK_TYPE_AUDIO}, + * {@link #TRACK_TYPE_VIDEO}, {@link #TRACK_TYPE_TEXT}. */ - public Builder(int type) { + public Builder(@TrackType int type) { + if (type != TRACK_TYPE_AUDIO && type != TRACK_TYPE_VIDEO && type != TRACK_TYPE_TEXT) { + throw new IllegalArgumentException("track type must be one of TRACK_TYPE_AUDIO, " + + "TRACK_TYPE_VIDEO, TRACK_TYPE_TEXT."); + } mType = type; } @@ -499,6 +512,7 @@ public final class TrackChangeEvent extends Event implements Parcelable { * Sets timestamp since the creation in milliseconds. * @param value the timestamp since the creation in milliseconds. * -1 indicates the value is unknown. + * @see #getTimeSinceCreatedMillis() */ public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) { checkNotUsed(); diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml index 0fef9f15c373..72b027af1bf6 100644 --- a/packages/SystemUI/res-keyguard/values/styles.xml +++ b/packages/SystemUI/res-keyguard/values/styles.xml @@ -17,7 +17,7 @@ */ --> -<resources xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> +<resources> <!-- Keyguard PIN pad styles --> <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView"> <item name="android:textSize">@dimen/kg_status_line_font_size</item> @@ -32,7 +32,9 @@ <item name="android:stateListAnimator">@null</item> </style> <style name="NumPadKey" parent="Theme.SystemUI"> - <item name="android:colorControlNormal">?androidprv:attr/colorSurface</item> + <!-- Studio can't directly reference ?androidprv:attr/colorSurface here, so this value + is resolved in {@link NumPadAnimator}. --> + <item name="android:colorControlNormal">@null</item> <item name="android:colorControlHighlight">?android:attr/colorAccent</item> <item name="android:background">@drawable/num_pad_key_background</item> </style> diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java index 570854ecaa36..abdd770c37d4 100644 --- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java +++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java @@ -29,6 +29,7 @@ import androidx.annotation.StyleRes; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; +import com.android.systemui.util.Utils; /** * Provides background color and radius animations for key pad buttons. @@ -100,7 +101,8 @@ class NumPadAnimator { ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle); TypedArray a = ctw.obtainStyledAttributes(customAttrs); - mNormalColor = a.getColor(0, 0); + mNormalColor = Utils.getPrivateAttrColorIfUnset(ctw, a, 0, 0, + com.android.internal.R.attr.colorSurface); mHighlightColor = a.getColor(1, 0); a.recycle(); diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java index fd3641cfdaa0..f3a95f711b7c 100644 --- a/packages/SystemUI/src/com/android/systemui/util/Utils.java +++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java @@ -21,8 +21,10 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.content.res.TypedArray; import android.provider.Settings; import android.text.TextUtils; +import android.view.ContextThemeWrapper; import android.view.View; import com.android.systemui.R; @@ -177,4 +179,23 @@ public class Utils { && resources.getBoolean(R.bool.config_use_split_notification_shade); } + /** + * Returns the color provided at the specified {@param attrIndex} in {@param a} if it exists, + * otherwise, returns the color from the private attribute {@param privAttrId}. + */ + public static int getPrivateAttrColorIfUnset(ContextThemeWrapper ctw, TypedArray a, + int attrIndex, int defColor, int privAttrId) { + // If the index is specified, use that value + if (a.hasValue(attrIndex)) { + return a.getColor(attrIndex, defColor); + } + + // Otherwise fallback to the value of the private attribute + int[] customAttrs = { privAttrId }; + a = ctw.obtainStyledAttributes(customAttrs); + int color = a.getColor(0, defColor); + a.recycle(); + return color; + } + } diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index e251700498ee..d922d2b06c89 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -1589,6 +1589,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku public ParceledListSlice<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter, int profileId, String packageName) { final int userId = UserHandle.getCallingUserId(); + final int callingUid = Binder.getCallingUid(); if (DEBUG) { Slog.i(TAG, "getInstalledProvidersForProfiles() " + userId); @@ -1601,7 +1602,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku synchronized (mLock) { if (mSecurityPolicy.isCallerInstantAppLocked()) { - Slog.w(TAG, "Instant uid " + Binder.getCallingUid() + Slog.w(TAG, "Instant uid " + callingUid + " cannot access widget providers"); return ParceledListSlice.emptyList(); } @@ -1614,11 +1615,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku for (int i = 0; i < providerCount; i++) { Provider provider = mProviders.get(i); AppWidgetProviderInfo info = provider.getInfoLocked(mContext); + final String providerPackageName = provider.id.componentName.getPackageName(); // Ignore an invalid provider, one not matching the filter, // or one that isn't in the given package, if any. boolean inPackage = packageName == null - || provider.id.componentName.getPackageName().equals(packageName); + || providerPackageName.equals(packageName); if (provider.zombie || (info.widgetCategory & categoryFilter) == 0 || !inPackage) { continue; } @@ -1627,7 +1629,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku final int providerProfileId = info.getProfile().getIdentifier(); if (providerProfileId == profileId && mSecurityPolicy.isProviderInCallerOrInProfileAndWhitelListed( - provider.id.componentName.getPackageName(), providerProfileId)) { + providerPackageName, providerProfileId) + && !mPackageManagerInternal.filterAppAccess(providerPackageName, callingUid, + userId)) { result.add(cloneIfLocalBinder(info)); } } diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java index c01523a4bc40..90694d0a5f64 100644 --- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java +++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java @@ -205,6 +205,7 @@ class RebootEscrowManager { Slog.i(TAG, "Using server based resume on reboot"); rebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(mContext, mStorage); } else { + Slog.i(TAG, "Using HAL based resume on reboot"); rebootEscrowProvider = new RebootEscrowProviderHalImpl(); } @@ -239,7 +240,7 @@ class RebootEscrowManager { return mKeyStoreManager; } - public RebootEscrowProviderInterface getRebootEscrowProvider() { + public RebootEscrowProviderInterface createRebootEscrowProviderIfNeeded() { // Initialize for the provider lazily. Because the device_config and service // implementation apps may change when system server is running. if (mRebootEscrowProvider == null) { @@ -249,6 +250,14 @@ class RebootEscrowManager { return mRebootEscrowProvider; } + public RebootEscrowProviderInterface getRebootEscrowProvider() { + return mRebootEscrowProvider; + } + + public void clearRebootEscrowProvider() { + mRebootEscrowProvider = null; + } + public int getBootCount() { return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.BOOT_COUNT, 0); @@ -308,8 +317,6 @@ class RebootEscrowManager { mStorage.removeRebootEscrow(user.id); } - // Clear the old key in keystore. - mKeyStoreManager.clearKeyStoreEncryptionKey(); onEscrowRestoreComplete(false, attemptCount); } @@ -395,9 +402,6 @@ class RebootEscrowManager { allUsersUnlocked &= restoreRebootEscrowForUser(user.id, escrowKey, kk); } - // Clear the old key in keystore. A new key will be generated by new RoR requests. - mKeyStoreManager.clearKeyStoreEncryptionKey(); - if (!allUsersUnlocked && mLoadEscrowDataErrorCode == ERROR_NONE) { mLoadEscrowDataErrorCode = ERROR_UNLOCK_ALL_USERS; } @@ -473,11 +477,17 @@ class RebootEscrowManager { if (success || (previousBootCount != -1 && bootCountDelta <= BOOT_COUNT_TOLERANCE)) { reportMetricOnRestoreComplete(success, attemptCount); } + + // Clear the old key in keystore. A new key will be generated by new RoR requests. + mKeyStoreManager.clearKeyStoreEncryptionKey(); + // Clear the saved reboot escrow provider + mInjector.clearRebootEscrowProvider(); clearMetricsStorage(); } private RebootEscrowKey getAndClearRebootEscrowKey(SecretKey kk) throws IOException { - RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider(); + RebootEscrowProviderInterface rebootEscrowProvider = + mInjector.createRebootEscrowProviderIfNeeded(); if (rebootEscrowProvider == null) { Slog.w(TAG, "Had reboot escrow data for users, but RebootEscrowProvider is unavailable"); @@ -529,9 +539,8 @@ class RebootEscrowManager { return; } - if (mInjector.getRebootEscrowProvider() == null) { - Slog.w(TAG, - "Had reboot escrow data for users, but RebootEscrowProvider is unavailable"); + if (mInjector.createRebootEscrowProviderIfNeeded() == null) { + Slog.w(TAG, "Not storing escrow data, RebootEscrowProvider is unavailable"); return; } @@ -586,13 +595,17 @@ class RebootEscrowManager { mRebootEscrowWanted = false; setRebootEscrowReady(false); - RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider(); + // We want to clear the internal data inside the provider, so always try to create the + // provider. + RebootEscrowProviderInterface rebootEscrowProvider = + mInjector.createRebootEscrowProviderIfNeeded(); if (rebootEscrowProvider == null) { Slog.w(TAG, "RebootEscrowProvider is unavailable for clear request"); } else { rebootEscrowProvider.clearRebootEscrowKey(); } + mInjector.clearRebootEscrowProvider(); clearMetricsStorage(); List<UserInfo> users = mUserManager.getUsers(); @@ -610,8 +623,7 @@ class RebootEscrowManager { RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider(); if (rebootEscrowProvider == null) { - Slog.w(TAG, - "Had reboot escrow data for users, but RebootEscrowProvider is unavailable"); + Slog.w(TAG, "Not storing escrow key, RebootEscrowProvider is unavailable"); clearRebootEscrowIfNeeded(); return ARM_REBOOT_ERROR_NO_PROVIDER; } @@ -677,11 +689,12 @@ class RebootEscrowManager { } boolean prepareRebootEscrow() { - if (mInjector.getRebootEscrowProvider() == null) { + clearRebootEscrowIfNeeded(); + if (mInjector.createRebootEscrowProviderIfNeeded() == null) { + Slog.w(TAG, "No reboot escrow provider, skipping resume on reboot preparation."); return false; } - clearRebootEscrowIfNeeded(); mRebootEscrowWanted = true; mEventLog.addEntry(RebootEscrowEvent.REQUESTED_LSKF); return true; @@ -807,6 +820,10 @@ class RebootEscrowManager { pw.print("mPendingRebootEscrowKey is "); pw.println(keySet ? "set" : "not set"); + RebootEscrowProviderInterface provider = mInjector.getRebootEscrowProvider(); + String providerType = provider == null ? "null" : String.valueOf(provider.getType()); + pw.print("RebootEscrowProvider type is " + providerType); + pw.println(); pw.println("Event log:"); pw.increaseIndent(); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 1e6e5cb97f45..52a5dc1e8982 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -735,19 +735,22 @@ public class NotificationManagerService extends SystemService { final List<UserInfo> activeUsers = mUm.getUsers(); for (UserInfo userInfo : activeUsers) { int userId = userInfo.getUserHandle().getIdentifier(); - if (isNASMigrationDone(userId)) { + if (isNASMigrationDone(userId) || mUm.isManagedProfile(userId)) { continue; } if (mAssistants.hasUserSet(userId)) { - mAssistants.loadDefaultsFromConfig(false); ComponentName defaultFromConfig = mAssistants.getDefaultFromConfig(); List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId); - if (allowedComponents.contains(defaultFromConfig)) { + if (allowedComponents.size() == 0) { + setNASMigrationDone(userId); + mAssistants.clearDefaults(); + continue; + } else if (allowedComponents.contains(defaultFromConfig)) { setNASMigrationDone(userId); mAssistants.resetDefaultFromConfig(); continue; } - //User selected different NAS or none, need onboarding + //User selected different NAS, need onboarding enqueueNotificationInternal(getContext().getPackageName(), getContext().getOpPackageName(), Binder.getCallingUid(), Binder.getCallingPid(), TAG, @@ -819,9 +822,11 @@ public class NotificationManagerService extends SystemService { } @VisibleForTesting - void setNASMigrationDone(int userId) { - Settings.Secure.putIntForUser(getContext().getContentResolver(), - Settings.Secure.NAS_SETTINGS_UPDATED, 1, userId); + void setNASMigrationDone(int baseUserId) { + for (int profileId : mUm.getProfileIds(baseUserId, false)) { + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Secure.NAS_SETTINGS_UPDATED, 1, profileId); + } } @VisibleForTesting @@ -5171,12 +5176,7 @@ public class NotificationManagerService extends SystemService { @Override public ComponentName getDefaultNotificationAssistant() { checkCallerIsSystem(); - ArraySet<ComponentName> defaultComponents = mAssistants.getDefaultComponents(); - if (defaultComponents.size() > 1) { - Slog.w(TAG, "More than one default NotificationAssistant: " - + defaultComponents.size()); - } - return CollectionUtils.firstOrNull(defaultComponents); + return mAssistants.getDefaultFromConfig(); } @Override @@ -9403,6 +9403,9 @@ public class NotificationManagerService extends SystemService { } ComponentName getDefaultFromConfig() { + if (mDefaultFromConfig == null) { + loadDefaultsFromConfig(false); + } return mDefaultFromConfig; } diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index c6d98e768ce3..464477df281f 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -92,6 +92,7 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * Package information used by {@link ShortcutService}. @@ -721,7 +722,7 @@ class ShortcutPackage extends ShortcutPackageItem { // If not reset yet, then reset. if (mLastResetTime < last) { - if (ShortcutService.DEBUG) { + if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format("%s: last reset=%d, now=%d, last=%d: resetting", getPackageName(), mLastResetTime, now, last)); } @@ -1101,7 +1102,7 @@ class ShortcutPackage extends ShortcutPackageItem { } final int manifestShortcutSize = newManifestShortcutList == null ? 0 : newManifestShortcutList.size(); - if (ShortcutService.DEBUG) { + if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format("Package %s has %d manifest shortcut(s), and %d share target(s)", getPackageName(), manifestShortcutSize, mShareTargets.size())); @@ -1113,7 +1114,7 @@ class ShortcutPackage extends ShortcutPackageItem { // disabled. return false; } - if (ShortcutService.DEBUG) { + if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format("Package %s %s, version %d -> %d", getPackageName(), (isNewApp ? "added" : "updated"), getPackageInfo().getVersionCode(), pi.getLongVersionCode())); @@ -1202,7 +1203,7 @@ class ShortcutPackage extends ShortcutPackageItem { } private boolean publishManifestShortcuts(List<ShortcutInfo> newManifestShortcutList) { - if (ShortcutService.DEBUG) { + if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format( "Package %s: publishing manifest shortcuts", getPackageName())); } @@ -1879,7 +1880,7 @@ class ShortcutPackage extends ShortcutPackageItem { final int depth = parser.getDepth(); final String tag = parser.getName(); - if (ShortcutService.DEBUG_LOAD) { + if (ShortcutService.DEBUG_LOAD || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format("depth=%d type=%d name=%s", depth, type, tag)); } if ((depth == 1) && TAG_ROOT.equals(tag)) { @@ -2015,7 +2016,7 @@ class ShortcutPackage extends ShortcutPackageItem { } final int depth = parser.getDepth(); final String tag = parser.getName(); - if (ShortcutService.DEBUG_LOAD) { + if (ShortcutService.DEBUG_LOAD || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format(" depth=%d type=%d name=%s", depth, type, tag)); } @@ -2099,7 +2100,7 @@ class ShortcutPackage extends ShortcutPackageItem { } final int depth = parser.getDepth(); final String tag = parser.getName(); - if (ShortcutService.DEBUG_LOAD) { + if (ShortcutService.DEBUG_LOAD || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, String.format(" depth=%d type=%d name=%s", depth, type, tag)); } @@ -2302,6 +2303,12 @@ class ShortcutPackage extends ShortcutPackageItem { // No need to invoke AppSearch when there's nothing to save. return; } + if (ShortcutService.DEBUG_REBOOT) { + Slog.d(TAG, "Saving shortcuts for user=" + mShortcutUser.getUserId() + + " pkg=" + getPackageName() + " ids=[" + + shortcuts.stream().map(ShortcutInfo::getId) + .collect(Collectors.joining(",")) + "]"); + } awaitInAppSearch("Saving shortcuts", session -> { final AndroidFuture<Boolean> future = new AndroidFuture<>(); session.put(new PutDocumentsRequest.Builder() @@ -2374,6 +2381,10 @@ class ShortcutPackage extends ShortcutPackageItem { shortcutIds.add(id); } } + if (ShortcutService.DEBUG_REBOOT) { + Slog.d(TAG, "Getting shortcuts for user=" + mShortcutUser.getUserId() + + " pkg=" + getPackageName() + " ids: [" + String.join(",", ids) + "]"); + } return awaitInAppSearch("Getting shortcut by id", session -> { final AndroidFuture<List<ShortcutInfo>> future = new AndroidFuture<>(); session.getByUri( @@ -2418,6 +2429,10 @@ class ShortcutPackage extends ShortcutPackageItem { private void forEachShortcutMutateIf(@NonNull final String query, @NonNull final Function<ShortcutInfo, Boolean> cb) { + if (ShortcutService.DEBUG_REBOOT) { + Slog.d(TAG, "Changing shortcuts for user=" + mShortcutUser.getUserId() + + " pkg=" + getPackageName()); + } final SearchResults res = awaitInAppSearch("Mutating shortcuts", session -> AndroidFuture.completedFuture(session.search(query, getSearchSpec()))); if (res == null) return; @@ -2439,6 +2454,10 @@ class ShortcutPackage extends ShortcutPackageItem { private void forEachShortcutStopWhen( @NonNull final String query, @NonNull final Function<ShortcutInfo, Boolean> cb) { + if (ShortcutService.DEBUG_REBOOT) { + Slog.d(TAG, "Iterating shortcuts for user=" + mShortcutUser.getUserId() + + " pkg=" + getPackageName()); + } final SearchResults res = awaitInAppSearch("Iterating shortcuts", session -> AndroidFuture.completedFuture(session.search(query, getSearchSpec()))); if (res == null) return; @@ -2452,6 +2471,10 @@ class ShortcutPackage extends ShortcutPackageItem { } private List<ShortcutInfo> getNextPage(@NonNull final SearchResults res) { + if (ShortcutService.DEBUG_REBOOT) { + Slog.d(TAG, "Get next page for search result for user=" + mShortcutUser.getUserId() + + " pkg=" + getPackageName()); + } final AndroidFuture<List<ShortcutInfo>> future = new AndroidFuture<>(); final List<ShortcutInfo> ret = new ArrayList<>(); final long callingIdentity = Binder.clearCallingIdentity(); @@ -2529,6 +2552,10 @@ class ShortcutPackage extends ShortcutPackageItem { @NonNull private AndroidFuture<AppSearchSession> setupSchema( @NonNull final AppSearchSession session) { + if (ShortcutService.DEBUG_REBOOT) { + Slog.d(TAG, "Setup Schema for user=" + mShortcutUser.getUserId() + + " pkg=" + getPackageName()); + } SetSchemaRequest.Builder schemaBuilder = new SetSchemaRequest.Builder() .addSchemas(AppSearchPerson.SCHEMA, AppSearchShortcutInfo.SCHEMA) .setForceOverride(true); @@ -2569,6 +2596,15 @@ class ShortcutPackage extends ShortcutPackageItem { } private void restoreParsedShortcuts(final boolean replace) { + if (ShortcutService.DEBUG_REBOOT) { + if (replace) { + Slog.d(TAG, "Replacing all shortcuts with the ones parsed from xml for user=" + + mShortcutUser.getUserId() + " pkg=" + getPackageName()); + } else { + Slog.d(TAG, "Restoring pinned shortcuts from xml for user=" + + mShortcutUser.getUserId() + " pkg=" + getPackageName()); + } + } if (replace) { removeShortcuts(); } diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index dcf730d4a0fd..8d03fceacee8 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -164,6 +164,7 @@ public class ShortcutService extends IShortcutService.Stub { static final boolean DEBUG = false; // STOPSHIP if true static final boolean DEBUG_LOAD = false; // STOPSHIP if true static final boolean DEBUG_PROCSTATE = false; // STOPSHIP if true + static final boolean DEBUG_REBOOT = true; @VisibleForTesting static final long DEFAULT_RESET_INTERVAL_SEC = 24 * 60 * 60; // 1 day @@ -659,7 +660,7 @@ public class ShortcutService extends IShortcutService.Stub { /** lifecycle event */ void onBootPhase(int phase) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "onBootPhase: " + phase); } switch (phase) { @@ -674,7 +675,7 @@ public class ShortcutService extends IShortcutService.Stub { /** lifecycle event */ void handleUnlockUser(int userId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "handleUnlockUser: user=" + userId); } synchronized (mUnlockedUsers) { @@ -699,7 +700,7 @@ public class ShortcutService extends IShortcutService.Stub { /** lifecycle event */ void handleStopUser(int userId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "handleStopUser: user=" + userId); } synchronized (mLock) { @@ -713,7 +714,7 @@ public class ShortcutService extends IShortcutService.Stub { @GuardedBy("mLock") private void unloadUserLocked(int userId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "unloadUserLocked: user=" + userId); } // Save all dirty information. @@ -945,7 +946,7 @@ public class ShortcutService extends IShortcutService.Stub { @VisibleForTesting void saveBaseStateLocked() { final AtomicFile file = getBaseStateFile(); - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "Saving to " + file.getBaseFile()); } @@ -978,7 +979,7 @@ public class ShortcutService extends IShortcutService.Stub { mRawLastResetTime = 0; final AtomicFile file = getBaseStateFile(); - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "Loading from " + file.getBaseFile()); } try (FileInputStream in = file.openRead()) { @@ -1028,7 +1029,7 @@ public class ShortcutService extends IShortcutService.Stub { @GuardedBy("mLock") private void saveUserLocked(@UserIdInt int userId) { final File path = getUserFile(userId); - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "Saving to " + path); } @@ -1086,7 +1087,7 @@ public class ShortcutService extends IShortcutService.Stub { @Nullable private ShortcutUser loadUserLocked(@UserIdInt int userId) { final File path = getUserFile(userId); - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "Loading from " + path); } final AtomicFile file = new AtomicFile(path); @@ -1095,7 +1096,7 @@ public class ShortcutService extends IShortcutService.Stub { try { in = file.openRead(); } catch (FileNotFoundException e) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "Not found " + path); } return null; @@ -1132,7 +1133,7 @@ public class ShortcutService extends IShortcutService.Stub { final int depth = parser.getDepth(); final String tag = parser.getName(); - if (DEBUG_LOAD) { + if (DEBUG_LOAD || DEBUG_REBOOT) { Slog.d(TAG, String.format("depth=%d type=%d name=%s", depth, type, tag)); } @@ -1157,7 +1158,7 @@ public class ShortcutService extends IShortcutService.Stub { private final Runnable mSaveDirtyInfoRunner = this::saveDirtyInfo; private void scheduleSaveInner(@UserIdInt int userId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "Scheduling to save for " + userId); } synchronized (mLock) { @@ -1172,7 +1173,7 @@ public class ShortcutService extends IShortcutService.Stub { @VisibleForTesting void saveDirtyInfo() { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "saveDirtyInfo"); } if (mShutdown.get()) { @@ -2942,6 +2943,10 @@ public class ShortcutService extends IShortcutService.Stub { @Nullable String packageName, @Nullable List<String> shortcutIds, @Nullable List<LocusId> locusIds, @Nullable ComponentName componentName, int queryFlags, int userId, int callingPid, int callingUid) { + if (DEBUG_REBOOT) { + Slog.d(TAG, "Getting shortcuts for launcher= " + callingPackage + + "user=" + userId + " pkg=" + packageName); + } final ArrayList<ShortcutInfo> ret = new ArrayList<>(); int flags = ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER; @@ -3639,7 +3644,7 @@ public class ShortcutService extends IShortcutService.Stub { */ @VisibleForTesting void checkPackageChanges(@UserIdInt int ownerUserId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "checkPackageChanges() ownerUserId=" + ownerUserId); } if (injectIsSafeModeEnabled()) { @@ -3685,6 +3690,9 @@ public class ShortcutService extends IShortcutService.Stub { @GuardedBy("mLock") private void rescanUpdatedPackagesLocked(@UserIdInt int userId, long lastScanTime) { + if (DEBUG_REBOOT) { + Slog.d(TAG, "rescan updated package user=" + userId + " last scanned=" + lastScanTime); + } final ShortcutUser user = getUserShortcutsLocked(userId); // Note after each OTA, we'll need to rescan all system apps, as their lastUpdateTime @@ -3708,7 +3716,7 @@ public class ShortcutService extends IShortcutService.Stub { } private void handlePackageAdded(String packageName, @UserIdInt int userId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, String.format("handlePackageAdded: %s user=%d", packageName, userId)); } synchronized (mLock) { @@ -3720,7 +3728,7 @@ public class ShortcutService extends IShortcutService.Stub { } private void handlePackageUpdateFinished(String packageName, @UserIdInt int userId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, String.format("handlePackageUpdateFinished: %s user=%d", packageName, userId)); } @@ -3736,7 +3744,7 @@ public class ShortcutService extends IShortcutService.Stub { } private void handlePackageRemoved(String packageName, @UserIdInt int packageUserId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, String.format("handlePackageRemoved: %s user=%d", packageName, packageUserId)); } @@ -3746,7 +3754,7 @@ public class ShortcutService extends IShortcutService.Stub { } private void handlePackageDataCleared(String packageName, int packageUserId) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, String.format("handlePackageDataCleared: %s user=%d", packageName, packageUserId)); } @@ -3761,7 +3769,7 @@ public class ShortcutService extends IShortcutService.Stub { handlePackageRemoved(packageName, packageUserId); return; } - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, String.format("handlePackageChanged: %s user=%d", packageName, packageUserId)); } @@ -3948,7 +3956,7 @@ public class ShortcutService extends IShortcutService.Stub { private void forUpdatedPackages(@UserIdInt int userId, long lastScanTime, boolean afterOta, Consumer<ApplicationInfo> callback) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "forUpdatedPackages for user " + userId + ", lastScanTime=" + lastScanTime + " afterOta=" + afterOta); } @@ -3960,7 +3968,7 @@ public class ShortcutService extends IShortcutService.Stub { // Also if it's right after an OTA, always re-scan all apps anyway, since the // shortcut parser might have changed. if (afterOta || (pi.lastUpdateTime >= lastScanTime)) { - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "Found updated package " + pi.packageName + " updateTime=" + pi.lastUpdateTime); } @@ -4313,7 +4321,7 @@ public class ShortcutService extends IShortcutService.Stub { @Override public void applyRestore(byte[] payload, @UserIdInt int userId) { enforceSystem(); - if (DEBUG) { + if (DEBUG || DEBUG_REBOOT) { Slog.d(TAG, "Restoring user " + userId); } synchronized (mLock) { diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java index 069944d955ea..e66cb03950cc 100644 --- a/services/core/java/com/android/server/pm/ShortcutUser.java +++ b/services/core/java/com/android/server/pm/ShortcutUser.java @@ -328,6 +328,10 @@ class ShortcutUser { public void rescanPackageIfNeeded(@NonNull String packageName, boolean forceRescan) { final boolean isNewApp = !mPackages.containsKey(packageName); + if (ShortcutService.DEBUG_REBOOT) { + Slog.d(TAG, "rescanPackageIfNeeded " + getUserId() + "@" + packageName + + ", forceRescan=" + forceRescan + " , isNewApp=" + isNewApp); + } final ShortcutPackage shortcutPackage = getPackageShortcuts(packageName); @@ -397,7 +401,7 @@ class ShortcutUser { } else { // Save each ShortcutPackageItem in a separate Xml file. final File path = getShortcutPackageItemFile(spi); - if (ShortcutService.DEBUG) { + if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) { Slog.d(TAG, "Saving package item " + spi.getPackageName() + " to " + path); } diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java index cd7f6854a37d..6f6bdac61fad 100644 --- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java +++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java @@ -394,13 +394,13 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, throw new IllegalStateException("Have not received sensor event."); } - if (latestEvent.values.length != mExpectedValues.size()) { + if (latestEvent.values.length < mExpectedValues.size()) { throw new RuntimeException("Number of supplied numeric range(s) does not " + "match the number of values in the latest sensor event for sensor: " + mSensor); } - for (int i = 0; i < latestEvent.values.length; i++) { + for (int i = 0; i < mExpectedValues.size(); i++) { if (!adheresToRange(latestEvent.values[i], mExpectedValues.get(i))) { return false; } diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp index 5140b9f6db58..0bd737bec460 100644 --- a/services/incremental/Android.bp +++ b/services/incremental/Android.bp @@ -77,6 +77,7 @@ cc_defaults { "libcutils", "libincfs", "liblog", + "libpermission", "libz", ], } diff --git a/services/incremental/TEST_MAPPING b/services/incremental/TEST_MAPPING index d93525600a2d..6aa8a939739a 100644 --- a/services/incremental/TEST_MAPPING +++ b/services/incremental/TEST_MAPPING @@ -24,7 +24,9 @@ }, { "name": "CtsIncrementalInstallHostTestCases" - }, + } + ], + "presubmit-large": [ { "name": "CtsInstalledLoadingProgressHostTests" } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java index 49a54ec1354b..aecc7942b266 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java @@ -112,14 +112,13 @@ public class RebootEscrowManagerTests { private MockableRebootEscrowInjected mInjected; private RebootEscrowManager mService; private SecretKey mAesKey; + private MockInjector mMockInjector; public interface MockableRebootEscrowInjected { int getBootCount(); long getCurrentTimeMillis(); - boolean forceServerBased(); - void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount, int escrowDurationInSeconds, int vbmetaDigestStatus, int durationSinceBootComplete); } @@ -127,11 +126,12 @@ public class RebootEscrowManagerTests { static class MockInjector extends RebootEscrowManager.Injector { private final IRebootEscrow mRebootEscrow; private final ResumeOnRebootServiceConnection mServiceConnection; - private final RebootEscrowProviderInterface mRebootEscrowProvider; + private final RebootEscrowProviderInterface mDefaultRebootEscrowProvider; private final UserManager mUserManager; private final MockableRebootEscrowInjected mInjected; private final RebootEscrowKeyStoreManager mKeyStoreManager; - private final boolean mServerBased; + private boolean mServerBased; + private RebootEscrowProviderInterface mRebootEscrowProviderInUse; MockInjector(Context context, UserManager userManager, IRebootEscrow rebootEscrow, @@ -149,7 +149,7 @@ public class RebootEscrowManagerTests { return mRebootEscrow; } }; - mRebootEscrowProvider = new RebootEscrowProviderHalImpl(halInjector); + mDefaultRebootEscrowProvider = new RebootEscrowProviderHalImpl(halInjector); mUserManager = userManager; mKeyStoreManager = keyStoreManager; mInjected = injected; @@ -166,7 +166,8 @@ public class RebootEscrowManagerTests { mServerBased = true; RebootEscrowProviderServerBasedImpl.Injector injector = new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection); - mRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(storage, injector); + mDefaultRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl( + storage, injector); mUserManager = userManager; mKeyStoreManager = keyStoreManager; mInjected = injected; @@ -184,15 +185,23 @@ public class RebootEscrowManagerTests { @Override public boolean serverBasedResumeOnReboot() { - if (mInjected.forceServerBased()) { - return true; - } return mServerBased; } @Override + public RebootEscrowProviderInterface createRebootEscrowProviderIfNeeded() { + mRebootEscrowProviderInUse = mDefaultRebootEscrowProvider; + return mRebootEscrowProviderInUse; + } + + @Override public RebootEscrowProviderInterface getRebootEscrowProvider() { - return mRebootEscrowProvider; + return mRebootEscrowProviderInUse; + } + + @Override + public void clearRebootEscrowProvider() { + mRebootEscrowProviderInUse = null; } @Override @@ -264,13 +273,15 @@ public class RebootEscrowManagerTests { when(mCallbacks.isUserSecure(NONSECURE_SECONDARY_USER_ID)).thenReturn(false); when(mCallbacks.isUserSecure(SECURE_SECONDARY_USER_ID)).thenReturn(true); mInjected = mock(MockableRebootEscrowInjected.class); - mService = new RebootEscrowManager(new MockInjector(mContext, mUserManager, mRebootEscrow, - mKeyStoreManager, mStorage, mInjected), mCallbacks, mStorage); + mMockInjector = new MockInjector(mContext, mUserManager, mRebootEscrow, + mKeyStoreManager, mStorage, mInjected); + mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage); } private void setServerBasedRebootEscrowProvider() throws Exception { - mService = new RebootEscrowManager(new MockInjector(mContext, mUserManager, - mServiceConnection, mKeyStoreManager, mStorage, mInjected), mCallbacks, mStorage); + mMockInjector = new MockInjector(mContext, mUserManager, mServiceConnection, + mKeyStoreManager, mStorage, mInjected); + mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage); } @Test @@ -317,6 +328,7 @@ public class RebootEscrowManagerTests { doThrow(ServiceSpecificException.class).when(mRebootEscrow).storeKey(any()); mService.clearRebootEscrow(); verify(mRebootEscrow).storeKey(eq(new byte[32])); + assertNull(mMockInjector.getRebootEscrowProvider()); } @Test @@ -785,7 +797,7 @@ public class RebootEscrowManagerTests { assertNull( mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); // Change the provider to server based, expect the reboot to fail - when(mInjected.forceServerBased()).thenReturn(true); + mMockInjector.mServerBased = true; assertEquals(ARM_REBOOT_ERROR_PROVIDER_MISMATCH, mService.armRebootEscrowIfNeeded()); assertNull( mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM)); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java index c11ac3a3e3a1..6722fff80d0b 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java @@ -213,7 +213,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase { mAssistants.loadDefaultsFromConfig(); assertEquals(new ArraySet<>(Arrays.asList(oldDefaultComponent)), mAssistants.getDefaultComponents()); - assertNull(mAssistants.getDefaultFromConfig()); + assertNull(mAssistants.mDefaultFromConfig); // Test loadDefaultFromConfig(false) only updates the mDefaultFromConfig when(mContext.getResources().getString( diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 37d7198ef150..a810acc68b2a 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -5753,11 +5753,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test - public void testNASSettingUpgrade_userSetNull_showOnBoarding() throws RemoteException { + public void testNASSettingUpgrade_userSetNull_noOnBoarding() throws RemoteException { ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component1"); TestableNotificationManagerService service = spy(mService); int userId = 11; setUsers(new int[]{userId}); + when(mUm.getProfileIds(userId, false)).thenReturn(new int[]{userId}); setNASMigrationDone(false, userId); when(mAssistants.getDefaultFromConfig()) .thenReturn(newDefaultComponent); @@ -5766,29 +5767,29 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.hasUserSet(userId)).thenReturn(true); service.migrateDefaultNASShowNotificationIfNecessary(); - assertFalse(service.isNASMigrationDone(userId)); - verify(service, times(1)).createNASUpgradeNotification(eq(userId)); - verify(mAssistants, times(0)).resetDefaultFromConfig(); + assertTrue(service.isNASMigrationDone(userId)); + verify(service, times(0)).createNASUpgradeNotification(eq(userId)); + verify(mAssistants, times(1)).clearDefaults(); + } - //Test user clear data before enable/disable from onboarding notification - ArrayMap<Boolean, ArrayList<ComponentName>> changedListeners = - generateResetComponentValues(); - when(mListeners.resetComponents(anyString(), anyInt())).thenReturn(changedListeners); - ArrayMap<Boolean, ArrayList<ComponentName>> changes = new ArrayMap<>(); - changes.put(true, new ArrayList(Arrays.asList(newDefaultComponent))); - changes.put(false, new ArrayList()); - when(mAssistants.resetComponents(anyString(), anyInt())).thenReturn(changes); + @Test + public void testNASSettingUpgrade_userSetSameDefault_noOnBoarding() throws RemoteException { + ComponentName defaultComponent = ComponentName.unflattenFromString("package/Component1"); + TestableNotificationManagerService service = spy(mService); + int userId = 11; + setUsers(new int[]{userId}); + when(mUm.getProfileIds(userId, false)).thenReturn(new int[]{userId}); + setNASMigrationDone(false, userId); + when(mAssistants.getDefaultFromConfig()) + .thenReturn(defaultComponent); + when(mAssistants.getAllowedComponents(anyInt())) + .thenReturn(new ArrayList(Arrays.asList(defaultComponent))); + when(mAssistants.hasUserSet(userId)).thenReturn(true); - //Clear data - service.getBinderService().clearData("package", userId, false); - //Test migrate flow again service.migrateDefaultNASShowNotificationIfNecessary(); - - //The notification should be still there - assertFalse(service.isNASMigrationDone(userId)); - verify(service, times(2)).createNASUpgradeNotification(eq(userId)); - verify(mAssistants, times(0)).resetDefaultFromConfig(); - assertEquals(null, service.getApprovedAssistant(userId)); + assertTrue(service.isNASMigrationDone(userId)); + verify(service, times(0)).createNASUpgradeNotification(eq(userId)); + verify(mAssistants, times(1)).resetDefaultFromConfig(); } @Test @@ -5842,6 +5843,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { int userId1 = 11; int userId2 = 12; setUsers(new int[]{userId1, userId2}); + when(mUm.getProfileIds(userId1, false)).thenReturn(new int[]{userId1}); + when(mUm.getProfileIds(userId2, false)).thenReturn(new int[]{userId2}); + setNASMigrationDone(false, userId1); setNASMigrationDone(false, userId2); when(mAssistants.getDefaultComponents()) @@ -5868,6 +5872,43 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testNASSettingUpgrade_multiProfile() throws RemoteException { + ComponentName oldDefaultComponent = ComponentName.unflattenFromString("package/Component1"); + ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component2"); + TestableNotificationManagerService service = spy(mService); + int userId1 = 11; + int userId2 = 12; //work profile + setUsers(new int[]{userId1, userId2}); + when(mUm.isManagedProfile(userId2)).thenReturn(true); + when(mUm.getProfileIds(userId1, false)).thenReturn(new int[]{userId1, userId2}); + + setNASMigrationDone(false, userId1); + setNASMigrationDone(false, userId2); + when(mAssistants.getDefaultComponents()) + .thenReturn(new ArraySet<>(Arrays.asList(oldDefaultComponent))); + when(mAssistants.getDefaultFromConfig()) + .thenReturn(newDefaultComponent); + //Both profiles: need onboarding + when(mAssistants.getAllowedComponents(userId1)) + .thenReturn(Arrays.asList(oldDefaultComponent)); + when(mAssistants.getAllowedComponents(userId2)) + .thenReturn(Arrays.asList(oldDefaultComponent)); + + when(mAssistants.hasUserSet(userId1)).thenReturn(true); + when(mAssistants.hasUserSet(userId2)).thenReturn(true); + + service.migrateDefaultNASShowNotificationIfNecessary(); + assertFalse(service.isNASMigrationDone(userId1)); + assertFalse(service.isNASMigrationDone(userId2)); + + // only user1 get notification + verify(service, times(1)).createNASUpgradeNotification(eq(userId1)); + verify(service, times(0)).createNASUpgradeNotification(eq(userId2)); + } + + + + @Test public void testNASSettingUpgrade_clearDataAfterMigrationIsDone() throws RemoteException { ComponentName defaultComponent = ComponentName.unflattenFromString("package/Component"); TestableNotificationManagerService service = spy(mService); @@ -5898,15 +5939,21 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test - public void testNASUpgradeNotificationDisableBroadcast() { - int userId = 11; - setUsers(new int[]{userId}); + public void testNASUpgradeNotificationDisableBroadcast_multiProfile() { + int userId1 = 11; + int userId2 = 12; + setUsers(new int[]{userId1, userId2}); + when(mUm.isManagedProfile(userId2)).thenReturn(true); + when(mUm.getProfileIds(userId1, false)).thenReturn(new int[]{userId1, userId2}); + TestableNotificationManagerService service = spy(mService); - setNASMigrationDone(false, userId); + setNASMigrationDone(false, userId1); + setNASMigrationDone(false, userId2); - simulateNASUpgradeBroadcast(ACTION_DISABLE_NAS, userId); + simulateNASUpgradeBroadcast(ACTION_DISABLE_NAS, userId1); - assertTrue(service.isNASMigrationDone(userId)); + assertTrue(service.isNASMigrationDone(userId1)); + assertTrue(service.isNASMigrationDone(userId2)); // User disabled the NAS from notification, the default stored in xml should be null // rather than the new default verify(mAssistants, times(1)).clearDefaults(); @@ -5914,7 +5961,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { //No more notification after disabled service.migrateDefaultNASShowNotificationIfNecessary(); - verify(service, times(0)).createNASUpgradeNotification(eq(userId)); + verify(service, times(0)).createNASUpgradeNotification(anyInt()); } @Test @@ -5922,6 +5969,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { int userId1 = 11; int userId2 = 12; setUsers(new int[]{userId1, userId2}); + when(mUm.getProfileIds(userId1, false)).thenReturn(new int[]{userId1}); + TestableNotificationManagerService service = spy(mService); setNASMigrationDone(false, userId1); setNASMigrationDone(false, userId2); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index b91497245dd1..8b9fc0fbf5b2 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -4216,7 +4216,6 @@ public class CarrierConfigManager { * it will override the framework default. * @hide */ - @SystemApi public static final String KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY = KEY_PREFIX + "publish_service_desc_feature_tag_map_override_string_array"; diff --git a/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java b/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java index 8762b6a712f2..0d63f7bba741 100644 --- a/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java +++ b/telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java @@ -501,6 +501,10 @@ public final class SipDelegateImsConfiguration implements Parcelable { * {@link SipMessage} was using the latest configuration during creation and not a stale * configuration due to race conditions between the configuration being updated and the RCS * application not receiving the updated configuration before generating a new message. + * <p> + * The version number should be a positive number that starts at 0 and increments sequentially + * as new {@link SipDelegateImsConfiguration} instances are created to update the IMS + * configuration state. * * @return the version number associated with this {@link SipDelegateImsConfiguration}. */ |