summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/framework/java/android/app/AlarmManager.java52
-rw-r--r--apex/jobscheduler/service/jni/Android.bp11
-rw-r--r--core/api/current.txt21
-rw-r--r--core/api/system-current.txt7
-rw-r--r--core/java/android/app/Activity.java4
-rw-r--r--core/java/android/app/ActivityThread.java8
-rw-r--r--core/java/android/app/IApplicationThread.aidl2
-rw-r--r--core/java/android/os/CountDownTimer.java21
-rw-r--r--core/java/android/os/Debug.java2
-rw-r--r--core/java/android/os/Parcelable.java39
-rw-r--r--core/java/android/service/translation/TranslationService.java1
-rw-r--r--core/java/android/view/SurfaceControl.java27
-rw-r--r--core/java/android/view/textservice/SpellCheckerSession.java159
-rw-r--r--core/java/android/view/textservice/TextServicesManager.java68
-rw-r--r--core/java/android/view/translation/TranslationResponse.java4
-rw-r--r--core/java/android/view/translation/UiTranslationController.java15
-rw-r--r--core/java/android/view/translation/UiTranslationManager.java30
-rw-r--r--core/java/android/widget/SpellChecker.java9
-rw-r--r--core/java/com/android/internal/app/IAppOpsCallback.aidl2
-rw-r--r--core/java/com/android/internal/app/IAppOpsService.aidl2
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java31
-rw-r--r--core/jni/android_view_SurfaceControl.cpp10
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java2
-rw-r--r--media/java/android/media/metrics/Event.java10
-rw-r--r--media/java/android/media/metrics/MediaMetricsManager.java2
-rw-r--r--media/java/android/media/metrics/NetworkEvent.java13
-rw-r--r--media/java/android/media/metrics/PlaybackErrorEvent.java12
-rw-r--r--media/java/android/media/metrics/PlaybackMetrics.java5
-rw-r--r--media/java/android/media/metrics/PlaybackStateEvent.java13
-rw-r--r--media/java/android/media/metrics/TrackChangeEvent.java22
-rw-r--r--packages/SystemUI/res-keyguard/values/styles.xml6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/Utils.java21
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java10
-rw-r--r--services/core/java/com/android/server/locksettings/RebootEscrowManager.java47
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java29
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java50
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java50
-rw-r--r--services/core/java/com/android/server/pm/ShortcutUser.java6
-rw-r--r--services/core/java/com/android/server/policy/DeviceStateProviderImpl.java4
-rw-r--r--services/incremental/Android.bp1
-rw-r--r--services/incremental/TEST_MAPPING4
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java42
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java2
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java105
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java1
-rw-r--r--telephony/java/android/telephony/ims/SipDelegateImsConfiguration.java4
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&lt;MyParcelable?&gt;
+ * = object : Parcelable.Creator&lt;MyParcelable?&gt; {
+ * override fun createFromParcel(`in`: Parcel): MyParcelable? {
+ * return MyParcelable(`in`)
+ * }
+ *
+ * override fun newArray(size: Int): Array&lt;MyParcelable?&gt; {
+ * 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}.
*/