Merge "Replace ColorDisplayController references"
diff --git a/Android.bp b/Android.bp
index ecdc082..7bdedc7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -77,7 +77,6 @@
"core/java/android/app/ISearchManager.aidl",
"core/java/android/app/ISearchManagerCallback.aidl",
"core/java/android/app/IServiceConnection.aidl",
- "core/java/android/app/ISmsAppService.aidl",
"core/java/android/app/IStopUserCallback.aidl",
"core/java/android/app/job/IJobCallback.aidl",
"core/java/android/app/job/IJobScheduler.aidl",
@@ -288,6 +287,7 @@
"core/java/android/service/carrier/ICarrierService.aidl",
"core/java/android/service/carrier/ICarrierMessagingCallback.aidl",
"core/java/android/service/carrier/ICarrierMessagingService.aidl",
+ "core/java/android/service/carrier/ICarrierMessagingClientService.aidl",
"core/java/android/service/contentsuggestions/IContentSuggestionsService.aidl",
"core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl",
"core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl",
@@ -746,6 +746,7 @@
"game-driver-protos",
"mediaplayer2-protos",
"android.hidl.base-V1.0-java",
+ "android.hardware.cas-V1.1-java",
"android.hardware.cas-V1.0-java",
"android.hardware.contexthub-V1.0-java",
"android.hardware.health-V1.0-java-constants",
@@ -908,6 +909,7 @@
"core/java/android/net/ProxyInfoParcelable.aidl",
"core/java/android/net/RouteInfoParcelable.aidl",
"core/java/android/net/StaticIpConfigurationParcelable.aidl",
+ "core/java/android/net/TcpKeepalivePacketDataParcelable.aidl",
"core/java/android/net/dhcp/DhcpServingParamsParcel.aidl",
"core/java/android/net/dhcp/IDhcpServer.aidl",
"core/java/android/net/dhcp/IDhcpServerCallbacks.aidl",
diff --git a/Android.mk b/Android.mk
index 65d4d24..9c65948 100644
--- a/Android.mk
+++ b/Android.mk
@@ -79,34 +79,6 @@
# ==== hiddenapi lists =======================================
ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true)
-.KATI_RESTAT: $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS)
-$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): \
- PRIVATE_FLAGS_INPUTS := $(PRIVATE_FLAGS_INPUTS) $(SOONG_HIDDENAPI_FLAGS)
-$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): \
- frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
- frameworks/base/config/hiddenapi-greylist.txt \
- frameworks/base/config/hiddenapi-greylist-max-p.txt \
- frameworks/base/config/hiddenapi-greylist-max-o.txt \
- frameworks/base/config/hiddenapi-force-blacklist.txt \
- $(INTERNAL_PLATFORM_HIDDENAPI_STUB_FLAGS) \
- $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE) \
- $(SOONG_HIDDENAPI_FLAGS)
- frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
- --csv $(INTERNAL_PLATFORM_HIDDENAPI_STUB_FLAGS) $(PRIVATE_FLAGS_INPUTS) \
- --greylist frameworks/base/config/hiddenapi-greylist.txt \
- --greylist-ignore-conflicts $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE) \
- --greylist-max-p frameworks/base/config/hiddenapi-greylist-max-p.txt \
- --greylist-max-o-ignore-conflicts \
- frameworks/base/config/hiddenapi-greylist-max-o.txt \
- --blacklist frameworks/base/config/hiddenapi-force-blacklist.txt \
- --output $@.tmp
- $(call commit-change-for-toc,$@)
-
-$(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA): \
- frameworks/base/tools/hiddenapi/merge_csv.py \
- $(PRIVATE_METADATA_INPUTS)
- frameworks/base/tools/hiddenapi/merge_csv.py $(PRIVATE_METADATA_INPUTS) > $@
-
$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS))
$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA))
endif # UNSAFE_DISABLE_HIDDENAPI_FLAGS
diff --git a/api/current.txt b/api/current.txt
index 417ae80..b321c224 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26,6 +26,7 @@
field public static final String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
field public static final String BIND_AUTOFILL_SERVICE = "android.permission.BIND_AUTOFILL_SERVICE";
field public static final String BIND_CALL_REDIRECTION_SERVICE = "android.permission.BIND_CALL_REDIRECTION_SERVICE";
+ field public static final String BIND_CARRIER_MESSAGING_CLIENT_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE";
field @Deprecated public static final String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
field public static final String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
field public static final String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
@@ -41,7 +42,6 @@
field public static final String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
field public static final String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
field public static final String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
- field public static final String BIND_SMS_APP_SERVICE = "android.permission.BIND_SMS_APP_SERVICE";
field public static final String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
@@ -645,6 +645,7 @@
field public static final int footerDividersEnabled = 16843311; // 0x101022f
field public static final int forceDarkAllowed = 16844172; // 0x101058c
field public static final int forceHasOverlappingRendering = 16844065; // 0x1010521
+ field public static final int forceUriPermissions = 16844197; // 0x10105a5
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
field public static final int foregroundServiceType = 16844191; // 0x101059f
@@ -6210,11 +6211,6 @@
method public void onSharedElementsReady();
}
- public class SmsAppService extends android.app.Service {
- ctor public SmsAppService();
- method public final android.os.IBinder onBind(android.content.Intent);
- }
-
public class StatusBarManager {
}
@@ -6742,6 +6738,7 @@
method public void setCrossProfileCalendarPackages(@NonNull android.content.ComponentName, @Nullable java.util.Set<java.lang.String>);
method public void setCrossProfileCallerIdDisabled(@NonNull android.content.ComponentName, boolean);
method public void setCrossProfileContactsSearchDisabled(@NonNull android.content.ComponentName, boolean);
+ method public void setDefaultSmsApplication(@NonNull android.content.ComponentName, @NonNull String);
method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.lang.String>);
method public void setDeviceOwnerLockScreenInfo(@NonNull android.content.ComponentName, CharSequence);
method public void setEndUserSessionMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
@@ -7252,6 +7249,7 @@
ctor public BackupManager(android.content.Context);
method public void dataChanged();
method public static void dataChanged(String);
+ method @Nullable public android.os.UserHandle getUserForAncestralSerialNumber(long);
method @Deprecated public int requestRestore(android.app.backup.RestoreObserver);
}
@@ -11879,6 +11877,7 @@
field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
field public String authority;
field public int flags;
+ field public boolean forceUriPermissions;
field public boolean grantUriPermissions;
field public int initOrder;
field @Deprecated public boolean isSyncable;
@@ -16935,6 +16934,7 @@
field public static final int REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4; // 0x4
field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3
field public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; // 0x5
+ field public static final int REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13; // 0xd
field public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7; // 0x7
field public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0; // 0x0
field public static final int SCALER_CROPPING_TYPE_FREEFORM = 1; // 0x1
@@ -19446,9 +19446,9 @@
method public static android.icu.text.BreakIterator getSentenceInstance(java.util.Locale);
method public static android.icu.text.BreakIterator getSentenceInstance(android.icu.util.ULocale);
method public abstract java.text.CharacterIterator getText();
- method public static android.icu.text.BreakIterator getTitleInstance();
- method public static android.icu.text.BreakIterator getTitleInstance(java.util.Locale);
- method public static android.icu.text.BreakIterator getTitleInstance(android.icu.util.ULocale);
+ method @Deprecated public static android.icu.text.BreakIterator getTitleInstance();
+ method @Deprecated public static android.icu.text.BreakIterator getTitleInstance(java.util.Locale);
+ method @Deprecated public static android.icu.text.BreakIterator getTitleInstance(android.icu.util.ULocale);
method public static android.icu.text.BreakIterator getWordInstance();
method public static android.icu.text.BreakIterator getWordInstance(java.util.Locale);
method public static android.icu.text.BreakIterator getWordInstance(android.icu.util.ULocale);
@@ -19465,7 +19465,7 @@
field public static final int KIND_CHARACTER = 0; // 0x0
field public static final int KIND_LINE = 2; // 0x2
field public static final int KIND_SENTENCE = 3; // 0x3
- field public static final int KIND_TITLE = 4; // 0x4
+ field @Deprecated public static final int KIND_TITLE = 4; // 0x4
field public static final int KIND_WORD = 1; // 0x1
field public static final int WORD_IDEO = 400; // 0x190
field public static final int WORD_IDEO_LIMIT = 500; // 0x1f4
@@ -23746,6 +23746,7 @@
ctor public ExifInterface(@NonNull java.io.InputStream) throws java.io.IOException;
method public double getAltitude(double);
method @Nullable public String getAttribute(@NonNull String);
+ method @Nullable public byte[] getAttributeBytes(@NonNull String);
method public double getAttributeDouble(@NonNull String, double);
method public int getAttributeInt(@NonNull String, int);
method @Nullable public long[] getAttributeRange(@NonNull String);
@@ -23901,6 +23902,7 @@
field public static final String TAG_USER_COMMENT = "UserComment";
field public static final String TAG_WHITE_BALANCE = "WhiteBalance";
field public static final String TAG_WHITE_POINT = "WhitePoint";
+ field public static final String TAG_XMP = "Xmp";
field public static final String TAG_X_RESOLUTION = "XResolution";
field public static final String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients";
field public static final String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning";
@@ -24051,7 +24053,8 @@
}
public static interface MediaCas.EventListener {
- method public void onEvent(android.media.MediaCas, int, int, @Nullable byte[]);
+ method public void onEvent(@NonNull android.media.MediaCas, int, int, @Nullable byte[]);
+ method public default void onSessionEvent(@NonNull android.media.MediaCas, @NonNull android.media.MediaCas.Session, int, int, @Nullable byte[]);
}
public static class MediaCas.PluginDescriptor {
@@ -24063,6 +24066,7 @@
method public void close();
method public void processEcm(@NonNull byte[], int, int) throws android.media.MediaCasException;
method public void processEcm(@NonNull byte[]) throws android.media.MediaCasException;
+ method public void sendSessionEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException;
method public void setPrivateData(@NonNull byte[]) throws android.media.MediaCasException;
}
@@ -24140,8 +24144,10 @@
field public static final int INFO_OUTPUT_FORMAT_CHANGED = -2; // 0xfffffffe
field public static final int INFO_TRY_AGAIN_LATER = -1; // 0xffffffff
field public static final String PARAMETER_KEY_HDR10_PLUS_INFO = "hdr10-plus-info";
+ field public static final String PARAMETER_KEY_OFFSET_TIME = "time-offset-us";
field public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
field public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";
+ field public static final String PARAMETER_KEY_SUSPEND_TIME = "drop-start-time-us";
field public static final String PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
@@ -24986,6 +24992,7 @@
field public static final String KEY_COLOR_STANDARD = "color-standard";
field public static final String KEY_COLOR_TRANSFER = "color-transfer";
field public static final String KEY_COMPLEXITY = "complexity";
+ field public static final String KEY_CREATE_INPUT_SURFACE_SUSPENDED = "create-input-buffers-suspended";
field public static final String KEY_DURATION = "durationUs";
field public static final String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
field public static final String KEY_FRAME_RATE = "frame-rate";
@@ -25003,8 +25010,10 @@
field public static final String KEY_LANGUAGE = "language";
field public static final String KEY_LATENCY = "latency";
field public static final String KEY_LEVEL = "level";
+ field public static final String KEY_MAX_FPS_TO_ENCODER = "max-fps-to-encoder";
field public static final String KEY_MAX_HEIGHT = "max-height";
field public static final String KEY_MAX_INPUT_SIZE = "max-input-size";
+ field public static final String KEY_MAX_PTS_GAP_TO_ENCODER = "max-pts-gap-to-encoder";
field public static final String KEY_MAX_WIDTH = "max-width";
field public static final String KEY_MIME = "mime";
field public static final String KEY_OPERATING_RATE = "operating-rate";
@@ -28600,7 +28609,7 @@
field public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
field @Deprecated public static final String EXTRA_NETWORK_INFO = "networkInfo";
field public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
- field public static final String EXTRA_NETWORK_TYPE = "networkType";
+ field @Deprecated public static final String EXTRA_NETWORK_TYPE = "networkType";
field public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
field @Deprecated public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
field public static final String EXTRA_REASON = "reason";
@@ -34194,7 +34203,6 @@
}
public static class Build.Partition {
- ctor public Build.Partition();
method public long getBuildTimeMillis();
method @NonNull public String getFingerprint();
method @NonNull public String getName();
@@ -41352,6 +41360,11 @@
field public static final android.os.Parcelable.Creator<android.service.carrier.CarrierIdentifier> CREATOR;
}
+ public class CarrierMessagingClientService extends android.app.Service {
+ ctor public CarrierMessagingClientService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ }
+
public abstract class CarrierMessagingService extends android.app.Service {
ctor public CarrierMessagingService();
method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
@@ -41693,6 +41706,7 @@
public static class NotificationListenerService.Ranking {
ctor public NotificationListenerService.Ranking();
+ method public boolean canBubble();
method public boolean canShowBadge();
method public android.app.NotificationChannel getChannel();
method public int getImportance();
@@ -42446,6 +42460,7 @@
method public static java.io.FileDescriptor accept(java.io.FileDescriptor, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
method public static boolean access(String, int) throws android.system.ErrnoException;
method public static void bind(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+ method public static void bind(java.io.FileDescriptor, java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException;
method public static void chmod(String, int) throws android.system.ErrnoException;
method public static void chown(String, int, int) throws android.system.ErrnoException;
method public static void close(java.io.FileDescriptor) throws android.system.ErrnoException;
@@ -42514,6 +42529,7 @@
method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException;
method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+ method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException;
method @Deprecated public static void setegid(int) throws android.system.ErrnoException;
method public static void setenv(String, String, boolean) throws android.system.ErrnoException;
method @Deprecated public static void seteuid(int) throws android.system.ErrnoException;
@@ -44131,7 +44147,7 @@
}
public final class AvailableNetworkInfo implements android.os.Parcelable {
- ctor public AvailableNetworkInfo(int, int, java.util.ArrayList<java.lang.String>);
+ ctor public AvailableNetworkInfo(int, int, java.util.List<java.lang.String>);
method public int describeContents();
method public java.util.List<java.lang.String> getMccMncs();
method public int getPriority();
@@ -45093,7 +45109,7 @@
method public int getNetworkType();
method public int getPhoneCount();
method public int getPhoneType();
- method public int getPreferredOpportunisticDataSubscription();
+ method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.ServiceState getServiceState();
method @Nullable public android.telephony.SignalStrength getSignalStrength();
method public int getSimCarrierId();
@@ -45129,6 +45145,7 @@
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isNetworkRoaming();
+ method public boolean isRttSupported();
method public boolean isSmsCapable();
method @Deprecated public boolean isTtyModeSupported();
method public boolean isVoiceCapable();
@@ -45154,13 +45171,13 @@
method @Deprecated public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void switchMultiSimConfig(int);
method public boolean updateAvailableNetworks(java.util.List<android.telephony.AvailableNetworkInfo>);
+ field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE";
field public static final String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
field public static final String ACTION_NETWORK_COUNTRY_CHANGED = "android.telephony.action.NETWORK_COUNTRY_CHANGED";
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
field public static final String ACTION_SECRET_CODE = "android.telephony.action.SECRET_CODE";
field public static final String ACTION_SHOW_VOICEMAIL_NOTIFICATION = "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION";
- field public static final String ACTION_SMS_APP_SERVICE = "android.telephony.action.SMS_APP_SERVICE";
field public static final String ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED = "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED";
field public static final String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED = "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED";
field public static final int APPTYPE_CSIM = 4; // 0x4
@@ -45661,9 +45678,9 @@
}
public interface GroupCallCallback {
- method public void onBroadcastSignalStrengthUpdated(@IntRange(from=0xffffffff, to=4) int);
- method public void onError(int, @Nullable String);
- method public void onGroupCallStateChanged(int, int);
+ method public default void onBroadcastSignalStrengthUpdated(@IntRange(from=0xffffffff, to=4) int);
+ method public default void onError(int, @Nullable String);
+ method public default void onGroupCallStateChanged(int, int);
field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff
}
@@ -45721,10 +45738,10 @@
}
public interface MbmsGroupCallSessionCallback {
- method public void onAvailableSaisUpdated(@NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.util.List<java.lang.Integer>>);
- method public void onError(int, @Nullable String);
- method public void onMiddlewareReady();
- method public void onServiceInterfaceAvailable(@NonNull String, int);
+ method public default void onAvailableSaisUpdated(@NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.util.List<java.lang.Integer>>);
+ method public default void onError(int, @Nullable String);
+ method public default void onMiddlewareReady();
+ method public default void onServiceInterfaceAvailable(@NonNull String, int);
}
public class MbmsStreamingSessionCallback {
@@ -50663,7 +50680,7 @@
method public void setClickable(boolean);
method public void setClipBounds(android.graphics.Rect);
method public void setClipToOutline(boolean);
- method public void setContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSession);
+ method public void setContentCaptureSession(@Nullable android.view.contentcapture.ContentCaptureSession);
method public void setContentDescription(CharSequence);
method public void setContextClickable(boolean);
method public void setDefaultFocusHighlightEnabled(boolean);
@@ -50771,6 +50788,7 @@
method public void setTouchDelegate(android.view.TouchDelegate);
method public void setTransitionAlpha(float);
method public final void setTransitionName(String);
+ method public void setTransitionVisibility(int);
method public void setTranslationX(float);
method public void setTranslationY(float);
method public void setTranslationZ(float);
@@ -53405,6 +53423,11 @@
package android.view.inspector {
+ public class GeneratedInspectionCompanionProvider implements android.view.inspector.InspectionCompanionProvider {
+ ctor public GeneratedInspectionCompanionProvider();
+ method @Nullable public <T> android.view.inspector.InspectionCompanion<T> provide(@NonNull Class<T>);
+ }
+
public interface InspectionCompanion<T> {
method @Nullable public default String getNodeName();
method public void mapProperties(@NonNull android.view.inspector.PropertyMapper);
@@ -53415,6 +53438,10 @@
ctor public InspectionCompanion.UninitializedPropertyMapException();
}
+ public interface InspectionCompanionProvider {
+ method @Nullable public <T> android.view.inspector.InspectionCompanion<T> provide(@NonNull Class<T>);
+ }
+
public final class IntEnumMapping {
method @Nullable public String get(int);
}
@@ -53548,7 +53575,7 @@
method @NonNull public java.util.List<android.view.textclassifier.ConversationActions.Message> getConversation();
method @Nullable public String getConversationId();
method @Nullable public java.util.List<java.lang.String> getHints();
- method @IntRange(from=0) public int getMaxSuggestions();
+ method @IntRange(from=0xffffffff) public int getMaxSuggestions();
method @NonNull public android.view.textclassifier.TextClassifier.EntityConfig getTypeConfig();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.textclassifier.ConversationActions.Request> CREATOR;
@@ -53561,7 +53588,7 @@
method @NonNull public android.view.textclassifier.ConversationActions.Request build();
method @NonNull public android.view.textclassifier.ConversationActions.Request.Builder setConversationId(@Nullable String);
method public android.view.textclassifier.ConversationActions.Request.Builder setHints(@Nullable java.util.List<java.lang.String>);
- method @NonNull public android.view.textclassifier.ConversationActions.Request.Builder setMaxSuggestions(@IntRange(from=0) int);
+ method @NonNull public android.view.textclassifier.ConversationActions.Request.Builder setMaxSuggestions(@IntRange(from=0xffffffff) int);
method @NonNull public android.view.textclassifier.ConversationActions.Request.Builder setTypeConfig(@Nullable android.view.textclassifier.TextClassifier.EntityConfig);
}
@@ -54845,6 +54872,7 @@
method public int getCheckedItemPosition();
method public android.util.SparseBooleanArray getCheckedItemPositions();
method public int getChoiceMode();
+ method public boolean getDrawSelectorOnTop();
method public int getListPaddingBottom();
method public int getListPaddingLeft();
method public int getListPaddingRight();
@@ -56245,6 +56273,7 @@
method public android.view.Menu getMenu();
method public android.view.MenuInflater getMenuInflater();
method public void inflate(@MenuRes int);
+ method public void setForceShowIcon(boolean);
method public void setGravity(int);
method public void setOnDismissListener(android.widget.PopupMenu.OnDismissListener);
method public void setOnMenuItemClickListener(android.widget.PopupMenu.OnMenuItemClickListener);
@@ -56344,7 +56373,11 @@
method @Nullable public android.graphics.PorterDuff.Mode getIndeterminateTintMode();
method public android.view.animation.Interpolator getInterpolator();
method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMax();
+ method @Px public int getMaxHeight();
+ method @Px public int getMaxWidth();
method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMin();
+ method @Px public int getMinHeight();
+ method @Px public int getMinWidth();
method @android.view.ViewDebug.ExportedProperty(category="progress") public int getProgress();
method @Nullable public android.content.res.ColorStateList getProgressBackgroundTintList();
method @Nullable public android.graphics.PorterDuff.Mode getProgressBackgroundTintMode();
@@ -56368,7 +56401,11 @@
method public void setInterpolator(android.content.Context, @InterpolatorRes int);
method public void setInterpolator(android.view.animation.Interpolator);
method public void setMax(int);
+ method public void setMaxHeight(@Px int);
+ method public void setMaxWidth(@Px int);
method public void setMin(int);
+ method public void setMinHeight(@Px int);
+ method public void setMinWidth(@Px int);
method public void setProgress(int);
method public void setProgress(int, boolean);
method public void setProgressBackgroundTintList(@Nullable android.content.res.ColorStateList);
@@ -56458,6 +56495,7 @@
ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
method public android.widget.RelativeLayout.LayoutParams generateLayoutParams(android.util.AttributeSet);
method public int getGravity();
+ method public int getIgnoreGravity();
method public void setGravity(int);
method public void setHorizontalGravity(int);
method public void setIgnoreGravity(int);
@@ -56631,6 +56669,7 @@
method public boolean isFillViewport();
method public boolean isSmoothScrollingEnabled();
method public boolean pageScroll(int);
+ method public void scrollToDescendant(android.view.View);
method public void setFillViewport(boolean);
method public void setSmoothScrollingEnabled(boolean);
method public final void smoothScrollBy(int, int);
@@ -56674,8 +56713,9 @@
method public CharSequence getQuery();
method @Nullable public CharSequence getQueryHint();
method public android.widget.CursorAdapter getSuggestionsAdapter();
- method public boolean isIconfiedByDefault();
+ method @Deprecated public boolean isIconfiedByDefault();
method public boolean isIconified();
+ method public boolean isIconifiedByDefault();
method public boolean isQueryRefinementEnabled();
method public boolean isSubmitButtonEnabled();
method public void onActionViewCollapsed();
@@ -57398,6 +57438,7 @@
ctor public ToggleButton(android.content.Context, android.util.AttributeSet, int);
ctor public ToggleButton(android.content.Context, android.util.AttributeSet);
ctor public ToggleButton(android.content.Context);
+ method public float getDisabledAlpha();
method public CharSequence getTextOff();
method public CharSequence getTextOn();
method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -57558,6 +57599,7 @@
@android.widget.RemoteViews.RemoteView public class ViewFlipper extends android.widget.ViewAnimator {
ctor public ViewFlipper(android.content.Context);
ctor public ViewFlipper(android.content.Context, android.util.AttributeSet);
+ method public int getFlipInterval();
method public boolean isAutoStart();
method public boolean isFlipping();
method public void setAutoStart(boolean);
diff --git a/api/removed.txt b/api/removed.txt
index 9f4b041..262ffec 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -344,7 +344,7 @@
public final class PowerManager {
method public void goToSleep(long);
method @Deprecated public void userActivity(long, boolean);
- method public void wakeUp(long);
+ method @Deprecated public void wakeUp(long);
}
public class RecoverySystem {
diff --git a/api/system-current.txt b/api/system-current.txt
index bf3c0a2..b7fc339 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -711,6 +711,7 @@
method @Deprecated public int requestRestore(android.app.backup.RestoreObserver, android.app.backup.BackupManagerMonitor);
method @Deprecated @RequiresPermission(android.Manifest.permission.BACKUP) public String selectBackupTransport(String);
method @RequiresPermission(android.Manifest.permission.BACKUP) public void selectBackupTransport(android.content.ComponentName, android.app.backup.SelectBackupTransportCallback);
+ method @RequiresPermission(android.Manifest.permission.BACKUP) public void setAncestralSerialNumber(long);
method @RequiresPermission(android.Manifest.permission.BACKUP) public void setAutoRestore(boolean);
method @RequiresPermission(android.Manifest.permission.BACKUP) public void setBackupEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.BACKUP) public void updateTransportAttributes(android.content.ComponentName, String, @Nullable android.content.Intent, String, @Nullable android.content.Intent, @Nullable String);
@@ -1071,16 +1072,17 @@
public final class RoleManager {
method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void addRoleHolderAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean addRoleHolderFromController(@NonNull String, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void clearRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @NonNull @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public java.util.List<java.lang.String> getHeldRolesFromController(@NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List<java.lang.String> getRoleHolders(@NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List<java.lang.String> getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void removeOnRoleHoldersChangedListenerAsUser(@NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void removeRoleHolderAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean removeRoleHolderFromController(@NonNull String, @NonNull String);
method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public void setRoleNamesFromController(@NonNull java.util.List<java.lang.String>);
+ field public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1; // 0x1
field public static final String ROLE_ASSISTANT = "android.app.role.ASSISTANT";
}
@@ -3317,11 +3319,11 @@
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int getGnssBatchSize();
method public int getGnssCapabilities();
method @Nullable public String getLocationControllerExtraPackage();
- method @Nullable public String getNetworkProviderPackage();
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void injectGnssMeasurementCorrections(@NonNull android.location.GnssMeasurementCorrections);
method public boolean isLocationControllerExtraPackageEnabled();
method public boolean isLocationEnabledForUser(android.os.UserHandle);
method public boolean isProviderEnabledForUser(String, android.os.UserHandle);
+ method public boolean isProviderPackage(String);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, android.location.BatchedLocationCallback, android.os.Handler);
method @Deprecated public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
method @Deprecated public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
@@ -3912,11 +3914,13 @@
public class ConnectivityManager {
method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull java.io.FileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
+ method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
method public boolean getAvoidBadWifi();
method @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS) public String getCaptivePortalServerUrl();
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementValue(int, boolean, @NonNull android.net.ConnectivityManager.TetheringEntitlementValueListener, @Nullable android.os.Handler);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean);
+ method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
@@ -4999,10 +5003,11 @@
method public boolean getEnableAdjustBrightness();
method public boolean getEnableDataSaver();
method public boolean getEnableFirewall();
+ method public boolean getEnableNightMode();
method public boolean getEnableQuickDoze();
method public boolean getForceAllAppsStandby();
method public boolean getForceBackgroundCheck();
- method public int getGpsMode();
+ method public int getLocationMode();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.os.BatterySaverPolicyConfig> CREATOR;
}
@@ -5024,10 +5029,11 @@
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableAdjustBrightness(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableDataSaver(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableFirewall(boolean);
+ method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableNightMode(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableQuickDoze(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setForceAllAppsStandby(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setForceBackgroundCheck(boolean);
- method @NonNull public android.os.BatterySaverPolicyConfig.Builder setGpsMode(int);
+ method @NonNull public android.os.BatterySaverPolicyConfig.Builder setLocationMode(int);
}
public class Binder implements android.os.IBinder {
@@ -5546,6 +5552,8 @@
method @NonNull public abstract java.util.List<android.permission.RuntimePermissionUsageInfo> onGetPermissionUsages(boolean, long);
method public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream);
method public abstract boolean onIsApplicationQualifiedForRole(@NonNull String, @NonNull String);
+ method @BinderThread public abstract boolean onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle);
+ method @BinderThread public abstract void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream);
method public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String);
method @NonNull public abstract java.util.Map<java.lang.String,java.util.List<java.lang.String>> onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String);
field public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService";
@@ -5747,9 +5755,15 @@
field public static final String NAMESPACE = "intelligence_attention";
}
+ public static interface DeviceConfig.MediaNative {
+ field public static final String NAMESPACE = "media_native";
+ }
+
public static interface DeviceConfig.NotificationAssistant {
field public static final String GENERATE_ACTIONS = "generate_actions";
field public static final String GENERATE_REPLIES = "generate_replies";
+ field public static final String MAX_MESSAGES_TO_EXTRACT = "max_messages_to_extract";
+ field public static final String MAX_SUGGESTIONS = "max_suggestions";
field public static final String NAMESPACE = "notification_assistant";
}
@@ -5763,10 +5777,19 @@
field public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
}
+ public static interface DeviceConfig.Runtime {
+ field public static final String NAMESPACE = "runtime";
+ field public static final String USE_PRECOMPILED_LAYOUT = "view.precompiled_layout_enabled";
+ }
+
public static interface DeviceConfig.RuntimeNative {
field public static final String NAMESPACE = "runtime_native";
}
+ public static interface DeviceConfig.RuntimeNativeBoot {
+ field public static final String NAMESPACE = "runtime_native_boot";
+ }
+
public static interface DeviceConfig.Storage {
field public static final String ISOLATED_STORAGE_ENABLED = "isolated_storage_enabled";
field public static final String NAMESPACE = "storage";
@@ -5960,7 +5983,6 @@
field public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH = "autofill_user_data_max_value_length";
field public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH = "autofill_user_data_min_value_length";
field public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category.";
- field public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled";
field public static final String DOZE_ALWAYS_ON = "doze_always_on";
field public static final String HUSH_GESTURE_USED = "hush_gesture_used";
field public static final String INSTANT_APPS_ENABLED = "instant_apps_enabled";
@@ -6019,11 +6041,12 @@
public abstract class RoleControllerService extends android.app.Service {
ctor public RoleControllerService();
- method public abstract void onAddRoleHolder(@NonNull String, @NonNull String, @NonNull android.app.role.RoleManagerCallback);
+ method public abstract void onAddRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent);
- method public abstract void onClearRoleHolders(@NonNull String, @NonNull android.app.role.RoleManagerCallback);
+ method public abstract void onClearRoleHolders(@NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
method public abstract void onGrantDefaultRoles(@NonNull android.app.role.RoleManagerCallback);
- method public abstract void onRemoveRoleHolder(@NonNull String, @NonNull String, @NonNull android.app.role.RoleManagerCallback);
+ method public abstract void onRemoveRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
+ method public abstract void onSmsKillSwitchToggled(boolean);
field public static final String SERVICE_INTERFACE = "android.rolecontrollerservice.RoleControllerService";
}
@@ -6302,8 +6325,6 @@
public abstract class ContentCaptureService extends android.app.Service {
ctor public ContentCaptureService();
- method @NonNull public final java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities();
- method @NonNull public final java.util.Set<java.lang.String> getContentCaptureDisabledPackages();
method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
method public void onConnected();
method public void onContentCaptureEvent(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.view.contentcapture.ContentCaptureEvent);
@@ -6312,9 +6333,7 @@
method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
method public void onDisconnected();
method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
- method public final void setActivityContentCaptureEnabled(@NonNull android.content.ComponentName, boolean);
method public final void setContentCaptureWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
- method public final void setPackageContentCaptureEnabled(@NonNull String, boolean);
field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
}
@@ -7847,6 +7866,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
method public void updateServiceLocation();
+ field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_DEBUG_EVENT = "android.telephony.action.DEBUG_EVENT";
field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
@@ -7854,6 +7874,8 @@
field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
+ field public static final String EXTRA_DEBUG_EVENT_DESCRIPTION = "android.telephony.extra.DEBUG_EVENT_DESCRIPTION";
+ field public static final String EXTRA_DEBUG_EVENT_ID = "android.telephony.extra.DEBUG_EVENT_ID";
field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
@@ -9262,11 +9284,7 @@
package android.view.autofill {
public final class AutofillManager {
- method @NonNull public java.util.Set<android.content.ComponentName> getAugmentedAutofillDisabledActivities();
- method @NonNull public java.util.Set<java.lang.String> getAugmentedAutofillDisabledPackages();
- method public void setActivityAugmentedAutofillEnabled(@NonNull android.content.ComponentName, boolean);
method public void setAugmentedAutofillWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
- method public void setPackageAugmentedAutofillEnabled(@NonNull String, boolean);
}
}
@@ -9296,6 +9314,8 @@
method @Nullable public android.view.contentcapture.ViewNode getViewNode();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureEvent> CREATOR;
+ field public static final int TYPE_INITIAL_VIEW_TREE_APPEARED = 5; // 0x5
+ field public static final int TYPE_INITIAL_VIEW_TREE_APPEARING = 4; // 0x4
field public static final int TYPE_VIEW_APPEARED = 1; // 0x1
field public static final int TYPE_VIEW_DISAPPEARED = 2; // 0x2
field public static final int TYPE_VIEW_TEXT_CHANGED = 3; // 0x3
diff --git a/api/test-current.txt b/api/test-current.txt
index 2a9a149..94e83ea 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -322,6 +322,14 @@
}
+package android.app.assist {
+
+ public static class AssistStructure.ViewNode {
+ ctor public AssistStructure.ViewNode();
+ }
+
+}
+
package android.app.backup {
public class BackupManager {
@@ -421,11 +429,11 @@
package android.app.role {
public final class RoleManager {
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void addRoleHolderAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void clearRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHolders(@NonNull String);
method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle);
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void removeRoleHolderAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
field public static final String ROLE_ASSISTANT = "android.app.role.ASSISTANT";
}
@@ -792,6 +800,33 @@
public class LocationManager {
method public String[] getBackgroundThrottlingWhitelist();
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.app.PendingIntent);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, android.os.UserHandle);
+ }
+
+ public final class LocationRequest implements android.os.Parcelable {
+ method public static android.location.LocationRequest create();
+ method public int describeContents();
+ method public long getExpireAt();
+ method public long getFastestInterval();
+ method public long getInterval();
+ method public int getNumUpdates();
+ method public int getQuality();
+ method public android.location.LocationRequest setExpireAt(long);
+ method public android.location.LocationRequest setExpireIn(long);
+ method public android.location.LocationRequest setFastestInterval(long);
+ method public android.location.LocationRequest setInterval(long);
+ method public android.location.LocationRequest setNumUpdates(int);
+ method public android.location.LocationRequest setQuality(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ACCURACY_BLOCK = 102; // 0x66
+ field public static final int ACCURACY_CITY = 104; // 0x68
+ field public static final int ACCURACY_FINE = 100; // 0x64
+ field public static final android.os.Parcelable.Creator<android.location.LocationRequest> CREATOR;
+ field public static final int POWER_HIGH = 203; // 0xcb
+ field public static final int POWER_LOW = 201; // 0xc9
+ field public static final int POWER_NONE = 200; // 0xc8
}
}
@@ -899,6 +934,7 @@
}
public class ConnectivityManager {
+ method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.os.Bundle);
field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
}
@@ -1761,6 +1797,7 @@
method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
method @NonNull public static java.io.File getVolumePath(@NonNull String) throws java.io.FileNotFoundException;
method @NonNull public static java.util.Collection<java.io.File> getVolumeScanPaths(@NonNull String) throws java.io.FileNotFoundException;
+ field public static final String EXTRA_ORIGINATED_FROM_SHELL = "android.intent.extra.originated_from_shell";
field public static final String SCAN_FILE_CALL = "scan_file";
field public static final String SCAN_VOLUME_CALL = "scan_volume";
}
@@ -1815,6 +1852,7 @@
field @Deprecated public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = "enabled_notification_policy_access_packages";
field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis";
field public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS = "location_access_check_interval_millis";
+ field public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
field public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
@@ -2042,6 +2080,40 @@
}
+package android.service.contentcapture {
+
+ @Deprecated public final class ContentCaptureEventsRequest implements android.os.Parcelable {
+ method @Deprecated public int describeContents();
+ method @Deprecated @NonNull public java.util.List<android.view.contentcapture.ContentCaptureEvent> getEvents();
+ method @Deprecated public void writeToParcel(android.os.Parcel, int);
+ field @Deprecated public static final android.os.Parcelable.Creator<android.service.contentcapture.ContentCaptureEventsRequest> CREATOR;
+ }
+
+ public abstract class ContentCaptureService extends android.app.Service {
+ ctor public ContentCaptureService();
+ method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
+ method public void onConnected();
+ method public void onContentCaptureEvent(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.view.contentcapture.ContentCaptureEvent);
+ method @Deprecated public void onContentCaptureEventsRequest(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.ContentCaptureEventsRequest);
+ method public void onCreateContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureContext, @NonNull android.view.contentcapture.ContentCaptureSessionId);
+ method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
+ method public void onDisconnected();
+ method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
+ method public final void setContentCaptureWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
+ field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
+ }
+
+ public final class SnapshotData implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.app.assist.AssistContent getAssistContent();
+ method public android.os.Bundle getAssistData();
+ method public android.app.assist.AssistStructure getAssistStructure();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.contentcapture.SnapshotData> CREATOR;
+ }
+
+}
+
package android.service.notification {
@Deprecated public abstract class ConditionProviderService extends android.app.Service {
@@ -2122,7 +2194,6 @@
public class TelephonyManager {
method public int checkCarrierPrivilegesForPackage(String);
method public int getCarrierIdListVersion();
- method public boolean isRttSupported();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
method public void setCarrierTestOverride(String, String, String, String, String, String, String);
field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
@@ -2597,17 +2668,56 @@
}
public final class AutofillManager {
- method @NonNull public java.util.Set<android.content.ComponentName> getAugmentedAutofillDisabledActivities();
- method @NonNull public java.util.Set<java.lang.String> getAugmentedAutofillDisabledPackages();
- method public void setActivityAugmentedAutofillEnabled(@NonNull android.content.ComponentName, boolean);
method public void setAugmentedAutofillWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
- method public void setPackageAugmentedAutofillEnabled(@NonNull String, boolean);
field public static final int FLAG_SMART_SUGGESTION_SYSTEM = 1; // 0x1
field public static final int MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS = 120000; // 0x1d4c0
}
}
+package android.view.contentcapture {
+
+ public final class ContentCaptureContext implements android.os.Parcelable {
+ method @Nullable public String getAction();
+ method @Nullable public android.content.ComponentName getActivityComponent();
+ method public int getDisplayId();
+ method @Nullable public android.os.Bundle getExtras();
+ method public int getFlags();
+ method @Nullable public android.view.contentcapture.ContentCaptureSessionId getParentSessionId();
+ method public int getTaskId();
+ method @Nullable public android.net.Uri getUri();
+ field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
+ field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
+ }
+
+ public final class ContentCaptureEvent implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getEventTime();
+ method @Nullable public android.view.autofill.AutofillId getId();
+ method @Nullable public java.util.List<android.view.autofill.AutofillId> getIds();
+ method @Nullable public CharSequence getText();
+ method public int getType();
+ method @Nullable public android.view.contentcapture.ViewNode getViewNode();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureEvent> CREATOR;
+ field public static final int TYPE_INITIAL_VIEW_TREE_APPEARED = 5; // 0x5
+ field public static final int TYPE_INITIAL_VIEW_TREE_APPEARING = 4; // 0x4
+ field public static final int TYPE_VIEW_APPEARED = 1; // 0x1
+ field public static final int TYPE_VIEW_DISAPPEARED = 2; // 0x2
+ field public static final int TYPE_VIEW_TEXT_CHANGED = 3; // 0x3
+ }
+
+ public final class ContentCaptureManager {
+ method public boolean isContentCaptureFeatureEnabled();
+ method public void setContentCaptureFeatureEnabled(boolean);
+ }
+
+ public final class ViewNode extends android.app.assist.AssistStructure.ViewNode {
+ method @Nullable public android.view.autofill.AutofillId getParentAutofillId();
+ }
+
+}
+
package android.view.inputmethod {
public final class InputMethodManager {
@@ -2664,7 +2774,7 @@
}
public class DatePicker extends android.widget.FrameLayout {
- method public int getMode();
+ method @android.view.inspector.InspectableProperty(name="datePickerMode", enumMapping={@android.view.inspector.InspectableProperty.EnumMap(value=android.widget.DatePicker.MODE_SPINNER, name="spinner"), @android.view.inspector.InspectableProperty.EnumMap(value=android.widget.DatePicker.MODE_CALENDAR, name="calendar")}) public int getMode();
field public static final int MODE_CALENDAR = 2; // 0x2
field public static final int MODE_SPINNER = 1; // 0x1
}
@@ -2700,7 +2810,7 @@
method public android.view.View getAmView();
method public android.view.View getHourView();
method public android.view.View getMinuteView();
- method public int getMode();
+ method @android.view.inspector.InspectableProperty(name="timePickerMode", enumMapping={@android.view.inspector.InspectableProperty.EnumMap(name="clock", value=android.widget.TimePicker.MODE_CLOCK), @android.view.inspector.InspectableProperty.EnumMap(name="spinner", value=android.widget.TimePicker.MODE_SPINNER)}) public int getMode();
method public android.view.View getPmView();
field public static final int MODE_CLOCK = 2; // 0x2
field public static final int MODE_SPINNER = 1; // 0x1
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 5dcb392b..46917e4 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -252,10 +252,12 @@
status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets();
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
- ISurfaceComposer::eDisplayIdMain));
+ mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();
+ if (mDisplayToken == nullptr)
+ return -1;
+
DisplayInfo dinfo;
- status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
+ status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo);
if (status)
return -1;
@@ -1014,16 +1016,13 @@
// At the end of the animation, we switch to the viewport that DisplayManager will apply
// later. This changes the coordinate system, and means we must move the surface up by
// the inset amount.
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
- ISurfaceComposer::eDisplayIdMain));
-
Rect layerStackRect(0, 0, mWidth, mHeight - mTargetInset);
Rect displayRect(0, mTargetInset, mWidth, mHeight);
SurfaceComposerClient::Transaction t;
t.setPosition(mFlingerSurfaceControl, 0, -mTargetInset)
.setCrop(mFlingerSurfaceControl, Rect(0, mTargetInset, mWidth, mHeight));
- t.setDisplayProjection(dtoken, 0 /* orientation */, layerStackRect, displayRect);
+ t.setDisplayProjection(mDisplayToken, 0 /* orientation */, layerStackRect, displayRect);
t.apply();
mTargetInset = mCurrentInset = 0;
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 04d4f9a..19616cb 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -171,6 +171,7 @@
EGLDisplay mDisplay;
EGLDisplay mContext;
EGLDisplay mSurface;
+ sp<IBinder> mDisplayToken;
sp<SurfaceControl> mFlingerSurfaceControl;
sp<Surface> mFlingerSurface;
bool mClockEnabled;
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 803f83c..056add5 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -16,11 +16,11 @@
name: "idmap2_defaults",
tidy: true,
tidy_checks: [
+ "modernize-*",
+ "-modernize-avoid-c-arrays",
"android-*",
"misc-*",
- "modernize-*",
"readability-*",
- "-modernize-avoid-c-arrays",
],
tidy_flags: [
"-system-headers",
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index 5d449e9..fa5ac8e 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -281,10 +281,10 @@
if (overlayable_info == nullptr) {
// If the resource does not have an overlayable definition, allow the resource to be overlaid.
// Once overlayable enforcement is turned on, this check will return false.
- return true;
+ return !target_package.DefinesOverlayable();
}
- if (!overlay_info.target_name.empty() && overlay_info.target_name != overlayable_info->name) {
+ if (overlay_info.target_name != overlayable_info->name) {
// If the overlay supplies a target overlayable name, the resource must belong to the
// overlayable defined with the specified name to be overlaid.
return false;
diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp
index 45f84fe..8514e12 100644
--- a/cmds/idmap2/tests/FileUtilsTests.cpp
+++ b/cmds/idmap2/tests/FileUtilsTests.cpp
@@ -40,9 +40,14 @@
const std::string& path ATTRIBUTE_UNUSED) -> bool { return true; });
ASSERT_THAT(v, NotNull());
ASSERT_EQ(v->size(), 6U);
- ASSERT_EQ(std::set<std::string>(v->begin(), v->end()),
- std::set<std::string>({root + "/.", root + "/..", root + "/overlay", root + "/target",
- root + "/system-overlay", root + "/system-overlay-invalid"}));
+ ASSERT_EQ(std::set<std::string>(v->begin(), v->end()), std::set<std::string>({
+ root + "/.",
+ root + "/..",
+ root + "/overlay",
+ root + "/target",
+ root + "/system-overlay",
+ root + "/system-overlay-invalid",
+ }));
}
TEST(FileUtilsTests, FindFilesFindApkFilesRecursive) {
@@ -51,13 +56,15 @@
return type == DT_REG && path.size() > 4 && path.compare(path.size() - 4, 4, ".apk") == 0;
});
ASSERT_THAT(v, NotNull());
- ASSERT_EQ(v->size(), 6U);
- ASSERT_EQ(std::set<std::string>(v->begin(), v->end()),
- std::set<std::string>({root + "/target/target.apk", root + "/overlay/overlay.apk",
- root + "/overlay/overlay-static-1.apk",
- root + "/overlay/overlay-static-2.apk",
- root + "/system-overlay/system-overlay.apk",
- root + "/system-overlay-invalid/system-overlay-invalid.apk"}));
+ ASSERT_EQ(v->size(), 9U);
+ ASSERT_EQ(
+ std::set<std::string>(v->begin(), v->end()),
+ std::set<std::string>(
+ {root + "/target/target.apk", root + "/target/target-no-overlayable.apk",
+ root + "/overlay/overlay.apk", root + "/overlay/overlay-no-name.apk",
+ root + "/overlay/overlay-no-name-static.apk", root + "/overlay/overlay-static-1.apk",
+ root + "/overlay/overlay-static-2.apk", root + "/system-overlay/system-overlay.apk",
+ root + "/system-overlay-invalid/system-overlay-invalid.apk"}));
}
TEST(FileUtilsTests, ReadFile) {
diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
index c550eaf..1216f9ec 100644
--- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp
+++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
@@ -163,8 +163,12 @@
TEST_F(Idmap2BinaryTests, Scan) {
SKIP_TEST_IF_CANT_EXEC_IDMAP2;
+ const std::string overlay_static_no_name_apk_path =
+ GetTestDataPath() + "/overlay/overlay-no-name-static.apk";
const std::string overlay_static_1_apk_path = GetTestDataPath() + "/overlay/overlay-static-1.apk";
const std::string overlay_static_2_apk_path = GetTestDataPath() + "/overlay/overlay-static-2.apk";
+ const std::string idmap_static_no_name_path =
+ Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_no_name_apk_path);
const std::string idmap_static_1_path =
Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_1_apk_path);
const std::string idmap_static_2_path =
@@ -184,11 +188,18 @@
ASSERT_THAT(result, NotNull());
ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
std::stringstream expected;
+ expected << idmap_static_no_name_path << std::endl;
expected << idmap_static_1_path << std::endl;
expected << idmap_static_2_path << std::endl;
ASSERT_EQ(result->stdout, expected.str());
std::stringstream error;
+ auto idmap_static_no_name_raw_string = utils::ReadFile(idmap_static_no_name_path);
+ auto idmap_static_no_name_raw_stream = std::istringstream(*idmap_static_no_name_raw_string);
+ auto idmap_static_no_name = Idmap::FromBinaryStream(idmap_static_no_name_raw_stream, error);
+ ASSERT_THAT(idmap_static_no_name, NotNull());
+ ASSERT_IDMAP(*idmap_static_no_name, GetTargetApkPath(), overlay_static_no_name_apk_path);
+
auto idmap_static_1_raw_string = utils::ReadFile(idmap_static_1_path);
auto idmap_static_1_raw_stream = std::istringstream(*idmap_static_1_raw_string);
auto idmap_static_1 = Idmap::FromBinaryStream(idmap_static_1_raw_stream, error);
@@ -201,6 +212,7 @@
ASSERT_THAT(idmap_static_2, NotNull());
ASSERT_IDMAP(*idmap_static_2, GetTargetApkPath(), overlay_static_2_apk_path);
+ unlink(idmap_static_no_name_path.c_str());
unlink(idmap_static_2_path.c_str());
unlink(idmap_static_1_path.c_str());
@@ -218,6 +230,7 @@
ASSERT_THAT(result, NotNull());
ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
ASSERT_EQ(result->stdout, expected.str());
+ unlink(idmap_static_no_name_path.c_str());
unlink(idmap_static_2_path.c_str());
unlink(idmap_static_1_path.c_str());
@@ -236,6 +249,7 @@
ASSERT_THAT(result, NotNull());
ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
ASSERT_EQ(result->stdout, expected.str());
+ unlink(idmap_static_no_name_path.c_str());
unlink(idmap_static_2_path.c_str());
unlink(idmap_static_1_path.c_str());
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index df28918..9e27ccd 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -224,7 +224,8 @@
ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
}
-TEST(IdmapTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
+// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
ASSERT_THAT(target_apk, NotNull());
@@ -260,7 +261,8 @@
ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_system_vendor
}
-TEST(IdmapTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
+// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
ASSERT_THAT(target_apk, NotNull());
@@ -290,17 +292,15 @@
ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
- ASSERT_EQ(types[0]->GetEntryCount(), 6U);
- ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
- ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
- ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/other
- ASSERT_EQ(types[0]->GetEntry(2), kNoEntry); // string/policy_product
- ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
- ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_system
- ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor
+ ASSERT_EQ(types[0]->GetEntryCount(), 3U);
+ ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0003U); // string/policy_public
+ ASSERT_EQ(types[0]->GetEntry(1), 0x0004U); // string/policy_system
+ ASSERT_EQ(types[0]->GetEntry(2), 0x0005U); // string/policy_system_vendor
}
-TEST(IdmapTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
+// Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
ASSERT_THAT(target_apk, NotNull());
@@ -340,6 +340,91 @@
ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor
}
+// The resources of APKs that do not include an overlayable declaration should not restrict what
+// resources can be overlaid.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) {
+ const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
+ std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
+ ASSERT_THAT(target_apk, NotNull());
+
+ const std::string overlay_apk_path(GetTestDataPath() +
+ "/system-overlay-invalid/system-overlay-invalid.apk");
+ std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
+ ASSERT_THAT(overlay_apk, NotNull());
+
+ std::stringstream error;
+ std::unique_ptr<const Idmap> idmap =
+ Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
+ PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
+ ASSERT_THAT(idmap, NotNull());
+
+ const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
+ ASSERT_EQ(dataBlocks.size(), 1U);
+
+ const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
+
+ ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
+ ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
+
+ const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
+ ASSERT_EQ(types.size(), 1U);
+
+ ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
+ ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
+ ASSERT_EQ(types[0]->GetEntryCount(), 6U);
+ ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
+ ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other
+ ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product
+ ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
+ ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_system
+ ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor
+}
+
+// The resources of APKs that do not include an overlayable declaration should not restrict what
+// resources can be overlaid.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) {
+ const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
+ std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
+ ASSERT_THAT(target_apk, NotNull());
+
+ const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay-no-name.apk");
+ std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
+ ASSERT_THAT(overlay_apk, NotNull());
+
+ std::stringstream error;
+ std::unique_ptr<const Idmap> idmap =
+ Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
+ PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
+ ASSERT_THAT(idmap, NotNull());
+
+ const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
+ ASSERT_EQ(dataBlocks.size(), 1U);
+
+ const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
+
+ ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
+ ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
+
+ const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
+ ASSERT_EQ(types.size(), 2U);
+
+ ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U);
+ ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
+ ASSERT_EQ(types[0]->GetEntryCount(), 1U);
+ ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
+
+ ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
+ ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
+ ASSERT_EQ(types[1]->GetEntryCount(), 4U);
+ ASSERT_EQ(types[1]->GetEntryOffset(), 9U);
+ ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
+ ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
+ ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
+ ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
+}
+
TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) {
std::string target_apk_path(GetTestDataPath());
for (int i = 0; i < 32; i++) {
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/overlay/AndroidManifest.xml
index 9f89d31..a7767a6 100644
--- a/cmds/idmap2/tests/data/overlay/AndroidManifest.xml
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="test.overlay">
<overlay
- android:targetPackage="test.target" />
+ android:targetPackage="test.target"
+ android:targetName="TestResources"/>
</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml
new file mode 100644
index 0000000..bc6b733
--- /dev/null
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.overlay.no.name">
+ <overlay
+ android:targetPackage="test.target"/>
+</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml
new file mode 100644
index 0000000..ed327ce
--- /dev/null
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.overlay.no.name.static">
+ <overlay
+ android:targetPackage="test.target"
+ android:targetName="TestResources"
+ android:isStatic="true"
+ android:priority="1" />
+</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml
index 39336cc..1c4dae6 100644
--- a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml
@@ -18,6 +18,7 @@
package="test.overlay.static1">
<overlay
android:targetPackage="test.target"
+ android:targetName="TestResources"
android:isStatic="true"
android:priority="1" />
</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml
index e1cc175..70efc86 100644
--- a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml
@@ -18,6 +18,7 @@
package="test.overlay.static2">
<overlay
android:targetPackage="test.target"
+ android:targetName="TestResources"
android:isStatic="true"
android:priority="2" />
</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/build b/cmds/idmap2/tests/data/overlay/build
index cba1086..e60da80 100644
--- a/cmds/idmap2/tests/data/overlay/build
+++ b/cmds/idmap2/tests/data/overlay/build
@@ -26,6 +26,20 @@
aapt2 link \
--no-resource-removal \
-I "$FRAMEWORK_RES_APK" \
+ --manifest AndroidManifestNoName.xml \
+ -o overlay-no-name.apk \
+ compiled.flata
+
+aapt2 link \
+ --no-resource-removal \
+ -I "$FRAMEWORK_RES_APK" \
+ --manifest AndroidManifestNoNameStatic.xml \
+ -o overlay-no-name-static.apk \
+ compiled.flata
+
+aapt2 link \
+ --no-resource-removal \
+ -I "$FRAMEWORK_RES_APK" \
--manifest AndroidManifestStatic1.xml \
-o overlay-static-1.apk \
compiled.flata
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
new file mode 100644
index 0000000..18ee43d
--- /dev/null
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
new file mode 100644
index 0000000..7d23c09
--- /dev/null
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
index 9a0f487..642ab90 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
index 3fc31c7..2ec5602 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay.apk b/cmds/idmap2/tests/data/overlay/overlay.apk
index b4cd7cf..5842da4 100644
--- a/cmds/idmap2/tests/data/overlay/overlay.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml
index 8af9064..5dacebd 100644
--- a/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml
+++ b/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml
@@ -14,8 +14,9 @@
limitations under the License.
-->
<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="test.overlay.system">
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.overlay.system">
<overlay
- android:targetPackage="test.target" />
+ android:targetPackage="test.target"
+ android:targetName="TestResources"/>
</manifest>
diff --git a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
index 90f30eb..a0fba43 100644
--- a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
+++ b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/build b/cmds/idmap2/tests/data/target/build
index 8569c4f..137ddb5 100644
--- a/cmds/idmap2/tests/data/target/build
+++ b/cmds/idmap2/tests/data/target/build
@@ -15,3 +15,7 @@
aapt2 compile --dir res -o compiled.flata
aapt2 link --manifest AndroidManifest.xml -A assets -o target.apk compiled.flata
rm compiled.flata
+
+aapt2 compile res/values/values.xml -o .
+aapt2 link --manifest AndroidManifest.xml -A assets -o target_no_overlayable.apk values_values.arsc.flat
+rm values_values.arsc.flat
\ No newline at end of file
diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
new file mode 100644
index 0000000..8676cbb
--- /dev/null
+++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
Binary files differ
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 3d74f8b..c497667 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -46,23 +46,22 @@
using namespace android;
-static uint32_t DEFAULT_DISPLAY_ID = ISurfaceComposer::eDisplayIdMain;
-
#define COLORSPACE_UNKNOWN 0
#define COLORSPACE_SRGB 1
#define COLORSPACE_DISPLAY_P3 2
-static void usage(const char* pname)
+static void usage(const char* pname, PhysicalDisplayId displayId)
{
fprintf(stderr,
"usage: %s [-hp] [-d display-id] [FILENAME]\n"
" -h: this message\n"
" -p: save the file as a png.\n"
- " -d: specify the display id to capture, default %d.\n"
+ " -d: specify the physical display ID to capture (default: %"
+ ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ")\n"
+ " see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n"
"If FILENAME ends with .png it will be saved as a png.\n"
"If FILENAME is not given, the results will be printed to stdout.\n",
- pname, DEFAULT_DISPLAY_ID
- );
+ pname, displayId);
}
static SkColorType flinger2skia(PixelFormat f)
@@ -127,9 +126,14 @@
int main(int argc, char** argv)
{
+ std::optional<PhysicalDisplayId> displayId = SurfaceComposerClient::getInternalDisplayId();
+ if (!displayId) {
+ fprintf(stderr, "Failed to get token for internal display\n");
+ return 1;
+ }
+
const char* pname = argv[0];
bool png = false;
- int32_t displayId = DEFAULT_DISPLAY_ID;
int c;
while ((c = getopt(argc, argv, "phd:")) != -1) {
switch (c) {
@@ -137,11 +141,11 @@
png = true;
break;
case 'd':
- displayId = atoi(optarg);
+ displayId = atoll(optarg);
break;
case '?':
case 'h':
- usage(pname);
+ usage(pname, *displayId);
return 1;
}
}
@@ -166,7 +170,7 @@
}
if (fd == -1) {
- usage(pname);
+ usage(pname, *displayId);
return 1;
}
@@ -192,9 +196,10 @@
ProcessState::self()->setThreadPoolMaxThreadCount(0);
ProcessState::self()->startThreadPool();
- sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
- if (display == NULL) {
- fprintf(stderr, "Unable to get handle for display %d\n", displayId);
+ const sp<IBinder> display = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
+ if (display == nullptr) {
+ fprintf(stderr, "Failed to get token for invalid display %"
+ ANDROID_PHYSICAL_DISPLAY_ID_FORMAT "\n", *displayId);
return 1;
}
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index ca10482..d6f045e 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -50,6 +50,7 @@
srcs: [
":statsd_aidl",
+ "src/active_config_list.proto",
"src/statsd_config.proto",
"src/FieldValue.cpp",
"src/hash.cpp",
@@ -214,7 +215,7 @@
"tests/anomaly/AnomalyTracker_test.cpp",
"tests/ConfigManager_test.cpp",
"tests/external/puller_util_test.cpp",
- "tests/external/StatsPuller_test.cpp",
+ "tests/external/StatsPuller_test.cpp",
"tests/indexed_priority_queue_test.cpp",
"tests/LogEntryMatcher_test.cpp",
"tests/LogEvent_test.cpp",
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 69cb264..250f5bf 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -14,18 +14,19 @@
* limitations under the License.
*/
-#define DEBUG false // STOPSHIP if true
+#define DEBUG false // STOPSHIP if true
#include "Log.h"
#include "statslog.h"
#include <android-base/file.h>
#include <dirent.h>
+#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
#include "StatsLogProcessor.h"
-#include "stats_log_util.h"
#include "android-base/stringprintf.h"
+#include "external/StatsPullerManager.h"
#include "guardrail/StatsdStats.h"
#include "metrics/CountMetricProducer.h"
-#include "external/StatsPullerManager.h"
+#include "stats_log_util.h"
#include "stats_util.h"
#include "storage/StorageManager.h"
@@ -67,9 +68,17 @@
const int FIELD_ID_DUMP_REPORT_REASON = 8;
const int FIELD_ID_STRINGS = 9;
+const int FIELD_ID_ACTIVE_CONFIG_LIST = 1;
+const int FIELD_ID_CONFIG_ID = 1;
+const int FIELD_ID_CONFIG_UID = 2;
+const int FIELD_ID_ACTIVE_METRIC = 3;
+const int FIELD_ID_METRIC_ID = 1;
+const int FIELD_ID_TIME_TO_LIVE_NANOS = 2;
+
#define NS_PER_HOUR 3600 * NS_PER_SEC
#define STATS_DATA_DIR "/data/misc/stats-data"
+#define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric"
// Cool down period for writing data to disk to avoid overwriting files.
#define WRITE_DATA_COOL_DOWN_SEC 5
@@ -507,6 +516,70 @@
mOnDiskDataConfigs.insert(key);
}
+void StatsLogProcessor::WriteMetricsActivationToDisk(int64_t currentTimeNs) {
+ std::lock_guard<std::mutex> lock(mMetricsMutex);
+ ProtoOutputStream proto;
+
+ for (const auto& pair : mMetricsManagers) {
+ uint64_t activeConfigListToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
+ FIELD_ID_ACTIVE_CONFIG_LIST);
+ proto.write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_ID, (long long)pair.first.GetId());
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_UID, pair.first.GetUid());
+
+ vector<const MetricProducer*> acrtiveMetrics;
+ pair.second->getActiveMetrics(acrtiveMetrics);
+ for (const MetricProducer* metric : acrtiveMetrics) {
+ if (metric->isActive()) {
+ uint64_t metricToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
+ FIELD_ID_ACTIVE_METRIC);
+ proto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_ID,
+ (long long)metric->getMetricId());
+ proto.write(FIELD_TYPE_INT64 | FIELD_ID_TIME_TO_LIVE_NANOS,
+ (long long)metric->getRemainingTtlNs(currentTimeNs));
+ proto.end(metricToken);
+ }
+ }
+ proto.end(activeConfigListToken);
+ }
+
+ string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
+ StorageManager::deleteFile(file_name.c_str());
+ android::base::unique_fd fd(
+ open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR));
+ if (fd == -1) {
+ ALOGE("Attempt to write %s but failed", file_name.c_str());
+ return;
+ }
+ proto.flush(fd.get());
+}
+
+void StatsLogProcessor::LoadMetricsActivationFromDisk() {
+ string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
+ int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
+ if (fd != -1) {
+ string content;
+ if (android::base::ReadFdToString(fd, &content)) {
+ ActiveConfigList activeConfigList;
+ if (activeConfigList.ParseFromString(content)) {
+ for (int i = 0; i < activeConfigList.active_config_size(); i++) {
+ const auto& config = activeConfigList.active_config(i);
+ ConfigKey key(config.uid(), config.config_id());
+ auto it = mMetricsManagers.find(key);
+ if (it == mMetricsManagers.end()) {
+ ALOGE("No config found for config %s", key.ToString().c_str());
+ continue;
+ }
+ VLOG("Setting active config %s", key.ToString().c_str());
+ it->second->setActiveMetrics(config, mTimeBaseNs);
+ }
+ }
+ VLOG("Successfully loaded %d active configs.", activeConfigList.active_config_size());
+ }
+ close(fd);
+ }
+ StorageManager::deleteFile(file_name.c_str());
+}
+
void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason) {
const int64_t timeNs = getElapsedRealtimeNs();
// Do not write to disk if we already have in the last few seconds.
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index a5ce9b6..77d9a2f 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -80,6 +80,12 @@
/* Flushes data to disk. Data on memory will be gone after written to disk. */
void WriteDataToDisk(const DumpReportReason dumpReportReason);
+ /* Persist metric activation status onto disk. */
+ void WriteMetricsActivationToDisk(int64_t currentTimeNs);
+
+ /* Load metric activation status from disk. */
+ void LoadMetricsActivationFromDisk();
+
// Reset all configs.
void resetConfigs();
@@ -188,6 +194,8 @@
FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast);
FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
+ FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
+
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index b26c713..86bf3ec 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -161,7 +161,8 @@
mConfigManager = new ConfigManager();
mProcessor = new StatsLogProcessor(
mUidMap, mPullerManager, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
- getElapsedRealtimeNs(), [this](const ConfigKey& key) {
+ getElapsedRealtimeNs(),
+ [this](const ConfigKey& key) {
sp<IStatsCompanionService> sc = getStatsCompanionService();
auto receiver = mConfigManager->GetConfigReceiver(key);
if (sc == nullptr) {
@@ -867,6 +868,7 @@
ENFORCE_UID(AID_SYSTEM);
VLOG("StatsService::informDeviceShutdown");
mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN);
+ mProcessor->WriteMetricsActivationToDisk(getElapsedRealtimeNs());
return Status::ok();
}
@@ -901,6 +903,7 @@
void StatsService::Startup() {
mConfigManager->Startup();
+ mProcessor->LoadMetricsActivationFromDisk();
}
void StatsService::Terminate() {
diff --git a/cmds/statsd/src/active_config_list.proto b/cmds/statsd/src/active_config_list.proto
new file mode 100644
index 0000000..0e9ee03
--- /dev/null
+++ b/cmds/statsd/src/active_config_list.proto
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package android.os.statsd;
+option java_package = "com.android.os";
+option java_multiple_files = true;
+option java_outer_classname = "ActiveConfigProto";
+
+message ActiveMetric {
+ // metric id
+ optional int64 metric_id = 1;
+ // Remaining time to live in nano seconds. -1 for infinity.
+ optional int64 time_to_live_nanos = 2;
+}
+
+message ActiveConfig {
+ // config id
+ optional int64 config_id = 1;
+ // config uid
+ optional int32 uid = 2;
+ // metrics
+ repeated ActiveMetric active_metric = 3;
+}
+
+// all configs and their metrics on device.
+message ActiveConfigList {
+ repeated ActiveConfig active_config = 1;
+}
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 5f47e06..07aced6 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -238,6 +238,8 @@
ProcessStartTime process_start_time = 169;
PermissionGrantRequestResultReported permission_grant_request_result_reported = 170;
BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
+ DeviceIdentifierAccessDenied device_identifier_access_denied = 172;
+ BubbleDeveloperErrorReported bubble_developer_error_reported = 173;
}
// Pulled events will start at field 10000.
@@ -2144,30 +2146,24 @@
}
optional HardwareType hardware_type = 1;
- /* hardware_location allows vendors to differentiate between multiple instances of
+ /**
+ * hardware_location allows vendors to differentiate between multiple instances of
* the same hardware_type. The specific locations are vendor defined integers,
* referring to board-specific numbering schemes.
*/
optional int32 hardware_location = 2;
- /* failure_code is specific to the HardwareType of the failed hardware.
- * It should use the enum values defined below.
+ /**
+ * failure_code is specific to the HardwareType of the failed hardware.
+ * It should use one of the enum values defined below.
*/
- enum MicrophoneFailureCode {
- MICROPHONE_FAILURE_COMPLETE = 0;
- }
- enum CodecFailureCode {
- CODEC_FAILURE_COMPLETE = 0;
- }
- enum SpeakerFailureCode {
- SPEAKER_FAILURE_COMPLETE = 0;
- SPEAKER_FAILURE_HIGH_Z = 1;
- SPEAKER_FAILURE_SHORT = 2;
- }
- enum FingerprintFailureCode {
- FINGERPRINT_FAILURE_COMPLETE = 0;
- FINGERPRINT_SENSOR_BROKEN = 1;
- FINGERPRINT_TOO_MANY_DEAD_PIXELS = 2;
+ enum HardwareErrorCode {
+ UNKNOWN = 0;
+ COMPLETE = 1;
+ SPEAKER_HIGH_Z = 2;
+ SPEAKER_SHORT = 3;
+ FINGERPRINT_SENSOR_BROKEN = 4;
+ FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5;
}
optional int32 failure_code = 3;
}
@@ -5349,6 +5345,27 @@
}
/**
+ * Logs System UI bubbles developer errors.
+ *
+ * Logged from:
+ * frameworks/base/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+ */
+message BubbleDeveloperErrorReported {
+
+ // The app package that is posting the bubble.
+ optional string package_name = 1;
+
+ // Bubble developer error type enums.
+ enum Error {
+ UNKNOWN = 0;
+ ACTIVITY_INFO_MISSING = 1;
+ ACTIVITY_INFO_NOT_RESIZABLE = 2;
+ DOCUMENT_LAUNCH_NOT_ALWAYS = 3;
+ }
+ optional Error error = 2 [default = UNKNOWN];
+}
+
+/**
* Logs that a constraint for a scheduled job has changed.
*
* Logged from:
@@ -5453,3 +5470,22 @@
optional bool is_granted = 4;
}
+/**
+ * Logs when a package is denied access to a device identifier based on the new access requirements.
+ *
+ * Logged from:
+ * frameworks/base/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+ */
+message DeviceIdentifierAccessDenied {
+ // The name of the package denied access to the requested device identifier.
+ optional string package_name = 1;
+
+ // The name of the device identifier method the package attempted to invoke.
+ optional string method_name = 2;
+
+ // True if the package is preinstalled.
+ optional bool is_preinstalled = 3;
+
+ // True if the package is privileged.
+ optional bool is_priv_app = 4;
+}
diff --git a/cmds/statsd/src/external/PullDataReceiver.h b/cmds/statsd/src/external/PullDataReceiver.h
index 0d505cb..b071682 100644
--- a/cmds/statsd/src/external/PullDataReceiver.h
+++ b/cmds/statsd/src/external/PullDataReceiver.h
@@ -28,9 +28,15 @@
class PullDataReceiver : virtual public RefBase{
public:
virtual ~PullDataReceiver() {}
- virtual void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data) = 0;
+ /**
+ * @param data The pulled data.
+ * @param pullSuccess Whether the pull succeeded. If the pull does not succeed, the data for the
+ * bucket should be invalidated.
+ */
+ virtual void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
+ bool pullSuccess) = 0;
};
} // namespace statsd
} // namespace os
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index c69384c..9b603d6 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -358,12 +358,13 @@
for (const auto& pullInfo : needToPull) {
vector<shared_ptr<LogEvent>> data;
- if (!Pull(pullInfo.first, &data)) {
+ bool pullSuccess = Pull(pullInfo.first, &data);
+ if (pullSuccess) {
+ StatsdStats::getInstance().notePullDelay(
+ pullInfo.first, getElapsedRealtimeNs() - elapsedTimeNs);
+ } else {
VLOG("pull failed at %lld, will try again later", (long long)elapsedTimeNs);
- continue;
}
- StatsdStats::getInstance().notePullDelay(pullInfo.first,
- getElapsedRealtimeNs() - elapsedTimeNs);
// Convention is to mark pull atom timestamp at request time.
// If we pull at t0, puller starts at t1, finishes at t2, and send back
@@ -380,8 +381,8 @@
for (const auto& receiverInfo : pullInfo.second) {
sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote();
if (receiverPtr != nullptr) {
- receiverPtr->onDataPulled(data);
- // we may have just come out of a coma, compute next pull time
+ receiverPtr->onDataPulled(data, pullSuccess);
+ // We may have just come out of a coma, compute next pull time.
int numBucketsAhead =
(elapsedTimeNs - receiverInfo->nextPullTimeNs) / receiverInfo->intervalNs;
receiverInfo->nextPullTimeNs += (numBucketsAhead + 1) * receiverInfo->intervalNs;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 37ccad5..37d5ba0 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -443,11 +443,21 @@
getAtomMetricStats(metricId).badValueType++;
}
+void StatsdStats::noteBucketDropped(int metricId) {
+ lock_guard<std::mutex> lock(mLock);
+ getAtomMetricStats(metricId).bucketDropped++;
+}
+
void StatsdStats::noteConditionChangeInNextBucket(int metricId) {
lock_guard<std::mutex> lock(mLock);
getAtomMetricStats(metricId).conditionChangeInNextBucket++;
}
+void StatsdStats::noteInvalidatedBucket(int metricId) {
+ lock_guard<std::mutex> lock(mLock);
+ getAtomMetricStats(metricId).invalidatedBucket++;
+}
+
StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int metricId) {
auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
if (atomMetricStatsIter != mAtomMetricStats.end()) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 01e9ca1..20ea7e5 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -360,11 +360,21 @@
void noteBadValueType(int atomId);
/**
+ * Buckets were dropped due to reclaim memory.
+ */
+ void noteBucketDropped(int metricId);
+
+ /**
* A condition change was too late, arrived in the wrong bucket and was skipped
*/
void noteConditionChangeInNextBucket(int atomId);
/**
+ * A bucket has been tagged as invalid.
+ */
+ void noteInvalidatedBucket(int metricId);
+
+ /**
* Reset the historical stats. Including all stats in icebox, and the tracked stats about
* metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
* to collect stats after reset() has been called.
@@ -408,6 +418,8 @@
long skippedForwardBuckets = 0;
long badValueType = 0;
long conditionChangeInNextBucket = 0;
+ long invalidatedBucket = 0;
+ long bucketDropped = 0;
} AtomMetricStats;
private:
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index eaba9be..40a4070 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -559,7 +559,7 @@
// Handles the oneof field in KeyValuePair atom.
if (isKeyValuePairAtom && depth == 2) {
- pos[depth] = 4;
+ pos[depth] = 5;
}
mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(elem.data.float32)));
@@ -575,7 +575,7 @@
// Handles the oneof field in KeyValuePair atom.
if (isKeyValuePairAtom && depth == 2) {
- pos[depth] = 3;
+ pos[depth] = 4;
}
mValues.push_back(FieldValue(Field(mTagId, pos, depth),
Value(string(elem.data.string, elem.len))));
@@ -593,7 +593,7 @@
}
// Handles the oneof field in KeyValuePair atom.
if (isKeyValuePairAtom && depth == 2) {
- pos[depth] = 2;
+ pos[depth] = 3;
}
mValues.push_back(
FieldValue(Field(mTagId, pos, depth), Value((int64_t)elem.data.int64)));
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 7cc57c1..350745b 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -243,6 +243,7 @@
void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
mPastBuckets.clear();
}
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 69bafc3..6c1c47b 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -444,6 +444,7 @@
void DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
mPastBuckets.clear();
}
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index c53c4ce..7e695a6 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -77,6 +77,7 @@
void EventMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
mProto->clear();
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
}
void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index c2878f0..2609937 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -406,9 +406,10 @@
return gaugeFields;
}
-void GaugeMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData) {
+void GaugeMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData,
+ bool pullSuccess) {
std::lock_guard<std::mutex> lock(mMutex);
- if (allData.size() == 0) {
+ if (!pullSuccess || allData.size() == 0) {
return;
}
for (const auto& data : allData) {
@@ -509,6 +510,7 @@
void GaugeMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
mPastBuckets.clear();
}
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index df08779..d480941 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -67,7 +67,8 @@
virtual ~GaugeMetricProducer();
// Handles when the pulled data arrives.
- void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data) override;
+ void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
+ bool pullSuccess) override;
// GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index f87849e..b362e37 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -112,6 +112,28 @@
mIsActive = true;
}
+void MetricProducer::setActiveLocked(int64_t currentTimeNs, int64_t remainingTtlNs) {
+ if (mEventActivationMap.size() == 0) {
+ return;
+ }
+ auto& activation = mEventActivationMap.begin()->second;
+ activation.activation_ns = currentTimeNs + remainingTtlNs - activation.ttl_ns;
+ activation.state = kActive;
+ mIsActive = true;
+ VLOG("setting new activation time to %lld, %lld, %lld", (long long)activation.activation_ns,
+ (long long)currentTimeNs, (long long)remainingTtlNs);
+}
+
+int64_t MetricProducer::getRemainingTtlNsLocked(int64_t currentTimeNs) const {
+ int64_t maxTtl = 0;
+ for (const auto& activation : mEventActivationMap) {
+ if (activation.second.state == kActive) {
+ maxTtl = std::max(maxTtl, activation.second.ttl_ns + activation.second.activation_ns -
+ currentTimeNs);
+ }
+ }
+ return maxTtl;
+}
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 09e2409..ca37bbb 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -179,10 +179,21 @@
mBucketSizeNs = bucketSize;
}
- inline const int64_t& getMetricId() {
+ inline const int64_t& getMetricId() const {
return mMetricId;
}
+ int64_t getRemainingTtlNs(int64_t currentTimeNs) const {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return getRemainingTtlNsLocked(currentTimeNs);
+ }
+
+ // Set metric to active for ttlNs.
+ void setActive(int64_t currentTimeNs, int64_t remainingTtlNs) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ setActiveLocked(currentTimeNs, remainingTtlNs);
+ }
+
// Let MetricProducer drop in-memory data to save memory.
// We still need to keep future data valid and anomaly tracking work, which means we will
// have to flush old data, informing anomaly trackers then safely drop old data.
@@ -202,6 +213,11 @@
activateLocked(activationTrackerIndex, elapsedTimestampNs);
}
+ bool isActive() const {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return isActiveLocked();
+ }
+
void addActivation(int activationTrackerIndex, int64_t ttl_seconds);
void flushIfExpire(int64_t elapsedTimestampNs);
@@ -227,6 +243,10 @@
return mIsActive;
}
+ int64_t getRemainingTtlNsLocked(int64_t currentTimeNs) const;
+
+ void setActiveLocked(int64_t currentTimeNs, int64_t remainingTtlNs);
+
/**
* Flushes the current bucket if the eventTime is after the current bucket's end time. This will
also flush the current partial bucket in memory.
@@ -348,6 +368,8 @@
bool mIsActive;
FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
+
+ FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index dd969c0..ca68117 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -122,6 +122,13 @@
StatsdStats::getInstance().noteConfigReceived(
key, mAllMetricProducers.size(), mAllConditionTrackers.size(), mAllAtomMatchers.size(),
mAllAnomalyTrackers.size(), mAnnotations, mConfigValid);
+ // Check active
+ for (const auto& metric : mAllMetricProducers) {
+ if (metric->isActive()) {
+ mIsActive = true;
+ break;
+ }
+ }
}
MetricsManager::~MetricsManager() {
@@ -304,8 +311,10 @@
int tagId = event.GetTagId();
int64_t eventTimeNs = event.GetElapsedTimestampNs();
+ bool isActive = false;
for (int metric : mMetricIndexesWithActivation) {
mAllMetricProducers[metric]->flushIfExpire(eventTimeNs);
+ isActive |= mAllMetricProducers[metric]->isActive();
}
if (mTagIds.find(tagId) == mTagIds.end()) {
@@ -323,10 +332,13 @@
if (matcherCache[it.first] == MatchingState::kMatched) {
for (int metricIndex : it.second) {
mAllMetricProducers[metricIndex]->activate(it.first, eventTimeNs);
+ isActive |= mAllMetricProducers[metricIndex]->isActive();
}
}
}
+ mIsActive = isActive;
+
// A bitmap to see which ConditionTracker needs to be re-evaluated.
vector<bool> conditionToBeEvaluated(mAllConditionTrackers.size(), false);
@@ -418,6 +430,25 @@
return totalSize;
}
+void MetricsManager::setActiveMetrics(ActiveConfig config, int64_t currentTimeNs) {
+ if (config.active_metric_size() == 0) {
+ ALOGW("No active metric for config %s", mConfigKey.ToString().c_str());
+ return;
+ }
+
+ for (int i = 0; i < config.active_metric_size(); i++) {
+ for (int metric : mMetricIndexesWithActivation) {
+ if (mAllMetricProducers[metric]->getMetricId() == config.active_metric(i).metric_id()) {
+ VLOG("Setting active metric: %lld",
+ (long long)mAllMetricProducers[metric]->getMetricId());
+ mAllMetricProducers[metric]->setActive(
+ currentTimeNs, config.active_metric(i).time_to_live_nanos());
+ mIsActive = true;
+ }
+ }
+ }
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index a31efbd..80982c3 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -16,12 +16,13 @@
#pragma once
-#include "external/StatsPullerManager.h"
+#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
#include "anomaly/AlarmMonitor.h"
#include "anomaly/AlarmTracker.h"
#include "anomaly/AnomalyTracker.h"
#include "condition/ConditionTracker.h"
#include "config/ConfigKey.h"
+#include "external/StatsPullerManager.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "logd/LogEvent.h"
#include "matchers/LogMatchingTracker.h"
@@ -123,6 +124,20 @@
// Does not change the state.
virtual size_t byteSize();
+ inline bool isActive() const {
+ return mIsActive;
+ }
+
+ inline void getActiveMetrics(std::vector<const MetricProducer*>& metrics) const {
+ for (const auto& metric : mAllMetricProducers) {
+ if (metric->isActive()) {
+ metrics.push_back(metric.get());
+ }
+ }
+ }
+
+ void setActiveMetrics(ActiveConfig config, int64_t currentTimeNs);
+
private:
// For test only.
inline int64_t getTtlEndNs() const { return mTtlEndNs; }
@@ -216,6 +231,9 @@
// The metrics that don't need to be uploaded or even reported.
std::set<int64_t> mNoReportMetricIds;
+ // Any metric active means the config is active.
+ bool mIsActive;
+
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions);
FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks);
FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
@@ -247,6 +265,8 @@
FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
+
+ FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 6aa8e84..d52c9ef 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -104,6 +104,7 @@
mSkipZeroDiffOutput(metric.skip_zero_diff_output()),
mUseZeroDefaultBase(metric.use_zero_default_base()),
mHasGlobalBase(false),
+ mCurrentBucketIsInvalid(false),
mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
: StatsdStats::kPullMaxDelayNs),
mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()) {
@@ -174,6 +175,7 @@
void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
mPastBuckets.clear();
}
@@ -308,6 +310,15 @@
}
}
+void ValueMetricProducer::invalidateCurrentBucket() {
+ if (!mCurrentBucketIsInvalid) {
+ // Only report once per invalid bucket.
+ StatsdStats::getInstance().noteInvalidatedBucket(mMetricId);
+ }
+ mCurrentBucketIsInvalid = true;
+ resetBase();
+}
+
void ValueMetricProducer::resetBase() {
for (auto& slice : mCurrentSlicedBucket) {
for (auto& interval : slice.second) {
@@ -323,6 +334,7 @@
VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
(long long)mCurrentBucketStartTimeNs);
StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
+ invalidateCurrentBucket();
return;
}
@@ -346,19 +358,20 @@
vector<std::shared_ptr<LogEvent>> allData;
if (!mPullerManager->Pull(mPullTagId, &allData)) {
ALOGE("Gauge Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
- resetBase();
+ invalidateCurrentBucket();
return;
}
const int64_t pullDelayNs = getElapsedRealtimeNs() - timestampNs;
+ StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
if (pullDelayNs > mMaxPullDelayNs) {
ALOGE("Pull finish too late for atom %d, longer than %lld", mPullTagId,
(long long)mMaxPullDelayNs);
StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
- StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
- resetBase();
+ // We are missing one pull from the bucket which means we will not have a complete view of
+ // what's going on.
+ invalidateCurrentBucket();
return;
}
- StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
if (timestampNs < mCurrentBucketStartTimeNs) {
// The data will be skipped in onMatchedLogEventInternalLocked, but we don't want to report
@@ -382,9 +395,16 @@
return mTimeBaseNs + ((currentTimeNs - mTimeBaseNs) / mBucketSizeNs) * mBucketSizeNs;
}
-void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData) {
+void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData,
+ bool pullSuccess) {
std::lock_guard<std::mutex> lock(mMutex);
if (mCondition) {
+ if (!pullSuccess) {
+ // If the pull failed, we won't be able to compute a diff.
+ invalidateCurrentBucket();
+ return;
+ }
+
if (allData.size() == 0) {
VLOG("Data pulled is empty");
StatsdStats::getInstance().noteEmptyData(mPullTagId);
@@ -399,12 +419,13 @@
// if the diff base will be cleared and this new data will serve as new diff base.
int64_t realEventTime = allData.at(0)->GetElapsedTimestampNs();
int64_t bucketEndTime = calcPreviousBucketEndTime(realEventTime) - 1;
- if (bucketEndTime < mCurrentBucketStartTimeNs) {
+ bool isEventLate = bucketEndTime < mCurrentBucketStartTimeNs;
+ if (isEventLate) {
VLOG("Skip bucket end pull due to late arrival: %lld vs %lld", (long long)bucketEndTime,
(long long)mCurrentBucketStartTimeNs);
StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
- return;
}
+
for (const auto& data : allData) {
LogEvent localCopy = data->makeCopy();
if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) ==
@@ -679,31 +700,13 @@
VLOG("finalizing bucket for %ld, dumping %d slices", (long)mCurrentBucketStartTimeNs,
(int)mCurrentSlicedBucket.size());
int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
-
int64_t bucketEndTime = eventTimeNs < fullBucketEndTimeNs ? eventTimeNs : fullBucketEndTimeNs;
- if (bucketEndTime - mCurrentBucketStartTimeNs >= mMinBucketSizeNs) {
+ bool isBucketLargeEnough = bucketEndTime - mCurrentBucketStartTimeNs >= mMinBucketSizeNs;
+ if (isBucketLargeEnough && !mCurrentBucketIsInvalid) {
// The current bucket is large enough to keep.
for (const auto& slice : mCurrentSlicedBucket) {
- ValueBucket bucket;
- bucket.mBucketStartNs = mCurrentBucketStartTimeNs;
- bucket.mBucketEndNs = bucketEndTime;
- for (const auto& interval : slice.second) {
- if (interval.hasValue) {
- // skip the output if the diff is zero
- if (mSkipZeroDiffOutput && mUseDiff && interval.value.isZero()) {
- continue;
- }
- bucket.valueIndex.push_back(interval.valueIndex);
- if (mAggregationType != ValueMetric::AVG) {
- bucket.values.push_back(interval.value);
- } else {
- double sum = interval.value.type == LONG ? (double)interval.value.long_value
- : interval.value.double_value;
- bucket.values.push_back(Value((double)sum / interval.sampleSize));
- }
- }
- }
+ ValueBucket bucket = buildPartialBucket(bucketEndTime, slice.second);
// it will auto create new vector of ValuebucketInfo if the key is not found.
if (bucket.valueIndex.size() > 0) {
auto& bucketList = mPastBuckets[slice.first];
@@ -714,6 +717,58 @@
mSkippedBuckets.emplace_back(mCurrentBucketStartTimeNs, bucketEndTime);
}
+ if (!mCurrentBucketIsInvalid) {
+ appendToFullBucket(eventTimeNs, fullBucketEndTimeNs);
+ }
+ initCurrentSlicedBucket();
+ mCurrentBucketIsInvalid = false;
+}
+
+ValueBucket ValueMetricProducer::buildPartialBucket(int64_t bucketEndTime,
+ const std::vector<Interval>& intervals) {
+ ValueBucket bucket;
+ bucket.mBucketStartNs = mCurrentBucketStartTimeNs;
+ bucket.mBucketEndNs = bucketEndTime;
+ for (const auto& interval : intervals) {
+ if (interval.hasValue) {
+ // skip the output if the diff is zero
+ if (mSkipZeroDiffOutput && mUseDiff && interval.value.isZero()) {
+ continue;
+ }
+ bucket.valueIndex.push_back(interval.valueIndex);
+ if (mAggregationType != ValueMetric::AVG) {
+ bucket.values.push_back(interval.value);
+ } else {
+ double sum = interval.value.type == LONG ? (double)interval.value.long_value
+ : interval.value.double_value;
+ bucket.values.push_back(Value((double)sum / interval.sampleSize));
+ }
+ }
+ }
+ return bucket;
+}
+
+void ValueMetricProducer::initCurrentSlicedBucket() {
+ for (auto it = mCurrentSlicedBucket.begin(); it != mCurrentSlicedBucket.end();) {
+ bool obsolete = true;
+ for (auto& interval : it->second) {
+ interval.hasValue = false;
+ interval.sampleSize = 0;
+ if (interval.seenNewData) {
+ obsolete = false;
+ }
+ interval.seenNewData = false;
+ }
+
+ if (obsolete) {
+ it = mCurrentSlicedBucket.erase(it);
+ } else {
+ it++;
+ }
+ }
+}
+
+void ValueMetricProducer::appendToFullBucket(int64_t eventTimeNs, int64_t fullBucketEndTimeNs) {
if (eventTimeNs > fullBucketEndTimeNs) { // If full bucket, send to anomaly tracker.
// Accumulate partial buckets with current value and then send to anomaly tracker.
if (mCurrentFullBucket.size() > 0) {
@@ -751,24 +806,6 @@
mCurrentFullBucket[slice.first] += slice.second[0].value.long_value;
}
}
-
- for (auto it = mCurrentSlicedBucket.begin(); it != mCurrentSlicedBucket.end();) {
- bool obsolete = true;
- for (auto& interval : it->second) {
- interval.hasValue = false;
- interval.sampleSize = 0;
- if (interval.seenNewData) {
- obsolete = false;
- }
- interval.seenNewData = false;
- }
-
- if (obsolete) {
- it = mCurrentSlicedBucket.erase(it);
- } else {
- it++;
- }
- }
}
size_t ValueMetricProducer::byteSizeLocked() const {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index a8dfc5b..40cf2e1 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -51,7 +51,8 @@
virtual ~ValueMetricProducer();
// Process data pulled on bucket boundary.
- void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data) override;
+ void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
+ bool pullSuccess) override;
// ValueMetric needs special logic if it's a pulled atom.
void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
@@ -102,6 +103,9 @@
// Calculate previous bucket end time based on current time.
int64_t calcPreviousBucketEndTime(const int64_t currentTimeNs);
+ // Mark the data as invalid.
+ void invalidateCurrentBucket();
+
const int mWhatMatcherIndex;
sp<EventMatcherWizard> mEventMatcherWizard;
@@ -155,6 +159,11 @@
void pullAndMatchEventsLocked(const int64_t timestampNs);
+ ValueBucket buildPartialBucket(int64_t bucketEndTime,
+ const std::vector<Interval>& intervals);
+ void initCurrentSlicedBucket();
+ void appendToFullBucket(int64_t eventTimeNs, int64_t fullBucketEndTimeNs);
+
// Reset diff base and mHasGlobalBase
void resetBase();
@@ -186,6 +195,12 @@
// diff against.
bool mHasGlobalBase;
+ // Invalid bucket. There was a problem in collecting data in the current bucket so we cannot
+ // trust any of the data in this bucket.
+ //
+ // For instance, one pull failed.
+ bool mCurrentBucketIsInvalid;
+
const int64_t mMaxPullDelayNs;
const bool mSplitBucketForAppUpgrade;
@@ -216,8 +231,15 @@
FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBase);
FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures);
FRIEND_TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey);
- FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFail);
+ FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange);
+ FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange);
+ FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket);
FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate);
+ FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed);
+ FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenInitialPullFailed);
+ FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed);
+ FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded);
+ FRIEND_TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange);
};
} // namespace statsd
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index cca09ac..73aab48 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -417,6 +417,8 @@
optional int64 skipped_forward_buckets = 4;
optional int64 bad_value_type = 5;
optional int64 condition_change_in_next_bucket = 6;
+ optional int64 invalidated_bucket = 7;
+ optional int64 bucket_dropped = 8;
}
repeated AtomMetricStats atom_metric_stats = 17;
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 9c9985e..f76a9ad 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -78,6 +78,8 @@
const int FIELD_ID_SKIPPED_FORWARD_BUCKETS = 4;
const int FIELD_ID_BAD_VALUE_TYPE = 5;
const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6;
+const int FIELD_ID_INVALIDATED_BUCKET = 7;
+const int FIELD_ID_BUCKET_DROPPED = 8;
namespace {
@@ -494,6 +496,10 @@
(long long)pair.second.badValueType);
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET,
(long long)pair.second.conditionChangeInNextBucket);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_INVALIDATED_BUCKET,
+ (long long)pair.second.invalidatedBucket);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_DROPPED,
+ (long long)pair.second.bucketDropped);
protoOutput->end(token);
}
diff --git a/cmds/statsd/statsd.rc b/cmds/statsd/statsd.rc
index cbf2a8d..e0cbd5d 100644
--- a/cmds/statsd/statsd.rc
+++ b/cmds/statsd/statsd.rc
@@ -26,3 +26,4 @@
# Create directory for statsd
mkdir /data/misc/stats-data/ 0770 statsd system
mkdir /data/misc/stats-service/ 0770 statsd system
+ mkdir /data/misc/stats-active-metric/ 0770 statsd system
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 3a5be43..eec3c73 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -155,7 +155,7 @@
EXPECT_EQ(33, item5.mValue.int_value);
const FieldValue& item6 = event1.getValues()[6];
- EXPECT_EQ(0x2010482, item6.mField.getField());
+ EXPECT_EQ(0x2010483, item6.mField.getField());
EXPECT_EQ(Type::LONG, item6.mValue.getType());
EXPECT_EQ(678L, item6.mValue.int_value);
@@ -165,7 +165,7 @@
EXPECT_EQ(44, item7.mValue.int_value);
const FieldValue& item8 = event1.getValues()[8];
- EXPECT_EQ(0x2010582, item8.mField.getField());
+ EXPECT_EQ(0x2010583, item8.mField.getField());
EXPECT_EQ(Type::LONG, item8.mValue.getType());
EXPECT_EQ(890L, item8.mValue.int_value);
@@ -175,7 +175,7 @@
EXPECT_EQ(1, item9.mValue.int_value);
const FieldValue& item10 = event1.getValues()[10];
- EXPECT_EQ(0x2010683, item10.mField.getField());
+ EXPECT_EQ(0x2010684, item10.mField.getField());
EXPECT_EQ(Type::STRING, item10.mValue.getType());
EXPECT_EQ("test2", item10.mValue.str_value);
@@ -185,7 +185,7 @@
EXPECT_EQ(2, item11.mValue.int_value);
const FieldValue& item12 = event1.getValues()[12];
- EXPECT_EQ(0x2010783, item12.mField.getField());
+ EXPECT_EQ(0x2010784, item12.mField.getField());
EXPECT_EQ(Type::STRING, item12.mValue.getType());
EXPECT_EQ("test1", item12.mValue.str_value);
@@ -195,7 +195,7 @@
EXPECT_EQ(111, item13.mValue.int_value);
const FieldValue& item14 = event1.getValues()[14];
- EXPECT_EQ(0x2010884, item14.mField.getField());
+ EXPECT_EQ(0x2010885, item14.mField.getField());
EXPECT_EQ(Type::FLOAT, item14.mValue.getType());
EXPECT_EQ(2.2f, item14.mValue.float_value);
@@ -205,7 +205,7 @@
EXPECT_EQ(222, item15.mValue.int_value);
const FieldValue& item16 = event1.getValues()[16];
- EXPECT_EQ(0x2018984, item16.mField.getField());
+ EXPECT_EQ(0x2018985, item16.mField.getField());
EXPECT_EQ(Type::FLOAT, item16.mValue.getType());
EXPECT_EQ(1.1f, item16.mValue.float_value);
}
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index d52be44..64008b5 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -286,6 +286,294 @@
EXPECT_TRUE(noData);
}
+TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) {
+ int uid = 1111;
+
+ // Setup a simple config, no activation
+ StatsdConfig config1;
+ config1.set_id(12341);
+ config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+ auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
+ *config1.add_atom_matcher() = wakelockAcquireMatcher;
+
+ long metricId1 = 1234561;
+ long metricId2 = 1234562;
+ auto countMetric1 = config1.add_count_metric();
+ countMetric1->set_id(metricId1);
+ countMetric1->set_what(wakelockAcquireMatcher.id());
+ countMetric1->set_bucket(FIVE_MINUTES);
+
+ auto countMetric2 = config1.add_count_metric();
+ countMetric2->set_id(metricId2);
+ countMetric2->set_what(wakelockAcquireMatcher.id());
+ countMetric2->set_bucket(FIVE_MINUTES);
+
+ ConfigKey cfgKey1(uid, 12341);
+ long timeBase1 = 1;
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
+
+ // Add another config, with two metrics, one with activation
+ StatsdConfig config2;
+ config2.set_id(12342);
+ config2.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+ *config2.add_atom_matcher() = wakelockAcquireMatcher;
+
+ long metricId3 = 1234561;
+ long metricId4 = 1234562;
+
+ auto countMetric3 = config2.add_count_metric();
+ countMetric3->set_id(metricId3);
+ countMetric3->set_what(wakelockAcquireMatcher.id());
+ countMetric3->set_bucket(FIVE_MINUTES);
+
+ auto countMetric4 = config2.add_count_metric();
+ countMetric4->set_id(metricId4);
+ countMetric4->set_what(wakelockAcquireMatcher.id());
+ countMetric4->set_bucket(FIVE_MINUTES);
+
+ auto metric3Activation = config2.add_metric_activation();
+ metric3Activation->set_metric_id(metricId3);
+ auto metric3ActivationTrigger = metric3Activation->add_event_activation();
+ metric3ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
+ metric3ActivationTrigger->set_ttl_seconds(100);
+
+ ConfigKey cfgKey2(uid, 12342);
+
+ // Add another config, with two metrics, both with activations
+ StatsdConfig config3;
+ config3.set_id(12342);
+ config3.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+ *config3.add_atom_matcher() = wakelockAcquireMatcher;
+
+ long metricId5 = 1234565;
+ long metricId6 = 1234566;
+ auto countMetric5 = config3.add_count_metric();
+ countMetric5->set_id(metricId5);
+ countMetric5->set_what(wakelockAcquireMatcher.id());
+ countMetric5->set_bucket(FIVE_MINUTES);
+
+ auto countMetric6 = config3.add_count_metric();
+ countMetric6->set_id(metricId6);
+ countMetric6->set_what(wakelockAcquireMatcher.id());
+ countMetric6->set_bucket(FIVE_MINUTES);
+
+ auto metric5Activation = config3.add_metric_activation();
+ metric5Activation->set_metric_id(metricId5);
+ auto metric5ActivationTrigger = metric5Activation->add_event_activation();
+ metric5ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
+ metric5ActivationTrigger->set_ttl_seconds(100);
+
+ auto metric6Activation = config3.add_metric_activation();
+ metric6Activation->set_metric_id(metricId6);
+ auto metric6ActivationTrigger = metric6Activation->add_event_activation();
+ metric6ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
+ metric6ActivationTrigger->set_ttl_seconds(200);
+
+ ConfigKey cfgKey3(uid, 12343);
+
+ processor->OnConfigUpdated(2, cfgKey2, config2);
+ processor->OnConfigUpdated(3, cfgKey3, config3);
+
+ EXPECT_EQ(3, processor->mMetricsManagers.size());
+ auto it = processor->mMetricsManagers.find(cfgKey1);
+ EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ auto& metricsManager1 = it->second;
+ EXPECT_TRUE(metricsManager1->isActive());
+
+ auto metricIt = metricsManager1->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId1) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
+ auto& metricProducer1 = *metricIt;
+ EXPECT_TRUE(metricProducer1->isActive());
+
+ metricIt = metricsManager1->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId2) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
+ auto& metricProducer2 = *metricIt;
+ EXPECT_TRUE(metricProducer2->isActive());
+
+ it = processor->mMetricsManagers.find(cfgKey2);
+ EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ auto& metricsManager2 = it->second;
+ EXPECT_TRUE(metricsManager2->isActive());
+
+ metricIt = metricsManager2->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId3) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
+ auto& metricProducer3 = *metricIt;
+ EXPECT_FALSE(metricProducer3->isActive());
+
+ metricIt = metricsManager2->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId4) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
+ auto& metricProducer4 = *metricIt;
+ EXPECT_TRUE(metricProducer4->isActive());
+
+ it = processor->mMetricsManagers.find(cfgKey3);
+ EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ auto& metricsManager3 = it->second;
+ EXPECT_FALSE(metricsManager3->isActive());
+
+ metricIt = metricsManager3->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId5) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
+ auto& metricProducer5 = *metricIt;
+ EXPECT_FALSE(metricProducer5->isActive());
+
+ metricIt = metricsManager3->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager3->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId6) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
+ auto& metricProducer6 = *metricIt;
+ EXPECT_FALSE(metricProducer6->isActive());
+
+ std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
+ auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1);
+ processor->OnLogEvent(event.get());
+
+ int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
+ EXPECT_TRUE(metricProducer3->isActive());
+ int64_t ttl3 = metricProducer3->getRemainingTtlNs(shutDownTime);
+ EXPECT_EQ(100, ttl3);
+ EXPECT_TRUE(metricProducer5->isActive());
+ int64_t ttl5 = metricProducer5->getRemainingTtlNs(shutDownTime);
+ EXPECT_EQ(100, ttl5);
+ EXPECT_TRUE(metricProducer6->isActive());
+ int64_t ttl6 = metricProducer6->getRemainingTtlNs(shutDownTime);
+ EXPECT_EQ(100 + 100 * NS_PER_SEC, ttl6);
+
+ processor->WriteMetricsActivationToDisk(timeBase1 + 100 * NS_PER_SEC);
+
+ long timeBase2 = 1000;
+ sp<StatsLogProcessor> processor2 =
+ CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
+ processor2->OnConfigUpdated(timeBase2, cfgKey2, config2);
+ processor2->OnConfigUpdated(timeBase2, cfgKey3, config3);
+
+ EXPECT_EQ(3, processor2->mMetricsManagers.size());
+ it = processor2->mMetricsManagers.find(cfgKey1);
+ EXPECT_TRUE(it != processor2->mMetricsManagers.end());
+ auto& metricsManager1001 = it->second;
+ EXPECT_TRUE(metricsManager1001->isActive());
+
+ metricIt = metricsManager1001->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId1) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
+ auto& metricProducer1001 = *metricIt;
+ EXPECT_TRUE(metricProducer1001->isActive());
+
+ metricIt = metricsManager1001->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId2) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
+ auto& metricProducer1002 = *metricIt;
+ EXPECT_TRUE(metricProducer1002->isActive());
+
+ it = processor2->mMetricsManagers.find(cfgKey2);
+ EXPECT_TRUE(it != processor2->mMetricsManagers.end());
+ auto& metricsManager1002 = it->second;
+ EXPECT_TRUE(metricsManager1002->isActive());
+
+ metricIt = metricsManager1002->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId3) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
+ auto& metricProducer1003 = *metricIt;
+ EXPECT_FALSE(metricProducer1003->isActive());
+
+ metricIt = metricsManager1002->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId4) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
+ auto& metricProducer1004 = *metricIt;
+ EXPECT_TRUE(metricProducer1004->isActive());
+
+ it = processor2->mMetricsManagers.find(cfgKey3);
+ EXPECT_TRUE(it != processor2->mMetricsManagers.end());
+ auto& metricsManager1003 = it->second;
+ EXPECT_FALSE(metricsManager1003->isActive());
+ EXPECT_EQ(2, metricsManager1003->mAllMetricProducers.size());
+
+ metricIt = metricsManager1003->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId5) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
+ auto& metricProducer1005 = *metricIt;
+ EXPECT_FALSE(metricProducer1005->isActive());
+
+ metricIt = metricsManager1003->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1003->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId6) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
+ auto& metricProducer1006 = *metricIt;
+ EXPECT_FALSE(metricProducer1006->isActive());
+
+ EXPECT_FALSE(metricProducer1003->isActive());
+ const auto& activation1003 = metricProducer1003->mEventActivationMap.begin()->second;
+ EXPECT_EQ(100 * NS_PER_SEC, activation1003.ttl_ns);
+ EXPECT_EQ(0, activation1003.activation_ns);
+ EXPECT_FALSE(metricProducer1005->isActive());
+ const auto& activation1005 = metricProducer1005->mEventActivationMap.begin()->second;
+ EXPECT_EQ(100 * NS_PER_SEC, activation1005.ttl_ns);
+ EXPECT_EQ(0, activation1005.activation_ns);
+ EXPECT_FALSE(metricProducer1006->isActive());
+ const auto& activation1006 = metricProducer1006->mEventActivationMap.begin()->second;
+ EXPECT_EQ(200 * NS_PER_SEC, activation1006.ttl_ns);
+ EXPECT_EQ(0, activation1006.activation_ns);
+
+ processor2->LoadMetricsActivationFromDisk();
+
+ EXPECT_TRUE(metricProducer1003->isActive());
+ EXPECT_EQ(timeBase2 + ttl3 - activation1003.ttl_ns, activation1003.activation_ns);
+ EXPECT_TRUE(metricProducer1005->isActive());
+ EXPECT_EQ(timeBase2 + ttl5 - activation1005.ttl_ns, activation1005.activation_ns);
+ EXPECT_TRUE(metricProducer1006->isActive());
+ EXPECT_EQ(timeBase2 + ttl6 - activation1006.ttl_ns, activation1003.activation_ns);
+}
+
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 0ffbb54..1725160 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -133,7 +133,7 @@
event->init();
allData.push_back(event);
- gaugeProducer.onDataPulled(allData);
+ gaugeProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
EXPECT_EQ(INT, it->mValue.getType());
@@ -151,7 +151,7 @@
event2->write(25);
event2->init();
allData.push_back(event2);
- gaugeProducer.onDataPulled(allData);
+ gaugeProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
EXPECT_EQ(INT, it->mValue.getType());
@@ -305,7 +305,7 @@
event->write(1);
event->init();
allData.push_back(event);
- gaugeProducer.onDataPulled(allData);
+ gaugeProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
@@ -328,7 +328,7 @@
event->write(3);
event->init();
allData.push_back(event);
- gaugeProducer.onDataPulled(allData);
+ gaugeProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin()
@@ -371,7 +371,7 @@
event->write(1);
event->init();
allData.push_back(event);
- gaugeProducer.onDataPulled(allData);
+ gaugeProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
@@ -440,7 +440,7 @@
event->write(110);
event->init();
allData.push_back(event);
- gaugeProducer.onDataPulled(allData);
+ gaugeProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin()
@@ -541,7 +541,7 @@
event->write(110);
event->init();
allData.push_back(event);
- gaugeProducer.onDataPulled(allData);
+ gaugeProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
@@ -590,7 +590,7 @@
event1->write(13);
event1->init();
- gaugeProducer.onDataPulled({event1});
+ gaugeProducer.onDataPulled({event1}, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
@@ -604,7 +604,7 @@
event2->write(15);
event2->init();
- gaugeProducer.onDataPulled({event2});
+ gaugeProducer.onDataPulled({event2}, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
@@ -619,7 +619,7 @@
event3->write(26);
event3->init();
- gaugeProducer.onDataPulled({event3});
+ gaugeProducer.onDataPulled({event3}, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin()
->second.front()
@@ -633,7 +633,7 @@
std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10);
event4->write("some value");
event4->init();
- gaugeProducer.onDataPulled({event4});
+ gaugeProducer.onDataPulled({event4}, /** succeed */ true);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
}
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index c0648ee..2979346 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -160,7 +160,7 @@
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -177,7 +177,7 @@
event->write(23);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -196,7 +196,7 @@
event->write(36);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -256,7 +256,7 @@
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval =
@@ -274,7 +274,7 @@
event->write(23);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -292,7 +292,7 @@
event->write(36);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -341,7 +341,7 @@
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -357,7 +357,7 @@
event->write(10);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -373,7 +373,7 @@
event->write(36);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
@@ -420,7 +420,7 @@
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -436,7 +436,7 @@
event->write(10);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -451,7 +451,7 @@
event->write(36);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
@@ -525,7 +525,7 @@
event->write(110);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
@@ -635,7 +635,7 @@
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
@@ -650,7 +650,7 @@
event->write(150);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
EXPECT_EQ(20L,
@@ -689,7 +689,7 @@
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
@@ -993,7 +993,7 @@
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -1011,7 +1011,7 @@
event->write(23);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -1032,7 +1032,7 @@
event->write(36);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
// startUpdated:false sum:12
@@ -1120,7 +1120,7 @@
event->write(110);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(false, curInterval.hasBase);
@@ -1224,7 +1224,7 @@
event->write(110);
event->init();
allData.push_back(event);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
@@ -1677,7 +1677,7 @@
allData.push_back(event1);
allData.push_back(event2);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval1.hasBase);
EXPECT_EQ(11, interval1.base.long_value);
@@ -1762,7 +1762,7 @@
allData.push_back(event1);
allData.push_back(event2);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval1.hasBase);
EXPECT_EQ(11, interval1.base.long_value);
@@ -1791,7 +1791,7 @@
event1->write(5);
event1->init();
allData.push_back(event1);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval2.hasBase);
@@ -1813,7 +1813,7 @@
event2->write(5);
event2->init();
allData.push_back(event2);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval2.hasBase);
@@ -1888,7 +1888,7 @@
allData.push_back(event1);
allData.push_back(event2);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval1.hasBase);
EXPECT_EQ(11, interval1.base.long_value);
@@ -1918,7 +1918,7 @@
event1->write(5);
event1->init();
allData.push_back(event1);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
@@ -1941,7 +1941,7 @@
event1->write(13);
event1->init();
allData.push_back(event1);
- valueProducer.onDataPulled(allData);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval2.hasBase);
@@ -1951,7 +1951,60 @@
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
}
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFail) {
+TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ // Used by onConditionChanged.
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
+ event->write(tagId);
+ event->write(100);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
+
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval& curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(100, curInterval.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+
+ vector<shared_ptr<LogEvent>> allData;
+ valueProducer.onDataPulled(allData, /** succeed */ false);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ EXPECT_EQ(false, curInterval.hasBase);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(false, valueProducer.mHasGlobalBase);
+}
+
+TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
ValueMetric metric;
metric.set_id(metricId);
metric.set_bucket(ONE_MINUTE);
@@ -2007,7 +2060,57 @@
EXPECT_EQ(false, valueProducer.mHasGlobalBase);
}
-TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
+TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
+ event->write(tagId);
+ event->write(100);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
+
+ valueProducer.mCondition = true;
+
+ vector<shared_ptr<LogEvent>> allData;
+ valueProducer.onDataPulled(allData, /** succeed */ false);
+ EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+
+ valueProducer.onConditionChanged(false, bucketStartTimeNs + 1);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval& curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(false, curInterval.hasBase);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(false, valueProducer.mHasGlobalBase);
+}
+
+TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
ValueMetric metric;
metric.set_id(metricId);
metric.set_bucket(ONE_MINUTE);
@@ -2030,7 +2133,7 @@
EXPECT_CALL(*pullerManager, Pull(tagId, _))
.WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
event->write(tagId);
event->write(120);
event->init();
@@ -2042,34 +2145,334 @@
eventMatcherWizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.mCondition = true;
+ valueProducer.mCondition = false;
+
+ // Max delay is set to 0 so pull will exceed max delay.
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
+ EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+}
+
+TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucket2StartTimeNs,
+ bucket2StartTimeNs, pullerManager);
+
+ valueProducer.mCondition = false;
+
+ // Event should be skipped since it is from previous bucket.
+ // Pull should not be called.
+ valueProducer.onConditionChanged(true, bucketStartTimeNs);
+ EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+}
+
+TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+ event->write(tagId);
+ event->write(100);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
+
+ valueProducer.mCondition = false;
+ valueProducer.mHasGlobalBase = false;
+
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
valueProducer.mHasGlobalBase = true;
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
- event->write(1);
- event->write(110);
- event->init();
- allData.push_back(event);
- valueProducer.onDataPulled(allData);
-
- // has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval& curInterval =
valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
- EXPECT_EQ(110, curInterval.base.long_value);
+ EXPECT_EQ(100, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(true, valueProducer.mHasGlobalBase);
+}
- valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
+TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
- // has one slice
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ // First onConditionChanged
+ .WillOnce(Return(false))
+ // Second onConditionChanged
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
+ event->write(tagId);
+ event->write(130);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
+
+ valueProducer.mCondition = true;
+
+ // Bucket start.
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+ event->write(1);
+ event->write(110);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
+
+ // This will fail and should invalidate the whole bucket since we do not have all the data
+ // needed to compute the metric value when the screen was on.
+ valueProducer.onConditionChanged(false, bucketStartTimeNs + 2);
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 3);
+
+ // Bucket end.
+ allData.clear();
+ shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ event2->write(1);
+ event2->write(140);
+ event2->init();
+ allData.push_back(event2);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
+
+ valueProducer.flushIfNeededLocked(bucket2StartTimeNs + 1);
+
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ // Contains base from last pull which was successful.
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval& curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(140, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(true, valueProducer.mHasGlobalBase);
+}
+
+TEST(ValueMetricProducerTest, TestInvalidBucketWhenInitialPullFailed) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ // First onConditionChanged
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
+ event->write(tagId);
+ event->write(120);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
+ // Second onConditionChanged
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
+ event->write(tagId);
+ event->write(130);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
+
+ valueProducer.mCondition = true;
+
+ // Bucket start.
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+ event->write(1);
+ event->write(110);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData, /** succeed */ false);
+
+ valueProducer.onConditionChanged(false, bucketStartTimeNs + 2);
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 3);
+
+ // Bucket end.
+ allData.clear();
+ shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ event2->write(1);
+ event2->write(140);
+ event2->init();
+ allData.push_back(event2);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
+
+ valueProducer.flushIfNeededLocked(bucket2StartTimeNs + 1);
+
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ // Contains base from last pull which was successful.
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval& curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(140, curInterval.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(true, valueProducer.mHasGlobalBase);
+}
+
+TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ // First onConditionChanged
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
+ event->write(tagId);
+ event->write(120);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
+ // Second onConditionChanged
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
+ event->write(tagId);
+ event->write(130);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
+
+ valueProducer.mCondition = true;
+
+ // Bucket start.
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+ event->write(1);
+ event->write(110);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData, /** succeed */ true);
+
+ // This will fail and should invalidate the whole bucket since we do not have all the data
+ // needed to compute the metric value when the screen was on.
+ valueProducer.onConditionChanged(false, bucketStartTimeNs + 2);
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 3);
+
+ // Bucket end.
+ allData.clear();
+ shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ event2->write(1);
+ event2->write(140);
+ event2->init();
+ allData.push_back(event2);
+ valueProducer.onDataPulled(allData, /** succeed */ false);
+
+ valueProducer.flushIfNeededLocked(bucket2StartTimeNs + 1);
+
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ // Last pull failed so based has been reset.
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval& curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(false, curInterval.hasBase);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(false, valueProducer.mHasGlobalBase);
}
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index 920a52d..d29e68e 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.os.BatteryManager;
import android.os.IPowerManager;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -71,7 +72,8 @@
if (val != 0) {
// if the request is not to set it to false, wake up the screen so that
// it can stay on as requested
- pm.wakeUp(SystemClock.uptimeMillis(), "PowerCommand", null);
+ pm.wakeUp(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_UNKNOWN, "PowerCommand", null);
}
pm.setStayOnSetting(val);
}
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index 6061b66..7edd128 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -33456,7 +33456,6 @@
HSPLandroid/view/SurfaceControl;->finalize()V
HSPLandroid/view/SurfaceControl;->getActiveColorMode(Landroid/os/IBinder;)I
HSPLandroid/view/SurfaceControl;->getActiveConfig(Landroid/os/IBinder;)I
-HSPLandroid/view/SurfaceControl;->getBuiltInDisplay(I)Landroid/os/IBinder;
HSPLandroid/view/SurfaceControl;->getDisplayColorModes(Landroid/os/IBinder;)[I
HSPLandroid/view/SurfaceControl;->getDisplayConfigs(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;
HSPLandroid/view/SurfaceControl;->getHandle()Landroid/os/IBinder;
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index a748959..a0d8a12 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -328,17 +328,12 @@
Landroid/content/om/IOverlayManager;->getOverlayInfo(Ljava/lang/String;I)Landroid/content/om/OverlayInfo;
Landroid/content/pm/IPackageDataObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->onRemoveCompleted(Ljava/lang/String;Z)V
Landroid/content/pm/IPackageDataObserver$Stub;-><init>()V
Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
-Landroid/content/pm/IPackageDataObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/content/pm/IPackageDataObserver$Stub;->TRANSACTION_onRemoveCompleted:I
Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
Landroid/content/pm/IPackageDeleteObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDeleteObserver$Stub;-><init>()V
Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver;
-Landroid/content/pm/IPackageDeleteObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/content/pm/IPackageDeleteObserver$Stub;->TRANSACTION_packageDeleted:I
Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/content/pm/IPackageDeleteObserver2$Stub;-><init>()V
@@ -437,8 +432,6 @@
Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/content/pm/IPackageStatsObserver$Stub;-><init>()V
Landroid/content/pm/IPackageStatsObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageStatsObserver;
-Landroid/content/pm/IPackageStatsObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/content/pm/IPackageStatsObserver$Stub;->TRANSACTION_onGetStatsCompleted:I
Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
Landroid/content/pm/IShortcutService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IShortcutService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IShortcutService;
@@ -489,7 +482,6 @@
Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I
Landroid/location/ILocationManager;->getAllProviders()Ljava/util/List;
-Landroid/location/ILocationManager;->getNetworkProviderPackage()Ljava/lang/String;
Landroid/location/INetInitiatedListener$Stub;-><init>()V
Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
Landroid/location/LocationManager$ListenerTransport;-><init>(Landroid/location/LocationManager;Landroid/location/LocationListener;Landroid/os/Looper;)V
@@ -836,7 +828,6 @@
Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
Landroid/os/IPowerManager;->releaseWakeLock(Landroid/os/IBinder;I)V
Landroid/os/IPowerManager;->userActivity(JII)V
-Landroid/os/IPowerManager;->wakeUp(JLjava/lang/String;Ljava/lang/String;)V
Landroid/os/IRecoverySystem$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IRecoverySystem;
Landroid/os/IRemoteCallback$Stub;-><init>()V
Landroid/os/IRemoteCallback;->sendResult(Landroid/os/Bundle;)V
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 5b3813d..c753710 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -17,6 +17,7 @@
package android.animation;
import android.annotation.UnsupportedAppUsage;
+import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -1071,7 +1072,7 @@
*
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public void cancel() {
if (currentChangingAnimations.size() > 0) {
LinkedHashMap<View, Animator> currentAnimCopy =
@@ -1107,7 +1108,7 @@
*
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public void cancel(int transitionType) {
switch (transitionType) {
case CHANGE_APPEARING:
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index a0464df..ebb03e7 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -20,6 +20,7 @@
import android.annotation.IntDef;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
+import android.os.Build;
import android.os.Looper;
import android.os.Trace;
import android.util.AndroidRuntimeException;
@@ -76,7 +77,13 @@
/**
* Internal constants
*/
- @UnsupportedAppUsage
+
+ /**
+ * System-wide animation scale.
+ *
+ * <p>To check whether animations are enabled system-wise use {@link #areAnimatorsEnabled()}.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static float sDurationScale = 1.0f;
/**
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index aac8f08..0eadd1d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -7155,7 +7155,8 @@
mInstrumentation.onEnterAnimationComplete();
onEnterAnimationComplete();
if (getWindow() != null && getWindow().getDecorView() != null) {
- getWindow().getDecorView().getViewTreeObserver().dispatchOnEnterAnimationComplete();
+ View decorView = getWindow().getDecorView();
+ decorView.getViewTreeObserver().dispatchOnEnterAnimationComplete();
}
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 9ee2f03..64b94a9 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -189,9 +189,19 @@
/**
* Special mode that means "allow only when app is in foreground." This is <b>not</b>
- * returned from {@link #checkOp}, {@link #noteOp}, {@link #startOp}; rather, when this
- * mode is set, these functions will return {@link #MODE_ALLOWED} when the app being
- * checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
+ * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather,
+ * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
+ * possible for it to be ultimately allowed, depending on the app's background state),
+ * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
+ * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
+ *
+ * <p>The only place you will this normally see this value is through
+ * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because
+ * you can't know the current state of the app being checked (and it can change at any
+ * point), you can only treat the result here as an indication that it will vary between
+ * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
+ * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do
+ * the actual check for access to the op.</p>
*/
public static final int MODE_FOREGROUND = 4;
@@ -4485,6 +4495,7 @@
* @hide
*/
public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
+ logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
try {
return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
Binder.getCallingUid(), proxiedPackageName);
@@ -4500,7 +4511,7 @@
*/
@UnsupportedAppUsage
public int noteOpNoThrow(int op, int uid, String packageName) {
- logNoteOpIfNeeded(op, packageName);
+ logOperationIfNeeded(op, packageName, null);
try {
return mService.noteOperation(op, uid, packageName);
} catch (RemoteException e) {
@@ -4608,6 +4619,7 @@
* @hide
*/
public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
+ logOperationIfNeeded(op, packageName, null);
try {
return mService.startOperation(getToken(mService), op, uid, packageName,
startIfModeDefault);
@@ -4624,6 +4636,7 @@
* @hide
*/
public void finishOp(int op, int uid, String packageName) {
+ logOperationIfNeeded(op, packageName, null);
try {
mService.finishOperation(getToken(mService), op, uid, packageName);
} catch (RemoteException e) {
@@ -4870,7 +4883,7 @@
return AppOpsManager.MODE_DEFAULT;
}
- private static void logNoteOpIfNeeded(int op, String callingPackage) {
+ private static void logOperationIfNeeded(int op, String callingPackage, String proxiedPackage) {
// Check if debug logging propety is enabled.
if (!SystemProperties.getBoolean(DEBUG_LOGGING_ENABLE_PROP, false)) {
return;
@@ -4908,6 +4921,6 @@
// Log a stack trace
Exception here = new Exception("HERE!");
android.util.Log.i(DEBUG_LOGGING_TAG, "Note operation package= " + callingPackage
- + " op= " + opStr, here);
+ + " proxied= " + proxiedPackage + " op= " + opStr, here);
}
}
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index e95d62f..cfe27c7 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -85,7 +85,7 @@
private static final String ATT_FG_SERVICE_SHOWN = "fgservice";
private static final String ATT_GROUP = "group";
private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system";
- private static final String ATT_ALLOW_BUBBLE = "allow_bubble";
+ private static final String ATT_ALLOW_BUBBLE = "can_bubble";
private static final String DELIMITER = ",";
/**
@@ -611,14 +611,6 @@
* shade, in a floating window on top of other apps.
*/
public boolean canBubble() {
- return isBubbleAllowed() && getImportance() >= IMPORTANCE_HIGH;
- }
-
- /**
- * Like {@link #canBubble()}, but only checks the permission, not the importance.
- * @hide
- */
- public boolean isBubbleAllowed() {
return mAllowBubbles;
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 428c9b0..3ff6973 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -6408,11 +6408,9 @@
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param packageName The name of the package to set as the default SMS application.
* @throws SecurityException if {@code admin} is not a device owner.
- *
- * @hide
*/
- @UnsupportedAppUsage
- public void setDefaultSmsApplication(@NonNull ComponentName admin, String packageName) {
+ public void setDefaultSmsApplication(@NonNull ComponentName admin,
+ @NonNull String packageName) {
throwIfParentInstance("setDefaultSmsApplication");
if (mService != null) {
try {
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 6006ad2..2b1e7cd 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -3,6 +3,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -715,9 +716,10 @@
ViewNode[] mChildren;
// TODO(b/111276913): temporarily made public / @hide until we decide what will be used by
- // ScreenObservation.
+ // COntent Capture.
/** @hide */
@SystemApi
+ @TestApi
public ViewNode() {
}
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index a6f6d06..868fbfe 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -751,6 +751,47 @@
}
/**
+ * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the
+ * serial number of the its ancestral work profile or {@code null} if there is none.
+ *
+ * <p> The ancestral serial number will have a corresponding {@link UserHandle} if the device
+ * has a work profile that was restored from another work profile with serial number
+ * {@code ancestralSerialNumber}.
+ *
+ * @see UserManager#getSerialNumberForUser(UserHandle)
+ */
+ @Nullable
+ public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
+ if (sService != null) {
+ try {
+ return sService.getUserForAncestralSerialNumber(ancestralSerialNumber);
+ } catch (RemoteException e) {
+ Log.e(TAG, "getUserForAncestralSerialNumber() couldn't connect");
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets the ancestral work profile for the calling user.
+ *
+ * <p> The ancestral work profile corresponds to the profile that was used to restore to the
+ * callers profile.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.BACKUP)
+ public void setAncestralSerialNumber(long ancestralSerialNumber) {
+ if (sService != null) {
+ try {
+ sService.setAncestralSerialNumber(ancestralSerialNumber);
+ } catch (RemoteException e) {
+ Log.e(TAG, "setAncestralSerialNumber() couldn't connect");
+ }
+ }
+ }
+
+ /**
* Returns an {@link Intent} for the specified transport's configuration UI.
* This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String,
* Intent, String)}.
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index eda8981..8386c72 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -22,6 +22,7 @@
import android.app.backup.IRestoreSession;
import android.app.backup.ISelectBackupTransportCallback;
import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
import android.content.Intent;
import android.content.ComponentName;
@@ -685,4 +686,24 @@
* {@link android.app.backup.IBackupManager.cancelBackups} for the calling user id.
*/
void cancelBackups();
+
+ /**
+ * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the serial
+ * number of the it's ancestral work profile.
+ *
+ * <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)}
+ * and it corresponds to the profile that was used to restore to the callers profile.
+ */
+ UserHandle getUserForAncestralSerialNumber(in long ancestralSerialNumber);
+
+ /**
+ * Sets the ancestral work profile for the calling user.
+ *
+ * <p> The ancestral work profile corresponds to the profile that was used to restore to the
+ * callers profile.
+ *
+ * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+ */
+ void setAncestralSerialNumber(in long ancestralSerialNumber);
+
}
diff --git a/core/java/android/app/role/IRoleManager.aidl b/core/java/android/app/role/IRoleManager.aidl
index cf62e8d..76dbf7e 100644
--- a/core/java/android/app/role/IRoleManager.aidl
+++ b/core/java/android/app/role/IRoleManager.aidl
@@ -32,13 +32,14 @@
List<String> getRoleHoldersAsUser(in String roleName, int userId);
- void addRoleHolderAsUser(in String roleName, in String packageName, int userId,
+ void addRoleHolderAsUser(in String roleName, in String packageName, int flags, int userId,
in IRoleManagerCallback callback);
- void removeRoleHolderAsUser(in String roleName, in String packageName, int userId,
+ void removeRoleHolderAsUser(in String roleName, in String packageName, int flags, int userId,
in IRoleManagerCallback callback);
- void clearRoleHoldersAsUser(in String roleName, int userId, in IRoleManagerCallback callback);
+ void clearRoleHoldersAsUser(in String roleName, int flags, int userId,
+ in IRoleManagerCallback callback);
void addOnRoleHoldersChangedListenerAsUser(IOnRoleHoldersChangedListener listener, int userId);
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index ddd5313..fa2a6a1 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -18,6 +18,7 @@
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -181,6 +182,22 @@
public static final String ROLE_ASSISTANT = "android.app.role.ASSISTANT";
/**
+ * @hide
+ */
+ @IntDef(flag = true, value = { MANAGE_HOLDERS_FLAG_DONT_KILL_APP })
+ public @interface ManageHoldersFlags {}
+
+ /**
+ * Flag parameter for {@link #addRoleHolderAsUser}, {@link #removeRoleHolderAsUser} and
+ * {@link #clearRoleHoldersAsUser} to indicate that apps should not be killed when changing
+ * their role holder status.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1;
+
+ /**
* The action used to request user approval of a role for an application.
*
* @hide
@@ -305,9 +322,9 @@
*
* @return a list of package names of the role holders, or an empty list if none.
*
- * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
+ * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback)
*
* @hide
*/
@@ -335,13 +352,14 @@
*
* @param roleName the name of the role to add the role holder for
* @param packageName the package name of the application to add to the role holders
+ * @param flags optional behavior flags
* @param user the user to add the role holder for
* @param executor the {@code Executor} to run the callback on.
* @param callback the callback for whether this call is successful
*
* @see #getRoleHoldersAsUser(String, UserHandle)
- * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
+ * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback)
*
* @hide
*/
@@ -349,15 +367,15 @@
@SystemApi
@TestApi
public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
- @NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor,
- @NonNull RoleManagerCallback callback) {
+ @ManageHoldersFlags int flags, @NonNull UserHandle user,
+ @CallbackExecutor @NonNull Executor executor, @NonNull RoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
Preconditions.checkNotNull(user, "user cannot be null");
Preconditions.checkNotNull(executor, "executor cannot be null");
Preconditions.checkNotNull(callback, "callback cannot be null");
try {
- mService.addRoleHolderAsUser(roleName, packageName, user.getIdentifier(),
+ mService.addRoleHolderAsUser(roleName, packageName, flags, user.getIdentifier(),
new RoleManagerCallbackDelegate(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -373,13 +391,14 @@
*
* @param roleName the name of the role to remove the role holder for
* @param packageName the package name of the application to remove from the role holders
+ * @param flags optional behavior flags
* @param user the user to remove the role holder for
* @param executor the {@code Executor} to run the callback on.
* @param callback the callback for whether this call is successful
*
* @see #getRoleHoldersAsUser(String, UserHandle)
- * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
+ * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback)
*
* @hide
*/
@@ -387,15 +406,15 @@
@SystemApi
@TestApi
public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
- @NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor,
- @NonNull RoleManagerCallback callback) {
+ @ManageHoldersFlags int flags, @NonNull UserHandle user,
+ @CallbackExecutor @NonNull Executor executor, @NonNull RoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
Preconditions.checkNotNull(user, "user cannot be null");
Preconditions.checkNotNull(executor, "executor cannot be null");
Preconditions.checkNotNull(callback, "callback cannot be null");
try {
- mService.removeRoleHolderAsUser(roleName, packageName, user.getIdentifier(),
+ mService.removeRoleHolderAsUser(roleName, packageName, flags, user.getIdentifier(),
new RoleManagerCallbackDelegate(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -410,27 +429,29 @@
* {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
*
* @param roleName the name of the role to remove role holders for
+ * @param flags optional behavior flags
* @param user the user to remove role holders for
* @param executor the {@code Executor} to run the callback on.
* @param callback the callback for whether this call is successful
*
* @see #getRoleHoldersAsUser(String, UserHandle)
- * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
+ * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
*
* @hide
*/
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@SystemApi
@TestApi
- public void clearRoleHoldersAsUser(@NonNull String roleName, @NonNull UserHandle user,
- @CallbackExecutor @NonNull Executor executor, @NonNull RoleManagerCallback callback) {
+ public void clearRoleHoldersAsUser(@NonNull String roleName, @ManageHoldersFlags int flags,
+ @NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor,
+ @NonNull RoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkNotNull(user, "user cannot be null");
Preconditions.checkNotNull(executor, "executor cannot be null");
Preconditions.checkNotNull(callback, "callback cannot be null");
try {
- mService.clearRoleHoldersAsUser(roleName, user.getIdentifier(),
+ mService.clearRoleHoldersAsUser(roleName, flags, user.getIdentifier(),
new RoleManagerCallbackDelegate(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 8cbe7a3..fafea34 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -52,6 +52,14 @@
public static final int NONE = 0;
/**
+ * A device level event like {@link #DEVICE_SHUTDOWN} does not have package name, but some
+ * user code always expect a non-null {@link #mPackage} for every event. Use
+ * {@link #DEVICE_EVENT_PACKAGE_NAME} as packageName for these device level events.
+ * @hide
+ */
+ public static final String DEVICE_EVENT_PACKAGE_NAME = "android";
+
+ /**
* @deprecated by {@link #ACTIVITY_RESUMED}
*/
@Deprecated
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 47a4a2d..f1bfe86 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -2748,6 +2748,19 @@
}
/**
+ * @see #setIsSyncable(Account, String, int)
+ * @hide
+ */
+ public static void setIsSyncableAsUser(Account account, String authority, int syncable,
+ int userId) {
+ try {
+ getContentService().setIsSyncableAsUser(account, authority, syncable, userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Gets the master auto-sync setting that applies to all the providers and accounts.
* If this is false then the per-provider auto-sync setting is ignored.
* <p>This method requires the caller to hold the permission
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 1d02375..9f6e236 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -126,6 +126,7 @@
* @param syncable, >0 denotes syncable, 0 means not syncable, <0 means unknown
*/
void setIsSyncable(in Account account, String providerName, int syncable);
+ void setIsSyncableAsUser(in Account account, String providerName, int syncable, int userId);
void setMasterSyncAutomatically(boolean flag);
void setMasterSyncAutomaticallyAsUser(boolean flag, int userId);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e2907e2..6e52b33 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -866,6 +866,14 @@
*/
public static final int INSTALL_ENABLE_ROLLBACK = 0x00040000;
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that package verification should be
+ * disabled for this package.
+ *
+ * @hide
+ */
+ public static final int INSTALL_DISABLE_VERIFICATION = 0x00080000;
+
/** @hide */
@IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
DONT_KILL_APP
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 4a2dbe7..cfe35b0 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -137,6 +137,32 @@
}
/**
+ * Provider for default browser
+ */
+ public interface DefaultBrowserProvider {
+
+ /**
+ * Get the package name of the default browser.
+ *
+ * @param userId the user id
+ *
+ * @return the package name of the default browser, or {@code null} if none
+ */
+ @Nullable
+ String getDefaultBrowser(@UserIdInt int userId);
+
+ /**
+ * Set the package name of the default browser.
+ *
+ * @param packageName package name of the default browser, or {@code null} to remove
+ * @param userId the user id
+ *
+ * @return whether the default browser was successfully set.
+ */
+ boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId);
+ }
+
+ /**
* Sets the location provider packages provider.
* @param provider The packages provider.
*/
@@ -843,4 +869,21 @@
* {@code token} can be completed.
*/
public abstract void finishPackageInstall(int token, boolean didLaunch);
+
+ /**
+ * Remove the default browser stored in the legacy package settings.
+ *
+ * @param userId the user id
+ *
+ * @return the package name of the default browser, or {@code null} if none
+ */
+ @Nullable
+ public abstract String removeLegacyDefaultBrowserPackageName(int userId);
+
+ /**
+ * Sets the default browser provider.
+ *
+ * @param provider the provider
+ */
+ public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider);
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 6044914..81ed110 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -5260,6 +5260,10 @@
com.android.internal.R.styleable.AndroidManifestProvider_grantUriPermissions,
false);
+ p.info.forceUriPermissions = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestProvider_forceUriPermissions,
+ false);
+
p.info.multiprocess = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestProvider_multiprocess,
false);
diff --git a/core/java/android/content/pm/ProviderInfo.java b/core/java/android/content/pm/ProviderInfo.java
index 379b783..f06a628 100644
--- a/core/java/android/content/pm/ProviderInfo.java
+++ b/core/java/android/content/pm/ProviderInfo.java
@@ -47,7 +47,13 @@
* grantUriPermissions} attribute.
*/
public boolean grantUriPermissions = false;
-
+
+ /** If true, always apply URI permission grants, as per the
+ * {@link android.R.styleable#AndroidManifestProvider_forceUriPermissions
+ * forceUriPermissions} attribute.
+ */
+ public boolean forceUriPermissions = false;
+
/**
* If non-null, these are the patterns that are allowed for granting URI
* permissions. Any URI that does not match one of these patterns will not
@@ -112,6 +118,7 @@
readPermission = orig.readPermission;
writePermission = orig.writePermission;
grantUriPermissions = orig.grantUriPermissions;
+ forceUriPermissions = orig.forceUriPermissions;
uriPermissionPatterns = orig.uriPermissionPatterns;
pathPermissions = orig.pathPermissions;
multiprocess = orig.multiprocess;
@@ -142,6 +149,7 @@
out.writeString(readPermission);
out.writeString(writePermission);
out.writeInt(grantUriPermissions ? 1 : 0);
+ out.writeInt(forceUriPermissions ? 1 : 0);
out.writeTypedArray(uriPermissionPatterns, parcelableFlags);
out.writeTypedArray(pathPermissions, parcelableFlags);
out.writeInt(multiprocess ? 1 : 0);
@@ -171,6 +179,7 @@
readPermission = in.readString();
writePermission = in.readString();
grantUriPermissions = in.readInt() != 0;
+ forceUriPermissions = in.readInt() != 0;
uriPermissionPatterns = in.createTypedArray(PatternMatcher.CREATOR);
pathPermissions = in.createTypedArray(PathPermission.CREATOR);
multiprocess = in.readInt() != 0;
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 536a1b7..8a92017 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1096,34 +1096,38 @@
* @param protoOutputStream Stream to write the Configuration object to.
* @param fieldId Field Id of the Configuration as defined in the parent message
* @param persisted Note if this proto will be persisted to disk
+ * @param critical If true, reduce amount of data written.
* @hide
*/
- public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean persisted) {
+ public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean persisted,
+ boolean critical) {
final long token = protoOutputStream.start(fieldId);
- protoOutputStream.write(FONT_SCALE, fontScale);
- protoOutputStream.write(MCC, mcc);
- protoOutputStream.write(MNC, mnc);
- if (mLocaleList != null) {
- mLocaleList.writeToProto(protoOutputStream, LOCALES);
+ if (!critical) {
+ protoOutputStream.write(FONT_SCALE, fontScale);
+ protoOutputStream.write(MCC, mcc);
+ protoOutputStream.write(MNC, mnc);
+ if (mLocaleList != null) {
+ mLocaleList.writeToProto(protoOutputStream, LOCALES);
+ }
+ protoOutputStream.write(SCREEN_LAYOUT, screenLayout);
+ protoOutputStream.write(COLOR_MODE, colorMode);
+ protoOutputStream.write(TOUCHSCREEN, touchscreen);
+ protoOutputStream.write(KEYBOARD, keyboard);
+ protoOutputStream.write(KEYBOARD_HIDDEN, keyboardHidden);
+ protoOutputStream.write(HARD_KEYBOARD_HIDDEN, hardKeyboardHidden);
+ protoOutputStream.write(NAVIGATION, navigation);
+ protoOutputStream.write(NAVIGATION_HIDDEN, navigationHidden);
+ protoOutputStream.write(UI_MODE, uiMode);
+ protoOutputStream.write(SMALLEST_SCREEN_WIDTH_DP, smallestScreenWidthDp);
+ protoOutputStream.write(DENSITY_DPI, densityDpi);
+ // For persistence, we do not care about window configuration
+ if (!persisted && windowConfiguration != null) {
+ windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION);
+ }
}
- protoOutputStream.write(SCREEN_LAYOUT, screenLayout);
- protoOutputStream.write(COLOR_MODE, colorMode);
- protoOutputStream.write(TOUCHSCREEN, touchscreen);
- protoOutputStream.write(KEYBOARD, keyboard);
- protoOutputStream.write(KEYBOARD_HIDDEN, keyboardHidden);
- protoOutputStream.write(HARD_KEYBOARD_HIDDEN, hardKeyboardHidden);
- protoOutputStream.write(NAVIGATION, navigation);
- protoOutputStream.write(NAVIGATION_HIDDEN, navigationHidden);
protoOutputStream.write(ORIENTATION, orientation);
- protoOutputStream.write(UI_MODE, uiMode);
protoOutputStream.write(SCREEN_WIDTH_DP, screenWidthDp);
protoOutputStream.write(SCREEN_HEIGHT_DP, screenHeightDp);
- protoOutputStream.write(SMALLEST_SCREEN_WIDTH_DP, smallestScreenWidthDp);
- protoOutputStream.write(DENSITY_DPI, densityDpi);
- // For persistence, we do not care about window configuration
- if (!persisted && windowConfiguration != null) {
- windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION);
- }
protoOutputStream.end(token);
}
@@ -1136,7 +1140,20 @@
* @hide
*/
public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
- writeToProto(protoOutputStream, fieldId, false);
+ writeToProto(protoOutputStream, fieldId, false /* persisted */, false /* critical */);
+ }
+
+ /**
+ * Write to a protocol buffer output stream.
+ * Protocol buffer message definition at {@link android.content.ConfigurationProto}
+ *
+ * @param protoOutputStream Stream to write the Configuration object to.
+ * @param fieldId Field Id of the Configuration as defined in the parent message
+ * @param critical If true, reduce amount of data written.
+ * @hide
+ */
+ public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId, boolean critical) {
+ writeToProto(protoOutputStream, fieldId, false /* persisted */, critical);
}
/**
diff --git a/core/java/android/content/rollback/IRollbackManager.aidl b/core/java/android/content/rollback/IRollbackManager.aidl
index 104661f..db9fcb6 100644
--- a/core/java/android/content/rollback/IRollbackManager.aidl
+++ b/core/java/android/content/rollback/IRollbackManager.aidl
@@ -40,4 +40,15 @@
// Exposed for test purposes only.
void expireRollbackForPackage(String packageName);
+
+ // Used by the staging manager to notify the RollbackManager that a session is
+ // being staged. In the case of multi-package sessions, the specified sessionId
+ // is that of the parent session.
+ //
+ // NOTE: This call is synchronous.
+ boolean notifyStagedSession(int sessionId);
+
+ // Used by the staging manager to notify the RollbackManager of the apk
+ // session for a staged session.
+ void notifyStagedApkSession(int originalSessionId, int apkSessionId);
}
diff --git a/core/java/android/content/rollback/PackageRollbackInfo.java b/core/java/android/content/rollback/PackageRollbackInfo.java
index d4ed35a..1d0ab5a 100644
--- a/core/java/android/content/rollback/PackageRollbackInfo.java
+++ b/core/java/android/content/rollback/PackageRollbackInfo.java
@@ -22,6 +22,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.IntArray;
+import android.util.SparseLongArray;
import java.util.ArrayList;
@@ -69,6 +70,23 @@
private final ArrayList<RestoreInfo> mPendingRestores;
/**
+ * Whether this instance represents the PackageRollbackInfo for an APEX module.
+ */
+ private final boolean mIsApex;
+
+ /*
+ * The list of users the package is installed for.
+ */
+ // NOTE: Not a part of the Parcelable representation of this object.
+ private final IntArray mInstalledUsers;
+
+ /**
+ * A mapping between user and an inode of theirs CE data snapshot.
+ */
+ // NOTE: Not a part of the Parcelable representation of this object.
+ private final SparseLongArray mCeSnapshotInodes;
+
+ /**
* Returns the name of the package to roll back from.
*/
public String getPackageName() {
@@ -116,20 +134,48 @@
}
/** @hide */
+ public boolean isApex() {
+ return mIsApex;
+ }
+
+ /** @hide */
+ public IntArray getInstalledUsers() {
+ return mInstalledUsers;
+ }
+
+ /** @hide */
+ public SparseLongArray getCeSnapshotInodes() {
+ return mCeSnapshotInodes;
+ }
+
+ /** @hide */
+ public void putCeSnapshotInode(int userId, long ceSnapshotInode) {
+ mCeSnapshotInodes.put(userId, ceSnapshotInode);
+ }
+
+ /** @hide */
public PackageRollbackInfo(VersionedPackage packageRolledBackFrom,
VersionedPackage packageRolledBackTo,
- @NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores) {
+ @NonNull IntArray pendingBackups, @NonNull ArrayList<RestoreInfo> pendingRestores,
+ boolean isApex, @NonNull IntArray installedUsers,
+ @NonNull SparseLongArray ceSnapshotInodes) {
this.mVersionRolledBackFrom = packageRolledBackFrom;
this.mVersionRolledBackTo = packageRolledBackTo;
this.mPendingBackups = pendingBackups;
this.mPendingRestores = pendingRestores;
+ this.mIsApex = isApex;
+ this.mInstalledUsers = installedUsers;
+ this.mCeSnapshotInodes = ceSnapshotInodes;
}
private PackageRollbackInfo(Parcel in) {
this.mVersionRolledBackFrom = VersionedPackage.CREATOR.createFromParcel(in);
this.mVersionRolledBackTo = VersionedPackage.CREATOR.createFromParcel(in);
+ this.mIsApex = in.readBoolean();
this.mPendingRestores = null;
this.mPendingBackups = null;
+ this.mInstalledUsers = null;
+ this.mCeSnapshotInodes = null;
}
@Override
@@ -141,6 +187,7 @@
public void writeToParcel(Parcel out, int flags) {
mVersionRolledBackFrom.writeToParcel(out, flags);
mVersionRolledBackTo.writeToParcel(out, flags);
+ out.writeBoolean(mIsApex);
}
public static final Parcelable.Creator<PackageRollbackInfo> CREATOR =
diff --git a/core/java/android/ddm/DdmHandleHello.java b/core/java/android/ddm/DdmHandleHello.java
index b2288fc..87568e8 100644
--- a/core/java/android/ddm/DdmHandleHello.java
+++ b/core/java/android/ddm/DdmHandleHello.java
@@ -16,13 +16,15 @@
package android.ddm;
+import android.os.Debug;
+import android.os.UserHandle;
+import android.util.Log;
+
+import dalvik.system.VMRuntime;
+
import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
import org.apache.harmony.dalvik.ddmc.DdmServer;
-import android.util.Log;
-import android.os.Debug;
-import android.os.UserHandle;
-import dalvik.system.VMRuntime;
import java.nio.ByteBuffer;
@@ -35,6 +37,8 @@
public static final int CHUNK_WAIT = type("WAIT");
public static final int CHUNK_FEAT = type("FEAT");
+ private static final int CLIENT_PROTOCOL_VERSION = 1;
+
private static DdmHandleHello mInstance = new DdmHandleHello();
private static final String[] FRAMEWORK_FEATURES = new String[] {
@@ -145,7 +149,7 @@
+ vmFlags.length() * 2
+ 1);
out.order(ChunkHandler.CHUNK_ORDER);
- out.putInt(DdmServer.CLIENT_PROTOCOL_VERSION);
+ out.putInt(CLIENT_PROTOCOL_VERSION);
out.putInt(android.os.Process.myPid());
out.putInt(vmIdent.length());
out.putInt(appName.length());
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 4bc2702..1881a0cd 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1901,6 +1901,7 @@
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING MOTION_TRACKING}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA LOGICAL_MULTI_CAMERA}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME MONOCHROME}</li>
+ * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA SECURE_IMAGE_DATA}</li>
* </ul></p>
* <p>This key is available on all devices.</p>
*
@@ -1918,6 +1919,7 @@
* @see #REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING
* @see #REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
* @see #REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
+ * @see #REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA
*/
@PublicKey
public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES =
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 6302aa5..a3e561c 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -972,6 +972,14 @@
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12;
+ /**
+ * <p>The camera device is capable of writing image data into a region of memory
+ * inaccessible to Android userspace or the Android kernel, and only accessible to
+ * trusted execution environments (TEE).</p>
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ */
+ public static final int REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13;
+
//
// Enumeration values for CameraCharacteristics#SCALER_CROPPING_TYPE
//
diff --git a/core/java/android/hardware/hdmi/HdmiClient.java b/core/java/android/hardware/hdmi/HdmiClient.java
index 45a79e1..bff8c39 100644
--- a/core/java/android/hardware/hdmi/HdmiClient.java
+++ b/core/java/android/hardware/hdmi/HdmiClient.java
@@ -56,6 +56,26 @@
}
/**
+ * Sends a volume key event to the primary audio receiver in the system. This method should only
+ * be called when the volume key is not handled by the local device. HDMI framework handles the
+ * logic of finding the address of the receiver.
+ *
+ * @param keyCode key code to send. Defined in {@link android.view.KeyEvent}.
+ * @param isPressed true if this is key press event
+ *
+ * @hide
+ * TODO(b/110094868): unhide for Q
+ */
+ public void sendVolumeKeyEvent(int keyCode, boolean isPressed) {
+ try {
+ mService.sendVolumeKeyEvent(getDeviceType(), keyCode, isPressed);
+ } catch (RemoteException e) {
+ Log.e(TAG, "sendVolumeKeyEvent threw exception ", e);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Sends vendor-specific command.
*
* @param targetAddress address of the target device
diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
index 1cd9920..95eaf75 100644
--- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
@@ -47,6 +47,7 @@
void deviceSelect(int deviceId, IHdmiControlCallback callback);
void portSelect(int portId, IHdmiControlCallback callback);
void sendKeyEvent(int deviceType, int keyCode, boolean isPressed);
+ void sendVolumeKeyEvent(int deviceType, int keyCode, boolean isPressed);
List<HdmiPortInfo> getPortInfo();
boolean canChangeSystemAudioMode();
boolean getSystemAudioMode();
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 843db6d..ffae361e 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -51,6 +51,7 @@
private static final int DO_TOGGLE_SOFT_INPUT = 105;
private static final int DO_FINISH_SESSION = 110;
private static final int DO_VIEW_CLICKED = 115;
+ private static final int DO_NOTIFY_IME_HIDDEN = 120;
HandlerCaller mCaller;
InputMethodSession mInputMethodSession;
@@ -129,6 +130,10 @@
mInputMethodSession.viewClicked(msg.arg1 == 1);
return;
}
+ case DO_NOTIFY_IME_HIDDEN: {
+ mInputMethodSession.notifyImeHidden();
+ return;
+ }
}
Log.w(TAG, "Unhandled message code: " + msg.what);
}
@@ -172,6 +177,11 @@
}
@Override
+ public void notifyImeHidden() {
+ mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_NOTIFY_IME_HIDDEN));
+ }
+
+ @Override
public void updateCursor(Rect newCursor) {
mCaller.executeOrSendMessage(
mCaller.obtainMessageO(DO_UPDATE_CURSOR, newCursor));
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 333cfbd..ab630fd 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -592,7 +592,6 @@
final boolean wasVisible = mIsPreRendered
? mDecorViewVisible && mWindowVisible : isInputViewShown();
if (mIsPreRendered) {
- // TODO: notify visibility to insets consumer.
if (DEBUG) {
Log.v(TAG, "Making IME window invisible");
}
@@ -658,6 +657,11 @@
}
}
+ private void notifyImeHidden() {
+ setImeWindowStatus(IME_ACTIVE | IME_INVISIBLE, mBackDisposition);
+ onPreRenderedWindowVisibilityChanged(false /* setVisible */);
+ }
+
private void setImeWindowStatus(int visibilityFlags, int backDisposition) {
mPrivOps.setImeWindowStatus(visibilityFlags, backDisposition);
}
@@ -760,6 +764,14 @@
}
InputMethodService.this.onUpdateCursorAnchorInfo(info);
}
+
+ /**
+ * Notify IME that window is hidden.
+ * @hide
+ */
+ public final void notifyImeHidden() {
+ InputMethodService.this.notifyImeHidden();
+ }
}
/**
diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
index b4b541d..31c948a 100644
--- a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
+++ b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
@@ -290,6 +290,12 @@
CallbackImpl::updateCursorAnchorInfo, mCallbackImpl, info));
}
}
+
+ @Override
+ public final void notifyImeHidden() {
+ // no-op for multi-session since IME is responsible controlling navigation bar buttons.
+ reportNotSupported();
+ }
}
private static final class MultiClientInputMethodSessionImpl
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ce2de9a..2aca55a 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -68,6 +68,7 @@
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -177,10 +178,10 @@
* The lookup key for a {@link NetworkInfo} object. Retrieve with
* {@link android.content.Intent#getParcelableExtra(String)}.
*
- * @deprecated Since {@link NetworkInfo} can vary based on UID, applications
- * should always obtain network information through
- * {@link #getActiveNetworkInfo()}.
- * @see #EXTRA_NETWORK_TYPE
+ * @deprecated The {@link NetworkInfo} object is deprecated, as many of its properties
+ * can't accurately represent modern network characteristics.
+ * Please obtain information about networks from the {@link NetworkCapabilities}
+ * or {@link LinkProperties} objects instead.
*/
@Deprecated
public static final String EXTRA_NETWORK_INFO = "networkInfo";
@@ -189,7 +190,11 @@
* Network type which triggered a {@link #CONNECTIVITY_ACTION} broadcast.
*
* @see android.content.Intent#getIntExtra(String, int)
+ * @deprecated The network type is not rich enough to represent the characteristics
+ * of modern networks. Please use {@link NetworkCapabilities} instead,
+ * in particular the transports.
*/
+ @Deprecated
public static final String EXTRA_NETWORK_TYPE = "networkType";
/**
@@ -1243,9 +1248,13 @@
* is no current default network.
*
* {@hide}
+ * @deprecated please use {@link #getLinkProperties(Network)} on the return
+ * value of {@link #getActiveNetwork()} instead. In particular,
+ * this method will return non-null LinkProperties even if the
+ * app is blocked by policy from using this network.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 109783091)
public LinkProperties getActiveLinkProperties() {
try {
return mService.getActiveLinkProperties();
@@ -1881,7 +1890,8 @@
* @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
* changes. Must be extended by applications that use this API.
*
- * @return A {@link SocketKeepalive} object, which can be used to control this keepalive object.
+ * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
+ * given socket.
**/
public SocketKeepalive createSocketKeepalive(@NonNull Network network,
@NonNull UdpEncapsulationSocket socket,
@@ -1910,6 +1920,8 @@
* @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
* changes. Must be extended by applications that use this API.
*
+ * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
+ * given socket.
* @hide
*/
@SystemApi
@@ -1925,6 +1937,34 @@
}
/**
+ * Request that keepalives be started on a TCP socket.
+ * The socket must be established.
+ *
+ * @param network The {@link Network} the socket is on.
+ * @param socket The socket that needs to be kept alive.
+ * @param executor The executor on which callback will be invoked. This implementation assumes
+ * the provided {@link Executor} runs the callbacks in sequence with no
+ * concurrency. Failing this, no guarantee of correctness can be made. It is
+ * the responsibility of the caller to ensure the executor provides this
+ * guarantee. A simple way of creating such an executor is with the standard
+ * tool {@code Executors.newSingleThreadExecutor}.
+ * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
+ * changes. Must be extended by applications that use this API.
+ *
+ * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
+ * given socket.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD)
+ public SocketKeepalive createSocketKeepalive(@NonNull Network network,
+ @NonNull Socket socket,
+ @NonNull Executor executor,
+ @NonNull Callback callback) {
+ return new TcpSocketKeepalive(mService, network, socket, executor, callback);
+ }
+
+ /**
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface. An attempt to add a route that
* already exists is ignored, but treated as successful.
@@ -3883,6 +3923,25 @@
}
/**
+ * Requests that the system open the captive portal app with the specified extras.
+ *
+ * <p>This endpoint is exclusively for use by the NetworkStack and is protected by the
+ * corresponding permission.
+ * @param appExtras Extras to include in the app start intent.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+ public void startCaptivePortalApp(Bundle appExtras) {
+ try {
+ mService.startCaptivePortalAppInternal(appExtras);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Determine whether the device is configured to avoid bad wifi.
* @hide
*/
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 1148ac1..872671f 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -27,6 +27,7 @@
import android.net.NetworkRequest;
import android.net.NetworkState;
import android.net.ProxyInfo;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
@@ -167,6 +168,7 @@
void setAcceptUnvalidated(in Network network, boolean accept, boolean always);
void setAvoidUnvalidated(in Network network);
void startCaptivePortalApp(in Network network);
+ void startCaptivePortalAppInternal(in Bundle appExtras);
boolean getAvoidBadWifi();
int getMultipathPreference(in Network Network);
@@ -188,6 +190,9 @@
int intervalSeconds, in Messenger messenger, in IBinder binder, String srcAddr,
String dstAddr);
+ void startTcpKeepalive(in Network network, in FileDescriptor fd, int intervalSeconds,
+ in Messenger messenger, in IBinder binder);
+
void stopKeepalive(in Network network, int slot);
String getCaptivePortalServerUrl();
diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java
index 16555d8..18726f7 100644
--- a/core/java/android/net/KeepalivePacketData.java
+++ b/core/java/android/net/KeepalivePacketData.java
@@ -96,7 +96,7 @@
out.writeByteArray(mPacket);
}
- private KeepalivePacketData(Parcel in) {
+ protected KeepalivePacketData(Parcel in) {
srcAddress = NetworkUtils.numericToInetAddress(in.readString());
dstAddress = NetworkUtils.numericToInetAddress(in.readString());
srcPort = in.readInt();
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java
index aa9f799..5c55a98b 100644
--- a/core/java/android/net/NattKeepalivePacketData.java
+++ b/core/java/android/net/NattKeepalivePacketData.java
@@ -16,6 +16,9 @@
package android.net;
+import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
+import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
+
import android.net.SocketKeepalive.InvalidPacketException;
import android.net.util.IpUtils;
import android.system.OsConstants;
@@ -44,11 +47,11 @@
throws InvalidPacketException {
if (!(srcAddress instanceof Inet4Address) || !(dstAddress instanceof Inet4Address)) {
- throw new InvalidPacketException(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
+ throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
}
if (dstPort != NattSocketKeepalive.NATT_PORT) {
- throw new InvalidPacketException(SocketKeepalive.ERROR_INVALID_PORT);
+ throw new InvalidPacketException(ERROR_INVALID_PORT);
}
int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1;
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index c3783783..273f8cd 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -178,6 +178,26 @@
*/
public static final int EVENT_SOCKET_KEEPALIVE = BASE + 13;
+ // TODO: move the above 2 constants down so they are in order once merge conflicts are resolved
+ /**
+ * Sent by the KeepaliveTracker to NetworkAgent to add a packet filter.
+ *
+ * For TCP keepalive offloads, keepalive packets are sent by the firmware. However, because the
+ * remote site will send ACK packets in response to the keepalive packets, the firmware also
+ * needs to be configured to properly filter the ACKs to prevent the system from waking up.
+ * This does not happen with UDP, so this message is TCP-specific.
+ * arg1 = slot number of the keepalive to filter for.
+ * obj = the keepalive packet to send repeatedly.
+ */
+ public static final int CMD_ADD_KEEPALIVE_PACKET_FILTER = BASE + 16;
+
+ /**
+ * Sent by the KeepaliveTracker to NetworkAgent to remove a packet filter. See
+ * {@link #CMD_ADD_KEEPALIVE_PACKET_FILTER}.
+ * arg1 = slot number of the keepalive packet filter to remove.
+ */
+ public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
+
/**
* Sent by ConnectivityService to inform this network transport of signal strength thresholds
* that when crossed should trigger a system wakeup and a NetworkCapabilities update.
@@ -329,6 +349,14 @@
preventAutomaticReconnect();
break;
}
+ case CMD_ADD_KEEPALIVE_PACKET_FILTER: {
+ addKeepalivePacketFilter(msg);
+ break;
+ }
+ case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: {
+ removeKeepalivePacketFilter(msg);
+ break;
+ }
}
}
@@ -478,6 +506,24 @@
}
/**
+ * Called by ConnectivityService to add specific packet filter to network hardware to block
+ * ACKs matching the sent keepalive packets. Implementations that support this feature must
+ * override this method.
+ */
+ protected void addKeepalivePacketFilter(Message msg) {
+ onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ }
+
+ /**
+ * Called by ConnectivityService to remove a packet filter installed with
+ * {@link #addKeepalivePacketFilter(Message)}. Implementations that support this feature
+ * must override this method.
+ */
+ protected void removeKeepalivePacketFilter(Message msg) {
+ onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
+ }
+
+ /**
* Called by ConnectivityService to inform this network transport of signal strength thresholds
* that when crossed should trigger a system wakeup and a NetworkCapabilities update.
*/
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 6a17203..ed410e2 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -76,6 +76,18 @@
throws SocketException;
/**
+ * Attaches a socket filter that drops all of incoming packets.
+ * @param fd the socket's {@link FileDescriptor}.
+ */
+ public static native void attachDropAllBPFFilter(FileDescriptor fd) throws SocketException;
+
+ /**
+ * Detaches a socket filter.
+ * @param fd the socket's {@link FileDescriptor}.
+ */
+ public static native void detachBPFFilter(FileDescriptor fd) throws SocketException;
+
+ /**
* Configures a socket for receiving ICMPv6 router solicitations and sending advertisements.
* @param fd the socket's {@link FileDescriptor}.
* @param ifIndex the interface index.
@@ -175,6 +187,16 @@
private static native void addArpEntry(byte[] ethAddr, byte[] netAddr, String ifname,
FileDescriptor fd) throws IOException;
+
+ /**
+ * Get the tcp repair window associated with the {@code fd}.
+ *
+ * @param fd the tcp socket's {@link FileDescriptor}.
+ * @return a {@link TcpRepairWindow} object indicates tcp window size.
+ */
+ public static native TcpRepairWindow getTcpRepairWindow(FileDescriptor fd)
+ throws ErrnoException;
+
/**
* @see Inet4AddressUtils#intToInet4AddressHTL(int)
* @deprecated Use either {@link Inet4AddressUtils#intToInet4AddressHTH(int)}
diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java
index a47c11a..07728be 100644
--- a/core/java/android/net/SocketKeepalive.java
+++ b/core/java/android/net/SocketKeepalive.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -110,14 +111,42 @@
public static final int MAX_INTERVAL_SEC = 3600;
/**
+ * An exception that embarks an error code.
+ * @hide
+ */
+ public static class ErrorCodeException extends Exception {
+ public final int error;
+ public ErrorCodeException(final int error, final Throwable e) {
+ super(e);
+ this.error = error;
+ }
+ public ErrorCodeException(final int error) {
+ this.error = error;
+ }
+ }
+
+ /**
+ * This socket is invalid.
+ * See the error code for details, and the optional cause.
+ * @hide
+ */
+ public static class InvalidSocketException extends ErrorCodeException {
+ public InvalidSocketException(final int error, final Throwable e) {
+ super(error, e);
+ }
+ public InvalidSocketException(final int error) {
+ super(error);
+ }
+ }
+
+ /**
* This packet is invalid.
* See the error code for details.
* @hide
*/
- public static class InvalidPacketException extends Exception {
- public final int error;
- public InvalidPacketException(int error) {
- this.error = error;
+ public static class InvalidPacketException extends ErrorCodeException {
+ public InvalidPacketException(final int error) {
+ super(error);
}
}
@@ -127,7 +156,7 @@
@NonNull private final SocketKeepalive.Callback mCallback;
@NonNull private final Looper mLooper;
@NonNull final Messenger mMessenger;
- @NonNull Integer mSlot;
+ @Nullable Integer mSlot;
SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network,
@NonNull Executor executor, @NonNull Callback callback) {
diff --git a/core/java/android/net/TcpKeepalivePacketData.java b/core/java/android/net/TcpKeepalivePacketData.java
new file mode 100644
index 0000000..f07dfb6
--- /dev/null
+++ b/core/java/android/net/TcpKeepalivePacketData.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net;
+
+import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.SocketKeepalive.InvalidPacketException;
+import android.net.util.IpUtils;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.system.OsConstants;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Objects;
+
+/**
+ * Represents the actual tcp keep alive packets which will be used for hardware offload.
+ * @hide
+ */
+public class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable {
+ private static final String TAG = "TcpKeepalivePacketData";
+
+ /** TCP sequence number. */
+ public final int tcpSeq;
+
+ /** TCP ACK number. */
+ public final int tcpAck;
+
+ /** TCP RCV window. */
+ public final int tcpWnd;
+
+ /** TCP RCV window scale. */
+ public final int tcpWndScale;
+
+ private static final int IPV4_HEADER_LENGTH = 20;
+ private static final int IPV6_HEADER_LENGTH = 40;
+ private static final int TCP_HEADER_LENGTH = 20;
+
+ // This should only be constructed via static factory methods, such as
+ // tcpKeepalivePacket.
+ private TcpKeepalivePacketData(TcpSocketInfo tcpDetails, byte[] data)
+ throws InvalidPacketException {
+ super(tcpDetails.srcAddress, tcpDetails.srcPort, tcpDetails.dstAddress,
+ tcpDetails.dstPort, data);
+ tcpSeq = tcpDetails.seq;
+ tcpAck = tcpDetails.ack;
+ // In the packet, the window is shifted right by the window scale.
+ tcpWnd = tcpDetails.rcvWnd;
+ tcpWndScale = tcpDetails.rcvWndScale;
+ }
+
+ /**
+ * Factory method to create tcp keepalive packet structure.
+ */
+ public static TcpKeepalivePacketData tcpKeepalivePacket(
+ TcpSocketInfo tcpDetails) throws InvalidPacketException {
+ final byte[] packet;
+ if ((tcpDetails.srcAddress instanceof Inet4Address)
+ && (tcpDetails.dstAddress instanceof Inet4Address)) {
+ packet = buildV4Packet(tcpDetails);
+ } else {
+ // TODO: support ipv6
+ throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
+ }
+
+ return new TcpKeepalivePacketData(tcpDetails, packet);
+ }
+
+ /**
+ * Build ipv4 tcp keepalive packet, not including the link-layer header.
+ */
+ // TODO : if this code is ever moved to the network stack, factorize constants with the ones
+ // over there.
+ private static byte[] buildV4Packet(TcpSocketInfo tcpDetails) {
+ final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH;
+ ByteBuffer buf = ByteBuffer.allocate(length);
+ buf.order(ByteOrder.BIG_ENDIAN);
+ // IP version and TOS. TODO : fetch this from getsockopt(SOL_IP, IP_TOS)
+ buf.putShort((short) 0x4500);
+ buf.putShort((short) length);
+ buf.putInt(0x4000); // ID, flags=DF, offset
+ // TODO : fetch TTL from getsockopt(SOL_IP, IP_TTL)
+ buf.put((byte) 64);
+ buf.put((byte) OsConstants.IPPROTO_TCP);
+ final int ipChecksumOffset = buf.position();
+ buf.putShort((short) 0); // IP checksum
+ buf.put(tcpDetails.srcAddress.getAddress());
+ buf.put(tcpDetails.dstAddress.getAddress());
+ buf.putShort((short) tcpDetails.srcPort);
+ buf.putShort((short) tcpDetails.dstPort);
+ buf.putInt(tcpDetails.seq); // Sequence Number
+ buf.putInt(tcpDetails.ack); // ACK
+ buf.putShort((short) 0x5010); // TCP length=5, flags=ACK
+ buf.putShort((short) (tcpDetails.rcvWnd >> tcpDetails.rcvWndScale)); // Window size
+ final int tcpChecksumOffset = buf.position();
+ buf.putShort((short) 0); // TCP checksum
+ // URG is not set therefore the urgent pointer is not included
+ buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
+ buf.putShort(tcpChecksumOffset, IpUtils.tcpChecksum(
+ buf, 0, IPV4_HEADER_LENGTH, TCP_HEADER_LENGTH));
+
+ return buf.array();
+ }
+
+ // TODO: add buildV6Packet.
+
+ /** Represents tcp/ip information. */
+ // TODO: Replace TcpSocketInfo with TcpKeepalivePacketDataParcelable.
+ public static class TcpSocketInfo {
+ public final InetAddress srcAddress;
+ public final InetAddress dstAddress;
+ public final int srcPort;
+ public final int dstPort;
+ public final int seq;
+ public final int ack;
+ public final int rcvWnd;
+ public final int rcvWndScale;
+
+ public TcpSocketInfo(InetAddress sAddr, int sPort, InetAddress dAddr,
+ int dPort, int writeSeq, int readSeq, int rWnd, int rWndScale) {
+ srcAddress = sAddr;
+ dstAddress = dAddr;
+ srcPort = sPort;
+ dstPort = dPort;
+ seq = writeSeq;
+ ack = readSeq;
+ rcvWnd = rWnd;
+ rcvWndScale = rWndScale;
+ }
+ }
+
+ @Override
+ public boolean equals(@Nullable final Object o) {
+ if (!(o instanceof TcpKeepalivePacketData)) return false;
+ final TcpKeepalivePacketData other = (TcpKeepalivePacketData) o;
+ return this.srcAddress.equals(other.srcAddress)
+ && this.dstAddress.equals(other.dstAddress)
+ && this.srcPort == other.srcPort
+ && this.dstPort == other.dstPort
+ && this.tcpAck == other.tcpAck
+ && this.tcpSeq == other.tcpSeq
+ && this.tcpWnd == other.tcpWnd
+ && this.tcpWndScale == other.tcpWndScale;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(srcAddress, dstAddress, srcPort, dstPort, tcpAck, tcpSeq, tcpWnd,
+ tcpWndScale);
+ }
+
+ /* Parcelable Implementation. */
+ /* Note that this object implements parcelable (and needs to keep doing this as it inherits
+ * from a class that does), but should usually be parceled as a stable parcelable using
+ * the toStableParcelable() and fromStableParcelable() methods.
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Write to parcel. */
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(tcpSeq);
+ out.writeInt(tcpAck);
+ out.writeInt(tcpWnd);
+ out.writeInt(tcpWndScale);
+ }
+
+ private TcpKeepalivePacketData(Parcel in) {
+ super(in);
+ tcpSeq = in.readInt();
+ tcpAck = in.readInt();
+ tcpWnd = in.readInt();
+ tcpWndScale = in.readInt();
+ }
+
+ /** Parcelable Creator. */
+ public static final Parcelable.Creator<TcpKeepalivePacketData> CREATOR =
+ new Parcelable.Creator<TcpKeepalivePacketData>() {
+ public TcpKeepalivePacketData createFromParcel(Parcel in) {
+ return new TcpKeepalivePacketData(in);
+ }
+
+ public TcpKeepalivePacketData[] newArray(int size) {
+ return new TcpKeepalivePacketData[size];
+ }
+ };
+
+ /**
+ * Convert this TcpKeepalivePacketData to a TcpKeepalivePacketDataParcelable.
+ */
+ @NonNull
+ public TcpKeepalivePacketDataParcelable toStableParcelable() {
+ final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable();
+ parcel.srcAddress = srcAddress.getAddress();
+ parcel.srcPort = srcPort;
+ parcel.dstAddress = dstAddress.getAddress();
+ parcel.dstPort = dstPort;
+ parcel.seq = tcpSeq;
+ parcel.ack = tcpAck;
+ return parcel;
+ }
+
+ @Override
+ public String toString() {
+ return "saddr: " + srcAddress
+ + " daddr: " + dstAddress
+ + " sport: " + srcPort
+ + " dport: " + dstPort
+ + " seq: " + tcpSeq
+ + " ack: " + tcpAck
+ + " wnd: " + tcpWnd
+ + " wndScale: " + tcpWndScale;
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsPart.java b/core/java/android/net/TcpKeepalivePacketDataParcelable.aidl
similarity index 74%
rename from telephony/java/android/telephony/ims/RcsPart.java
rename to core/java/android/net/TcpKeepalivePacketDataParcelable.aidl
index da50173..7329c63 100644
--- a/telephony/java/android/telephony/ims/RcsPart.java
+++ b/core/java/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.telephony.ims;
-import android.os.Parcelable;
+package android.net;
-/**
- * A part of a composite {@link RcsMessage}.
- * @hide - TODO(sahinc) make this public
- */
-public abstract class RcsPart implements Parcelable {
+parcelable TcpKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+ int seq;
+ int ack;
}
diff --git a/core/java/android/net/TcpRepairWindow.java b/core/java/android/net/TcpRepairWindow.java
new file mode 100644
index 0000000..86034f0
--- /dev/null
+++ b/core/java/android/net/TcpRepairWindow.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+/**
+ * Corresponds to C's {@code struct tcp_repair_window} from
+ * include/uapi/linux/tcp.h
+ *
+ * @hide
+ */
+public final class TcpRepairWindow {
+ public final int sndWl1;
+ public final int sndWnd;
+ public final int maxWindow;
+ public final int rcvWnd;
+ public final int rcvWup;
+ public final int rcvWndScale;
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public TcpRepairWindow(final int sndWl1, final int sndWnd, final int maxWindow,
+ final int rcvWnd, final int rcvWup, final int rcvWndScale) {
+ this.sndWl1 = sndWl1;
+ this.sndWnd = sndWnd;
+ this.maxWindow = maxWindow;
+ this.rcvWnd = rcvWnd;
+ this.rcvWup = rcvWup;
+ this.rcvWndScale = rcvWndScale;
+ }
+}
diff --git a/core/java/android/net/TcpSocketKeepalive.java b/core/java/android/net/TcpSocketKeepalive.java
new file mode 100644
index 0000000..8f6ee7b
--- /dev/null
+++ b/core/java/android/net/TcpSocketKeepalive.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.net.Socket;
+import java.util.concurrent.Executor;
+
+/** @hide */
+final class TcpSocketKeepalive extends SocketKeepalive {
+
+ private final Socket mSocket;
+
+ TcpSocketKeepalive(@NonNull IConnectivityManager service,
+ @NonNull Network network,
+ @NonNull Socket socket,
+ @NonNull Executor executor,
+ @NonNull Callback callback) {
+ super(service, network, executor, callback);
+ mSocket = socket;
+ }
+
+ /**
+ * Starts keepalives. {@code mSocket} must be a connected TCP socket.
+ *
+ * - The application must not write to or read from the socket after calling this method, until
+ * onDataReceived, onStopped, or onError are called. If it does, the keepalive will fail
+ * with {@link #ERROR_SOCKET_NOT_IDLE}, or {@code #ERROR_INVALID_SOCKET} if the socket
+ * experienced an error (as in poll(2) returned POLLERR); if this happens, the data received
+ * from the socket may be invalid, and the socket can't be recovered.
+ * - If the socket has data in the send or receive buffer, then this call will fail with
+ * {@link #ERROR_SOCKET_NOT_IDLE} and can be retried after the data has been processed.
+ * An app could ensure this by using an application-layer protocol where it can receive
+ * acknowledgement that it will go into keepalive mode. It could then go into keepalive
+ * mode after having read the acknowledgement, draining the socket.
+ */
+ @Override
+ void startImpl(int intervalSec) {
+ try {
+ final FileDescriptor fd = mSocket.getFileDescriptor$();
+ mService.startTcpKeepalive(mNetwork, fd, intervalSec, mMessenger, new Binder());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error starting packet keepalive: ", e);
+ stopLooper();
+ }
+ }
+
+ @Override
+ void stopImpl() {
+ try {
+ if (mSlot != null) {
+ mService.stopKeepalive(mNetwork, mSlot);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error stopping packet keepalive: ", e);
+ stopLooper();
+ }
+ }
+}
diff --git a/core/java/android/net/ip/IIpClient.aidl b/core/java/android/net/ip/IIpClient.aidl
index 7769ec2..a4a80e1 100644
--- a/core/java/android/net/ip/IIpClient.aidl
+++ b/core/java/android/net/ip/IIpClient.aidl
@@ -17,6 +17,7 @@
import android.net.ProxyInfoParcelable;
import android.net.ProvisioningConfigurationParcelable;
+import android.net.TcpKeepalivePacketDataParcelable;
/** @hide */
oneway interface IIpClient {
@@ -29,4 +30,6 @@
void setTcpBufferSizes(in String tcpBufferSizes);
void setHttpProxy(in ProxyInfoParcelable proxyInfo);
void setMulticastFilter(boolean enabled);
+ void addKeepalivePacketFilter(int slot, in TcpKeepalivePacketDataParcelable pkt);
+ void removeKeepalivePacketFilter(int slot);
}
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 141d33b..1f33693 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -19,6 +19,7 @@
import android.annotation.MainThread;
import android.annotation.Nullable;
import android.annotation.WorkerThread;
+
import java.util.ArrayDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
@@ -70,7 +71,7 @@
* protected Long doInBackground(URL... urls) {
* int count = urls.length;
* long totalSize = 0;
- * for (int i = 0; i < count; i++) {
+ * for (int i = 0; i < count; i++) {
* totalSize += Downloader.downloadFile(urls[i]);
* publishProgress((int) ((i / (float) count) * 100));
* // Escape early if cancel() is called
@@ -158,13 +159,22 @@
* </ul>
*
* <h2>Memory observability</h2>
- * <p>AsyncTask guarantees that all callback calls are synchronized in such a way that the following
- * operations are safe without explicit synchronizations.</p>
+ * <p>AsyncTask guarantees that all callback calls are synchronized to ensure the following
+ * without explicit synchronizations.</p>
* <ul>
- * <li>Set member fields in the constructor or {@link #onPreExecute}, and refer to them
- * in {@link #doInBackground}.
- * <li>Set member fields in {@link #doInBackground}, and refer to them in
- * {@link #onProgressUpdate} and {@link #onPostExecute}.
+ * <li>The memory effects of {@link #onPreExecute}, and anything else
+ * executed before the call to {@link #execute}, including the construction
+ * of the AsyncTask object, are visible to {@link #doInBackground}.
+ * <li>The memory effects of {@link #doInBackground} are visible to
+ * {@link #onPostExecute}.
+ * <li>Any memory effects of {@link #doInBackground} preceding a call
+ * to {@link #publishProgress} are visible to the corresponding
+ * {@link #onProgressUpdate} call. (But {@link #doInBackground} continues to
+ * run, and care needs to be taken that later updates in {@link #doInBackground}
+ * do not interfere with an in-progress {@link #onProgressUpdate} call.)
+ * <li>Any memory effects preceding a call to {@link #cancel} are visible
+ * after a call to {@link #isCancelled} that returns true as a result, or
+ * during and after a resulting call to {@link #onCancelled}.
* </ul>
*
* <h2>Order of execution</h2>
@@ -388,6 +398,10 @@
* specified parameters are the parameters passed to {@link #execute}
* by the caller of this task.
*
+ * This will normally run on a background thread. But to better
+ * support testing frameworks, it is recommended that this also tolerates
+ * direct execution on the foreground thread, as part of the {@link #execute} call.
+ *
* This method can call {@link #publishProgress} to publish updates
* on the UI thread.
*
@@ -404,6 +418,8 @@
/**
* Runs on the UI thread before {@link #doInBackground}.
+ * Invoked directly by {@link #execute} or {@link #executeOnExecutor}.
+ * The default version does nothing.
*
* @see #onPostExecute
* @see #doInBackground
@@ -414,7 +430,10 @@
/**
* <p>Runs on the UI thread after {@link #doInBackground}. The
- * specified result is the value returned by {@link #doInBackground}.</p>
+ * specified result is the value returned by {@link #doInBackground}.
+ * To better support testing frameworks, it is recommended that this be
+ * written to tolerate direct execution as part of the execute() call.
+ * The default version does nothing.</p>
*
* <p>This method won't be invoked if the task was cancelled.</p>
*
@@ -432,6 +451,7 @@
/**
* Runs on the UI thread after {@link #publishProgress} is invoked.
* The specified values are the values passed to {@link #publishProgress}.
+ * The default version does nothing.
*
* @param values The values indicating progress.
*
@@ -466,7 +486,8 @@
/**
* <p>Applications should preferably override {@link #onCancelled(Object)}.
* This method is invoked by the default implementation of
- * {@link #onCancelled(Object)}.</p>
+ * {@link #onCancelled(Object)}.
+ * The default version does nothing.</p>
*
* <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
* {@link #doInBackground(Object[])} has finished.</p>
@@ -504,12 +525,16 @@
* an attempt to stop the task.</p>
*
* <p>Calling this method will result in {@link #onCancelled(Object)} being
- * invoked on the UI thread after {@link #doInBackground(Object[])}
- * returns. Calling this method guarantees that {@link #onPostExecute(Object)}
- * is never invoked. After invoking this method, you should check the
- * value returned by {@link #isCancelled()} periodically from
- * {@link #doInBackground(Object[])} to finish the task as early as
- * possible.</p>
+ * invoked on the UI thread after {@link #doInBackground(Object[])} returns.
+ * Calling this method guarantees that onPostExecute(Object) is never
+ * subsequently invoked, even if <tt>cancel</tt> returns false, but
+ * {@link #onPostExecute} has not yet run. To finish the
+ * task as early as possible, check {@link #isCancelled()} periodically from
+ * {@link #doInBackground(Object[])}.</p>
+ *
+ * <p>This only requests cancellation. It never waits for a running
+ * background task to terminate, even if <tt>mayInterruptIfRunning</tt> is
+ * true.</p>
*
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java
index b6e2b69..a107a7a 100644
--- a/core/java/android/os/BatterySaverPolicyConfig.java
+++ b/core/java/android/os/BatterySaverPolicyConfig.java
@@ -47,10 +47,11 @@
private final boolean mEnableAdjustBrightness;
private final boolean mEnableDataSaver;
private final boolean mEnableFirewall;
+ private final boolean mEnableNightMode;
private final boolean mEnableQuickDoze;
private final boolean mForceAllAppsStandby;
private final boolean mForceBackgroundCheck;
- private final int mGpsMode;
+ private final int mLocationMode;
private BatterySaverPolicyConfig(Builder in) {
mAdjustBrightnessFactor = Math.max(0, Math.min(in.mAdjustBrightnessFactor, 1f));
@@ -67,11 +68,12 @@
mEnableAdjustBrightness = in.mEnableAdjustBrightness;
mEnableDataSaver = in.mEnableDataSaver;
mEnableFirewall = in.mEnableFirewall;
+ mEnableNightMode = in.mEnableNightMode;
mEnableQuickDoze = in.mEnableQuickDoze;
mForceAllAppsStandby = in.mForceAllAppsStandby;
mForceBackgroundCheck = in.mForceBackgroundCheck;
- mGpsMode = Math.max(PowerManager.MIN_LOCATION_MODE,
- Math.min(in.mGpsMode, PowerManager.MAX_LOCATION_MODE));
+ mLocationMode = Math.max(PowerManager.MIN_LOCATION_MODE,
+ Math.min(in.mLocationMode, PowerManager.MAX_LOCATION_MODE));
}
private BatterySaverPolicyConfig(Parcel in) {
@@ -101,10 +103,11 @@
mEnableAdjustBrightness = in.readBoolean();
mEnableDataSaver = in.readBoolean();
mEnableFirewall = in.readBoolean();
+ mEnableNightMode = in.readBoolean();
mEnableQuickDoze = in.readBoolean();
mForceAllAppsStandby = in.readBoolean();
mForceBackgroundCheck = in.readBoolean();
- mGpsMode = Math.max(PowerManager.MIN_LOCATION_MODE,
+ mLocationMode = Math.max(PowerManager.MIN_LOCATION_MODE,
Math.min(in.readInt(), PowerManager.MAX_LOCATION_MODE));
}
@@ -150,10 +153,11 @@
dest.writeBoolean(mEnableAdjustBrightness);
dest.writeBoolean(mEnableDataSaver);
dest.writeBoolean(mEnableFirewall);
+ dest.writeBoolean(mEnableNightMode);
dest.writeBoolean(mEnableQuickDoze);
dest.writeBoolean(mForceAllAppsStandby);
dest.writeBoolean(mForceBackgroundCheck);
- dest.writeInt(mGpsMode);
+ dest.writeInt(mLocationMode);
}
@Override
@@ -168,11 +172,12 @@
+ "animation_disabled=" + mDisableAnimation + ","
+ "aod_disabled=" + mDisableAod + ","
+ "datasaver_disabled=" + !mEnableDataSaver + ","
+ + "enable_night_mode=" + mEnableNightMode + ","
+ "firewall_disabled=" + !mEnableFirewall + ","
+ "force_all_apps_standby=" + mForceAllAppsStandby + ","
+ "force_background_check=" + mForceBackgroundCheck + ","
+ "fullbackup_deferred=" + mDeferFullBackup + ","
- + "gps_mode=" + mGpsMode + ","
+ + "gps_mode=" + mLocationMode + ","
+ "keyvaluebackup_deferred=" + mDeferKeyValueBackup + ","
+ "launch_boost_disabled=" + mDisableLaunchBoost + ","
+ "optional_sensors_disabled=" + mDisableOptionalSensors + ","
@@ -260,6 +265,11 @@
return mEnableFirewall;
}
+ /** Whether or not to enable night mode while in Battery Saver. */
+ public boolean getEnableNightMode() {
+ return mEnableNightMode;
+ }
+
/** Whether or not to enable Quick Doze while in Battery Saver. */
public boolean getEnableQuickDoze() {
return mEnableQuickDoze;
@@ -275,9 +285,9 @@
return mForceBackgroundCheck;
}
- /** The GPS mode while in Battery Saver. */
- public int getGpsMode() {
- return mGpsMode;
+ /** The location mode while in Battery Saver. */
+ public int getLocationMode() {
+ return mLocationMode;
}
/** Builder class for constructing {@link BatterySaverPolicyConfig} objects. */
@@ -297,10 +307,11 @@
private boolean mEnableAdjustBrightness = false;
private boolean mEnableDataSaver = false;
private boolean mEnableFirewall = false;
+ private boolean mEnableNightMode = false;
private boolean mEnableQuickDoze = false;
private boolean mForceAllAppsStandby = false;
private boolean mForceBackgroundCheck = false;
- private int mGpsMode = PowerManager.LOCATION_MODE_NO_CHANGE;
+ private int mLocationMode = PowerManager.LOCATION_MODE_NO_CHANGE;
public Builder() {
}
@@ -424,6 +435,13 @@
return this;
}
+ /** Set whether or not to enable night mode while in Battery Saver. */
+ @NonNull
+ public Builder setEnableNightMode(boolean enableNightMode) {
+ mEnableNightMode = enableNightMode;
+ return this;
+ }
+
/** Set whether or not to enable Quick Doze while in Battery Saver. */
@NonNull
public Builder setEnableQuickDoze(boolean enableQuickDoze) {
@@ -445,10 +463,10 @@
return this;
}
- /** Set the GPS mode while in Battery Saver. */
+ /** Set the location mode while in Battery Saver. */
@NonNull
- public Builder setGpsMode(@PowerManager.LocationPowerSaveMode int gpsMode) {
- mGpsMode = gpsMode;
+ public Builder setLocationMode(@PowerManager.LocationPowerSaveMode int locationMode) {
+ mLocationMode = locationMode;
return this;
}
diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java
index 3a5b8a8..27f7e22 100644
--- a/core/java/android/os/BugreportManager.java
+++ b/core/java/android/os/BugreportManager.java
@@ -24,7 +24,8 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
-import android.os.IBinder.DeathRecipient;
+
+import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
import java.lang.annotation.Retention;
@@ -127,13 +128,16 @@
@NonNull BugreportParams params,
@NonNull @CallbackExecutor Executor executor,
@NonNull BugreportCallback callback) {
- // TODO(b/111441001): Enforce android.Manifest.permission.DUMP if necessary.
+ Preconditions.checkNotNull(bugreportFd);
+ Preconditions.checkNotNull(params);
+ Preconditions.checkNotNull(executor);
+ Preconditions.checkNotNull(callback);
DumpstateListener dsListener = new DumpstateListener(executor, callback);
try {
// Note: mBinder can get callingUid from the binder transaction.
mBinder.startBugreport(-1 /* callingUid */,
mContext.getOpPackageName(),
- (bugreportFd != null ? bugreportFd.getFileDescriptor() : new FileDescriptor()),
+ bugreportFd.getFileDescriptor(),
(screenshotFd != null
? screenshotFd.getFileDescriptor() : new FileDescriptor()),
params.getMode(), dsListener);
@@ -154,8 +158,7 @@
}
}
- private final class DumpstateListener extends IDumpstateListener.Stub
- implements DeathRecipient {
+ private final class DumpstateListener extends IDumpstateListener.Stub {
private final Executor mExecutor;
private final BugreportCallback mCallback;
@@ -165,11 +168,6 @@
}
@Override
- public void binderDied() {
- // TODO(b/111441001): implement
- }
-
- @Override
public void onProgress(int progress) throws RemoteException {
final long identity = Binder.clearCallingIdentity();
try {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 2d61a4e..83a7654 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1120,11 +1120,9 @@
/** The name identifying the system partition. */
public static final String PARTITION_NAME_SYSTEM = "system";
- private String mName;
- private String mFingerprint;
- private long mTimeMs;
-
- public Partition() {}
+ private final String mName;
+ private final String mFingerprint;
+ private final long mTimeMs;
private Partition(String name, String fingerprint, long timeMs) {
mName = name;
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index ddec688..68f9288 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -103,7 +103,7 @@
* Return the debug layer app's on-disk and in-APK lib directories
*/
private static String getDebugLayerAppPaths(Context context, String app) {
- ApplicationInfo appInfo;
+ final ApplicationInfo appInfo;
try {
appInfo = context.getPackageManager().getApplicationInfo(
app, PackageManager.MATCH_ALL);
@@ -113,15 +113,15 @@
return null;
}
- String abi = chooseAbi(appInfo);
+ final String abi = chooseAbi(appInfo);
- StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
sb.append(appInfo.nativeLibraryDir)
.append(File.pathSeparator);
sb.append(appInfo.sourceDir)
.append("!/lib/")
.append(abi);
- String paths = sb.toString();
+ final String paths = sb.toString();
if (DEBUG) Log.v(TAG, "Debug layer app libs: " + paths);
@@ -143,13 +143,13 @@
if (isDebuggable(context) || (getCanLoadSystemLibraries() == 1)) {
- int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
+ final int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
if (enable != 0) {
- String gpuDebugApp = coreSettings.getString(Settings.Global.GPU_DEBUG_APP);
+ final String gpuDebugApp = coreSettings.getString(Settings.Global.GPU_DEBUG_APP);
- String packageName = context.getPackageName();
+ final String packageName = context.getPackageName();
if ((gpuDebugApp != null && packageName != null)
&& (!gpuDebugApp.isEmpty() && !packageName.isEmpty())
@@ -163,12 +163,12 @@
// If there is a debug layer app specified, add its path.
- String gpuDebugLayerApp =
+ final String gpuDebugLayerApp =
coreSettings.getString(Settings.Global.GPU_DEBUG_LAYER_APP);
if (gpuDebugLayerApp != null && !gpuDebugLayerApp.isEmpty()) {
Log.i(TAG, "GPU debug layer app: " + gpuDebugLayerApp);
- String paths = getDebugLayerAppPaths(context, gpuDebugLayerApp);
+ final String paths = getDebugLayerAppPaths(context, gpuDebugLayerApp);
if (paths != null) {
// Append the path so files placed in the app's base directory will
// override the external path
@@ -176,14 +176,14 @@
}
}
- String layers = coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS);
+ final String layers = coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS);
Log.i(TAG, "Vulkan debug layer list: " + layers);
if (layers != null && !layers.isEmpty()) {
setDebugLayers(layers);
}
- String layersGLES =
+ final String layersGLES =
coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS_GLES);
Log.i(TAG, "GLES debug layer list: " + layersGLES);
@@ -208,7 +208,7 @@
private static final Map<OpenGlDriverChoice, String> sDriverMap = buildMap();
private static Map<OpenGlDriverChoice, String> buildMap() {
- Map<OpenGlDriverChoice, String> map = new HashMap<>();
+ final Map<OpenGlDriverChoice, String> map = new HashMap<>();
map.put(OpenGlDriverChoice.DEFAULT, "default");
map.put(OpenGlDriverChoice.ANGLE, "angle");
map.put(OpenGlDriverChoice.NATIVE, "native");
@@ -219,7 +219,7 @@
private static List<String> getGlobalSettingsString(Bundle bundle, String globalSetting) {
List<String> valueList = null;
- String settingsValue = bundle.getString(globalSetting);
+ final String settingsValue = bundle.getString(globalSetting);
if (settingsValue != null) {
valueList = new ArrayList<>(Arrays.asList(settingsValue.split(",")));
@@ -242,18 +242,16 @@
}
private static String getDriverForPkg(Bundle bundle, String packageName) {
- String allUseAngle =
+ final String allUseAngle =
bundle.getString(Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE);
if ((allUseAngle != null) && allUseAngle.equals("1")) {
return sDriverMap.get(OpenGlDriverChoice.ANGLE);
}
- List<String> globalSettingsDriverPkgs =
- getGlobalSettingsString(bundle,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS);
- List<String> globalSettingsDriverValues =
- getGlobalSettingsString(bundle,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES);
+ final List<String> globalSettingsDriverPkgs = getGlobalSettingsString(
+ bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS);
+ final List<String> globalSettingsDriverValues = getGlobalSettingsString(
+ bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES);
// Make sure we have a good package name
if ((packageName == null) || (packageName.isEmpty())) {
@@ -270,7 +268,7 @@
return sDriverMap.get(OpenGlDriverChoice.DEFAULT);
}
- int pkgIndex = getGlobalSettingsPkgIndex(packageName, globalSettingsDriverPkgs);
+ final int pkgIndex = getGlobalSettingsPkgIndex(packageName, globalSettingsDriverPkgs);
if (pkgIndex < 0) {
return sDriverMap.get(OpenGlDriverChoice.DEFAULT);
@@ -283,10 +281,10 @@
* Get the ANGLE package name.
*/
private String getAnglePackageName(Context context) {
- Intent intent = new Intent(ACTION_ANGLE_FOR_ANDROID);
+ final Intent intent = new Intent(ACTION_ANGLE_FOR_ANDROID);
- List<ResolveInfo> resolveInfos = context.getPackageManager()
- .queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
+ final List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(
+ intent, PackageManager.MATCH_SYSTEM_ONLY);
if (resolveInfos.size() != 1) {
Log.e(TAG, "Invalid number of ANGLE packages. Required: 1, Found: "
+ resolveInfos.size());
@@ -315,8 +313,8 @@
* - devices that are running a userdebug build (ro.debuggable) or can inject libraries for
* debugging (PR_SET_DUMPABLE).
*/
- boolean appIsDebuggable = isDebuggable(context);
- boolean deviceIsDebuggable = getCanLoadSystemLibraries() == 1;
+ final boolean appIsDebuggable = isDebuggable(context);
+ final boolean deviceIsDebuggable = getCanLoadSystemLibraries() == 1;
if (!(appIsDebuggable || deviceIsDebuggable)) {
Log.v(TAG, "Skipping loading temporary rules file: "
+ "appIsDebuggable = " + appIsDebuggable + ", "
@@ -324,7 +322,7 @@
return false;
}
- String angleTempRules = SystemProperties.get(ANGLE_TEMP_RULES);
+ final String angleTempRules = SystemProperties.get(ANGLE_TEMP_RULES);
if ((angleTempRules == null) || angleTempRules.isEmpty()) {
Log.v(TAG, "System property '" + ANGLE_TEMP_RULES + "' is not set or is empty");
@@ -333,16 +331,16 @@
Log.i(TAG, "Detected system property " + ANGLE_TEMP_RULES + ": " + angleTempRules);
- File tempRulesFile = new File(angleTempRules);
+ final File tempRulesFile = new File(angleTempRules);
if (tempRulesFile.exists()) {
Log.i(TAG, angleTempRules + " exists, loading file.");
try {
- FileInputStream stream = new FileInputStream(angleTempRules);
+ final FileInputStream stream = new FileInputStream(angleTempRules);
try {
- FileDescriptor rulesFd = stream.getFD();
- long rulesOffset = 0;
- long rulesLength = stream.getChannel().size();
+ final FileDescriptor rulesFd = stream.getFD();
+ final long rulesOffset = 0;
+ final long rulesLength = stream.getChannel().size();
Log.i(TAG, "Loaded temporary ANGLE rules from " + angleTempRules);
setAngleInfo(paths, packageName, devOptIn, rulesFd, rulesOffset, rulesLength);
@@ -377,11 +375,11 @@
String devOptIn) {
// Pass the rules file to loader for ANGLE decisions
try {
- AssetManager angleAssets =
+ final AssetManager angleAssets =
context.getPackageManager().getResourcesForApplication(angleInfo).getAssets();
try {
- AssetFileDescriptor assetsFd = angleAssets.openFd(ANGLE_RULES_FILE);
+ final AssetFileDescriptor assetsFd = angleAssets.openFd(ANGLE_RULES_FILE);
setAngleInfo(paths, packageName, devOptIn, assetsFd.getFileDescriptor(),
assetsFd.getStartOffset(), assetsFd.getLength());
@@ -404,9 +402,8 @@
* Pull ANGLE whitelist from GlobalSettings and compare against current package
*/
private boolean checkAngleWhitelist(Bundle bundle, String packageName) {
- List<String> angleWhitelist =
- getGlobalSettingsString(bundle,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST);
+ final List<String> angleWhitelist =
+ getGlobalSettingsString(bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST);
return angleWhitelist.contains(packageName);
}
@@ -420,7 +417,7 @@
return;
}
- String devOptIn = getDriverForPkg(bundle, packageName);
+ final String devOptIn = getDriverForPkg(bundle, packageName);
if (DEBUG) {
Log.v(TAG, "ANGLE Developer option for '" + packageName + "' "
+ "set to: '" + devOptIn + "'");
@@ -438,9 +435,9 @@
// load a driver, GraphicsEnv::shouldUseAngle() has seen the package name before
// and can confidently answer yes/no based on the previously set developer
// option value.
- boolean whitelisted = checkAngleWhitelist(bundle, packageName);
- boolean defaulted = devOptIn.equals(sDriverMap.get(OpenGlDriverChoice.DEFAULT));
- boolean rulesCheck = (whitelisted || !defaulted);
+ final boolean whitelisted = checkAngleWhitelist(bundle, packageName);
+ final boolean defaulted = devOptIn.equals(sDriverMap.get(OpenGlDriverChoice.DEFAULT));
+ final boolean rulesCheck = (whitelisted || !defaulted);
if (!rulesCheck) {
return;
}
@@ -452,13 +449,13 @@
Log.v(TAG, "ANGLE developer option for " + packageName + ": " + devOptIn);
}
- String anglePkgName = getAnglePackageName(context);
+ final String anglePkgName = getAnglePackageName(context);
if (anglePkgName.isEmpty()) {
Log.e(TAG, "Failed to find ANGLE package.");
return;
}
- ApplicationInfo angleInfo;
+ final ApplicationInfo angleInfo;
try {
angleInfo = context.getPackageManager().getApplicationInfo(anglePkgName,
PackageManager.MATCH_SYSTEM_ONLY);
@@ -467,10 +464,10 @@
return;
}
- String abi = chooseAbi(angleInfo);
+ final String abi = chooseAbi(angleInfo);
// Build a path that includes installed native libs and APK
- String paths = angleInfo.nativeLibraryDir
+ final String paths = angleInfo.nativeLibraryDir
+ File.pathSeparator
+ angleInfo.sourceDir
+ "!/lib/"
@@ -493,12 +490,12 @@
* Choose whether the current process should use the builtin or an updated driver.
*/
private static void chooseDriver(Context context, Bundle coreSettings) {
- String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
+ final String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
if (driverPackageName == null || driverPackageName.isEmpty()) {
return;
}
- ApplicationInfo driverInfo;
+ final ApplicationInfo driverInfo;
try {
driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName,
PackageManager.MATCH_SYSTEM_ONLY);
@@ -519,7 +516,7 @@
// To minimize risk of driver updates crippling the device beyond user repair, never use an
// updated driver for privileged or non-updated system apps. Presumably pre-installed apps
// were tested thoroughly with the pre-installed driver.
- ApplicationInfo ai = context.getApplicationInfo();
+ final ApplicationInfo ai = context.getApplicationInfo();
if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
return;
@@ -529,7 +526,7 @@
// 0: Default (Invalid values fallback to default as well)
// 1: All apps use Game Driver
// 2: All apps use system graphics driver
- int gameDriverAllApps = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
+ final int gameDriverAllApps = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
if (gameDriverAllApps == 2) {
if (DEBUG) {
Log.w(TAG, "Game Driver is turned off on this device");
@@ -546,7 +543,7 @@
}
return;
}
- boolean isOptIn =
+ final boolean isOptIn =
getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
.contains(ai.packageName);
if (!isOptIn
@@ -563,13 +560,13 @@
// on the blacklist, terminate early when it's on the blacklist.
try {
// TODO(b/121350991) Switch to DeviceConfig with property listener.
- String base64String =
+ final String base64String =
coreSettings.getString(Settings.Global.GAME_DRIVER_BLACKLIST);
if (base64String != null && !base64String.isEmpty()) {
- Blacklists blacklistsProto = Blacklists.parseFrom(
- Base64.decode(base64String, BASE64_FLAGS));
- List<Blacklist> blacklists = blacklistsProto.getBlacklistsList();
- long driverVersionCode = driverInfo.longVersionCode;
+ final Blacklists blacklistsProto =
+ Blacklists.parseFrom(Base64.decode(base64String, BASE64_FLAGS));
+ final List<Blacklist> blacklists = blacklistsProto.getBlacklistsList();
+ final long driverVersionCode = driverInfo.longVersionCode;
for (Blacklist blacklist : blacklists) {
if (blacklist.getVersionCode() == driverVersionCode) {
for (String packageName : blacklist.getPackageNamesList()) {
@@ -589,7 +586,7 @@
}
}
- String abi = chooseAbi(driverInfo);
+ final String abi = chooseAbi(driverInfo);
if (abi == null) {
if (DEBUG) {
// This is the normal case for the pre-installed empty driver package, don't spam
@@ -600,13 +597,13 @@
return;
}
- StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
sb.append(driverInfo.nativeLibraryDir)
.append(File.pathSeparator);
sb.append(driverInfo.sourceDir)
.append("!/lib/")
.append(abi);
- String paths = sb.toString();
+ final String paths = sb.toString();
if (DEBUG) Log.v(TAG, "gfx driver package libs: " + paths);
setDriverPath(paths);
@@ -623,7 +620,7 @@
* Should only be called after chooseDriver().
*/
public static void earlyInitEGL() {
- Thread eglInitThread = new Thread(
+ final Thread eglInitThread = new Thread(
() -> {
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
},
@@ -632,7 +629,7 @@
}
private static String chooseAbi(ApplicationInfo ai) {
- String isa = VMRuntime.getCurrentInstructionSet();
+ final String isa = VMRuntime.getCurrentInstructionSet();
if (ai.primaryCpuAbi != null &&
isa.equals(VMRuntime.getInstructionSet(ai.primaryCpuAbi))) {
return ai.primaryCpuAbi;
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index e8704af..e6c12c7 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -469,6 +469,11 @@
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
+ /** @hide */
+ public final boolean postDelayed(Runnable r, int what, long delayMillis) {
+ return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
+ }
+
/**
* Causes the Runnable r to be added to the message queue, to be run
* after the specified amount of time elapses.
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 093897a..bdef575 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -42,7 +42,7 @@
boolean isWakeLockLevelSupported(int level);
void userActivity(long time, int event, int flags);
- void wakeUp(long time, String reason, String opPackageName);
+ void wakeUp(long time, int reason, String details, String opPackageName);
void goToSleep(long time, int reason, int flags);
void nap(long time);
boolean isInteractive();
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 0441ba2..2ecf9d1 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -435,6 +435,106 @@
public static final int GO_TO_SLEEP_FLAG_NO_DOZE = 1 << 0;
/**
+ * @hide
+ */
+ @IntDef(prefix = { "WAKE_REASON_" }, value = {
+ WAKE_REASON_UNKNOWN,
+ WAKE_REASON_POWER_BUTTON,
+ WAKE_REASON_APPLICATION,
+ WAKE_REASON_PLUGGED_IN,
+ WAKE_REASON_GESTURE,
+ WAKE_REASON_CAMERA_LAUNCH,
+ WAKE_REASON_WAKE_KEY,
+ WAKE_REASON_WAKE_MOTION,
+ WAKE_REASON_HDMI,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WakeReason{}
+
+ /**
+ * Wake up reason code: Waking for an unknown reason.
+ * @hide
+ */
+ public static final int WAKE_REASON_UNKNOWN = 0;
+
+ /**
+ * Wake up reason code: Waking up due to power button press.
+ * @hide
+ */
+ public static final int WAKE_REASON_POWER_BUTTON = 1;
+
+ /**
+ * Wake up reason code: Waking up because an application requested it.
+ * @hide
+ */
+ public static final int WAKE_REASON_APPLICATION = 2;
+
+ /**
+ * Wake up reason code: Waking up due to being plugged in or docked on a wireless charger.
+ * @hide
+ */
+ public static final int WAKE_REASON_PLUGGED_IN = 3;
+
+ /**
+ * Wake up reason code: Waking up due to a user performed gesture (e.g. douple tapping on the
+ * screen).
+ * @hide
+ */
+ public static final int WAKE_REASON_GESTURE = 4;
+
+ /**
+ * Wake up reason code: Waking up due to the camera being launched.
+ * @hide
+ */
+ public static final int WAKE_REASON_CAMERA_LAUNCH = 5;
+
+ /**
+ * Wake up reason code: Waking up because a wake key other than power was pressed.
+ * @hide
+ */
+ public static final int WAKE_REASON_WAKE_KEY = 6;
+
+ /**
+ * Wake up reason code: Waking up because a wake motion was performed.
+ *
+ * For example, a trackball that was set to wake the device up was spun.
+ * @hide
+ */
+ public static final int WAKE_REASON_WAKE_MOTION = 7;
+
+ /**
+ * Wake up reason code: Waking due to HDMI.
+ * @hide
+ */
+ public static final int WAKE_REASON_HDMI = 8;
+
+ /**
+ * Wake up reason code: Waking due to the lid being opened.
+ * @hide
+ */
+ public static final int WAKE_REASON_LID = 9;
+
+ /**
+ * Convert the wake reason to a string for debugging purposes.
+ * @hide
+ */
+ public static String wakeReasonToString(@WakeReason int wakeReason) {
+ switch (wakeReason) {
+ case WAKE_REASON_UNKNOWN: return "WAKE_REASON_UNKNOWN";
+ case WAKE_REASON_POWER_BUTTON: return "WAKE_REASON_POWER_BUTTON";
+ case WAKE_REASON_APPLICATION: return "WAKE_REASON_APPLICATION";
+ case WAKE_REASON_PLUGGED_IN: return "WAKE_REASON_PLUGGED_IN";
+ case WAKE_REASON_GESTURE: return "WAKE_REASON_GESTURE";
+ case WAKE_REASON_CAMERA_LAUNCH: return "WAKE_REASON_CAMERA_LAUNCH";
+ case WAKE_REASON_WAKE_KEY: return "WAKE_REASON_WAKE_KEY";
+ case WAKE_REASON_WAKE_MOTION: return "WAKE_REASON_WAKE_MOTION";
+ case WAKE_REASON_HDMI: return "WAKE_REASON_HDMI";
+ case WAKE_REASON_LID: return "WAKE_REASON_LID";
+ default: return Integer.toString(wakeReason);
+ }
+ }
+
+ /**
* The value to pass as the 'reason' argument to reboot() to reboot into
* recovery mode for tasks other than applying system updates, such as
* doing factory resets.
@@ -566,7 +666,7 @@
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({ServiceType.GPS,
+ @IntDef({ServiceType.LOCATION,
ServiceType.VIBRATION,
ServiceType.ANIMATION,
ServiceType.FULL_BACKUP,
@@ -583,7 +683,7 @@
})
public @interface ServiceType {
int NULL = 0;
- int GPS = 1;
+ int LOCATION = 1;
int VIBRATION = 2;
int ANIMATION = 3;
int FULL_BACKUP = 4;
@@ -614,6 +714,11 @@
* Whether to go into Deep Doze as soon as the screen turns off or not.
*/
int QUICK_DOZE = 15;
+
+ /**
+ * Whether to enable night mode when battery saver is enabled.
+ */
+ int NIGHT_MODE = 16;
}
/**
@@ -970,22 +1075,68 @@
* @see #userActivity
* @see #goToSleep
*
+ * @deprecated Use {@link #wakeUp(long, int, String)} instead.
* @removed Requires signature permission.
*/
+ @Deprecated
public void wakeUp(long time) {
- try {
- mService.wakeUp(time, "wakeUp", mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ wakeUp(time, WAKE_REASON_UNKNOWN, "wakeUp");
}
/**
+ * Forces the device to wake up from sleep.
+ * <p>
+ * If the device is currently asleep, wakes it up, otherwise does nothing.
+ * This is what happens when the power key is pressed to turn on the screen.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param time The time when the request to wake up was issued, in the
+ * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+ * order the wake up request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to wake up.
+ *
+ * @param details A free form string to explain the specific details behind the wake up for
+ * debugging purposes.
+ *
+ * @see #userActivity
+ * @see #goToSleep
+ *
+ * @deprecated Use {@link #wakeUp(long, int, String)} instead.
* @hide
*/
- public void wakeUp(long time, String reason) {
+ @Deprecated
+ public void wakeUp(long time, String details) {
+ wakeUp(time, WAKE_REASON_UNKNOWN, details);
+ }
+
+ /**
+ * Forces the device to wake up from sleep.
+ * <p>
+ * If the device is currently asleep, wakes it up, otherwise does nothing.
+ * This is what happens when the power key is pressed to turn on the screen.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param time The time when the request to wake up was issued, in the
+ * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+ * order the wake up request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to wake up.
+ *
+ * @param reason The reason for the wake up.
+ *
+ * @param details A free form string to explain the specific details behind the wake up for
+ * debugging purposes.
+ *
+ * @see #userActivity
+ * @see #goToSleep
+ * @hide
+ */
+ public void wakeUp(long time, @WakeReason int reason, String details) {
try {
- mService.wakeUp(time, reason, mContext.getOpPackageName());
+ mService.wakeUp(time, reason, details, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1400,11 +1551,11 @@
*/
@LocationPowerSaveMode
public int getLocationPowerSaveMode() {
- final PowerSaveState powerSaveState = getPowerSaveState(ServiceType.GPS);
+ final PowerSaveState powerSaveState = getPowerSaveState(ServiceType.LOCATION);
if (!powerSaveState.globalBatterySaverEnabled) {
return LOCATION_MODE_NO_CHANGE;
}
- return powerSaveState.gpsMode;
+ return powerSaveState.locationMode;
}
/**
diff --git a/core/java/android/os/PowerSaveState.java b/core/java/android/os/PowerSaveState.java
index 4918ad1..4a5e894 100644
--- a/core/java/android/os/PowerSaveState.java
+++ b/core/java/android/os/PowerSaveState.java
@@ -19,7 +19,7 @@
* Data class for battery saver state. It contains the data
* <p>
* 1. Whether battery saver mode is enabled
- * 2. Specific parameters to use in battery saver mode(i.e. screen brightness, gps mode)
+ * 2. Specific parameters to use in battery saver mode (i.e. screen brightness, location mode)
*
* @hide
*/
@@ -35,12 +35,12 @@
* {@link PowerManager#isPowerSaveMode()}
*/
public final boolean globalBatterySaverEnabled;
- public final int gpsMode;
+ public final int locationMode;
public final float brightnessFactor;
public PowerSaveState(Builder builder) {
batterySaverEnabled = builder.mBatterySaverEnabled;
- gpsMode = builder.mGpsMode;
+ locationMode = builder.mLocationMode;
brightnessFactor = builder.mBrightnessFactor;
globalBatterySaverEnabled = builder.mGlobalBatterySaverEnabled;
}
@@ -48,7 +48,7 @@
public PowerSaveState(Parcel in) {
batterySaverEnabled = in.readByte() != 0;
globalBatterySaverEnabled = in.readByte() != 0;
- gpsMode = in.readInt();
+ locationMode = in.readInt();
brightnessFactor = in.readFloat();
}
@@ -61,14 +61,14 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (batterySaverEnabled ? 1 : 0));
dest.writeByte((byte) (globalBatterySaverEnabled ? 1 : 0));
- dest.writeInt(gpsMode);
+ dest.writeInt(locationMode);
dest.writeFloat(brightnessFactor);
}
public static final class Builder {
private boolean mBatterySaverEnabled = false;
private boolean mGlobalBatterySaverEnabled = false;
- private int mGpsMode = 0;
+ private int mLocationMode = 0;
private float mBrightnessFactor = 0.5f;
public Builder() {}
@@ -83,8 +83,8 @@
return this;
}
- public Builder setGpsMode(int mode) {
- mGpsMode = mode;
+ public Builder setLocationMode(int mode) {
+ mLocationMode = mode;
return this;
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 0a60764..e2b5730 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -734,10 +734,13 @@
public static final String DISALLOW_SYSTEM_ERROR_DIALOGS = "no_system_error_dialogs";
/**
- * Specifies if what is copied in the clipboard of this profile can
- * be pasted in related profiles. Does not restrict if the clipboard of related profiles can be
- * pasted in this profile.
- * The default value is <code>false</code>.
+ * Specifies if the clipboard contents can be exported by pasting the data into other users or
+ * profiles. This restriction doesn't prevent import, such as someone pasting clipboard data
+ * from other profiles or users. The default value is {@code false}.
+ *
+ * <p><strong>Note</strong>: Because it's possible to extract data from screenshots using
+ * optical character recognition (OCR), we strongly recommend combining this user restriction
+ * with {@link DevicePolicyManager#setScreenCaptureDisabled(ComponentName, boolean)}.
*
* <p>Key for user restrictions.
* <p>Type: Boolean
diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl
index ee6744b..7e9ba5d 100644
--- a/core/java/android/permission/IPermissionController.aidl
+++ b/core/java/android/permission/IPermissionController.aidl
@@ -30,6 +30,9 @@
void revokeRuntimePermissions(in Bundle request, boolean doDryRun, int reason,
String callerPackageName, in RemoteCallback callback);
void getRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe);
+ void restoreRuntimePermissionBackup(in UserHandle user, in ParcelFileDescriptor pipe);
+ void restoreDelayedRuntimePermissionBackup(String packageName, in UserHandle user,
+ in RemoteCallback callback);
void getAppPermissions(String packageName, in RemoteCallback callback);
void revokeRuntimePermission(String packageName, String permissionName);
void countPermissionApps(in List<String> permissionNames, int flags,
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index c59e573..89967c3 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -24,6 +24,8 @@
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.internal.util.Preconditions.checkStringNotEmpty;
+import static java.lang.Math.min;
+
import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
@@ -60,6 +62,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -278,6 +281,49 @@
}
/**
+ * Restore a backup of the runtime permissions.
+ *
+ * @param backup the backup to restore. The backup is sent asynchronously, hence it should not
+ * be modified after calling this method.
+ * @param user The user to be restore
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
+ public void restoreRuntimePermissionBackup(@NonNull byte[] backup, @NonNull UserHandle user) {
+ checkNotNull(backup);
+ checkNotNull(user);
+
+ sRemoteService.scheduleAsyncRequest(
+ new PendingRestoreRuntimePermissionBackup(sRemoteService, backup, user));
+ }
+
+ /**
+ * Restore a backup of the runtime permissions that has been delayed.
+ *
+ * @param packageName The package that is ready to have it's permissions restored.
+ * @param user The user to restore
+ * @param executor Executor to execute the callback on
+ * @param callback Is called with {@code true} iff there is still more delayed backup left
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
+ public void restoreDelayedRuntimePermissionBackup(@NonNull String packageName,
+ @NonNull UserHandle user,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<Boolean> callback) {
+ checkNotNull(packageName);
+ checkNotNull(user);
+ checkNotNull(executor);
+ checkNotNull(callback);
+
+ sRemoteService.scheduleRequest(
+ new PendingRestoreDelayedRuntimePermissionBackup(sRemoteService, packageName,
+ user, executor, callback));
+ }
+
+ /**
* Gets the runtime permissions for an app.
*
* @param packageName The package for which to query.
@@ -520,6 +566,80 @@
}
/**
+ * Task to send a large amount of data to a remote service.
+ */
+ private static class FileWriterTask extends AsyncTask<byte[], Void, Void> {
+ private static final int CHUNK_SIZE = 4 * 1024;
+
+ private ParcelFileDescriptor mLocalPipe;
+ private ParcelFileDescriptor mRemotePipe;
+
+ @Override
+ protected void onPreExecute() {
+ ParcelFileDescriptor[] pipe;
+ try {
+ pipe = ParcelFileDescriptor.createPipe();
+ } catch (IOException e) {
+ Log.e(TAG, "Could not create pipe needed to send runtime permission backup",
+ e);
+ return;
+ }
+
+ mRemotePipe = pipe[0];
+ mLocalPipe = pipe[1];
+ }
+
+ /**
+ * Get the file descriptor the remote service should read the data from.
+ *
+ * @return The file the data should be read from
+ */
+ ParcelFileDescriptor getRemotePipe() {
+ return mRemotePipe;
+ }
+
+ /**
+ * Send the data to the remove service.
+ *
+ * @param in The data to send
+ *
+ * @return ignored
+ */
+ @Override
+ protected Void doInBackground(byte[]... in) {
+ byte[] buffer = in[0];
+ try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(mLocalPipe)) {
+ for (int offset = 0; offset < buffer.length; offset += CHUNK_SIZE) {
+ out.write(buffer, offset, min(CHUNK_SIZE, buffer.length - offset));
+ }
+ } catch (IOException | NullPointerException e) {
+ Log.e(TAG, "Error sending runtime permission backup", e);
+ }
+
+ return null;
+ }
+
+ /**
+ * Interrupt the send of the data.
+ *
+ * <p>Needs to be called when canceling this task as it might be hung.
+ */
+ void interruptRead() {
+ IoUtils.closeQuietly(mLocalPipe);
+ }
+
+ @Override
+ protected void onCancelled() {
+ onPostExecute(null);
+ }
+
+ @Override
+ protected void onPostExecute(Void ignored) {
+ IoUtils.closeQuietly(mLocalPipe);
+ }
+ }
+
+ /**
* Request for {@link #revokeRuntimePermissions}
*/
private static final class PendingRevokeRuntimePermissionRequest extends
@@ -668,6 +788,97 @@
}
/**
+ * Request for {@link #restoreRuntimePermissionBackup}
+ */
+ private static final class PendingRestoreRuntimePermissionBackup implements
+ AbstractRemoteService.AsyncRequest<IPermissionController> {
+ private final @NonNull FileWriterTask mBackupSender;
+ private final @NonNull byte[] mBackup;
+ private final @NonNull UserHandle mUser;
+
+ private PendingRestoreRuntimePermissionBackup(@NonNull RemoteService service,
+ @NonNull byte[] backup, @NonNull UserHandle user) {
+ mBackup = backup;
+ mUser = user;
+
+ mBackupSender = new FileWriterTask();
+ }
+
+ @Override
+ public void run(@NonNull IPermissionController service) {
+ ParcelFileDescriptor remotePipe = mBackupSender.getRemotePipe();
+ try {
+ service.restoreRuntimePermissionBackup(mUser, remotePipe);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error sending runtime permission backup", e);
+ mBackupSender.cancel(false);
+ } finally {
+ // Remote pipe end is duped by binder call. Local copy is not needed anymore
+ IoUtils.closeQuietly(remotePipe);
+ }
+
+ mBackupSender.execute(mBackup);
+ }
+ }
+
+ /**
+ * Request for {@link #restoreDelayedRuntimePermissionBackup(String, UserHandle, Executor,
+ * Consumer<Boolean>)}
+ */
+ private static final class PendingRestoreDelayedRuntimePermissionBackup extends
+ AbstractRemoteService.PendingRequest<RemoteService, IPermissionController> {
+ private final @NonNull String mPackageName;
+ private final @NonNull UserHandle mUser;
+ private final @NonNull Executor mExecutor;
+ private final @NonNull Consumer<Boolean> mCallback;
+
+ private final @NonNull RemoteCallback mRemoteCallback;
+
+ private PendingRestoreDelayedRuntimePermissionBackup(@NonNull RemoteService service,
+ @NonNull String packageName, @NonNull UserHandle user, @NonNull Executor executor,
+ @NonNull Consumer<Boolean> callback) {
+ super(service);
+
+ mPackageName = packageName;
+ mUser = user;
+ mExecutor = executor;
+ mCallback = callback;
+
+ mRemoteCallback = new RemoteCallback(result -> executor.execute(() -> {
+ long token = Binder.clearCallingIdentity();
+ try {
+ callback.accept(result.getBoolean(KEY_RESULT, false));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+
+ finish();
+ }
+ }), null);
+ }
+
+ @Override
+ protected void onTimeout(RemoteService remoteService) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mExecutor.execute(
+ () -> mCallback.accept(true));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ getService().getServiceInterface().restoreDelayedRuntimePermissionBackup(
+ mPackageName, mUser, mRemoteCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error restoring delayed permissions for " + mPackageName, e);
+ }
+ }
+ }
+
+ /**
* Request for {@link #getAppPermissions}
*/
private static final class PendingGetAppPermissionRequest extends
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index 482f4a8..fb6c061 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -28,6 +28,7 @@
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.Manifest;
+import android.annotation.BinderThread;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
@@ -48,6 +49,7 @@
import com.android.internal.util.Preconditions;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -104,6 +106,28 @@
@NonNull OutputStream backup);
/**
+ * Restore a backup of the runtime permissions.
+ *
+ * @param user The user to restore
+ * @param backup The stream to read the backup from
+ */
+ @BinderThread
+ public abstract void onRestoreRuntimePermissionsBackup(@NonNull UserHandle user,
+ @NonNull InputStream backup);
+
+ /**
+ * Restore a delayed backup of the runtime permissions.
+ *
+ * @param packageName The app to restore
+ * @param user The user to restore
+ *
+ * @return {@code true} iff there is still delayed backup left
+ */
+ @BinderThread
+ public abstract boolean onRestoreDelayedRuntimePermissionsBackup(@NonNull String packageName,
+ @NonNull UserHandle user);
+
+ /**
* Gets the runtime permissions for an app.
*
* @param packageName The package for which to query.
@@ -207,6 +231,36 @@
}
@Override
+ public void restoreRuntimePermissionBackup(UserHandle user, ParcelFileDescriptor pipe) {
+ checkNotNull(user);
+ checkNotNull(pipe);
+
+ enforceCallingPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, null);
+
+ try (InputStream backup = new ParcelFileDescriptor.AutoCloseInputStream(pipe)) {
+ onRestoreRuntimePermissionsBackup(user, backup);
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Could not open pipe to read backup from", e);
+ }
+ }
+
+ @Override
+ public void restoreDelayedRuntimePermissionBackup(String packageName, UserHandle user,
+ RemoteCallback callback) {
+ checkNotNull(packageName);
+ checkNotNull(user);
+ checkNotNull(callback);
+
+ enforceCallingPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, null);
+
+ boolean hasMoreBackup = onRestoreDelayedRuntimePermissionsBackup(packageName, user);
+
+ Bundle result = new Bundle();
+ result.putBoolean(PermissionControllerManager.KEY_RESULT, hasMoreBackup);
+ callback.sendResult(result);
+ }
+
+ @Override
public void getAppPermissions(String packageName, RemoteCallback callback) {
checkNotNull(packageName, "packageName");
checkNotNull(callback, "callback");
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index de54a8aa..f63c0adb 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -772,19 +772,6 @@
* @param callBlockReason The reason why the call is blocked.
* @param callScreeningAppName The call screening application name which block the call.
* @param callScreeningComponentName The call screening component name which block the call.
- * @param callIdPackageName The package name of the
- * {@link android.telecom.CallScreeningService} which provided
- * {@link CallIdentification}.
- * @param callIdAppName The app name of the {@link android.telecom.CallScreeningService}
- * which provided {@link CallIdentification}.
- * @param callIdName The caller name provided by the
- * {@link android.telecom.CallScreeningService}.
- * @param callIdDescription The caller description provided by the
- * {@link android.telecom.CallScreeningService}.
- * @param callIdDetails The caller details provided by the
- * {@link android.telecom.CallScreeningService}.
- * @param callIdCallType The caller type provided by the
- * {@link android.telecom.CallScreeningService}.
*
* @result The URI of the call log entry belonging to the user that made or received this
* call. This could be of the shadow provider. Do not return it to non-system apps,
@@ -803,37 +790,10 @@
number, userToBeInsertedTo, addForAllUsers));
}
final ContentResolver resolver = context.getContentResolver();
- int numberPresentation = PRESENTATION_ALLOWED;
- TelecomManager tm = null;
- try {
- tm = TelecomManager.from(context);
- } catch (UnsupportedOperationException e) {}
+ String accountAddress = getLogAccountAddress(context, accountHandle);
- String accountAddress = null;
- if (tm != null && accountHandle != null) {
- PhoneAccount account = tm.getPhoneAccount(accountHandle);
- if (account != null) {
- Uri address = account.getSubscriptionAddress();
- if (address != null) {
- accountAddress = address.getSchemeSpecificPart();
- }
- }
- }
-
- // Remap network specified number presentation types
- // PhoneConstants.PRESENTATION_xxx to calllog number presentation types
- // Calls.PRESENTATION_xxx, in order to insulate the persistent calllog
- // from any future radio changes.
- // If the number field is empty set the presentation type to Unknown.
- if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
- numberPresentation = PRESENTATION_RESTRICTED;
- } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
- numberPresentation = PRESENTATION_PAYPHONE;
- } else if (TextUtils.isEmpty(number)
- || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
- numberPresentation = PRESENTATION_UNKNOWN;
- }
+ int numberPresentation = getLogNumberPresentation(number, presentation);
if (numberPresentation != PRESENTATION_ALLOWED) {
number = "";
if (ci != null) {
@@ -1138,8 +1098,7 @@
if (TextUtils.isEmpty(countryIso)) {
return;
}
- final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number,
- getCurrentCountryIso(context));
+ final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
if (TextUtils.isEmpty(normalizedNumber)) {
return;
}
@@ -1148,6 +1107,54 @@
resolver.update(Data.CONTENT_URI, values, Data._ID + "=?", new String[] {dataId});
}
+ /**
+ * Remap network specified number presentation types
+ * PhoneConstants.PRESENTATION_xxx to calllog number presentation types
+ * Calls.PRESENTATION_xxx, in order to insulate the persistent calllog
+ * from any future radio changes.
+ * If the number field is empty set the presentation type to Unknown.
+ */
+ private static int getLogNumberPresentation(String number, int presentation) {
+ if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+ return presentation;
+ }
+
+ if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
+ return presentation;
+ }
+
+ if (TextUtils.isEmpty(number)
+ || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
+ return PRESENTATION_UNKNOWN;
+ }
+
+ return PRESENTATION_ALLOWED;
+ }
+
+ private static String getLogAccountAddress(Context context,
+ PhoneAccountHandle accountHandle) {
+ TelecomManager tm = null;
+ try {
+ tm = TelecomManager.from(context);
+ } catch (UnsupportedOperationException e) {
+ if (VERBOSE_LOG) {
+ Log.v(LOG_TAG, "No TelecomManager found to get account address.");
+ }
+ }
+
+ String accountAddress = null;
+ if (tm != null && accountHandle != null) {
+ PhoneAccount account = tm.getPhoneAccount(accountHandle);
+ if (account != null) {
+ Uri address = account.getSubscriptionAddress();
+ if (address != null) {
+ accountAddress = address.getSchemeSpecificPart();
+ }
+ }
+ }
+ return accountAddress;
+ }
+
private static String getCurrentCountryIso(Context context) {
String countryIso = null;
final CountryDetector detector = (CountryDetector) context.getSystemService(
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 92650e1..5ac31dc 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -147,6 +147,25 @@
* Whether the Notification Assistant should generate contextual actions for notifications.
*/
String GENERATE_ACTIONS = "generate_actions";
+
+ String MAX_MESSAGES_TO_EXTRACT = "max_messages_to_extract";
+
+ String MAX_SUGGESTIONS = "max_suggestions";
+ }
+
+ /**
+ * Namespace for all runtime related features.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface Runtime {
+ String NAMESPACE = "runtime";
+
+ /**
+ * Whether or not we use the precompiled layout.
+ */
+ String USE_PRECOMPILED_LAYOUT = "view.precompiled_layout_enabled";
}
/**
@@ -160,6 +179,27 @@
}
/**
+ * Namespace for all runtime native boot related features. Boot in this case refers to the
+ * fact that the properties only take affect after rebooting the device.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface RuntimeNativeBoot {
+ String NAMESPACE = "runtime_native_boot";
+ }
+
+ /**
+ * Namespace for all media native related features.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface MediaNative {
+ String NAMESPACE = "media_native";
+ }
+
+ /**
* Namespace for all activity manager related features that are used at the native level.
* These features are applied at reboot.
*
@@ -209,6 +249,14 @@
* Whether to show location access check notifications.
*/
String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";
+
+ /**
+ * Whether to disable the new device identifier access restrictions.
+ *
+ * @hide
+ */
+ String PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED =
+ "device_identifier_access_restrictions_disabled";
}
/**
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 0743c23..67c8400 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -110,6 +110,16 @@
public static final String SCAN_VOLUME_CALL = "scan_volume";
/**
+ * Extra used with {@link #SCAN_FILE_CALL} or {@link #SCAN_VOLUME_CALL} to indicate that
+ * the file path originated from shell.
+ *
+ * {@hide}
+ */
+ @TestApi
+ public static final String EXTRA_ORIGINATED_FROM_SHELL =
+ "android.intent.extra.originated_from_shell";
+
+ /**
* The method name used by the media scanner and mtp to tell the media provider to
* rescan and reclassify that have become unhidden because of renaming folders or
* removing nomedia files
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e14bb66..a8976aa 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5704,7 +5704,6 @@
* Defines whether Content Capture is enabled for the user.
* @hide
*/
- @SystemApi
@TestApi
public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled";
@@ -8295,6 +8294,16 @@
private static final Validator NOTIFICATION_BADGING_VALIDATOR = BOOLEAN_VALIDATOR;
/**
+ * Whether the notification bubbles are globally enabled
+ * The value is boolean (1 or 0).
+ * @hide
+ */
+ @TestApi
+ public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
+
+ private static final Validator NOTIFICATION_BUBBLES_VALIDATOR = BOOLEAN_VALIDATOR;
+
+ /**
* Whether notifications are dismissed by a right-to-left swipe (instead of a left-to-right
* swipe).
*
@@ -8605,6 +8614,7 @@
ASSIST_GESTURE_WAKE_ENABLED,
VR_DISPLAY_MODE,
NOTIFICATION_BADGING,
+ NOTIFICATION_BUBBLES,
NOTIFICATION_DISMISS_RTL,
QS_AUTO_ADDED_TILES,
SCREENSAVER_ENABLED,
@@ -8767,6 +8777,7 @@
VALIDATORS.put(ASSIST_GESTURE_WAKE_ENABLED, ASSIST_GESTURE_WAKE_ENABLED_VALIDATOR);
VALIDATORS.put(VR_DISPLAY_MODE, VR_DISPLAY_MODE_VALIDATOR);
VALIDATORS.put(NOTIFICATION_BADGING, NOTIFICATION_BADGING_VALIDATOR);
+ VALIDATORS.put(NOTIFICATION_BUBBLES, NOTIFICATION_BUBBLES_VALIDATOR);
VALIDATORS.put(NOTIFICATION_DISMISS_RTL, NOTIFICATION_DISMISS_RTL_VALIDATOR);
VALIDATORS.put(QS_AUTO_ADDED_TILES, QS_AUTO_ADDED_TILES_VALIDATOR);
VALIDATORS.put(SCREENSAVER_ENABLED, SCREENSAVER_ENABLED_VALIDATOR);
@@ -11443,6 +11454,7 @@
* <pre>
* advertise_is_enabled (boolean)
* datasaver_disabled (boolean)
+ * enable_night_mode (boolean)
* launch_boost_disabled (boolean)
* vibration_disabled (boolean)
* animation_disabled (boolean)
diff --git a/core/java/android/rolecontrollerservice/IRoleControllerService.aidl b/core/java/android/rolecontrollerservice/IRoleControllerService.aidl
index ac5be06..40852ea 100644
--- a/core/java/android/rolecontrollerservice/IRoleControllerService.aidl
+++ b/core/java/android/rolecontrollerservice/IRoleControllerService.aidl
@@ -23,13 +23,15 @@
*/
oneway interface IRoleControllerService {
- void onAddRoleHolder(in String roleName, in String packageName,
+ void onAddRoleHolder(in String roleName, in String packageName, int flags,
in IRoleManagerCallback callback);
- void onRemoveRoleHolder(in String roleName, in String packageName,
+ void onRemoveRoleHolder(in String roleName, in String packageName, int flags,
in IRoleManagerCallback callback);
- void onClearRoleHolders(in String roleName, in IRoleManagerCallback callback);
+ void onClearRoleHolders(in String roleName, int flags, in IRoleManagerCallback callback);
void onGrantDefaultRoles(in IRoleManagerCallback callback);
+
+ void onSmsKillSwitchToggled(boolean smsRestrictionEnabled);
}
diff --git a/core/java/android/rolecontrollerservice/RoleControllerService.java b/core/java/android/rolecontrollerservice/RoleControllerService.java
index 6eda504..c846b07 100644
--- a/core/java/android/rolecontrollerservice/RoleControllerService.java
+++ b/core/java/android/rolecontrollerservice/RoleControllerService.java
@@ -61,32 +61,33 @@
return new IRoleControllerService.Stub() {
@Override
- public void onAddRoleHolder(String roleName, String packageName,
+ public void onAddRoleHolder(String roleName, String packageName, int flags,
IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName,
"packageName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
- RoleControllerService.this.onAddRoleHolder(roleName, packageName,
+ RoleControllerService.this.onAddRoleHolder(roleName, packageName, flags,
new RoleManagerCallbackDelegate(callback));
}
@Override
- public void onRemoveRoleHolder(String roleName, String packageName,
+ public void onRemoveRoleHolder(String roleName, String packageName, int flags,
IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName,
"packageName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
- RoleControllerService.this.onRemoveRoleHolder(roleName, packageName,
+ RoleControllerService.this.onRemoveRoleHolder(roleName, packageName, flags,
new RoleManagerCallbackDelegate(callback));
}
@Override
- public void onClearRoleHolders(String roleName, IRoleManagerCallback callback) {
+ public void onClearRoleHolders(String roleName, int flags,
+ IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
- RoleControllerService.this.onClearRoleHolders(roleName,
+ RoleControllerService.this.onClearRoleHolders(roleName, flags,
new RoleManagerCallbackDelegate(callback));
}
@@ -96,6 +97,11 @@
RoleControllerService.this.onGrantDefaultRoles(new RoleManagerCallbackDelegate(
callback));
}
+
+ @Override
+ public void onSmsKillSwitchToggled(boolean smsRestrictionEnabled) {
+ RoleControllerService.this.onSmsKillSwitchToggled(smsRestrictionEnabled);
+ }
};
}
@@ -108,37 +114,49 @@
*
* @param roleName the name of the role to add the role holder for
* @param packageName the package name of the application to add to the role holders
+ * @param flags optional behavior flags
* @param callback the callback for whether this call is successful
*
- * @see RoleManager#addRoleHolderAsUser(String, String, UserHandle, Executor,
+ * @see RoleManager#addRoleHolderAsUser(String, String, int, UserHandle, Executor,
* RoleManagerCallback)
*/
public abstract void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName,
- @NonNull RoleManagerCallback callback);
+ @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback);
/**
* Remove a specific application from the holders of a role.
*
* @param roleName the name of the role to remove the role holder for
* @param packageName the package name of the application to remove from the role holders
+ * @param flags optional behavior flags
* @param callback the callback for whether this call is successful
*
- * @see RoleManager#removeRoleHolderAsUser(String, String, UserHandle, Executor,
+ * @see RoleManager#removeRoleHolderAsUser(String, String, int, UserHandle, Executor,
* RoleManagerCallback)
*/
public abstract void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName,
- @NonNull RoleManagerCallback callback);
+ @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback);
/**
* Remove all holders of a role.
*
* @param roleName the name of the role to remove role holders for
+ * @param flags optional behavior flags
* @param callback the callback for whether this call is successful
*
- * @see RoleManager#clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
+ * @see RoleManager#clearRoleHoldersAsUser(String, int, UserHandle, Executor,
+ * RoleManagerCallback)
*/
public abstract void onClearRoleHolders(@NonNull String roleName,
- @NonNull RoleManagerCallback callback);
+ @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback);
+
+ /**
+ * Cleanup appop/permissions state in response to sms kill switch toggle
+ *
+ * @param smsRestrictionEnabled whether kill switch was turned on
+ */
+ //STOPSHIP: remove this api before shipping a final version
+ public abstract void onSmsKillSwitchToggled(boolean smsRestrictionEnabled);
/**
* Called by system to grant default permissions and roles.
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index 8e0f522..81d066d 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -234,7 +234,12 @@
}
/**
- * Implementation specific {@code dump}.
+ * Implementation specific {@code dump}. The child class can override the method to provide
+ * additional information about the Service's state into the dumpsys output.
+ *
+ * @param pw The PrintWriter to which you should dump your state. This will be closed for
+ * you after you return.
+ * @param args additional arguments to the dump request.
*/
protected void dump(@NonNull PrintWriter pw,
@SuppressWarnings("unused") @NonNull String[] args) {
diff --git a/core/java/android/app/SmsAppService.java b/core/java/android/service/carrier/CarrierMessagingClientService.java
similarity index 67%
rename from core/java/android/app/SmsAppService.java
rename to core/java/android/service/carrier/CarrierMessagingClientService.java
index 3829d71..13f4fc4 100644
--- a/core/java/android/app/SmsAppService.java
+++ b/core/java/android/service/carrier/CarrierMessagingClientService.java
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.app;
+package android.service.carrier;
+import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
@@ -24,10 +25,11 @@
* it so that the process is always running, which allows the app to have a persistent connection
* to the server.
*
- * <p>The service must have an {@link android.telephony.TelephonyManager#ACTION_SMS_APP_SERVICE}
+ * <p>The service must have an
+ * {@link android.telephony.TelephonyManager#ACTION_CARRIER_MESSAGING_CLIENT_SERVICE}
* action in the intent handler, and be protected with
- * {@link android.Manifest.permission#BIND_SMS_APP_SERVICE}. However the service does not have to
- * be exported.
+ * {@link android.Manifest.permission#BIND_CARRIER_MESSAGING_CLIENT_SERVICE}.
+ * However the service does not have to be exported.
*
* <p>The service must be associated with a non-main process, meaning it must have an
* {@code android:process} tag in its manifest entry.
@@ -45,27 +47,27 @@
*
* <p>Example: First, define a subclass in the application:
* <pre>
- * public class MySmsAppService extends SmsAppService {
+ * public class MyCarrierMessagingClientService extends CarrierMessagingClientService {
* }
* </pre>
* Then, declare it in its {@code AndroidManifest.xml}:
* <pre>
* <service
- * android:name=".MySmsAppService"
+ * android:name=".MyCarrierMessagingClientService"
* android:exported="false"
* android:process=":persistent"
- * android:permission="android.permission.BIND_SMS_APP_SERVICE">
+ * android:permission="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE">
* <intent-filter>
- * <action android:name="android.telephony.action.SMS_APP_SERVICE" />
+ * <action android:name="android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE" />
* </intent-filter>
* </service>
* </pre>
*/
-public class SmsAppService extends Service {
- private final ISmsAppService mImpl;
+public class CarrierMessagingClientService extends Service {
+ private final ICarrierMessagingClientServiceImpl mImpl;
- public SmsAppService() {
- mImpl = new ISmsAppServiceImpl();
+ public CarrierMessagingClientService() {
+ mImpl = new ICarrierMessagingClientServiceImpl();
}
@Override
@@ -73,6 +75,6 @@
return mImpl.asBinder();
}
- private class ISmsAppServiceImpl extends ISmsAppService.Stub {
+ private class ICarrierMessagingClientServiceImpl extends ICarrierMessagingClientService.Stub {
}
}
diff --git a/core/java/android/app/ISmsAppService.aidl b/core/java/android/service/carrier/ICarrierMessagingClientService.aidl
similarity index 88%
rename from core/java/android/app/ISmsAppService.aidl
rename to core/java/android/service/carrier/ICarrierMessagingClientService.aidl
index 1ac2ec6..dbe7d12 100644
--- a/core/java/android/app/ISmsAppService.aidl
+++ b/core/java/android/service/carrier/ICarrierMessagingClientService.aidl
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package android.app;
+package android.service.carrier;
/**
* @hide
*/
-interface ISmsAppService {
+interface ICarrierMessagingClientService {
}
diff --git a/core/java/android/service/contentcapture/ContentCaptureEventsRequest.java b/core/java/android/service/contentcapture/ContentCaptureEventsRequest.java
index db242a2..ca6676d 100644
--- a/core/java/android/service/contentcapture/ContentCaptureEventsRequest.java
+++ b/core/java/android/service/contentcapture/ContentCaptureEventsRequest.java
@@ -17,6 +17,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.contentcapture.ContentCaptureEvent;
@@ -32,6 +33,7 @@
* @hide
*/
@SystemApi
+@TestApi
@Deprecated
public final class ContentCaptureEventsRequest implements Parcelable {
// TODO(b/121051220): remove .java and .aidl once service implementation doesn't use it anymore
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index 020de7f..c98f09e 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
@@ -48,9 +49,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
/**
* A service used to capture the content of the screen to provide contextual data in other areas of
@@ -59,6 +58,7 @@
* @hide
*/
@SystemApi
+@TestApi
public abstract class ContentCaptureService extends Service {
private static final String TAG = ContentCaptureService.class.getSimpleName();
@@ -166,10 +166,6 @@
/**
* Explicitly limits content capture to the given packages and activities.
*
- * <p>When the whitelist is set, it overrides the values passed to
- * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}
- * and {@link #setPackageContentCaptureEnabled(String, boolean)}.
- *
* <p>To reset the whitelist, call it passing {@code null} to both arguments.
*
* <p>Useful when the service wants to restrict content capture to a category of apps, like
@@ -194,76 +190,6 @@
}
/**
- * Defines whether content capture should be enabled for activities with such
- * {@link android.content.ComponentName}.
- *
- * <p>Useful to blacklist a particular activity.
- */
- public final void setActivityContentCaptureEnabled(@NonNull ComponentName activity,
- boolean enabled) {
- final IContentCaptureServiceCallback callback = mCallback;
- if (callback == null) {
- Log.w(TAG, "setActivityContentCaptureEnabled(): no server callback");
- return;
- }
- try {
- callback.setActivityContentCaptureEnabled(activity, enabled);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Defines whether content capture should be enabled for activities of the app with such
- * {@code packageName}.
- *
- * <p>Useful to blacklist any activity from a particular app.
- */
- public final void setPackageContentCaptureEnabled(@NonNull String packageName,
- boolean enabled) {
- final IContentCaptureServiceCallback callback = mCallback;
- if (callback == null) {
- Log.w(TAG, "setPackageContentCaptureEnabled(): no server callback");
- return;
- }
- try {
- callback.setPackageContentCaptureEnabled(packageName, enabled);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Gets the activities where content capture was disabled by
- * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}.
- */
- @NonNull
- public final Set<ComponentName> getContentCaptureDisabledActivities() {
- final IContentCaptureServiceCallback callback = mCallback;
- if (callback == null) {
- Log.w(TAG, "getContentCaptureDisabledActivities(): no server callback");
- return Collections.emptySet();
- }
- //TODO(b/122595322): implement (using SyncResultReceiver)
- return null;
- }
-
- /**
- * Gets the apps where content capture was disabled by
- * {@link #setPackageContentCaptureEnabled(String, boolean)}.
- */
- @NonNull
- public final Set<String> getContentCaptureDisabledPackages() {
- final IContentCaptureServiceCallback callback = mCallback;
- if (callback == null) {
- Log.w(TAG, "getContentCaptureDisabledPackages(): no server callback");
- return Collections.emptySet();
- }
- //TODO(b/122595322): implement (using SyncResultReceiver)
- return null;
- }
-
- /**
* Called when the Android system connects to service.
*
* <p>You should generally do initialization here rather than in {@link #onCreate}.
diff --git a/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl b/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl
index e84bd6f..2a729b6 100644
--- a/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl
+++ b/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl
@@ -28,8 +28,4 @@
*/
oneway interface IContentCaptureServiceCallback {
void setContentCaptureWhitelist(in List<String> packages, in List<ComponentName> activities);
- void setActivityContentCaptureEnabled(in ComponentName activity, boolean enabled);
- void setPackageContentCaptureEnabled(in String packageName, boolean enabled);
- void getContentCaptureDisabledActivities(in IResultReceiver receiver);
- void getContentCaptureDisabledPackages(in IResultReceiver receiver);
}
diff --git a/core/java/android/service/contentcapture/SnapshotData.java b/core/java/android/service/contentcapture/SnapshotData.java
index bc2116a..c3af1f0 100644
--- a/core/java/android/service/contentcapture/SnapshotData.java
+++ b/core/java/android/service/contentcapture/SnapshotData.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.os.Bundle;
@@ -31,6 +32,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class SnapshotData implements Parcelable {
private final @NonNull Bundle mAssistData;
diff --git a/core/java/android/service/dreams/Sandman.java b/core/java/android/service/dreams/Sandman.java
index eeb340b..efb8923 100644
--- a/core/java/android/service/dreams/Sandman.java
+++ b/core/java/android/service/dreams/Sandman.java
@@ -91,8 +91,9 @@
// and the UI mode manager starting a dream. We want the system to already
// be awake by the time this happens. Otherwise the dream may not start.
PowerManager powerManager =
- (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ context.getSystemService(PowerManager.class);
powerManager.wakeUp(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_PLUGGED_IN,
"android.service.dreams:DREAM");
} else {
Slog.i(TAG, "Activating dream by user request.");
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index d4e8879..d3285bb 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1503,6 +1503,7 @@
private boolean mNoisy;
private ArrayList<Notification.Action> mSmartActions;
private ArrayList<CharSequence> mSmartReplies;
+ private boolean mCanBubble;
public Ranking() {}
@@ -1677,6 +1678,17 @@
return mLastAudiblyAlertedMs;
}
+ /**
+ * Returns whether the user has allowed bubbles globally, at the app level, and at the
+ * channel level for this notification.
+ *
+ * <p>This does not take into account the current importance of the notification, the
+ * current DND state, or whether the posting app is foreground.</p>
+ */
+ public boolean canBubble() {
+ return mCanBubble;
+ }
+
/** @hide */
public boolean isNoisy() {
return mNoisy;
@@ -1693,7 +1705,7 @@
ArrayList<SnoozeCriterion> snoozeCriteria, boolean showBadge,
int userSentiment, boolean hidden, long lastAudiblyAlertedMs,
boolean noisy, ArrayList<Notification.Action> smartActions,
- ArrayList<CharSequence> smartReplies) {
+ ArrayList<CharSequence> smartReplies, boolean canBubble) {
mKey = key;
mRank = rank;
mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
@@ -1713,6 +1725,7 @@
mNoisy = noisy;
mSmartActions = smartActions;
mSmartReplies = smartReplies;
+ mCanBubble = canBubble;
}
/**
@@ -1766,6 +1779,7 @@
private ArrayMap<String, Boolean> mNoisy;
private ArrayMap<String, ArrayList<Notification.Action>> mSmartActions;
private ArrayMap<String, ArrayList<CharSequence>> mSmartReplies;
+ private boolean[] mCanBubble;
private RankingMap(NotificationRankingUpdate rankingUpdate) {
mRankingUpdate = rankingUpdate;
@@ -1796,7 +1810,7 @@
getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
getShowBadge(key), getUserSentiment(key), getHidden(key),
getLastAudiblyAlerted(key), getNoisy(key), getSmartActions(key),
- getSmartReplies(key));
+ getSmartReplies(key), canBubble(key));
return rank >= 0;
}
@@ -1972,6 +1986,19 @@
return mSmartReplies.get(key);
}
+ private boolean canBubble(String key) {
+ synchronized (this) {
+ if (mRanks == null) {
+ buildRanksLocked();
+ }
+ if (mCanBubble == null) {
+ mCanBubble = mRankingUpdate.getCanBubble();
+ }
+ }
+ int keyIndex = mRanks.getOrDefault(key, -1);
+ return keyIndex >= 0 ? mCanBubble[keyIndex] : false;
+ }
+
// Locked by 'this'
private void buildRanksLocked() {
String[] orderedKeys = mRankingUpdate.getOrderedKeys();
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index ebaeff8..230ae27 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -41,13 +41,14 @@
private final Bundle mSmartReplies;
private final Bundle mLastAudiblyAlerted;
private final Bundle mNoisy;
+ private final boolean[] mCanBubble;
public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
Bundle visibilityOverrides, Bundle suppressedVisualEffects,
int[] importance, Bundle explanation, Bundle overrideGroupKeys,
Bundle channels, Bundle overridePeople, Bundle snoozeCriteria,
Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions,
- Bundle smartReplies, Bundle lastAudiblyAlerted, Bundle noisy) {
+ Bundle smartReplies, Bundle lastAudiblyAlerted, Bundle noisy, boolean[] canBubble) {
mKeys = keys;
mInterceptedKeys = interceptedKeys;
mVisibilityOverrides = visibilityOverrides;
@@ -65,6 +66,7 @@
mSmartReplies = smartReplies;
mLastAudiblyAlerted = lastAudiblyAlerted;
mNoisy = noisy;
+ mCanBubble = canBubble;
}
public NotificationRankingUpdate(Parcel in) {
@@ -86,6 +88,8 @@
mSmartReplies = in.readBundle();
mLastAudiblyAlerted = in.readBundle();
mNoisy = in.readBundle();
+ mCanBubble = new boolean[mKeys.length];
+ in.readBooleanArray(mCanBubble);
}
@Override
@@ -112,6 +116,7 @@
out.writeBundle(mSmartReplies);
out.writeBundle(mLastAudiblyAlerted);
out.writeBundle(mNoisy);
+ out.writeBooleanArray(mCanBubble);
}
public static final Parcelable.Creator<NotificationRankingUpdate> CREATOR
@@ -192,4 +197,8 @@
public Bundle getNoisy() {
return mNoisy;
}
+
+ public boolean[] getCanBubble() {
+ return mCanBubble;
+ }
}
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 949328f..915a18e 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -94,7 +94,8 @@
private final DecorationInfo mDecorationInfo = new DecorationInfo();
private final ArrayList<DecorationInfo> mDecorations = new ArrayList<>();
- @UnsupportedAppUsage
+ /** Not allowed to access. If it's for memory leak workaround, it was already fixed M. */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static final TextLine[] sCached = new TextLine[3];
/**
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 44353b1..81643e9 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -2182,6 +2182,13 @@
return Character.isWhitespace(codePoint) || codePoint == NBSP_CODE_POINT;
}
+ /** @hide */
+ @Nullable
+ public static String withoutPrefix(@Nullable String prefix, @Nullable String str) {
+ if (prefix == null || str == null) return str;
+ return str.startsWith(prefix) ? str.substring(prefix.length()) : str;
+ }
+
/**
* Remove html, remove bad characters, and truncate string.
*
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 59e562f..62ed901 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -40,6 +40,7 @@
import android.view.View.AttachInfo;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeIdManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
@@ -154,13 +155,7 @@
}
private boolean isShown(View view) {
- // The first two checks are made also made by isShown() which
- // however traverses the tree up to the parent to catch that.
- // Therefore, we do some fail fast check to minimize the up
- // tree traversal.
- return (view.mAttachInfo != null
- && view.mAttachInfo.mWindowVisibility == View.VISIBLE
- && view.isShown());
+ return (view != null) && (view.getWindowVisibility() == View.VISIBLE && view.isShown());
}
public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
@@ -340,13 +335,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId == AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = mViewRootImpl.mView;
- } else {
- root = findViewByAccessibilityId(accessibilityViewId);
- }
- if (root != null && isShown(root)) {
+ final View root = findViewByAccessibilityId(accessibilityViewId);
+ if (root != null) {
mPrefetcher.prefetchAccessibilityNodeInfos(
root, virtualDescendantId, flags, infos, arguments);
}
@@ -396,12 +386,7 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = findViewByAccessibilityId(accessibilityViewId);
- } else {
- root = mViewRootImpl.mView;
- }
+ final View root = findViewByAccessibilityId(accessibilityViewId);
if (root != null) {
final int resolvedViewId = root.getContext().getResources()
.getIdentifier(viewId, null, null);
@@ -462,13 +447,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = findViewByAccessibilityId(accessibilityViewId);
- } else {
- root = mViewRootImpl.mView;
- }
- if (root != null && isShown(root)) {
+ final View root = findViewByAccessibilityId(accessibilityViewId);
+ if (root != null) {
AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
if (provider != null) {
infos = provider.findAccessibilityNodeInfosByText(text,
@@ -550,13 +530,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = findViewByAccessibilityId(accessibilityViewId);
- } else {
- root = mViewRootImpl.mView;
- }
- if (root != null && isShown(root)) {
+ final View root = findViewByAccessibilityId(accessibilityViewId);
+ if (root != null) {
switch (focusType) {
case AccessibilityNodeInfo.FOCUS_ACCESSIBILITY: {
View host = mViewRootImpl.mAccessibilityFocusedHost;
@@ -583,7 +558,7 @@
} break;
case AccessibilityNodeInfo.FOCUS_INPUT: {
View target = root.findFocus();
- if (target == null || !isShown(target)) {
+ if (!isShown(target)) {
break;
}
AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
@@ -645,13 +620,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = findViewByAccessibilityId(accessibilityViewId);
- } else {
- root = mViewRootImpl.mView;
- }
- if (root != null && isShown(root)) {
+ final View root = findViewByAccessibilityId(accessibilityViewId);
+ if (root != null) {
View nextView = root.focusSearch(direction);
if (nextView != null) {
next = nextView.createAccessibilityNodeInfo();
@@ -705,13 +675,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View target = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- target = findViewByAccessibilityId(accessibilityViewId);
- } else {
- target = mViewRootImpl.mView;
- }
- if (target != null && isShown(target)) {
+ final View target = findViewByAccessibilityId(accessibilityViewId);
+ if (target != null) {
if (action == R.id.accessibilityActionClickOnClickableSpan) {
// Handle this hidden action separately
succeeded = handleClickableSpanActionUiThread(
@@ -791,15 +756,13 @@
}
private View findViewByAccessibilityId(int accessibilityId) {
- View root = mViewRootImpl.mView;
- if (root == null) {
- return null;
+ if (accessibilityId == AccessibilityNodeInfo.ROOT_ITEM_ID) {
+ return mViewRootImpl.mView;
+ } else {
+ final View foundView =
+ AccessibilityNodeIdManager.getInstance().findView(accessibilityId);
+ return isShown(foundView) ? foundView : null;
}
- View foundView = root.findViewByAccessibilityId(accessibilityId);
- if (foundView != null && !isShown(foundView)) {
- return null;
- }
- return foundView;
}
private void applyAppScaleAndMagnificationSpecIfNeeded(List<AccessibilityNodeInfo> infos,
@@ -1171,7 +1134,7 @@
}
View child = children.get(i);
if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
- && isShown(child)) {
+ && isShown(child)) {
AccessibilityNodeInfo info = null;
AccessibilityNodeProvider provider =
child.getAccessibilityNodeProvider();
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index ccd0fc1..03e8a0f 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -22,7 +22,6 @@
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.graphics.FrameInfo;
-import android.graphics.Insets;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Build;
import android.os.Handler;
@@ -914,25 +913,11 @@
super(looper, vsyncSource);
}
+ // TODO(b/116025192): physicalDisplayId is ignored because SF only emits VSYNC events for
+ // the internal display and DisplayEventReceiver#scheduleVsync only allows requesting VSYNC
+ // for the internal display implicitly.
@Override
- public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
- // Ignore vsync from secondary display.
- // This can be problematic because the call to scheduleVsync() is a one-shot.
- // We need to ensure that we will still receive the vsync from the primary
- // display which is the one we really care about. Ideally we should schedule
- // vsync for a particular display.
- // At this time Surface Flinger won't send us vsyncs for secondary displays
- // but that could change in the future so let's log a message to help us remember
- // that we need to fix this.
- if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
- Log.d(TAG, "Received vsync from secondary display, but we don't support "
- + "this case yet. Choreographer needs a way to explicitly request "
- + "vsync for a specific display to ensure it doesn't lose track "
- + "of its scheduled vsync.");
- scheduleVsync();
- return;
- }
-
+ public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
// Post the vsync event to the Handler.
// The idea is to prevent incoming vsync events from completely starving
// the message queue. If there are no messages in the queue with timestamps
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index edd3f1a..3e8002f 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -136,12 +136,11 @@
*
* @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}
* timebase.
- * @param builtInDisplayId The surface flinger built-in display id such as
- * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}.
+ * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
* @param frame The frame number. Increases by one for each vertical sync interval.
*/
@UnsupportedAppUsage
- public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
+ public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
}
/**
@@ -149,12 +148,11 @@
*
* @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()}
* timebase.
- * @param builtInDisplayId The surface flinger built-in display id such as
- * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_HDMI}.
+ * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
* @param connected True if the display is connected, false if it disconnected.
*/
@UnsupportedAppUsage
- public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
+ public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
}
/**
@@ -174,14 +172,14 @@
// Called from native code.
@SuppressWarnings("unused")
@UnsupportedAppUsage
- private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
- onVsync(timestampNanos, builtInDisplayId, frame);
+ private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
+ onVsync(timestampNanos, physicalDisplayId, frame);
}
// Called from native code.
@SuppressWarnings("unused")
@UnsupportedAppUsage
- private void dispatchHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
- onHotplug(timestampNanos, builtInDisplayId, connected);
+ private void dispatchHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
+ onHotplug(timestampNanos, physicalDisplayId, connected);
}
}
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 03d9955..3e749f4 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -37,7 +37,7 @@
}
/** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
public abstract void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
CanvasProperty<Float> ry, CanvasProperty<Paint> paint);
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 7026d2b..2ba1e01 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -18,10 +18,10 @@
import static android.view.InsetsState.TYPE_IME;
+import android.inputmethodservice.InputMethodService;
import android.os.Parcel;
import android.text.TextUtils;
import android.view.SurfaceControl.Transaction;
-import android.view.WindowInsets.Type;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
@@ -73,11 +73,7 @@
return;
}
- if (setVisible) {
- mController.show(Type.IME);
- } else {
- mController.hide(Type.IME);
- }
+ mController.applyImeVisibility(setVisible);
}
@Override
@@ -91,6 +87,30 @@
mHasWindowFocus = false;
}
+ /**
+ * Request {@link InputMethodManager} to show the IME.
+ * @return @see {@link android.view.InsetsSourceConsumer.ShowResult}.
+ */
+ @Override
+ @ShowResult int requestShow(boolean fromIme) {
+ // TODO: ResultReceiver for IME.
+ // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag.
+ if (fromIme) {
+ return ShowResult.SHOW_IMMEDIATELY;
+ }
+
+ return getImm().requestImeShow(null /* resultReceiver */)
+ ? ShowResult.SHOW_DELAYED : ShowResult.SHOW_FAILED;
+ }
+
+ /**
+ * Notify {@link InputMethodService} that IME window is hidden.
+ */
+ @Override
+ void notifyHidden() {
+ getImm().notifyImeHidden();
+ }
+
private boolean isDummyOrEmptyEditor(EditorInfo info) {
// TODO(b/123044812): Handle dummy input gracefully in IME Insets API
return info == null || (info.fieldId <= 0 && info.inputType <= 0);
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 625ddc2..583651d 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -180,9 +180,10 @@
for (int i = items.size() - 1; i >= 0; i--) {
final InsetsSourceConsumer consumer = items.valueAt(i);
final InsetsSource source = mInitialInsetsState.getSource(consumer.getType());
+ final InsetsSourceControl control = consumer.getControl();
final SurfaceControl leash = consumer.getControl().getLeash();
- mTmpMatrix.setTranslate(source.getFrame().left, source.getFrame().top);
+ mTmpMatrix.setTranslate(control.getSurfacePosition().x, control.getSurfacePosition().y);
mTmpFrame.set(source.getFrame());
addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 8e77379..7ad97a6 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -29,11 +29,16 @@
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Log;
+import android.util.Pair;
import android.util.Property;
import android.util.SparseArray;
+import android.view.InsetsSourceConsumer.ShowResult;
import android.view.InsetsState.InternalInsetType;
import android.view.SurfaceControl.Transaction;
+import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetType;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
import com.android.internal.annotations.VisibleForTesting;
@@ -46,11 +51,13 @@
*/
public class InsetsController implements WindowInsetsController {
- // TODO: Use animation scaling and more optimal duration.
- private static final int ANIMATION_DURATION_MS = 400;
+ private static final int ANIMATION_DURATION_SHOW_MS = 275;
+ private static final int ANIMATION_DURATION_HIDE_MS = 340;
+ private static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
private static final int DIRECTION_NONE = 0;
private static final int DIRECTION_SHOW = 1;
private static final int DIRECTION_HIDE = 2;
+
@IntDef ({DIRECTION_NONE, DIRECTION_SHOW, DIRECTION_HIDE})
private @interface AnimationDirection{}
@@ -103,6 +110,8 @@
private ObjectAnimator mAnimator;
private @AnimationDirection int mAnimationDirection;
+ private int mPendingTypesToShow;
+
public InsetsController(ViewRootImpl viewRoot) {
mViewRoot = viewRoot;
mAnimCallback = () -> {
@@ -193,6 +202,12 @@
@Override
public void show(@InsetType int types) {
+ show(types, false /* fromIme */);
+ }
+
+ private void show(@InsetType int types, boolean fromIme) {
+ // TODO: Support a ResultReceiver for IME.
+ // TODO(b/123718661): Make show() work for multi-session IME.
int typesReady = 0;
final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
for (int i = internalTypes.size() - 1; i >= 0; i--) {
@@ -201,15 +216,18 @@
// Only one animator (with multiple InsetType) can run at a time.
// previous one should be cancelled for simplicity.
cancelExistingAnimation();
- } else if (consumer.isVisible() || mAnimationDirection == DIRECTION_SHOW) {
- // no-op: already shown or animating in.
+ } else if (consumer.isVisible()
+ && (mAnimationDirection == DIRECTION_NONE
+ || mAnimationDirection == DIRECTION_HIDE)) {
+ // no-op: already shown or animating in (because window visibility is
+ // applied before starting animation).
// TODO: When we have more than one types: handle specific case when
// show animation is going on, but the current type is not becoming visible.
continue;
}
typesReady |= InsetsState.toPublicType(consumer.getType());
}
- applyAnimation(typesReady, true /* show */);
+ applyAnimation(typesReady, true /* show */, fromIme);
}
@Override
@@ -220,35 +238,114 @@
InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
if (mAnimationDirection == DIRECTION_SHOW) {
cancelExistingAnimation();
- } else if (!consumer.isVisible() || mAnimationDirection == DIRECTION_HIDE) {
+ } else if (!consumer.isVisible()
+ && (mAnimationDirection == DIRECTION_NONE
+ || mAnimationDirection == DIRECTION_HIDE)) {
// no-op: already hidden or animating out.
continue;
}
typesReady |= InsetsState.toPublicType(consumer.getType());
}
- applyAnimation(typesReady, false /* show */);
+ applyAnimation(typesReady, false /* show */, false /* fromIme */);
}
@Override
public void controlWindowInsetsAnimation(@InsetType int types,
WindowInsetsAnimationControlListener listener) {
+ controlWindowInsetsAnimation(types, listener, false /* fromIme */);
+ }
+
+ private void controlWindowInsetsAnimation(@InsetType int types,
+ WindowInsetsAnimationControlListener listener, boolean fromIme) {
+ if (types == 0) {
+ // nothing to animate.
+ return;
+ }
// TODO: Check whether we already have a controller.
final ArraySet<Integer> internalTypes = mState.toInternalType(types);
final SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();
+
+ Pair<Integer, Boolean> typesReadyPair = collectConsumers(fromIme, internalTypes, consumers);
+ int typesReady = typesReadyPair.first;
+ boolean isReady = typesReadyPair.second;
+ if (!isReady) {
+ // IME isn't ready, all requested types would be shown once IME is ready.
+ mPendingTypesToShow = typesReady;
+ // TODO: listener for pending types.
+ return;
+ }
+
+ // pending types from previous request.
+ typesReady = collectPendingConsumers(typesReady, consumers);
+
+ if (typesReady == 0) {
+ listener.onCancelled();
+ return;
+ }
+
+ final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(consumers,
+ mFrame, mState, listener, typesReady,
+ () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this);
+ mAnimationControls.add(controller);
+ }
+
+ /**
+ * @return Pair of (types ready to animate, is ready to animate).
+ */
+ private Pair<Integer, Boolean> collectConsumers(boolean fromIme,
+ ArraySet<Integer> internalTypes, SparseArray<InsetsSourceConsumer> consumers) {
+ int typesReady = 0;
+ boolean isReady = true;
for (int i = internalTypes.size() - 1; i >= 0; i--) {
InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
if (consumer.getControl() != null) {
+ if (!consumer.isVisible()) {
+ // Show request
+ switch(consumer.requestShow(fromIme)) {
+ case ShowResult.SHOW_IMMEDIATELY:
+ typesReady |= InsetsState.toPublicType(TYPE_IME);
+ break;
+ case ShowResult.SHOW_DELAYED:
+ isReady = false;
+ break;
+ case ShowResult.SHOW_FAILED:
+ // IME cannot be shown (since it didn't have focus), proceed
+ // with animation of other types.
+ if (mPendingTypesToShow != 0) {
+ // remove IME from pending because view no longer has focus.
+ mPendingTypesToShow &= ~InsetsState.toPublicType(TYPE_IME);
+ }
+ break;
+ }
+ } else {
+ // Hide request
+ // TODO: Move notifyHidden() to beginning of the hide animation
+ // (when visibility actually changes using hideDirectly()).
+ consumer.notifyHidden();
+ typesReady |= InsetsState.toPublicType(consumer.getType());
+ }
consumers.put(consumer.getType(), consumer);
} else {
// TODO: Let calling app know it's not possible, or wait
// TODO: Remove it from types
}
}
- final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(consumers,
- mFrame, mState, listener, types,
- () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this);
- mAnimationControls.add(controller);
+ return new Pair<>(typesReady, isReady);
+ }
+
+ private int collectPendingConsumers(@InsetType int typesReady,
+ SparseArray<InsetsSourceConsumer> consumers) {
+ if (mPendingTypesToShow != 0) {
+ typesReady |= mPendingTypesToShow;
+ final ArraySet<Integer> internalTypes = mState.toInternalType(mPendingTypesToShow);
+ for (int i = internalTypes.size() - 1; i >= 0; i--) {
+ InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
+ consumers.put(consumer.getType(), consumer);
+ }
+ mPendingTypesToShow = 0;
+ }
+ return typesReady;
}
private void applyLocalVisibilityOverride() {
@@ -293,6 +390,19 @@
return mViewRoot;
}
+ /**
+ * Used by {@link ImeInsetsSourceConsumer} when IME decides to be shown/hidden.
+ * @hide
+ */
+ @VisibleForTesting
+ public void applyImeVisibility(boolean setVisible) {
+ if (setVisible) {
+ show(Type.IME, true /* fromIme */);
+ } else {
+ hide(Type.IME);
+ }
+ }
+
private InsetsSourceConsumer createConsumerOfType(int type) {
if (type == TYPE_IME) {
return new ImeInsetsSourceConsumer(mState, Transaction::new, this);
@@ -321,7 +431,7 @@
}
}
- private void applyAnimation(@InsetType final int types, boolean show) {
+ private void applyAnimation(@InsetType final int types, boolean show, boolean fromIme) {
if (types == 0) {
// nothing to animate.
return;
@@ -341,7 +451,10 @@
show ? controller.getHiddenStateInsets() : controller.getShownStateInsets(),
show ? controller.getShownStateInsets() : controller.getHiddenStateInsets()
);
- mAnimator.setDuration(ANIMATION_DURATION_MS);
+ mAnimator.setDuration(show
+ ? ANIMATION_DURATION_SHOW_MS
+ : ANIMATION_DURATION_HIDE_MS);
+ mAnimator.setInterpolator(INTERPOLATOR);
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
@@ -366,7 +479,7 @@
// TODO: Instead of clearing this here, properly wire up
// InsetsAnimationControlImpl.finish() to remove this from mAnimationControls.
mAnimationControls.clear();
- controlWindowInsetsAnimation(types, listener);
+ controlWindowInsetsAnimation(types, listener, fromIme);
}
private void hideDirectly(@InsetType int types) {
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index cccfd87..eab83ce 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -16,12 +16,15 @@
package android.view;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.view.InsetsState.InternalInsetType;
import android.view.SurfaceControl.Transaction;
import com.android.internal.annotations.VisibleForTesting;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.function.Supplier;
/**
@@ -30,6 +33,25 @@
*/
public class InsetsSourceConsumer {
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {ShowResult.SHOW_IMMEDIATELY, ShowResult.SHOW_DELAYED, ShowResult.SHOW_FAILED})
+ @interface ShowResult {
+ /**
+ * Window type is ready to be shown, will be shown immidiately.
+ */
+ int SHOW_IMMEDIATELY = 0;
+ /**
+ * Result will be delayed. Window needs to be prepared or request is not from controller.
+ * Request will be delegated to controller and may or may not be shown.
+ */
+ int SHOW_DELAYED = 1;
+ /**
+ * Window will not be shown because one of the conditions couldn't be met.
+ * (e.g. in IME's case, when no editor is focused.)
+ */
+ int SHOW_FAILED = 2;
+ }
+
protected final InsetsController mController;
protected boolean mVisible;
private final Supplier<Transaction> mTransactionSupplier;
@@ -104,6 +126,25 @@
return mVisible;
}
+ /**
+ * Request to show current window type.
+ *
+ * @param fromController {@code true} if request is coming from controller.
+ * (e.g. in IME case, controller is
+ * {@link android.inputmethodservice.InputMethodService}).
+ * @return @see {@link ShowResult}.
+ */
+ @ShowResult int requestShow(boolean fromController) {
+ return ShowResult.SHOW_IMMEDIATELY;
+ }
+
+ /**
+ * Notify listeners that window is now hidden.
+ */
+ void notifyHidden() {
+ // no-op for types that always return ShowResult#SHOW_IMMEDIATELY.
+ }
+
private void setVisible(boolean visible) {
if (mVisible == visible) {
return;
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 9383e6c..9fb6bdb 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -29,10 +29,13 @@
private final @InternalInsetType int mType;
private final SurfaceControl mLeash;
+ private final Point mSurfacePosition;
- public InsetsSourceControl(@InternalInsetType int type, SurfaceControl leash) {
+ public InsetsSourceControl(@InternalInsetType int type, SurfaceControl leash,
+ Point surfacePosition) {
mType = type;
mLeash = leash;
+ mSurfacePosition = surfacePosition;
}
public int getType() {
@@ -46,6 +49,19 @@
public InsetsSourceControl(Parcel in) {
mType = in.readInt();
mLeash = in.readParcelable(null /* loader */);
+ mSurfacePosition = in.readParcelable(null /* loader */);
+ }
+
+ public boolean setSurfacePosition(int left, int top) {
+ if (mSurfacePosition.equals(left, top)) {
+ return false;
+ }
+ mSurfacePosition.set(left, top);
+ return true;
+ }
+
+ public Point getSurfacePosition() {
+ return mSurfacePosition;
}
@Override
@@ -57,6 +73,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeParcelable(mLeash, 0 /* flags*/);
+ dest.writeParcelable(mSurfacePosition, 0 /* flags*/);
}
public static final Creator<InsetsSourceControl> CREATOR
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 6a290b7..c130250 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -33,6 +33,8 @@
import android.os.Message;
import android.os.SystemProperties;
import android.os.Trace;
+import android.provider.DeviceConfig;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
@@ -42,13 +44,14 @@
import com.android.internal.R;
import dalvik.system.PathClassLoader;
-import java.io.File;
-import java.lang.reflect.Method;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
import java.util.HashMap;
/**
@@ -78,8 +81,6 @@
private static final String TAG = LayoutInflater.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final String USE_PRECOMPILED_LAYOUT_SYSTEM_PROPERTY
- = "view.precompiled_layout_enabled";
private static final String COMPILED_VIEW_DEX_FILE_NAME = "/compiled_view.dex";
/** Empty stack trace used to avoid log spam in re-throw exceptions. */
@@ -400,8 +401,19 @@
}
private void initPrecompiledViews() {
- initPrecompiledViews(
- SystemProperties.getBoolean(USE_PRECOMPILED_LAYOUT_SYSTEM_PROPERTY, false));
+ // Use the device config if enabled, otherwise default to the system property.
+ String usePrecompiledLayout = DeviceConfig.getProperty(
+ DeviceConfig.Runtime.NAMESPACE,
+ DeviceConfig.Runtime.USE_PRECOMPILED_LAYOUT);
+ boolean enabled = false;
+ if (TextUtils.isEmpty(usePrecompiledLayout)) {
+ enabled = SystemProperties.getBoolean(
+ DeviceConfig.Runtime.USE_PRECOMPILED_LAYOUT,
+ false);
+ } else {
+ enabled = Boolean.parseBoolean(usePrecompiledLayout);
+ }
+ initPrecompiledViews(enabled);
}
private void initPrecompiledViews(boolean enablePrecompiledViews) {
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index 78ad0da..1dbc46b 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -24,6 +24,7 @@
import android.graphics.Paint;
import android.graphics.RecordingCanvas;
import android.graphics.RenderNode;
+import android.os.Build;
import android.util.SparseIntArray;
import com.android.internal.util.VirtualRefBasePtr;
@@ -282,7 +283,7 @@
throw new UnsupportedOperationException();
}
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
public void setTarget(View view) {
mViewTarget = view;
setTarget(mViewTarget.mRenderNode);
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index c189afe..dc11d3d 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -143,7 +143,7 @@
private long mCurrTime;
private long mPrevTime;
private boolean mInProgress;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768938)
private int mSpanSlop;
@UnsupportedAppUsage
private int mMinSpan;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 8061cc3..c0a4028 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -44,6 +44,7 @@
import android.hardware.HardwareBuffer;
import android.hardware.display.DisplayedContentSample;
import android.hardware.display.DisplayedContentSamplingAttributes;
+import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -131,7 +132,8 @@
private static native boolean nativeClearAnimationFrameStats();
private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
- private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
+ private static native long[] nativeGetPhysicalDisplayIds();
+ private static native IBinder nativeGetPhysicalDisplayToken(long physicalDisplayId);
private static native IBinder nativeCreateDisplay(String name, boolean secure);
private static native void nativeDestroyDisplay(IBinder displayToken);
private static native void nativeSetDisplaySurface(long transactionObj,
@@ -329,24 +331,6 @@
*/
private static final int SURFACE_OPAQUE = 0x02;
-
- /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
- * these are different from the logical display ids used elsewhere in the framework */
-
- /**
- * Built-in physical display id: Main display.
- * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
- * @hide
- */
- public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
-
- /**
- * Built-in physical display id: Attached HDMI display.
- * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
- * @hide
- */
- public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
-
// Display power modes.
/**
* Display power mode off: used while blanking the screen.
@@ -1729,9 +1713,28 @@
/**
* @hide
*/
- @UnsupportedAppUsage
- public static IBinder getBuiltInDisplay(int builtInDisplayId) {
- return nativeGetBuiltInDisplay(builtInDisplayId);
+ public static long[] getPhysicalDisplayIds() {
+ return nativeGetPhysicalDisplayIds();
+ }
+
+ /**
+ * @hide
+ */
+ public static IBinder getPhysicalDisplayToken(long physicalDisplayId) {
+ return nativeGetPhysicalDisplayToken(physicalDisplayId);
+ }
+
+ /**
+ * TODO(116025192): Remove this stopgap once framework is display-agnostic.
+ *
+ * @hide
+ */
+ public static IBinder getInternalDisplayToken() {
+ final long[] physicalDisplayIds = getPhysicalDisplayIds();
+ if (physicalDisplayIds.length == 0) {
+ return null;
+ }
+ return getPhysicalDisplayToken(physicalDisplayIds[0]);
}
/**
@@ -1790,8 +1793,12 @@
public static Bitmap screenshot(Rect sourceCrop, int width, int height,
boolean useIdentityTransform, int rotation) {
// TODO: should take the display as a parameter
- IBinder displayToken = SurfaceControl.getBuiltInDisplay(
- SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
+ final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
+ if (displayToken == null) {
+ Log.w(TAG, "Failed to take screenshot because internal display is disconnected");
+ return null;
+ }
+
if (rotation == ROTATION_90 || rotation == ROTATION_270) {
rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90;
}
@@ -2194,7 +2201,7 @@
/**
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
sc.checkNotReleased();
nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack);
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index ecbec65..cd5207c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -492,7 +492,7 @@
if (mBackgroundControl == null) {
return;
}
- if ((mSurfaceFlags & PixelFormat.OPAQUE) != 0) {
+ if ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0) {
mBackgroundControl.show();
mBackgroundControl.setLayer(Integer.MIN_VALUE);
} else {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 992b996..cb8f703 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -82,6 +82,7 @@
import android.sysprop.DisplayProperties;
import android.text.InputType;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.LayoutDirection;
@@ -102,6 +103,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeIdManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
@@ -126,7 +128,6 @@
import android.widget.ScrollBarDrawable;
import com.android.internal.R;
-import com.android.internal.util.Preconditions;
import com.android.internal.view.TooltipPopup;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.widget.ScrollBarUtils;
@@ -813,6 +814,8 @@
*/
private static final String CONTENT_CAPTURE_LOG_TAG = "View.ContentCapture";
+ private static final boolean DEBUG_CONTENT_CAPTURE = false;
+
/**
* When set to true, this view will save its attribute data.
*
@@ -3393,9 +3396,12 @@
* Masks for mPrivateFlags4, as generated by dumpFlags():
*
* |-------|-------|-------|-------|
- * 1111 PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK
- * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED
- * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED
+ * 1111 PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK
+ * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED
+ * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED
+ * 1 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED
+ * 1 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE
+ * 11 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK
* |-------|-------|-------|-------|
*/
@@ -3422,6 +3428,17 @@
private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED = 0x10;
private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED = 0x20;
+ /*
+ * Flags used to cache the value returned by isImportantForContentCapture while the view
+ * hierarchy is being traversed.
+ */
+ private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED = 0x40;
+ private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE = 0x80;
+
+ private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK =
+ PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED
+ | PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE;
+
/* End of masks for mPrivateFlags4 */
/** @hide */
@@ -4140,17 +4157,24 @@
* The layout parameters associated with this view and used by the parent
* {@link android.view.ViewGroup} to determine how this view should be
* laid out.
+ *
+ * The field should not be used directly. Instead {@link #getLayoutParams()} and {@link
+ * #setLayoutParams(ViewGroup.LayoutParams)} should be used. The setter guarantees internal
+ * state correctness of the class.
* {@hide}
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
protected ViewGroup.LayoutParams mLayoutParams;
/**
* The view flags hold various views states.
+ *
+ * Use {@link #setTransitionVisibility(int)} to change the visibility of this view without
+ * triggering updates.
* {@hide}
*/
@ViewDebug.ExportedProperty(formatToHexString = true)
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
int mViewFlags;
static class TransformationInfo {
@@ -4235,47 +4259,51 @@
/**
* The offset, in pixels, by which the content of this view is scrolled
* horizontally.
+ * Please use {@link View#getScrollX()} and {@link View#setScrollX(int)} instead of
+ * accessing these directly.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "scrolling")
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
protected int mScrollX;
/**
* The offset, in pixels, by which the content of this view is scrolled
* vertically.
+ * Please use {@link View#getScrollY()} and {@link View#setScrollY(int)} instead of
+ * accessing these directly.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "scrolling")
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
protected int mScrollY;
/**
- * The left padding in pixels, that is the distance in pixels between the
- * left edge of this view and the left edge of its content.
+ * The final computed left padding in pixels that is used for drawing. This is the distance in
+ * pixels between the left edge of this view and the left edge of its content.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "padding")
@UnsupportedAppUsage
protected int mPaddingLeft = 0;
/**
- * The right padding in pixels, that is the distance in pixels between the
- * right edge of this view and the right edge of its content.
+ * The final computed right padding in pixels that is used for drawing. This is the distance in
+ * pixels between the right edge of this view and the right edge of its content.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "padding")
@UnsupportedAppUsage
protected int mPaddingRight = 0;
/**
- * The top padding in pixels, that is the distance in pixels between the
- * top edge of this view and the top edge of its content.
+ * The final computed top padding in pixels that is used for drawing. This is the distance in
+ * pixels between the top edge of this view and the top edge of its content.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "padding")
@UnsupportedAppUsage
protected int mPaddingTop;
/**
- * The bottom padding in pixels, that is the distance in pixels between the
- * bottom edge of this view and the bottom edge of its content.
+ * The final computed bottom padding in pixels that is used for drawing. This is the distance in
+ * pixels between the bottom edge of this view and the bottom edge of its content.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "padding")
@@ -4327,7 +4355,7 @@
private MatchIdPredicate mMatchIdPredicate;
/**
- * Cache the paddingRight set by the user to append to the scrollbar's size.
+ * The right padding after RTL resolution, but before taking account of scroll bars.
*
* @hide
*/
@@ -4335,7 +4363,7 @@
protected int mUserPaddingRight;
/**
- * Cache the paddingBottom set by the user to append to the scrollbar's size.
+ * The resolved bottom padding before taking account of scroll bars.
*
* @hide
*/
@@ -4343,7 +4371,7 @@
protected int mUserPaddingBottom;
/**
- * Cache the paddingLeft set by the user to append to the scrollbar's size.
+ * The left padding after RTL resolution, but before taking account of scroll bars.
*
* @hide
*/
@@ -4365,14 +4393,16 @@
int mUserPaddingEnd;
/**
- * Cache initial left padding.
+ * The left padding as set by a setter method, a background's padding, or via XML property
+ * resolution. This value is the padding before LTR resolution or taking account of scrollbars.
*
* @hide
*/
int mUserPaddingLeftInitial;
/**
- * Cache initial right padding.
+ * The right padding as set by a setter method, a background's padding, or via XML property
+ * resolution. This value is the padding before LTR resolution or taking account of scrollbars.
*
* @hide
*/
@@ -4384,12 +4414,14 @@
private static final int UNDEFINED_PADDING = Integer.MIN_VALUE;
/**
- * Cache if a left padding has been defined
+ * Cache if a left padding has been defined explicitly via padding, horizontal padding,
+ * or leftPadding in XML, or by setPadding(...) or setRelativePadding(...)
*/
private boolean mLeftPaddingDefined = false;
/**
- * Cache if a right padding has been defined
+ * Cache if a right padding has been defined explicitly via padding, horizontal padding,
+ * or rightPadding in XML, or by setPadding(...) or setRelativePadding(...)
*/
private boolean mRightPaddingDefined = false;
@@ -5042,12 +5074,17 @@
* view (through {@link #setContentCaptureSession(ContentCaptureSession)}.
*/
@Nullable
- private WeakReference<ContentCaptureSession> mContentCaptureSession;
+ private ContentCaptureSession mContentCaptureSession;
@LayoutRes
private int mSourceLayoutId = ID_NULL;
/**
+ * Cached reference to the {@link ContentCaptureSession}, is reset on {@link #invalidate()}.
+ */
+ private ContentCaptureSession mCachedContentCaptureSession;
+
+ /**
* Simple constructor to use when creating a view from code.
*
* @param context The Context the view is running in, through which it can
@@ -5293,7 +5330,7 @@
case com.android.internal.R.styleable.View_paddingVertical:
paddingVertical = a.getDimensionPixelSize(attr, -1);
break;
- case com.android.internal.R.styleable.View_paddingLeft:
+ case com.android.internal.R.styleable.View_paddingLeft:
leftPadding = a.getDimensionPixelSize(attr, -1);
mUserPaddingLeftInitial = leftPadding;
leftPaddingDefined = true;
@@ -5759,7 +5796,7 @@
setOverScrollMode(overScrollMode);
- // Cache start/end user padding as we cannot fully resolve padding here (we dont have yet
+ // Cache start/end user padding as we cannot fully resolve padding here (we don't have yet
// the resolved layout direction). Those cached values will be used later during padding
// resolution.
mUserPaddingStart = startPadding;
@@ -5774,6 +5811,8 @@
mLeftPaddingDefined = leftPaddingDefined;
mRightPaddingDefined = rightPaddingDefined;
+ // Valid paddingHorizontal/paddingVertical beats leftPadding, rightPadding, topPadding,
+ // bottomPadding, and padding set by background. Valid padding beats everything.
if (padding >= 0) {
leftPadding = padding;
topPadding = padding;
@@ -5826,6 +5865,8 @@
}
}
+ // mPaddingTop and mPaddingBottom may have been set by setBackground(Drawable) so must pass
+ // them on if topPadding or bottomPadding are not valid.
internalSetPadding(
mUserPaddingLeftInitial,
topPadding >= 0 ? topPadding : mPaddingTop,
@@ -8233,15 +8274,7 @@
* </ul>
*/
public void onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) {
- if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW,
- "onProvideContentCaptureStructure() for " + getClass().getSimpleName());
- }
- try {
- onProvideStructure(structure, VIEW_STRUCTURE_FOR_CONTENT_CAPTURE, flags);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- }
+ onProvideStructure(structure, VIEW_STRUCTURE_FOR_CONTENT_CAPTURE, flags);
}
/** @hide */
@@ -8952,6 +8985,27 @@
* @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
*/
public final boolean isImportantForContentCapture() {
+ boolean isImportant;
+ if ((mPrivateFlags4 & PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED) != 0) {
+ isImportant = (mPrivateFlags4 & PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE) != 0;
+ return isImportant;
+ }
+
+ isImportant = calculateIsImportantForContentCapture();
+
+ mPrivateFlags4 &= ~PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE;
+ if (isImportant) {
+ mPrivateFlags4 |= PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE;
+ }
+ mPrivateFlags4 |= PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED;
+ return isImportant;
+ }
+
+ /**
+ * Calculates whether the flag is important for content capture so it can be used by
+ * {@link #isImportantForContentCapture()} while the tree is traversed.
+ */
+ private boolean calculateIsImportantForContentCapture() {
// Check parent mode to ensure we're important
ViewParent parent = mParent;
while (parent instanceof View) {
@@ -8992,9 +9046,6 @@
}
// View group is important if at least one children also is
- //TODO(b/111276913): decide if we really need to send the relevant parents or just the
- // leaves (with absolute coordinates). If it's the latter, then we need to update this
- // javadoc and ViewGroup's implementation.
if (this instanceof ViewGroup) {
final ViewGroup group = (ViewGroup) this;
for (int i = 0; i < group.getChildCount(); i++) {
@@ -9031,6 +9082,10 @@
* </ol>
*/
private void notifyAppearedOrDisappearedForContentCaptureIfNeeded(boolean appeared) {
+ AttachInfo ai = mAttachInfo;
+ // Skip it while the view is being laided out for the first time
+ if (ai != null && !ai.mReadyForContentCaptureUpdates) return;
+
if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW,
"notifyContentCapture(" + appeared + ") for " + getClass().getSimpleName());
@@ -9043,24 +9098,27 @@
}
private void notifyAppearedOrDisappearedForContentCaptureIfNeededNoTrace(boolean appeared) {
+ AttachInfo ai = mAttachInfo;
+
// First check if context has client, so it saves a service lookup when it doesn't
if (!mContext.isContentCaptureSupported()) return;
// Then check if it's enabled in the context...
- final ContentCaptureManager ccm = mContext.getSystemService(ContentCaptureManager.class);
+ final ContentCaptureManager ccm = ai != null ? ai.getContentCaptureManager(mContext)
+ : mContext.getSystemService(ContentCaptureManager.class);
if (ccm == null || !ccm.isContentCaptureEnabled()) return;
// ... and finally at the view level
// NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled()
if (!isImportantForContentCapture()) return;
- final ContentCaptureSession session = getContentCaptureSession(ccm);
+ ContentCaptureSession session = getContentCaptureSession();
if (session == null) return;
if (appeared) {
if (!isLaidOut() || getVisibility() != VISIBLE
|| (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0) {
- if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ if (DEBUG_CONTENT_CAPTURE) {
Log.v(CONTENT_CAPTURE_LOG_TAG, "Ignoring 'appeared' on " + this + ": laid="
+ isLaidOut() + ", visibleToUser=" + isVisibleToUser()
+ ", visible=" + (getVisibility() == VISIBLE)
@@ -9071,8 +9129,12 @@
}
return;
}
- mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
- mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
+ setNotifiedContentCaptureAppeared();
+
+ // TODO(b/123307965): instead of post, we should queue it on AttachInfo and then
+ // dispatch on RootImpl, as we're doing with the removed ones (in that case, we should
+ // merge the delayNotifyContentCaptureDisappeared() into a more generic method that
+ // takes a session and a command, where the command is either view added or removed
// The code below doesn't take much for a unique view, but it's called for all views
// the first time the view hiearchy is laid off, which could acccumulative delay the
@@ -9086,7 +9148,7 @@
} else {
if ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) == 0
|| (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0) {
- if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ if (DEBUG_CONTENT_CAPTURE) {
Log.v(CONTENT_CAPTURE_LOG_TAG, "Ignoring 'disappeared' on " + this + ": laid="
+ isLaidOut() + ", visibleToUser=" + isVisibleToUser()
+ ", visible=" + (getVisibility() == VISIBLE)
@@ -9099,11 +9161,24 @@
}
mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
- Choreographer.getInstance().postCallback(Choreographer.CALLBACK_COMMIT,
- () -> session.notifyViewDisappeared(getAutofillId()), /* token= */ null);
+
+ if (ai != null) {
+ ai.delayNotifyContentCaptureDisappeared(session, getAutofillId());
+ } else {
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on gone for " + this);
+ }
+ Choreographer.getInstance().postCallback(Choreographer.CALLBACK_COMMIT,
+ () -> session.notifyViewDisappeared(getAutofillId()), /* token= */ null);
+ }
}
}
+ private void setNotifiedContentCaptureAppeared() {
+ mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
+ mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
+ }
+
/**
* Sets the (optional) {@link ContentCaptureSession} associated with this view.
*
@@ -9127,9 +9202,8 @@
* {@link ContentCaptureSession#createContentCaptureSession(
* android.view.contentcapture.ContentCaptureContext)}.
*/
- public void setContentCaptureSession(@NonNull ContentCaptureSession contentCaptureSession) {
- mContentCaptureSession = new WeakReference<>(
- Preconditions.checkNotNull(contentCaptureSession));
+ public void setContentCaptureSession(@Nullable ContentCaptureSession contentCaptureSession) {
+ mContentCaptureSession = contentCaptureSession;
}
/**
@@ -9141,8 +9215,18 @@
*/
@Nullable
public final ContentCaptureSession getContentCaptureSession() {
+ if (mCachedContentCaptureSession != null) {
+ return mCachedContentCaptureSession;
+ }
+
+ mCachedContentCaptureSession = getAndCacheContentCaptureSession();
+ return mCachedContentCaptureSession;
+ }
+
+ @Nullable
+ private ContentCaptureSession getAndCacheContentCaptureSession() {
// First try the session explicitly set by setContentCaptureSession()
- if (mContentCaptureSession != null) return mContentCaptureSession.get();
+ if (mContentCaptureSession != null) return mContentCaptureSession;
// Then the session explicitly set in an ancestor
ContentCaptureSession session = null;
@@ -9159,21 +9243,6 @@
return session;
}
- /**
- * Optimized version of {@link #getContentCaptureSession()} that avoids a service lookup.
- */
- @Nullable
- private ContentCaptureSession getContentCaptureSession(@NonNull ContentCaptureManager ccm) {
- if (mContentCaptureSession != null) return mContentCaptureSession.get();
-
- ContentCaptureSession session = null;
- if (mParent instanceof View) {
- session = ((View) mParent).getContentCaptureSession(ccm);
- }
-
- return session != null ? session : ccm.getMainContentCaptureSession();
- }
-
@Nullable
private AutofillManager getAutofillManager() {
return mContext.getSystemService(AutofillManager.class);
@@ -9346,6 +9415,62 @@
}
/**
+ * Dispatches the initial Content Capture events for a view structure.
+ *
+ * @hide
+ */
+ public void dispatchInitialProvideContentCaptureStructure(@NonNull ContentCaptureManager ccm) {
+ AttachInfo ai = mAttachInfo;
+ if (ai == null) {
+ Log.w(CONTENT_CAPTURE_LOG_TAG,
+ "dispatchProvideContentCaptureStructure(): no AttachInfo for " + this);
+ return;
+ }
+
+ // We must set it before checkign if the view itself is important, because it might
+ // initially not be (for example, if it's empty), although that might change later (for
+ // example, if important views are added)
+ ai.mReadyForContentCaptureUpdates = true;
+
+ if (!isImportantForContentCapture()) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.DEBUG)) {
+ Log.d(CONTENT_CAPTURE_LOG_TAG,
+ "dispatchProvideContentCaptureStructure(): decorView is not important");
+ }
+ return;
+ }
+
+ ai.mContentCaptureManager = ccm;
+
+ ContentCaptureSession session = getContentCaptureSession();
+ if (session == null) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.DEBUG)) {
+ Log.d(CONTENT_CAPTURE_LOG_TAG,
+ "dispatchProvideContentCaptureStructure(): no session for " + this);
+ }
+ return;
+ }
+
+ session.internalNotifyViewHierarchyEvent(/* started= */ true);
+ try {
+ dispatchProvideContentCaptureStructure();
+ } finally {
+ session.internalNotifyViewHierarchyEvent(/* started= */ false);
+ }
+ }
+
+ /** @hide */
+ void dispatchProvideContentCaptureStructure() {
+ ContentCaptureSession session = getContentCaptureSession();
+ if (session != null) {
+ ViewStructure structure = session.newViewStructure(this);
+ onProvideContentCaptureStructure(structure, /* flags= */ 0);
+ setNotifiedContentCaptureAppeared();
+ session.notifyViewAppeared(structure);
+ }
+ }
+
+ /**
* @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
*
* Note: Called from the default {@link AccessibilityDelegate}.
@@ -12801,14 +12926,17 @@
}
/**
- * Change the visibility of the View without triggering any other changes. This is
- * important for transitions, where visibility changes should not adjust focus or
- * trigger a new layout. This is only used when the visibility has already been changed
- * and we need a transient value during an animation. When the animation completes,
- * the original visibility value is always restored.
+ * Changes the visibility of this View without triggering any other changes. This should only
+ * be used by animation frameworks, such as {@link android.transition.Transition}, where
+ * visibility changes should not adjust focus or trigger a new layout. Application developers
+ * should use {@link #setVisibility} instead to ensure that the hierarchy is correctly updated.
+ *
+ * <p>Only call this method when a temporary visibility must be applied during an
+ * animation and the original visibility value is guaranteed to be reset after the
+ * animation completes. Use {@link #setVisibility} in all other cases.</p>
*
* @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
- * @hide
+ * @see #setVisibility(int)
*/
public void setTransitionVisibility(@Visibility int visibility) {
mViewFlags = (mViewFlags & ~View.VISIBILITY_MASK) | visibility;
@@ -16068,7 +16196,7 @@
* @return true if the View subclass handles alpha (the return value for onSetAlpha()) and
* the new value for the alpha property is different from the old value
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768435)
boolean setAlphaNoInvalidation(float alpha) {
ensureTransformationInfo();
if (mTransformationInfo.mAlpha != alpha) {
@@ -17457,6 +17585,10 @@
return;
}
+ // Reset content capture caches
+ mPrivateFlags4 &= ~PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK;
+ mCachedContentCaptureSession = null;
+
if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
|| (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
|| (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
@@ -18910,6 +19042,7 @@
jumpDrawablesToCurrentState();
+ AccessibilityNodeIdManager.getInstance().registerViewWithId(this, getAccessibilityViewId());
resetSubtreeAccessibilityStateChanged();
// rebuild, since Outline not maintained while View is detached
@@ -19302,6 +19435,8 @@
if ((mViewFlags & TOOLTIP) == TOOLTIP) {
hideTooltip();
}
+
+ AccessibilityNodeIdManager.getInstance().unregisterViewWithId(getAccessibilityViewId());
}
private void cleanupDraw() {
@@ -19413,7 +19548,7 @@
* @param info the {@link android.view.View.AttachInfo} to associated with
* this view
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
mAttachInfo = info;
if (mOverlay != null) {
@@ -19479,7 +19614,7 @@
notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
}
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void dispatchDetachedFromWindow() {
AttachInfo info = mAttachInfo;
if (info != null) {
@@ -21614,6 +21749,7 @@
* @return The known solid color background for this view, or 0 if the color may vary
*/
@ViewDebug.ExportedProperty(category = "drawing")
+ @InspectableProperty
@ColorInt
public int getSolidColor() {
return 0;
@@ -23815,24 +23951,6 @@
}
/**
- * Finds a view by its unuque and stable accessibility id.
- *
- * @param accessibilityId The searched accessibility id.
- * @return The found view.
- */
- @UnsupportedAppUsage
- final <T extends View> T findViewByAccessibilityId(int accessibilityId) {
- if (accessibilityId < 0) {
- return null;
- }
- T view = findViewByAccessibilityIdTraversal(accessibilityId);
- if (view != null) {
- return view.includeForAccessibility() ? view : null;
- }
- return null;
- }
-
- /**
* Performs the traversal to find a view by its unique and stable accessibility id.
*
* <strong>Note:</strong>This method does not stop at the root namespace
@@ -27963,6 +28081,23 @@
View mTooltipHost;
/**
+ * The initial structure has been reported so the view is ready to report updates.
+ */
+ boolean mReadyForContentCaptureUpdates;
+
+ /**
+ * Map of ids (per session) that need to be notified after as gone the view hierchy is
+ * traversed.
+ */
+ // TODO(b/121197119): use SparseArray once session id becomes integer
+ ArrayMap<String, ArrayList<AutofillId>> mContentCaptureRemovedIds;
+
+ /**
+ * Cached reference to the {@link ContentCaptureManager}.
+ */
+ ContentCaptureManager mContentCaptureManager;
+
+ /**
* Creates a new set of attachment information with the specified
* events handler and thread.
*
@@ -27980,6 +28115,31 @@
mRootCallbacks = effectPlayer;
mTreeObserver = new ViewTreeObserver(context);
}
+
+ private void delayNotifyContentCaptureDisappeared(@NonNull ContentCaptureSession session,
+ @NonNull AutofillId id) {
+ if (mContentCaptureRemovedIds == null) {
+ // Most of the time there will be just one session, so intial capacity is 1
+ mContentCaptureRemovedIds = new ArrayMap<>(1);
+ }
+ String sessionId = session.getId();
+ // TODO: life would be much easier if we provided a MultiMap implementation somwhere...
+ ArrayList<AutofillId> ids = mContentCaptureRemovedIds.get(sessionId);
+ if (ids == null) {
+ ids = new ArrayList<>();
+ mContentCaptureRemovedIds.put(sessionId, ids);
+ }
+ ids.add(id);
+ }
+
+ @Nullable
+ private ContentCaptureManager getContentCaptureManager(@NonNull Context context) {
+ if (mContentCaptureManager != null) {
+ return mContentCaptureManager;
+ }
+ mContentCaptureManager = context.getSystemService(ContentCaptureManager.class);
+ return mContentCaptureManager;
+ }
}
/**
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 94d1b6d..6beae37 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -24,6 +24,7 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
+import android.os.Build;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.DisplayMetrics;
@@ -314,7 +315,7 @@
private final float mHorizontalScrollFactor;
private final boolean mShowMenuShortcutsWhenKeyboardPresent;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915)
private boolean sHasPermanentMenuKey;
@UnsupportedAppUsage
private boolean sHasPermanentMenuKeySet;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0986cfa..d2b40f7 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -60,6 +60,8 @@
import android.view.animation.LayoutAnimationController;
import android.view.animation.Transformation;
import android.view.autofill.Helper;
+import android.view.inspector.InspectableProperty;
+import android.view.inspector.InspectableProperty.EnumMap;
import com.android.internal.R;
@@ -773,6 +775,11 @@
@ViewDebug.IntToString(from = FOCUS_AFTER_DESCENDANTS, to = "FOCUS_AFTER_DESCENDANTS"),
@ViewDebug.IntToString(from = FOCUS_BLOCK_DESCENDANTS, to = "FOCUS_BLOCK_DESCENDANTS")
})
+ @InspectableProperty(enumMapping = {
+ @EnumMap(value = FOCUS_BEFORE_DESCENDANTS, name = "beforeDescendants"),
+ @EnumMap(value = FOCUS_AFTER_DESCENDANTS, name = "afterDescendants"),
+ @EnumMap(value = FOCUS_BLOCK_DESCENDANTS, name = "blocksDescendants")
+ })
public int getDescendantFocusability() {
return mGroupFlags & FLAG_MASK_FOCUSABILITY;
}
@@ -1391,6 +1398,7 @@
* Check whether this ViewGroup should ignore focus requests for itself and its children.
*/
@ViewDebug.ExportedProperty(category = "focus")
+ @InspectableProperty
public boolean getTouchscreenBlocksFocus() {
return (mGroupFlags & FLAG_TOUCHSCREEN_BLOCKS_FOCUS) != 0;
}
@@ -3116,6 +3124,7 @@
* Returns true if MotionEvents dispatched to this ViewGroup can be split to multiple children.
* @return true if MotionEvents dispatched to this ViewGroup can be split to multiple children.
*/
+ @InspectableProperty(name = "splitMotionEvents")
public boolean isMotionEventSplittingEnabled() {
return (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) == FLAG_SPLIT_MOTION_EVENTS;
}
@@ -3132,6 +3141,7 @@
* {@link android.view.ViewOutlineProvider#BACKGROUND} was given to
* {@link #setOutlineProvider(ViewOutlineProvider)} and false otherwise.
*/
+ @InspectableProperty
public boolean isTransitionGroup() {
if ((mGroupFlags & FLAG_IS_TRANSITION_GROUP_SET) != 0) {
return ((mGroupFlags & FLAG_IS_TRANSITION_GROUP) != 0);
@@ -3603,7 +3613,7 @@
return;
}
- final ChildListForAutoFill children = getChildrenForAutofill(flags);
+ final ChildListForAutoFillOrContentCapture children = getChildrenForAutofill(flags);
final int childrenCount = children.size();
structure.setChildCount(childrenCount);
for (int i = 0; i < childrenCount; i++) {
@@ -3614,13 +3624,31 @@
children.recycle();
}
+ /** @hide */
+ @Override
+ public void dispatchProvideContentCaptureStructure() {
+ super.dispatchProvideContentCaptureStructure();
+
+ if (!isLaidOut()) return;
+
+ final ChildListForAutoFillOrContentCapture children = getChildrenForContentCapture();
+ final int childrenCount = children.size();
+ for (int i = 0; i < childrenCount; i++) {
+ final View child = children.get(i);
+ child.dispatchProvideContentCaptureStructure();
+ }
+ children.recycle();
+ }
+
/**
* Gets the children for autofill. Children for autofill are the first
* level descendants that are important for autofill. The returned
* child list object is pooled and the caller must recycle it once done.
* @hide */
- private @NonNull ChildListForAutoFill getChildrenForAutofill(@AutofillFlags int flags) {
- final ChildListForAutoFill children = ChildListForAutoFill.obtain();
+ private @NonNull ChildListForAutoFillOrContentCapture getChildrenForAutofill(
+ @AutofillFlags int flags) {
+ final ChildListForAutoFillOrContentCapture children = ChildListForAutoFillOrContentCapture
+ .obtain();
populateChildrenForAutofill(children, flags);
return children;
}
@@ -3647,6 +3675,34 @@
}
}
+ private @NonNull ChildListForAutoFillOrContentCapture getChildrenForContentCapture() {
+ final ChildListForAutoFillOrContentCapture children = ChildListForAutoFillOrContentCapture
+ .obtain();
+ populateChildrenForContentCapture(children);
+ return children;
+ }
+
+ /** @hide */
+ private void populateChildrenForContentCapture(ArrayList<View> list) {
+ final int childrenCount = mChildrenCount;
+ if (childrenCount <= 0) {
+ return;
+ }
+ final ArrayList<View> preorderedList = buildOrderedChildList();
+ final boolean customOrder = preorderedList == null
+ && isChildrenDrawingOrderEnabled();
+ for (int i = 0; i < childrenCount; i++) {
+ final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+ final View child = (preorderedList == null)
+ ? mChildren[childIndex] : preorderedList.get(childIndex);
+ if (child.isImportantForContentCapture()) {
+ list.add(child);
+ } else if (child instanceof ViewGroup) {
+ ((ViewGroup) child).populateChildrenForContentCapture(list);
+ }
+ }
+ }
+
private static View getAndVerifyPreorderedView(ArrayList<View> preorderedList, View[] children,
int childIndex) {
final View child;
@@ -4390,6 +4446,7 @@
* false otherwise.
*/
@ViewDebug.ExportedProperty(category = "drawing")
+ @InspectableProperty
public boolean getClipChildren() {
return ((mGroupFlags & FLAG_CLIP_CHILDREN) != 0);
}
@@ -4447,6 +4504,7 @@
* @attr ref android.R.styleable#ViewGroup_clipToPadding
*/
@ViewDebug.ExportedProperty(category = "drawing")
+ @InspectableProperty
public boolean getClipToPadding() {
return hasBooleanFlag(FLAG_CLIP_TO_PADDING);
}
@@ -6294,6 +6352,7 @@
*
* @return the current animation controller
*/
+ @InspectableProperty
public LayoutAnimationController getLayoutAnimation() {
return mLayoutAnimationController;
}
@@ -6313,6 +6372,7 @@
* Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
*/
@Deprecated
+ @InspectableProperty(name = "animationCache")
public boolean isAnimationCacheEnabled() {
return (mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE;
}
@@ -6350,6 +6410,7 @@
* Child views may no longer have their caching behavior disabled by parents.
*/
@Deprecated
+ @InspectableProperty(name = "alwaysDrawnWithCache")
public boolean isAlwaysDrawnWithCacheEnabled() {
return (mGroupFlags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE;
}
@@ -6493,6 +6554,12 @@
@ViewDebug.IntToString(from = PERSISTENT_SCROLLING_CACHE, to = "SCROLLING"),
@ViewDebug.IntToString(from = PERSISTENT_ALL_CACHES, to = "ALL")
})
+ @InspectableProperty(enumMapping = {
+ @EnumMap(value = PERSISTENT_NO_CACHE, name = "none"),
+ @EnumMap(value = PERSISTENT_ANIMATION_CACHE, name = "animation"),
+ @EnumMap(value = PERSISTENT_SCROLLING_CACHE, name = "scrolling"),
+ @EnumMap(value = PERSISTENT_ALL_CACHES, name = "all"),
+ })
public int getPersistentDrawingCache() {
return mPersistentDrawingCache;
}
@@ -6570,6 +6637,10 @@
*
* @see #setLayoutMode(int)
*/
+ @InspectableProperty(enumMapping = {
+ @EnumMap(value = LAYOUT_MODE_CLIP_BOUNDS, name = "clipBounds"),
+ @EnumMap(value = LAYOUT_MODE_OPTICAL_BOUNDS, name = "opticalBounds")
+ })
public int getLayoutMode() {
if (mLayoutMode == LAYOUT_MODE_UNDEFINED) {
int inheritedLayoutMode = (mParent instanceof ViewGroup) ?
@@ -7261,6 +7332,7 @@
* make a group appear to be focused when its child EditText or button
* is focused.
*/
+ @InspectableProperty
public boolean addStatesFromChildren() {
return (mGroupFlags & FLAG_ADD_STATES_FROM_CHILDREN) != 0;
}
@@ -8544,16 +8616,16 @@
/**
* Pooled class that to hold the children for autifill.
*/
- static class ChildListForAutoFill extends ArrayList<View> {
+ private static class ChildListForAutoFillOrContentCapture extends ArrayList<View> {
private static final int MAX_POOL_SIZE = 32;
- private static final Pools.SimplePool<ChildListForAutoFill> sPool =
+ private static final Pools.SimplePool<ChildListForAutoFillOrContentCapture> sPool =
new Pools.SimplePool<>(MAX_POOL_SIZE);
- public static ChildListForAutoFill obtain() {
- ChildListForAutoFill list = sPool.acquire();
+ public static ChildListForAutoFillOrContentCapture obtain() {
+ ChildListForAutoFillOrContentCapture list = sPool.acquire();
if (list == null) {
- list = new ChildListForAutoFill();
+ list = new ChildListForAutoFillOrContentCapture();
}
return list;
}
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index a0ab362..68c0d9e 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -1139,12 +1139,6 @@
boolean hardwareAccelerated = mView.isHardwareAccelerated();
- // alpha requires slightly different treatment than the other (transform) properties.
- // The logic in setAlpha() is not simply setting mAlpha, plus the invalidation
- // logic is dependent on how the view handles an internal call to onSetAlpha().
- // We track what kinds of properties are set, and how alpha is handled when it is
- // set, and perform the invalidation steps appropriately.
- boolean alphaHandled = false;
if (!hardwareAccelerated) {
mView.invalidateParentCaches();
}
@@ -1159,11 +1153,7 @@
for (int i = 0; i < count; ++i) {
NameValuesHolder values = valueList.get(i);
float value = values.mFromValue + fraction * values.mDeltaValue;
- if (values.mNameConstant == ALPHA) {
- alphaHandled = mView.setAlphaNoInvalidation(value);
- } else {
- setValue(values.mNameConstant, value);
- }
+ setValue(values.mNameConstant, value);
}
}
if ((propertyMask & TRANSFORM_MASK) != 0) {
@@ -1171,13 +1161,8 @@
mView.mPrivateFlags |= View.PFLAG_DRAWN; // force another invalidation
}
}
- // invalidate(false) in all cases except if alphaHandled gets set to true
- // via the call to setAlphaNoInvalidation(), above
- if (alphaHandled) {
- mView.invalidate(true);
- } else {
- mView.invalidateViewProperty(false, false);
- }
+
+ mView.invalidateViewProperty(false, false);
if (mUpdateListener != null) {
mUpdateListener.onAnimationUpdate(animation);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9a317db..67cca56 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -95,6 +95,7 @@
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.view.accessibility.AccessibilityManager.HighTextContrastChangeListener;
+import android.view.accessibility.AccessibilityNodeIdManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
@@ -103,7 +104,10 @@
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
+import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
+import android.view.contentcapture.ContentCaptureManager;
+import android.view.contentcapture.MainContentCaptureSession;
import android.view.inputmethod.InputMethodManager;
import android.widget.Scroller;
@@ -154,6 +158,7 @@
private static final boolean DEBUG_FPS = false;
private static final boolean DEBUG_INPUT_STAGES = false || LOCAL_LOGV;
private static final boolean DEBUG_KEEP_SCREEN_ON = false || LOCAL_LOGV;
+ private static final boolean DEBUG_CONTENT_CAPTURE = false || LOCAL_LOGV;
/**
* Set to false if we do not want to use the multi threaded renderer even though
@@ -180,7 +185,7 @@
* @see #USE_NEW_INSETS_PROPERTY
* @hide
*/
- public static final int sNewInsetsMode =
+ public static int sNewInsetsMode =
SystemProperties.getInt(USE_NEW_INSETS_PROPERTY, 0);
/**
@@ -412,6 +417,7 @@
boolean mApplyInsetsRequested;
boolean mLayoutRequested;
boolean mFirst;
+ boolean mPerformContentCapture;
boolean mReportNextDraw;
boolean mFullRedrawNeeded;
boolean mNewSurfaceNeeded;
@@ -608,6 +614,7 @@
mTransparentRegion = new Region();
mPreviousTransparentRegion = new Region();
mFirst = true; // true for the first time the view is added
+ mPerformContentCapture = true; // also true for the first time the view is added
mAdded = false;
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
context);
@@ -2756,6 +2763,24 @@
}
}
+ if (mAttachInfo.mContentCaptureRemovedIds != null) {
+ MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager
+ .getMainContentCaptureSession();
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureViewsGone");
+ try {
+ for (int i = 0; i < mAttachInfo.mContentCaptureRemovedIds.size(); i++) {
+ String sessionId = mAttachInfo.mContentCaptureRemovedIds
+ .keyAt(i);
+ ArrayList<AutofillId> ids = mAttachInfo.mContentCaptureRemovedIds
+ .valueAt(i);
+ mainSession.notifyViewsDisappeared(sessionId, ids);
+ }
+ mAttachInfo.mContentCaptureRemovedIds = null;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
+ }
+
mIsInTraversal = false;
}
@@ -3451,6 +3476,35 @@
pendingDrawFinished();
}
}
+ if (mPerformContentCapture) {
+ performContentCapture();
+ }
+ }
+
+ private void performContentCapture() {
+ mPerformContentCapture = false; // One-time offer!
+ final View rootView = mView;
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.v(mTag, "dispatchContentCapture() on " + rootView);
+ }
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "dispatchContentCapture() for "
+ + getClass().getSimpleName());
+ }
+ try {
+ // First check if context supports it, so it saves a service lookup when it doesn't
+ if (!mContext.isContentCaptureSupported()) return;
+
+ // Then check if it's enabled in the contex itself.
+ final ContentCaptureManager ccm = mContext
+ .getSystemService(ContentCaptureManager.class);
+ if (ccm == null || !ccm.isContentCaptureEnabled()) return;
+
+ // Content capture is a go!
+ rootView.dispatchInitialProvideContentCaptureStructure(ccm);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
}
private boolean draw(boolean fullRedrawNeeded) {
@@ -7901,17 +7955,14 @@
// Intercept accessibility focus events fired by virtual nodes to keep
// track of accessibility focus position in such nodes.
final int eventType = event.getEventType();
+ final View source = getSourceForAccessibilityEvent(event);
switch (eventType) {
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
- final long sourceNodeId = event.getSourceNodeId();
- final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
- sourceNodeId);
- View source = mView.findViewByAccessibilityId(accessibilityViewId);
if (source != null) {
AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
if (provider != null) {
final int virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
- sourceNodeId);
+ event.getSourceNodeId());
final AccessibilityNodeInfo node;
node = provider.createAccessibilityNodeInfo(virtualNodeId);
setAccessibilityFocus(source, node);
@@ -7919,15 +7970,8 @@
}
} break;
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
- final long sourceNodeId = event.getSourceNodeId();
- final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
- sourceNodeId);
- View source = mView.findViewByAccessibilityId(accessibilityViewId);
- if (source != null) {
- AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
- if (provider != null) {
- setAccessibilityFocus(null, null);
- }
+ if (source != null && source.getAccessibilityNodeProvider() != null) {
+ setAccessibilityFocus(null, null);
}
} break;
@@ -7940,6 +7984,13 @@
return true;
}
+ private View getSourceForAccessibilityEvent(AccessibilityEvent event) {
+ final long sourceNodeId = event.getSourceNodeId();
+ final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+ sourceNodeId);
+ return AccessibilityNodeIdManager.getInstance().findView(accessibilityViewId);
+ }
+
/**
* Updates the focused virtual view, when necessary, in response to a
* content changed event.
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 16bafe2..35ed7bf 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -16,6 +16,11 @@
package android.view;
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Constants for interfacing with WindowManagerService and WindowManagerPolicyInternal.
* @hide
@@ -89,6 +94,35 @@
/** Screen turned off because of timeout */
int OFF_BECAUSE_OF_TIMEOUT = 3;
+ @IntDef(prefix = { "ON_BECAUSE_OF_" }, value = {
+ ON_BECAUSE_OF_USER,
+ ON_BECAUSE_OF_APPLICATION,
+ ON_BECAUSE_OF_UNKNOWN,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface OnReason{}
+
+ /** Convert the on reason to a human readable format */
+ static String onReasonToString(@OnReason int why) {
+ switch (why) {
+ case ON_BECAUSE_OF_USER:
+ return "ON_BECAUSE_OF_USER";
+ case ON_BECAUSE_OF_APPLICATION:
+ return "ON_BECAUSE_OF_APPLICATION";
+ case ON_BECAUSE_OF_UNKNOWN:
+ return "ON_BECAUSE_OF_UNKNOWN";
+ default:
+ return Integer.toString(why);
+ }
+ }
+
+ /** Screen turned on because of a user-initiated action. */
+ int ON_BECAUSE_OF_USER = 1;
+ /** Screen turned on because of an application request or event */
+ int ON_BECAUSE_OF_APPLICATION = 2;
+ /** Screen turned on for an unknown reason */
+ int ON_BECAUSE_OF_UNKNOWN = 3;
+
int APPLICATION_LAYER = 2;
int APPLICATION_MEDIA_SUBLAYER = -2;
int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 6aafa34..06207a9 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -36,6 +36,7 @@
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -183,7 +184,7 @@
boolean mIsTouchExplorationEnabled;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768939)
boolean mIsHighTextContrastEnabled;
AccessibilityPolicy mAccessibilityPolicy;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeIdManager.java b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
new file mode 100644
index 0000000..1ac7047
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import android.util.SparseArray;
+import android.view.View;
+
+/** @hide */
+public final class AccessibilityNodeIdManager {
+ private SparseArray<View> mIdsToViews = new SparseArray<>();
+ private static AccessibilityNodeIdManager sIdManager;
+
+ /**
+ * Gets singleton.
+ * @return The instance.
+ */
+ public static synchronized AccessibilityNodeIdManager getInstance() {
+ if (sIdManager == null) {
+ sIdManager = new AccessibilityNodeIdManager();
+ }
+ return sIdManager;
+ }
+
+ private AccessibilityNodeIdManager() {
+ }
+
+ /**
+ * Register view to be kept track of by the accessibility system.
+ * Must be paired with unregisterView, otherwise this will leak.
+ * @param view The view to be registered.
+ * @param id The accessibilityViewId of the view.
+ */
+ public void registerViewWithId(View view, int id) {
+ mIdsToViews.append(id, view);
+ }
+
+ /**
+ * Unregister view, accessibility won't keep track of this view after this call.
+ * @param id The id returned from registerView when the view as first associated.
+ */
+ public void unregisterViewWithId(int id) {
+ mIdsToViews.remove(id);
+ }
+
+ /**
+ * Accessibility uses this to find the view in the hierarchy.
+ * @param id The accessibility view id.
+ * @return The view.
+ */
+ public View findView(int id) {
+ final View view = mIdsToViews.get(id);
+ return view != null && view.includeForAccessibility() ? view : null;
+ }
+}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 64c34f6..1c96b87 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -79,7 +79,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
//TODO: use java.lang.ref.Cleaner once Android supports Java 9
import sun.misc.Cleaner;
@@ -1769,45 +1768,6 @@
}
/**
- * Defines whether augmented autofill should be triggered for activities with such
- * {@link android.content.ComponentName}.
- *
- * <p>Useful to blacklist a particular activity.
- *
- * <p><b>Note:</b> This method should only be called by the app providing the augmented autofill
- * service, and it's ignored if the caller isn't it.
- *
- * @hide
- */
- @SystemApi
- @TestApi
- //TODO(b/122654591): @TestApi is needed because CtsAutoFillServiceTestCases hosts the service
- //in the same package as the test, and that module is compiled with SDK=test_current
- public void setActivityAugmentedAutofillEnabled(@NonNull ComponentName activity,
- boolean enabled) {
- // TODO(b/123100824): implement
- }
-
- /**
- * Defines whether augmented autofill should be triggered for activities of the app with such
- * {@code packageName}.
- *
- * <p>Useful to blacklist any activity from a particular app.
- *
- * <p><b>Note:</b> This method should only be called by the app providing the augmented autofill
- * service, and it's ignored if the caller isn't it.
- *
- * @hide
- */
- @SystemApi
- @TestApi
- //TODO(b/122654591): @TestApi is needed because CtsAutoFillServiceTestCases hosts the service
- //in the same package as the test, and that module is compiled with SDK=test_current
- public void setPackageAugmentedAutofillEnabled(@NonNull String packageName, boolean enabled) {
- // TODO(b/123100824): implement
- }
-
- /**
* Explicitly limits augmented autofill to the given packages and activities.
*
* <p>When the whitelist is set, it overrides the values passed to
@@ -1838,38 +1798,6 @@
// TODO(b/123100824): implement
}
- /**
- * Gets the activities where augmented autofill was disabled by
- * {@link #setActivityAugmentedAutofillEnabled(ComponentName, boolean)}.
- *
- * <p><b>Note:</b> This method should only be called by the app providing the augmented autofill
- * service, and it's ignored if the caller isn't it.
- *
- * @hide
- */
- @SystemApi
- @TestApi
- @NonNull
- public Set<ComponentName> getAugmentedAutofillDisabledActivities() {
- return null; // TODO(b/123100824): implement
- }
-
- /**
- * Gets the apps where content capture was disabled by
- * {@link #setPackageAugmentedAutofillEnabled(String, boolean)}.
- *
- * <p><b>Note:</b> This method should only be called by the app providing the augmented autofill
- * service, and it's ignored if the caller isn't it.
- *
- * @hide
- */
- @SystemApi
- @TestApi
- @NonNull
- public Set<String> getAugmentedAutofillDisabledPackages() {
- return null; // TODO(b/123100824): implement
- }
-
private void requestShowFillUi(int sessionId, AutofillId id, int width, int height,
Rect anchorBounds, IAutofillWindowPresenter presenter) {
final View anchor = findView(id);
diff --git a/core/java/android/view/contentcapture/ChildContentCaptureSession.java b/core/java/android/view/contentcapture/ChildContentCaptureSession.java
index 63c21f3..acb81e0 100644
--- a/core/java/android/view/contentcapture/ChildContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ChildContentCaptureSession.java
@@ -93,6 +93,11 @@
}
@Override
+ public void internalNotifyViewHierarchyEvent(boolean started) {
+ getMainCaptureSession().notifyInitialViewHierarchyEvent(mId, started);
+ }
+
+ @Override
boolean isContentCaptureEnabled() {
return getMainCaptureSession().isContentCaptureEnabled();
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureContext.java b/core/java/android/view/contentcapture/ContentCaptureContext.java
index 5814759..6a9759d 100644
--- a/core/java/android/view/contentcapture/ContentCaptureContext.java
+++ b/core/java/android/view/contentcapture/ContentCaptureContext.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
@@ -57,6 +58,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static final int FLAG_DISABLED_BY_APP = 0x1;
/**
@@ -67,6 +69,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static final int FLAG_DISABLED_BY_FLAG_SECURE = 0x2;
/** @hide */
@@ -136,6 +139,7 @@
* @hide
*/
@SystemApi
+ @TestApi
@Nullable
public Bundle getExtras() {
return mExtras;
@@ -147,6 +151,7 @@
* @hide
*/
@SystemApi
+ @TestApi
@Nullable
public Uri getUri() {
return mUri;
@@ -158,6 +163,7 @@
* @hide
*/
@SystemApi
+ @TestApi
@Nullable
public String getAction() {
return mAction;
@@ -169,6 +175,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public int getTaskId() {
return mTaskId;
}
@@ -179,6 +186,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public @Nullable ComponentName getActivityComponent() {
return mComponentName;
}
@@ -191,6 +199,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public @Nullable ContentCaptureSessionId getParentSessionId() {
return mParentSessionId == null ? null : new ContentCaptureSessionId(mParentSessionId);
}
@@ -207,6 +216,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public int getDisplayId() {
return mDisplayId;
}
@@ -220,7 +230,8 @@
* @hide
*/
@SystemApi
- public @ContextCreationFlags int getFlags() {
+ @TestApi
+ public @ContextCreationFlags int getFlags() {
return mFlags;
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index a6d4472..22254cd 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -36,6 +37,7 @@
/** @hide */
@SystemApi
+@TestApi
public final class ContentCaptureEvent implements Parcelable {
private static final String TAG = ContentCaptureEvent.class.getSimpleName();
@@ -69,13 +71,33 @@
*/
public static final int TYPE_VIEW_TEXT_CHANGED = 3;
- // TODO(b/111276913): add event to indicate when FLAG_SECURE was changed?
+ /**
+ * Called before events (such as {@link #TYPE_VIEW_APPEARED}) representing the initial view
+ * hierarchy are sent.
+ *
+ * <p><b>NOTE</b>: there is no guarantee this event will be sent. For example, it's not sent
+ * if the initial view hierarchy doesn't initially have any view that's important for content
+ * capture.
+ */
+ public static final int TYPE_INITIAL_VIEW_TREE_APPEARING = 4;
+
+ /**
+ * Called after events (such as {@link #TYPE_VIEW_APPEARED}) representing the initial view
+ * hierarchy are sent.
+ *
+ * <p><b>NOTE</b>: there is no guarantee this event will be sent. For example, it's not sent
+ * if the initial view hierarchy doesn't initially have any view that's important for content
+ * capture.
+ */
+ public static final int TYPE_INITIAL_VIEW_TREE_APPEARED = 5;
/** @hide */
@IntDef(prefix = { "TYPE_" }, value = {
TYPE_VIEW_APPEARED,
TYPE_VIEW_DISAPPEARED,
- TYPE_VIEW_TEXT_CHANGED
+ TYPE_VIEW_TEXT_CHANGED,
+ TYPE_INITIAL_VIEW_TREE_APPEARING,
+ TYPE_INITIAL_VIEW_TREE_APPEARED
})
@Retention(RetentionPolicy.SOURCE)
public @interface EventType{}
@@ -108,14 +130,19 @@
return this;
}
- private void setAutofillIds(@NonNull ArrayList<AutofillId> ids) {
+ /** @hide */
+ public ContentCaptureEvent setAutofillIds(@NonNull ArrayList<AutofillId> ids) {
mIds = Preconditions.checkNotNull(ids);
+ return this;
}
/**
* Adds an autofill id to the this event, merging the single id into a list if necessary.
- * @hide */
+ *
+ * @hide
+ */
public ContentCaptureEvent addAutofillId(@NonNull AutofillId id) {
+ Preconditions.checkNotNull(id);
if (mIds == null) {
mIds = new ArrayList<>();
if (mId == null) {
@@ -193,7 +220,8 @@
* Gets the type of the event.
*
* @return one of {@link #TYPE_VIEW_APPEARED}, {@link #TYPE_VIEW_DISAPPEARED},
- * or {@link #TYPE_VIEW_TEXT_CHANGED}.
+ * {@link #TYPE_VIEW_TEXT_CHANGED}, {@link #TYPE_INITIAL_VIEW_TREE_APPEARING}, or
+ * {@link #TYPE_INITIAL_VIEW_TREE_APPEARED}.
*/
public @EventType int getType() {
return mType;
@@ -372,6 +400,10 @@
return "VIEW_DISAPPEARED";
case TYPE_VIEW_TEXT_CHANGED:
return "VIEW_TEXT_CHANGED";
+ case TYPE_INITIAL_VIEW_TREE_APPEARING:
+ return "INITIAL_VIEW_HIERARCHY_STARTED";
+ case TYPE_INITIAL_VIEW_TREE_APPEARED:
+ return "INITIAL_VIEW_HIERARCHY_FINISHED";
default:
return "UKNOWN_TYPE: " + type;
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index f31856c..2512b95 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -22,6 +22,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.annotation.UiThread;
import android.content.ComponentName;
import android.content.Context;
@@ -46,7 +47,7 @@
* of every method.
*/
/**
- * TODO(b/111276913): add javadocs / implement
+ * TODO(b/123577059): add javadocs / implement
*/
@SystemService(Context.CONTENT_CAPTURE_MANAGER_SERVICE)
public final class ContentCaptureManager {
@@ -120,6 +121,7 @@
}
/** @hide */
+ @UiThread
public void onActivityStarted(@NonNull IBinder applicationToken,
@NonNull ComponentName activityComponent, int flags) {
synchronized (mLock) {
@@ -129,6 +131,7 @@
}
/** @hide */
+ @UiThread
public void onActivityStopped() {
getMainContentCaptureSession().destroy();
}
@@ -140,6 +143,7 @@
*
* @hide
*/
+ @UiThread
public void flush(@FlushReason int reason) {
getMainContentCaptureSession().flush(reason);
}
@@ -217,6 +221,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public boolean isContentCaptureFeatureEnabled() {
if (mService == null) return false;
@@ -249,6 +254,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public void setContentCaptureFeatureEnabled(boolean enabled) {
if (DEBUG) Log.d(TAG, "setContentCaptureFeatureEnabled(): setting to " + enabled);
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 68a3e8a..e028961 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -204,6 +204,12 @@
return mId.hashCode();
}
+ /** @hide */
+ @NonNull
+ public String getId() {
+ return mId;
+ }
+
/**
* Creates a new {@link ContentCaptureSession}.
*
@@ -362,6 +368,9 @@
abstract void internalNotifyViewTextChanged(@NonNull AutofillId id,
@Nullable CharSequence text);
+ /** @hide */
+ public abstract void internalNotifyViewHierarchyEvent(boolean started);
+
/**
* Creates a {@link ViewStructure} for a "standard" view.
*
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 034c8fa..eb945b5 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -15,6 +15,8 @@
*/
package android.view.contentcapture;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_INITIAL_VIEW_TREE_APPEARED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_INITIAL_VIEW_TREE_APPEARING;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_FINISHED;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_APPEARED;
@@ -24,10 +26,9 @@
import static android.view.contentcapture.ContentCaptureHelper.VERBOSE;
import static android.view.contentcapture.ContentCaptureHelper.getSanitizedString;
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UiThread;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ParceledListSlice;
@@ -56,16 +57,14 @@
* <p>This session is created when the activity starts and finished when it stops; clients can use
* it to create children activities.
*
- * <p><b>NOTE: all methods in this class should return right away, or do the real work in a handler
- * thread. Hence, the only field that must be thread-safe is {@code mEnabled}, which is called at
- * the beginning of every method.
- *
* @hide
*/
public final class MainContentCaptureSession extends ContentCaptureSession {
private static final String TAG = MainContentCaptureSession.class.getSimpleName();
+ private static final boolean FORCE_FLUSH = true;
+
/**
* Handler message used to flush the buffer.
*/
@@ -164,46 +163,28 @@
*
* @hide
*/
- void start(@NonNull IBinder applicationToken, @NonNull ComponentName activityComponent,
+ @UiThread
+ void start(@NonNull IBinder token, @NonNull ComponentName component,
int flags) {
if (!isContentCaptureEnabled()) return;
if (VERBOSE) {
- Log.v(TAG, "start(): token=" + applicationToken + ", comp="
- + ComponentName.flattenToShortString(activityComponent));
+ Log.v(TAG, "start(): token=" + token + ", comp="
+ + ComponentName.flattenToShortString(component));
}
- mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleStartSession, this,
- applicationToken, activityComponent, flags));
- }
-
- @Override
- void flush(@FlushReason int reason) {
- mHandler.sendMessage(
- obtainMessage(MainContentCaptureSession::handleForceFlush, this, reason));
- }
-
- @Override
- void onDestroy() {
- mHandler.removeMessages(MSG_FLUSH);
- mHandler.sendMessage(
- obtainMessage(MainContentCaptureSession::handleDestroySession, this));
- }
-
- private void handleStartSession(@NonNull IBinder token, @NonNull ComponentName componentName,
- int flags) {
- if (handleHasStarted()) {
+ if (hasStarted()) {
// TODO(b/122959591): make sure this is expected (and when), or use Log.w
if (DEBUG) {
Log.d(TAG, "ignoring handleStartSession(" + token + "/"
- + ComponentName.flattenToShortString(componentName) + " while on state "
+ + ComponentName.flattenToShortString(component) + " while on state "
+ getStateAsString(mState));
}
return;
}
mState = STATE_WAITING_FOR_SERVER;
mApplicationToken = token;
- mComponentName = componentName;
+ mComponentName = component;
if (VERBOSE) {
Log.v(TAG, "handleStartSession(): token=" + token + ", act="
@@ -213,28 +194,36 @@
try {
if (mSystemServerInterface == null) return;
- mSystemServerInterface.startSession(mApplicationToken, componentName, mId, flags,
+ mSystemServerInterface.startSession(mApplicationToken, component, mId, flags,
new IResultReceiver.Stub() {
@Override
public void send(int resultCode, Bundle resultData) {
- IBinder binder = null;
+ final IBinder binder;
if (resultData != null) {
binder = resultData.getBinder(EXTRA_BINDER);
if (binder == null) {
Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result");
- handleResetSession(STATE_DISABLED | STATE_INTERNAL_ERROR);
+ mHandler.post(() -> resetSession(
+ STATE_DISABLED | STATE_INTERNAL_ERROR));
return;
}
+ } else {
+ binder = null;
}
- handleSessionStarted(resultCode, binder);
+ mHandler.post(() -> onSessionStarted(resultCode, binder));
}
});
} catch (RemoteException e) {
- Log.w(TAG, "Error starting session for " + componentName.flattenToShortString() + ": "
- + e);
+ Log.w(TAG, "Error starting session for " + component.flattenToShortString() + ": " + e);
}
}
+ @Override
+ void onDestroy() {
+ mHandler.removeMessages(MSG_FLUSH);
+ mHandler.post(() -> destroySession());
+ }
+
/**
* Callback from {@code system_server} after call to
* {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int,
@@ -243,7 +232,8 @@
* @param resultCode session state
* @param binder handle to {@code IContentCaptureDirectManager}
*/
- private void handleSessionStarted(int resultCode, @Nullable IBinder binder) {
+ @UiThread
+ private void onSessionStarted(int resultCode, @Nullable IBinder binder) {
if (binder != null) {
mDirectServiceInterface = IContentCaptureDirectManager.Stub.asInterface(binder);
mDirectServiceVulture = () -> {
@@ -258,7 +248,7 @@
}
if ((resultCode & STATE_DISABLED) != 0) {
- handleResetSession(resultCode);
+ resetSession(resultCode);
} else {
mState = resultCode;
mDisabled.set(false);
@@ -270,10 +260,16 @@
}
}
- private void handleSendEvent(@NonNull ContentCaptureEvent event, boolean forceFlush) {
+ @UiThread
+ private void sendEvent(@NonNull ContentCaptureEvent event) {
+ sendEvent(event, /* forceFlush= */ false);
+ }
+
+ @UiThread
+ private void sendEvent(@NonNull ContentCaptureEvent event, boolean forceFlush) {
final int eventType = event.getType();
if (VERBOSE) Log.v(TAG, "handleSendEvent(" + getDebugState() + "): " + event);
- if (!handleHasStarted() && eventType != ContentCaptureEvent.TYPE_SESSION_STARTED) {
+ if (!hasStarted() && eventType != ContentCaptureEvent.TYPE_SESSION_STARTED) {
// TODO(b/120494182): comment when this could happen (dialogs?)
Log.v(TAG, "handleSendEvent(" + getDebugState() + ", "
+ ContentCaptureEvent.getTypeAsString(eventType)
@@ -334,7 +330,7 @@
final boolean bufferEvent = numberEvents < MAX_BUFFER_SIZE;
if (bufferEvent && !forceFlush) {
- handleScheduleFlush(FLUSH_REASON_IDLE_TIMEOUT, /* checkExisting= */ true);
+ scheduleFlush(FLUSH_REASON_IDLE_TIMEOUT, /* checkExisting= */ true);
return;
}
@@ -348,7 +344,7 @@
Log.d(TAG, "Closing session for " + getDebugState()
+ " after " + numberEvents + " delayed events");
}
- handleResetSession(STATE_DISABLED | STATE_NO_RESPONSE);
+ resetSession(STATE_DISABLED | STATE_NO_RESPONSE);
// TODO(b/111276913): blacklist activity / use special flag to indicate that
// when it's launched again
return;
@@ -365,19 +361,21 @@
flushReason = FLUSH_REASON_FULL;
}
- handleForceFlush(flushReason);
+ flush(flushReason);
}
- private boolean handleHasStarted() {
+ @UiThread
+ private boolean hasStarted() {
return mState != UNKNOWN_STATE;
}
- private void handleScheduleFlush(@FlushReason int reason, boolean checkExisting) {
+ @UiThread
+ private void scheduleFlush(@FlushReason int reason, boolean checkExisting) {
if (VERBOSE) {
Log.v(TAG, "handleScheduleFlush(" + getDebugState(reason)
+ ", checkExisting=" + checkExisting);
}
- if (!handleHasStarted()) {
+ if (!hasStarted()) {
if (VERBOSE) Log.v(TAG, "handleScheduleFlush(): session not started yet");
return;
}
@@ -398,20 +396,22 @@
Log.v(TAG, "handleScheduleFlush(): scheduled to flush in "
+ FLUSHING_FREQUENCY_MS + "ms: " + TimeUtils.logTimeOfDay(mNextFlush));
}
- mHandler.sendMessageDelayed(
- obtainMessage(MainContentCaptureSession::handleFlushIfNeeded, this, reason)
- .setWhat(MSG_FLUSH), FLUSHING_FREQUENCY_MS);
+ // Post using a Runnable directly to trim a few μs from PooledLambda.obtainMessage()
+ mHandler.postDelayed(() -> flushIfNeeded(reason), MSG_FLUSH, FLUSHING_FREQUENCY_MS);
}
- private void handleFlushIfNeeded(@FlushReason int reason) {
+ @UiThread
+ private void flushIfNeeded(@FlushReason int reason) {
if (mEvents == null || mEvents.isEmpty()) {
if (VERBOSE) Log.v(TAG, "Nothing to flush");
return;
}
- handleForceFlush(reason);
+ flush(reason);
}
- private void handleForceFlush(@FlushReason int reason) {
+ @Override
+ @UiThread
+ void flush(@FlushReason int reason) {
if (mEvents == null) return;
if (mDisabled.get()) {
@@ -426,7 +426,7 @@
+ "client not ready: " + mEvents);
}
if (!mHandler.hasMessages(MSG_FLUSH)) {
- handleScheduleFlush(reason, /* checkExisting= */ false);
+ scheduleFlush(reason, /* checkExisting= */ false);
}
return;
}
@@ -443,7 +443,7 @@
mFlushHistory.log(logRecord);
mHandler.removeMessages(MSG_FLUSH);
- final ParceledListSlice<ContentCaptureEvent> events = handleClearEvents();
+ final ParceledListSlice<ContentCaptureEvent> events = clearEvents();
mDirectServiceInterface.sendEvents(events);
} catch (RemoteException e) {
Log.w(TAG, "Error sending " + numberEvents + " for " + getDebugState()
@@ -455,7 +455,8 @@
* Resets the buffer and return a {@link ParceledListSlice} with the previous events.
*/
@NonNull
- private ParceledListSlice<ContentCaptureEvent> handleClearEvents() {
+ @UiThread
+ private ParceledListSlice<ContentCaptureEvent> clearEvents() {
// NOTE: we must save a reference to the current mEvents and then set it to to null,
// otherwise clearing it would clear it in the receiving side if the service is also local.
final List<ContentCaptureEvent> events = mEvents == null
@@ -465,7 +466,8 @@
return new ParceledListSlice<>(events);
}
- private void handleDestroySession() {
+ @UiThread
+ private void destroySession() {
if (DEBUG) {
Log.d(TAG, "Destroying session (ctx=" + mContext + ", id=" + mId + ") with "
+ (mEvents == null ? 0 : mEvents.size()) + " event(s) for "
@@ -484,7 +486,8 @@
// TODO(b/122454205): once we support multiple sessions, we might need to move some of these
// clearings out.
- private void handleResetSession(int newState) {
+ @UiThread
+ private void resetSession(int newState) {
if (VERBOSE) {
Log.v(TAG, "handleResetSession(" + getActivityName() + "): from "
+ getStateAsString(mState) + " to " + getStateAsString(newState));
@@ -518,6 +521,11 @@
}
@Override
+ public void internalNotifyViewHierarchyEvent(boolean started) {
+ notifyInitialViewHierarchyEvent(mId, started);
+ }
+
+ @Override
boolean isContentCaptureEnabled() {
return super.isContentCaptureEnabled() && mManager.isContentCaptureEnabled();
}
@@ -532,37 +540,52 @@
// change should also get get rid of the "internalNotifyXXXX" methods above
void notifyChildSessionStarted(@NonNull String parentSessionId,
@NonNull String childSessionId, @NonNull ContentCaptureContext clientContext) {
- mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
- new ContentCaptureEvent(childSessionId, TYPE_SESSION_STARTED)
- .setParentSessionId(parentSessionId)
- .setClientContext(clientContext),
- /* forceFlush= */ true));
+ sendEvent(new ContentCaptureEvent(childSessionId, TYPE_SESSION_STARTED)
+ .setParentSessionId(parentSessionId).setClientContext(clientContext),
+ FORCE_FLUSH);
}
void notifyChildSessionFinished(@NonNull String parentSessionId,
@NonNull String childSessionId) {
- mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
- new ContentCaptureEvent(childSessionId, TYPE_SESSION_FINISHED)
- .setParentSessionId(parentSessionId), /* forceFlush= */ true));
+ sendEvent(new ContentCaptureEvent(childSessionId, TYPE_SESSION_FINISHED)
+ .setParentSessionId(parentSessionId), FORCE_FLUSH);
}
void notifyViewAppeared(@NonNull String sessionId, @NonNull ViewStructureImpl node) {
- mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
- new ContentCaptureEvent(sessionId, TYPE_VIEW_APPEARED)
- .setViewNode(node.mNode), /* forceFlush= */ false));
+ sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_APPEARED)
+ .setViewNode(node.mNode));
}
void notifyViewDisappeared(@NonNull String sessionId, @NonNull AutofillId id) {
- mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
- new ContentCaptureEvent(sessionId, TYPE_VIEW_DISAPPEARED).setAutofillId(id),
- /* forceFlush= */ false));
+ sendEvent(
+ new ContentCaptureEvent(sessionId, TYPE_VIEW_DISAPPEARED).setAutofillId(id));
+ }
+
+ /** @hide */
+ public void notifyViewsDisappeared(@NonNull String sessionId,
+ @NonNull ArrayList<AutofillId> ids) {
+ final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, TYPE_VIEW_DISAPPEARED);
+ if (ids.size() == 1) {
+ event.setAutofillId(ids.get(0));
+ } else {
+ event.setAutofillIds(ids);
+ }
+ sendEvent(event);
}
void notifyViewTextChanged(@NonNull String sessionId, @NonNull AutofillId id,
@Nullable CharSequence text) {
- mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleSendEvent, this,
- new ContentCaptureEvent(sessionId, TYPE_VIEW_TEXT_CHANGED).setAutofillId(id)
- .setText(text), /* forceFlush= */ false));
+ sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_TEXT_CHANGED).setAutofillId(id)
+ .setText(text));
+ }
+
+ void notifyInitialViewHierarchyEvent(@NonNull String sessionId, boolean started) {
+ if (started) {
+ sendEvent(new ContentCaptureEvent(sessionId, TYPE_INITIAL_VIEW_TREE_APPEARING));
+ } else {
+ sendEvent(new ContentCaptureEvent(sessionId, TYPE_INITIAL_VIEW_TREE_APPEARED),
+ FORCE_FLUSH);
+ }
}
@Override
diff --git a/core/java/android/view/contentcapture/ViewNode.java b/core/java/android/view/contentcapture/ViewNode.java
index 0cabafa..924bb9a 100644
--- a/core/java/android/view/contentcapture/ViewNode.java
+++ b/core/java/android/view/contentcapture/ViewNode.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.assist.AssistStructure;
import android.graphics.Matrix;
import android.graphics.Rect;
@@ -42,6 +43,7 @@
// instead
/** @hide */
@SystemApi
+@TestApi
public final class ViewNode extends AssistStructure.ViewNode {
private static final String TAG = ViewNode.class.getSimpleName();
@@ -598,7 +600,7 @@
/** @hide */
public static @Nullable ViewNode readFromParcel(@NonNull Parcel parcel) {
final long nodeFlags = parcel.readLong();
- return nodeFlags == 0 ? new ViewNode() : new ViewNode(nodeFlags, parcel);
+ return nodeFlags == 0 ? null : new ViewNode(nodeFlags, parcel);
}
/** @hide */
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 7fee3ef..8a09788 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -16,6 +16,7 @@
package android.view.inputmethod;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
import android.annotation.DrawableRes;
@@ -26,6 +27,7 @@
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
+import android.annotation.UserIdInt;
import android.app.ActivityThread;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -46,6 +48,7 @@
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.Trace;
+import android.os.UserHandle;
import android.provider.Settings;
import android.text.style.SuggestionSpan;
import android.util.Log;
@@ -336,7 +339,11 @@
// For scheduling work on the main thread. This also serves as our
// global lock.
- @UnsupportedAppUsage
+ // Remark on @UnsupportedAppUsage: there were context leaks on old versions
+ // of android (b/37043700), so developers used this field to perform manual clean up.
+ // Leaks were fixed, hacks were backported to AppCompatActivity,
+ // so an access to the field is closed.
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
final H mH;
// Our generic input connection if the current target does not have its own.
@@ -372,13 +379,15 @@
* This is the view that should currently be served by an input method,
* regardless of the state of setting that up.
*/
- @UnsupportedAppUsage
+ // See comment to mH field in regard to @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
View mServedView;
/**
* This is then next view that will be served by the input method, when
* we get around to updating things.
*/
- @UnsupportedAppUsage
+ // See comment to mH field in regard to @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
View mNextServedView;
/**
* This is set when we are in the process of connecting, to determine
@@ -954,17 +963,69 @@
return mIInputContext;
}
+ /**
+ * Returns the list of installed input methods.
+ *
+ * <p>On multi user environment, this API returns a result for the calling process user.</p>
+ *
+ * @return {@link List} of {@link InputMethodInfo}.
+ */
public List<InputMethodInfo> getInputMethodList() {
try {
- return mService.getInputMethodList();
+ // We intentionally do not use UserHandle.getCallingUserId() here because for system
+ // services InputMethodManagerInternal.getInputMethodListAsUser() should be used
+ // instead.
+ return mService.getInputMethodList(UserHandle.myUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
+ /**
+ * Returns the list of installed input methods for the specified user.
+ *
+ * @param userId user ID to query
+ * @return {@link List} of {@link InputMethodInfo}.
+ * @hide
+ */
+ @RequiresPermission(INTERACT_ACROSS_USERS_FULL)
+ public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId) {
+ try {
+ return mService.getInputMethodList(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns the list of enabled input methods.
+ *
+ * <p>On multi user environment, this API returns a result for the calling process user.</p>
+ *
+ * @return {@link List} of {@link InputMethodInfo}.
+ */
public List<InputMethodInfo> getEnabledInputMethodList() {
try {
- return mService.getEnabledInputMethodList();
+ // We intentionally do not use UserHandle.getCallingUserId() here because for system
+ // services InputMethodManagerInternal.getEnabledInputMethodListAsUser() should be used
+ // instead.
+ return mService.getEnabledInputMethodList(UserHandle.myUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns the list of enabled input methods for the specified user.
+ *
+ * @param userId user ID to query
+ * @return {@link List} of {@link InputMethodInfo}.
+ * @hide
+ */
+ @RequiresPermission(INTERACT_ACROSS_USERS_FULL)
+ public List<InputMethodInfo> getEnabledInputMethodListAsUser(@UserIdInt int userId) {
+ try {
+ return mService.getEnabledInputMethodList(userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -972,6 +1033,9 @@
/**
* Returns a list of enabled input method subtypes for the specified input method info.
+ *
+ * <p>On multi user environment, this API returns a result for the calling process user.</p>
+ *
* @param imi An input method info whose subtypes list will be returned.
* @param allowsImplicitlySelectedSubtypes A boolean flag to allow to return the implicitly
* selected subtypes. If an input method info doesn't have enabled subtypes, the framework
@@ -1887,6 +1951,36 @@
}
/**
+ * Call showSoftInput with currently focused view.
+ * @return {@code true} if IME can be shown.
+ * @hide
+ */
+ public boolean requestImeShow(ResultReceiver resultReceiver) {
+ synchronized (mH) {
+ if (mServedView == null) {
+ return false;
+ }
+ showSoftInput(mServedView, 0 /* flags */, resultReceiver);
+ return true;
+ }
+ }
+
+ /**
+ * Notify IME directly that it is no longer visible.
+ * @hide
+ */
+ public void notifyImeHidden() {
+ synchronized (mH) {
+ try {
+ if (mCurMethod != null) {
+ mCurMethod.notifyImeHidden();
+ }
+ } catch (RemoteException re) {
+ }
+ }
+ }
+
+ /**
* Report the current selection range.
*
* <p><strong>Editor authors</strong>, you need to call this method whenever
diff --git a/core/java/android/view/inputmethod/InputMethodSession.java b/core/java/android/view/inputmethod/InputMethodSession.java
index de15f33..eb81628 100644
--- a/core/java/android/view/inputmethod/InputMethodSession.java
+++ b/core/java/android/view/inputmethod/InputMethodSession.java
@@ -184,4 +184,11 @@
* insertion point and composition string.
*/
public void updateCursorAnchorInfo(CursorAnchorInfo cursorAnchorInfo);
+
+ /**
+ * Notifies {@link android.inputmethodservice.InputMethodService} that IME has been
+ * hidden from user.
+ * @hide
+ */
+ public void notifyImeHidden();
}
diff --git a/core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java b/core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java
new file mode 100644
index 0000000..8faae1f
--- /dev/null
+++ b/core/java/android/view/inspector/GeneratedInspectionCompanionProvider.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inspector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * An inspection companion provider that loads pre-generated inspection companions
+ *
+ * @see android.processor.view.inspector.PlatformInspectableProcessor
+ */
+public class GeneratedInspectionCompanionProvider implements InspectionCompanionProvider {
+ /**
+ * The suffix used for the generated class
+ */
+ private static final String COMPANION_SUFFIX = "$$InspectionCompanion";
+
+ @Override
+ @Nullable
+ @SuppressWarnings("unchecked")
+ public <T> InspectionCompanion<T> provide(@NonNull Class<T> cls) {
+ final String companionName = cls.getName() + COMPANION_SUFFIX;
+
+ try {
+ final Class<InspectionCompanion<T>> companionClass =
+ (Class<InspectionCompanion<T>>) cls.getClassLoader().loadClass(companionName);
+ return companionClass.newInstance();
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ return null;
+ }
+ }
+}
diff --git a/core/java/android/view/inspector/InspectionCompanionProvider.java b/core/java/android/view/inspector/InspectionCompanionProvider.java
new file mode 100644
index 0000000..c08f49c
--- /dev/null
+++ b/core/java/android/view/inspector/InspectionCompanionProvider.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.inspector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * An interface for services that can provide inspection companions for a class.
+ */
+public interface InspectionCompanionProvider {
+ /**
+ * Provide an {@link InspectionCompanion} for the supplied class.
+ *
+ * Implementing classes must not cache companion instances, and should instantiate a new one
+ * for each request.
+ *
+ * @param cls A {@link Class} representing the inspectable type
+ * @param <T> The type to find the companion for
+ * @return The inspection companion for the supplied type
+ */
+ @Nullable
+ <T> InspectionCompanion<T> provide(@NonNull Class<T> cls);
+}
diff --git a/core/java/android/view/textclassifier/ConversationActions.java b/core/java/android/view/textclassifier/ConversationActions.java
index 502181f..cf31445 100644
--- a/core/java/android/view/textclassifier/ConversationActions.java
+++ b/core/java/android/view/textclassifier/ConversationActions.java
@@ -393,9 +393,10 @@
}
/**
- * Return the maximal number of suggestions the caller wants, value 0 means no restriction.
+ * Return the maximal number of suggestions the caller wants, value -1 means no restriction
+ * and this is the default.
*/
- @IntRange(from = 0)
+ @IntRange(from = -1)
public int getMaxSuggestions() {
return mMaxSuggestions;
}
@@ -443,7 +444,7 @@
private List<Message> mConversation;
@Nullable
private TextClassifier.EntityConfig mTypeConfig;
- private int mMaxSuggestions;
+ private int mMaxSuggestions = -1;
@Nullable
private String mConversationId;
@Nullable
@@ -477,12 +478,11 @@
}
/**
- * Sets the maximum number of suggestions you want.
- * <p>
- * Value 0 means no restriction.
+ * Sets the maximum number of suggestions you want. Value -1 means no restriction and
+ * this is the default.
*/
@NonNull
- public Builder setMaxSuggestions(@IntRange(from = 0) int maxSuggestions) {
+ public Builder setMaxSuggestions(@IntRange(from = -1) int maxSuggestions) {
mMaxSuggestions = Preconditions.checkArgumentNonnegative(maxSuggestions);
return this;
}
diff --git a/core/java/android/view/textclassifier/IntentFactory.java b/core/java/android/view/textclassifier/IntentFactory.java
index d9c03c8..9f3b97f 100644
--- a/core/java/android/view/textclassifier/IntentFactory.java
+++ b/core/java/android/view/textclassifier/IntentFactory.java
@@ -50,7 +50,8 @@
new Intent(Intent.ACTION_TRANSLATE)
// TODO: Probably better to introduce a "translate" scheme instead of
// using EXTRA_TEXT.
- .putExtra(Intent.EXTRA_TEXT, text),
+ .putExtra(Intent.EXTRA_TEXT, text)
+ .putExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER, true),
text.hashCode()));
}
}
diff --git a/core/java/android/view/textclassifier/TemplateClassificationIntentFactory.java b/core/java/android/view/textclassifier/TemplateClassificationIntentFactory.java
new file mode 100644
index 0000000..2467802
--- /dev/null
+++ b/core/java/android/view/textclassifier/TemplateClassificationIntentFactory.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.textclassifier;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Preconditions;
+
+import com.google.android.textclassifier.AnnotatorModel;
+import com.google.android.textclassifier.RemoteActionTemplate;
+
+import java.time.Instant;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Creates intents based on {@link RemoteActionTemplate} objects for a ClassificationResult.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public final class TemplateClassificationIntentFactory implements IntentFactory {
+ private static final String TAG = TextClassifier.DEFAULT_LOG_TAG;
+ private final TemplateIntentFactory mTemplateIntentFactory;
+ private final IntentFactory mFallback;
+
+ public TemplateClassificationIntentFactory(TemplateIntentFactory templateIntentFactory,
+ IntentFactory fallback) {
+ mTemplateIntentFactory = Preconditions.checkNotNull(templateIntentFactory);
+ mFallback = Preconditions.checkNotNull(fallback);
+ }
+
+ /**
+ * Returns a list of {@link android.view.textclassifier.TextClassifierImpl.LabeledIntent}
+ * that are constructed from the classification result.
+ */
+ @NonNull
+ @Override
+ public List<TextClassifierImpl.LabeledIntent> create(
+ Context context,
+ String text,
+ boolean foreignText,
+ @Nullable Instant referenceTime,
+ @Nullable AnnotatorModel.ClassificationResult classification) {
+ if (classification == null) {
+ return Collections.emptyList();
+ }
+ RemoteActionTemplate[] remoteActionTemplates = classification.getRemoteActionTemplates();
+ if (ArrayUtils.isEmpty(remoteActionTemplates)) {
+ // RemoteActionTemplate is missing, fallback.
+ Log.w(TAG, "RemoteActionTemplate is missing, fallback to LegacyIntentFactory.");
+ return mFallback.create(context, text, foreignText, referenceTime, classification);
+ }
+ final List<TextClassifierImpl.LabeledIntent> labeledIntents =
+ mTemplateIntentFactory.create(remoteActionTemplates);
+ if (foreignText) {
+ IntentFactory.insertTranslateAction(labeledIntents, context, text.trim());
+ }
+ return labeledIntents;
+ }
+}
diff --git a/core/java/android/view/textclassifier/TemplateIntentFactory.java b/core/java/android/view/textclassifier/TemplateIntentFactory.java
index 97e11bb..5278843 100644
--- a/core/java/android/view/textclassifier/TemplateIntentFactory.java
+++ b/core/java/android/view/textclassifier/TemplateIntentFactory.java
@@ -17,7 +17,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -25,64 +24,29 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.Preconditions;
-import com.google.android.textclassifier.AnnotatorModel;
import com.google.android.textclassifier.NamedVariant;
import com.google.android.textclassifier.RemoteActionTemplate;
-import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Creates intents based on {@link RemoteActionTemplate} objects.
+ *
* @hide
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public final class TemplateIntentFactory implements IntentFactory {
+public final class TemplateIntentFactory {
private static final String TAG = TextClassifier.DEFAULT_LOG_TAG;
- private final IntentFactory mFallback;
- public TemplateIntentFactory(IntentFactory fallback) {
- mFallback = Preconditions.checkNotNull(fallback);
- }
-
- /**
- * Returns a list of {@link android.view.textclassifier.TextClassifierImpl.LabeledIntent}
- * that are constructed from the classification result.
- */
@NonNull
- @Override
public List<TextClassifierImpl.LabeledIntent> create(
- Context context,
- String text,
- boolean foreignText,
- @Nullable Instant referenceTime,
- @Nullable AnnotatorModel.ClassificationResult classification) {
- if (classification == null) {
+ @Nullable RemoteActionTemplate[] remoteActionTemplates) {
+ if (ArrayUtils.isEmpty(remoteActionTemplates)) {
return Collections.emptyList();
}
- RemoteActionTemplate[] remoteActionTemplates = classification.getRemoteActionTemplates();
- if (ArrayUtils.isEmpty(remoteActionTemplates)) {
- // RemoteActionTemplate is missing, fallback.
- Log.w(TAG, "RemoteActionTemplate is missing, fallback to LegacyIntentFactory.");
- return mFallback.create(context, text, foreignText, referenceTime, classification);
- }
- final List<TextClassifierImpl.LabeledIntent> labeledIntents =
- new ArrayList<>(createFromRemoteActionTemplates(remoteActionTemplates));
- if (foreignText) {
- IntentFactory.insertTranslateAction(labeledIntents, context, text.trim());
- }
- labeledIntents.forEach(
- action -> action.getIntent()
- .putExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER, true));
- return labeledIntents;
- }
-
- private static List<TextClassifierImpl.LabeledIntent> createFromRemoteActionTemplates(
- RemoteActionTemplate[] remoteActionTemplates) {
final List<TextClassifierImpl.LabeledIntent> labeledIntents = new ArrayList<>();
for (RemoteActionTemplate remoteActionTemplate : remoteActionTemplates) {
Intent intent = createIntent(remoteActionTemplate);
@@ -100,6 +64,9 @@
);
labeledIntents.add(labeledIntent);
}
+ labeledIntents.forEach(
+ action -> action.getIntent()
+ .putExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER, true));
return labeledIntents;
}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 14afa33..295c8b7 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -113,6 +113,7 @@
private final ModelFileManager mActionsModelFileManager;
private final IntentFactory mIntentFactory;
+ private final TemplateIntentFactory mTemplateIntentFactory;
public TextClassifierImpl(
Context context, TextClassificationConstants settings, TextClassifier fallback) {
@@ -142,8 +143,10 @@
ActionsSuggestionsModel::getVersion,
ActionsSuggestionsModel::getLocales));
+ mTemplateIntentFactory = new TemplateIntentFactory();
mIntentFactory = mSettings.isTemplateIntentFactoryEnabled()
- ? new TemplateIntentFactory(new LegacyIntentFactory())
+ ? new TemplateClassificationIntentFactory(
+ mTemplateIntentFactory, new LegacyIntentFactory())
: new LegacyIntentFactory();
}
@@ -189,7 +192,10 @@
refTime.toInstant().toEpochMilli(),
refTime.getZone().getId(),
localesString),
- mContext);
+ // Passing null here to suppress intent generation
+ // TODO: Use an explicit flag to suppress it.
+ /* appContext */ null,
+ /* deviceLocales */null);
final int size = results.length;
for (int i = 0; i < size; i++) {
tsBuilder.setEntityType(results[i].getCollection(), results[i].getScore());
@@ -233,7 +239,11 @@
refTime.toInstant().toEpochMilli(),
refTime.getZone().getId(),
localesString),
- mContext);
+ mContext,
+ // TODO: Pass the locale list once it is supported in
+ // native side.
+ LocaleList.getDefault().get(0).toLanguageTag()
+ );
if (results.length > 0) {
return createClassificationResult(
results, string,
@@ -389,32 +399,13 @@
new ActionsSuggestionsModel.Conversation(nativeMessages);
ActionsSuggestionsModel.ActionSuggestion[] nativeSuggestions =
- actionsImpl.suggestActions(nativeConversation, null);
-
- Collection<String> expectedTypes = resolveActionTypesFromRequest(request);
- List<ConversationAction> conversationActions = new ArrayList<>();
- int maxSuggestions = nativeSuggestions.length;
- if (request.getMaxSuggestions() > 0) {
- maxSuggestions = Math.min(request.getMaxSuggestions(), nativeSuggestions.length);
- }
- for (int i = 0; i < maxSuggestions; i++) {
- ActionsSuggestionsModel.ActionSuggestion nativeSuggestion = nativeSuggestions[i];
- String actionType = nativeSuggestion.getActionType();
- if (!expectedTypes.contains(actionType)) {
- continue;
- }
- conversationActions.add(
- new ConversationAction.Builder(actionType)
- .setTextReply(nativeSuggestion.getResponseText())
- .setConfidenceScore(nativeSuggestion.getScore())
- .build());
- }
- String resultId = ActionsSuggestionsHelper.createResultId(
- mContext,
- request.getConversation(),
- mActionModelInUse.getVersion(),
- mActionModelInUse.getSupportedLocales());
- return new ConversationActions(conversationActions, resultId);
+ actionsImpl.suggestActionsWithIntents(
+ nativeConversation,
+ null,
+ mContext,
+ // TODO: Pass the locale list once it is supported in native side.
+ LocaleList.getDefault().get(0).toLanguageTag());
+ return createConversationActionResult(request, nativeSuggestions);
} catch (Throwable t) {
// Avoid throwing from this method. Log the error.
Log.e(LOG_TAG, "Error suggesting conversation actions.", t);
@@ -422,6 +413,43 @@
return mFallback.suggestConversationActions(request);
}
+ private ConversationActions createConversationActionResult(
+ ConversationActions.Request request,
+ ActionsSuggestionsModel.ActionSuggestion[] nativeSuggestions) {
+ Collection<String> expectedTypes = resolveActionTypesFromRequest(request);
+ List<ConversationAction> conversationActions = new ArrayList<>();
+ for (ActionsSuggestionsModel.ActionSuggestion nativeSuggestion : nativeSuggestions) {
+ if (request.getMaxSuggestions() >= 0
+ && conversationActions.size() == request.getMaxSuggestions()) {
+ break;
+ }
+ String actionType = nativeSuggestion.getActionType();
+ if (!expectedTypes.contains(actionType)) {
+ continue;
+ }
+ List<LabeledIntent> labeledIntents =
+ mTemplateIntentFactory.create(nativeSuggestion.getRemoteActionTemplates());
+ RemoteAction remoteAction = null;
+ // Given that we only support implicit intent here, we should expect there is just one
+ // intent for each action type.
+ if (!labeledIntents.isEmpty()) {
+ remoteAction = labeledIntents.get(0).asRemoteAction(mContext);
+ }
+ conversationActions.add(
+ new ConversationAction.Builder(actionType)
+ .setConfidenceScore(nativeSuggestion.getScore())
+ .setTextReply(nativeSuggestion.getResponseText())
+ .setAction(remoteAction)
+ .build());
+ }
+ String resultId = ActionsSuggestionsHelper.createResultId(
+ mContext,
+ request.getConversation(),
+ mActionModelInUse.getVersion(),
+ mActionModelInUse.getSupportedLocales());
+ return new ConversationActions(conversationActions, resultId);
+ }
+
@Nullable
private String detectLanguageTagsFromText(CharSequence text) {
TextLanguage.Request request = new TextLanguage.Request.Builder(text).build();
@@ -462,11 +490,13 @@
}
if (mAnnotatorImpl == null || !Objects.equals(mAnnotatorModelInUse, bestModel)) {
Log.d(DEFAULT_LOG_TAG, "Loading " + bestModel);
- destroyAnnotatorImplIfExistsLocked();
final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
try {
if (pfd != null) {
+ // The current annotator model may be still used by another thread / model.
+ // Do not call close() here, and let the GC to clean it up when no one else
+ // is using it.
mAnnotatorImpl = new AnnotatorModel(pfd.getFd());
mAnnotatorModelInUse = bestModel;
}
@@ -478,14 +508,6 @@
}
}
- @GuardedBy("mLock") // Do not call outside this lock.
- private void destroyAnnotatorImplIfExistsLocked() {
- if (mAnnotatorImpl != null) {
- mAnnotatorImpl.close();
- mAnnotatorImpl = null;
- }
- }
-
private LangIdModel getLangIdImpl() throws FileNotFoundException {
synchronized (mLock) {
if (mLangIdImpl == null) {
@@ -522,7 +544,8 @@
new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
try {
if (pfd != null) {
- mActionsImpl = new ActionsSuggestionsModel(pfd.getFd());
+ mActionsImpl = new ActionsSuggestionsModel(
+ pfd.getFd(), getAnnotatorImpl(LocaleList.getDefault()));
mActionModelInUse = bestModel;
}
} finally {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 99895bd..542df45 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -82,6 +82,8 @@
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputContentInfo;
import android.view.inputmethod.InputMethodManager;
+import android.view.inspector.InspectableProperty;
+import android.view.inspector.InspectableProperty.EnumMap;
import android.widget.RemoteViews.OnClickHandler;
import com.android.internal.R;
@@ -440,8 +442,10 @@
/**
* Handles one frame of a fling
+ *
+ * To interrupt a fling early you should use smoothScrollBy(0,0) instead
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private FlingRunnable mFlingRunnable;
/**
@@ -481,7 +485,7 @@
/**
* Optional callback to notify client when scroll position has changed
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769353)
private OnScrollListener mOnScrollListener;
/**
@@ -1221,6 +1225,12 @@
*
* @return The current choice mode
*/
+ @InspectableProperty(enumMapping = {
+ @EnumMap(value = CHOICE_MODE_NONE, name = "none"),
+ @EnumMap(value = CHOICE_MODE_SINGLE, name = "singleChoice"),
+ @EnumMap(value = CHOICE_MODE_MULTIPLE, name = "multipleChoice"),
+ @EnumMap(value = CHOICE_MODE_MULTIPLE_MODAL, name = "multipleChoiceModal")
+ })
public int getChoiceMode() {
return mChoiceMode;
}
@@ -1421,6 +1431,7 @@
* @return true if fast scroll is enabled, false otherwise
*/
@ViewDebug.ExportedProperty
+ @InspectableProperty
public boolean isFastScrollEnabled() {
if (mFastScroll == null) {
return mFastScrollEnabled;
@@ -1485,6 +1496,7 @@
* @see #setSmoothScrollbarEnabled(boolean)
*/
@ViewDebug.ExportedProperty
+ @InspectableProperty(name = "smoothScrollbar")
public boolean isSmoothScrollbarEnabled() {
return mSmoothScrollbarEnabled;
}
@@ -1601,15 +1613,6 @@
return false;
}
- /** @hide */
- @Override
- public View findViewByAccessibilityIdTraversal(int accessibilityId) {
- if (accessibilityId == getAccessibilityViewId()) {
- return this;
- }
- return super.findViewByAccessibilityIdTraversal(accessibilityId);
- }
-
/**
* Indicates whether the children's drawing cache is used during a scroll.
* By default, the drawing cache is enabled but this will consume more memory.
@@ -1620,6 +1623,7 @@
* @see View#setDrawingCacheEnabled(boolean)
*/
@ViewDebug.ExportedProperty
+ @InspectableProperty(name = "scrollingCache")
public boolean isScrollingCacheEnabled() {
return mScrollingCacheEnabled;
}
@@ -1667,6 +1671,7 @@
* @see Filterable
*/
@ViewDebug.ExportedProperty
+ @InspectableProperty
public boolean isTextFilterEnabled() {
return mTextFilterEnabled;
}
@@ -1697,6 +1702,7 @@
* @return true if the content is stacked from the bottom edge, false otherwise
*/
@ViewDebug.ExportedProperty
+ @InspectableProperty
public boolean isStackFromBottom() {
return mStackFromBottom;
}
@@ -2813,6 +2819,18 @@
}
/**
+ * Returns whether the selection highlight drawable should be drawn on top of the item or
+ * behind it.
+ *
+ * @return true if selector is drawn on top, false otherwise
+ * @attr ref android.R.styleable#AbsListView_drawSelectorOnTop
+ */
+ @InspectableProperty
+ public boolean getDrawSelectorOnTop() {
+ return mDrawSelectorOnTop;
+ }
+
+ /**
* Set a Drawable that should be used to highlight the currently selected item.
*
* @param resID A Drawable resource to use as the selection highlight.
@@ -2845,6 +2863,7 @@
*
* @return the drawable used to display the selector
*/
+ @InspectableProperty(name = "listSelector")
public Drawable getSelector() {
return mSelector;
}
@@ -4662,7 +4681,8 @@
mScroller = new OverScroller(getContext());
}
- @UnsupportedAppUsage
+ // Use AbsListView#fling(int) instead
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void start(int initialVelocity) {
int initialY = initialVelocity < 0 ? Integer.MAX_VALUE : 0;
mLastFlingY = initialY;
@@ -4740,7 +4760,8 @@
postOnAnimation(this);
}
- @UnsupportedAppUsage
+ // To interrupt a fling early you should use smoothScrollBy(0,0) instead
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void endFling() {
mTouchMode = TOUCH_MODE_REST;
@@ -6272,6 +6293,11 @@
* @return {@link #TRANSCRIPT_MODE_DISABLED}, {@link #TRANSCRIPT_MODE_NORMAL} or
* {@link #TRANSCRIPT_MODE_ALWAYS_SCROLL}
*/
+ @InspectableProperty(enumMapping = {
+ @EnumMap(value = TRANSCRIPT_MODE_DISABLED, name = "disabled"),
+ @EnumMap(value = TRANSCRIPT_MODE_NORMAL, name = "normal"),
+ @EnumMap(value = TRANSCRIPT_MODE_ALWAYS_SCROLL, name = "alwaysScroll")
+ })
public int getTranscriptMode() {
return mTranscriptMode;
}
@@ -6309,6 +6335,7 @@
* @return The cache color hint
*/
@ViewDebug.ExportedProperty(category = "drawing")
+ @InspectableProperty
@ColorInt
public int getCacheColorHint() {
return mCacheColorHint;
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index a85c585..c8be1d6 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -34,6 +34,7 @@
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -252,6 +253,7 @@
* @attr ref android.R.styleable#SeekBar_thumbTint
* @see #setThumbTintList(ColorStateList)
*/
+ @InspectableProperty(name = "thumbTint")
@Nullable
public ColorStateList getThumbTintList() {
return mThumbTintList;
@@ -284,6 +286,7 @@
* @attr ref android.R.styleable#SeekBar_thumbTintMode
* @see #setThumbTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getThumbTintMode() {
return mThumbTintMode;
@@ -406,6 +409,7 @@
* @attr ref android.R.styleable#SeekBar_tickMarkTint
* @see #setTickMarkTintList(ColorStateList)
*/
+ @InspectableProperty(name = "tickMarkTint")
@Nullable
public ColorStateList getTickMarkTintList() {
return mTickMarkTintList;
@@ -438,6 +442,7 @@
* @attr ref android.R.styleable#SeekBar_tickMarkTintMode
* @see #setTickMarkTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getTickMarkTintMode() {
return mTickMarkTintMode;
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 7d6564f..9bc055e 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -35,12 +35,12 @@
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -362,27 +362,33 @@
*
* @attr ref android.R.styleable#AutoCompleteTextView_completionHint
*/
+ @InspectableProperty
public CharSequence getCompletionHint() {
return mHintText;
}
/**
- * <p>Returns the current width for the auto-complete drop down list. This can
- * be a fixed width, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill the screen, or
- * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p>
+ * Returns the current width for the auto-complete drop down list.
+ *
+ * This can be a fixed width, or {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * to fill the screen, or {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
+ * to fit the width of its anchor view.
*
* @return the width for the drop down list
*
* @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth
*/
+ @InspectableProperty
public int getDropDownWidth() {
return mPopup.getWidth();
}
/**
- * <p>Sets the current width for the auto-complete drop down list. This can
- * be a fixed width, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill the screen, or
- * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p>
+ * Sets the current width for the auto-complete drop down list.
+ *
+ * This can be a fixed width, or {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * to fill the screen, or {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
+ * to fit the width of its anchor view.
*
* @param width the width to use
*
@@ -393,24 +399,27 @@
}
/**
- * <p>Returns the current height for the auto-complete drop down list. This can
- * be a fixed height, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill
- * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height
- * of the drop down's content.</p>
+ * <p>Returns the current height for the auto-complete drop down list.
+ *
+ * This can be a fixed width, or {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * to fill the screen, or {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
+ * to fit the width of its anchor view.
*
* @return the height for the drop down list
*
* @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight
*/
+ @InspectableProperty
public int getDropDownHeight() {
return mPopup.getHeight();
}
/**
- * <p>Sets the current height for the auto-complete drop down list. This can
- * be a fixed height, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill
- * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height
- * of the drop down's content.</p>
+ * Sets the current height for the auto-complete drop down list.
+ *
+ * This can be a fixed width, or {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * to fill the screen, or {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
+ * to fit the width of its anchor view.
*
* @param height the height to use
*
@@ -452,6 +461,7 @@
*
* @attr ref android.R.styleable#PopupWindow_popupBackground
*/
+ @InspectableProperty(name = "popupBackground")
public Drawable getDropDownBackground() {
return mPopup.getBackground();
}
@@ -496,6 +506,7 @@
*
* @attr ref android.R.styleable#ListPopupWindow_dropDownVerticalOffset
*/
+ @InspectableProperty
public int getDropDownVerticalOffset() {
return mPopup.getVerticalOffset();
}
@@ -518,6 +529,7 @@
*
* @attr ref android.R.styleable#ListPopupWindow_dropDownHorizontalOffset
*/
+ @InspectableProperty
public int getDropDownHorizontalOffset() {
return mPopup.getHorizontalOffset();
}
@@ -610,6 +622,7 @@
*
* @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold
*/
+ @InspectableProperty(name = "completionThreshold")
public int getThreshold() {
return mThreshold;
}
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 2ff815d..6c74c8c 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -34,6 +34,7 @@
import android.icu.util.TimeZone;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -149,6 +150,7 @@
* @attr ref android.R.styleable#CalendarView_shownWeekCount
* @deprecated No longer used by Material-style CalendarView.
*/
+ @InspectableProperty
@Deprecated
public int getShownWeekCount() {
return mDelegate.getShownWeekCount();
@@ -175,6 +177,7 @@
* @attr ref android.R.styleable#CalendarView_selectedWeekBackgroundColor
* @deprecated No longer used by Material-style CalendarView.
*/
+ @InspectableProperty
@ColorInt
@Deprecated
public int getSelectedWeekBackgroundColor() {
@@ -202,6 +205,7 @@
* @attr ref android.R.styleable#CalendarView_focusedMonthDateColor
* @deprecated No longer used by Material-style CalendarView.
*/
+ @InspectableProperty
@ColorInt
@Deprecated
public int getFocusedMonthDateColor() {
@@ -229,6 +233,7 @@
* @attr ref android.R.styleable#CalendarView_unfocusedMonthDateColor
* @deprecated No longer used by Material-style CalendarView.
*/
+ @InspectableProperty
@ColorInt
@Deprecated
public int getUnfocusedMonthDateColor() {
@@ -256,6 +261,7 @@
* @attr ref android.R.styleable#CalendarView_weekNumberColor
* @deprecated No longer used by Material-style CalendarView.
*/
+ @InspectableProperty
@ColorInt
@Deprecated
public int getWeekNumberColor() {
@@ -285,6 +291,7 @@
*/
@ColorInt
@Deprecated
+ @InspectableProperty
public int getWeekSeparatorLineColor() {
return mDelegate.getWeekSeparatorLineColor();
}
@@ -324,6 +331,7 @@
* @return The vertical bar drawable.
* @deprecated No longer used by Material-style CalendarView.
*/
+ @InspectableProperty
@Deprecated
public Drawable getSelectedDateVerticalBar() {
return mDelegate.getSelectedDateVerticalBar();
@@ -347,6 +355,7 @@
*
* @attr ref android.R.styleable#CalendarView_weekDayTextAppearance
*/
+ @InspectableProperty
public @StyleRes int getWeekDayTextAppearance() {
return mDelegate.getWeekDayTextAppearance();
}
@@ -369,6 +378,7 @@
*
* @attr ref android.R.styleable#CalendarView_dateTextAppearance
*/
+ @InspectableProperty
public @StyleRes int getDateTextAppearance() {
return mDelegate.getDateTextAppearance();
}
@@ -385,6 +395,7 @@
*
* @attr ref android.R.styleable#CalendarView_minDate
*/
+ @InspectableProperty
public long getMinDate() {
return mDelegate.getMinDate();
}
@@ -414,6 +425,7 @@
*
* @attr ref android.R.styleable#CalendarView_maxDate
*/
+ @InspectableProperty
public long getMaxDate() {
return mDelegate.getMaxDate();
}
@@ -452,6 +464,7 @@
*
* @attr ref android.R.styleable#CalendarView_showWeekNumber
*/
+ @InspectableProperty
@Deprecated
public boolean getShowWeekNumber() {
return mDelegate.getShowWeekNumber();
@@ -472,6 +485,7 @@
*
* @attr ref android.R.styleable#CalendarView_firstDayOfWeek
*/
+ @InspectableProperty
public int getFirstDayOfWeek() {
return mDelegate.getFirstDayOfWeek();
}
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 1472b01..b7fdcbe 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -35,6 +35,7 @@
import android.view.ViewHierarchyEncoder;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -121,6 +122,7 @@
}
@ViewDebug.ExportedProperty
+ @InspectableProperty
public boolean isChecked() {
return mChecked;
}
@@ -237,6 +239,7 @@
* @attr ref android.R.styleable#CheckedTextView_checkMarkTint
* @see #setCheckMarkTintList(ColorStateList)
*/
+ @InspectableProperty(name = "checkMarkTint")
@Nullable
public ColorStateList getCheckMarkTintList() {
return mCheckMarkTintList;
@@ -269,6 +272,7 @@
* @attr ref android.R.styleable#CheckedTextView_checkMarkTintMode
* @see #setCheckMarkTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getCheckMarkTintMode() {
return mCheckMarkTintMode;
@@ -328,6 +332,7 @@
*
* @attr ref android.R.styleable#CheckedTextView_checkMark
*/
+ @InspectableProperty(name = "checkMark")
public Drawable getCheckMarkDrawable() {
return mCheckMarkDrawable;
}
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index d11c03a..66c35d9 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -29,6 +29,7 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -145,6 +146,7 @@
*
* @see #setCountDown(boolean)
*/
+ @InspectableProperty
public boolean isCountDown() {
return mCountDown;
}
@@ -206,6 +208,7 @@
/**
* Returns the current format string as set through {@link #setFormat}.
*/
+ @InspectableProperty
public String getFormat() {
return mFormat;
}
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index d35bec8..a0f93da 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -39,6 +39,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -145,6 +146,7 @@
return handled;
}
+ @InspectableProperty
@ViewDebug.ExportedProperty
@Override
public boolean isChecked() {
@@ -282,6 +284,7 @@
* @see #setButtonDrawable(Drawable)
* @see #setButtonDrawable(int)
*/
+ @InspectableProperty(name = "button")
@Nullable
public Drawable getButtonDrawable() {
return mButtonDrawable;
@@ -314,6 +317,7 @@
* @attr ref android.R.styleable#CompoundButton_buttonTint
* @see #setButtonTintList(ColorStateList)
*/
+ @InspectableProperty(name = "buttonTint")
@Nullable
public ColorStateList getButtonTintList() {
return mButtonTintList;
@@ -342,6 +346,7 @@
* @attr ref android.R.styleable#CompoundButton_buttonTintMode
* @see #setButtonTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getButtonTintMode() {
return mButtonTintMode;
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index df53795..cca951c 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -37,6 +37,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -212,6 +213,10 @@
* @attr ref android.R.styleable#DatePicker_datePickerMode
* @hide Visible for testing only.
*/
+ @InspectableProperty(name = "datePickerMode", enumMapping = {
+ @InspectableProperty.EnumMap(value = MODE_SPINNER, name = "spinner"),
+ @InspectableProperty.EnumMap(value = MODE_CALENDAR, name = "calendar")
+ })
@DatePickerMode
@TestApi
public int getMode() {
@@ -257,6 +262,7 @@
/**
* @return The selected year.
*/
+ @InspectableProperty(hasAttributeId = false)
public int getYear() {
return mDelegate.getYear();
}
@@ -264,6 +270,7 @@
/**
* @return The selected month.
*/
+ @InspectableProperty(hasAttributeId = false)
public int getMonth() {
return mDelegate.getMonth();
}
@@ -271,6 +278,7 @@
/**
* @return The selected day of month.
*/
+ @InspectableProperty(hasAttributeId = false)
public int getDayOfMonth() {
return mDelegate.getDayOfMonth();
}
@@ -285,6 +293,7 @@
*
* @return The minimal supported date.
*/
+ @InspectableProperty
public long getMinDate() {
return mDelegate.getMinDate().getTimeInMillis();
}
@@ -310,6 +319,7 @@
*
* @return The maximal supported date.
*/
+ @InspectableProperty
public long getMaxDate() {
return mDelegate.getMaxDate().getTimeInMillis();
}
@@ -411,6 +421,7 @@
*
* @attr ref android.R.styleable#DatePicker_firstDayOfWeek
*/
+ @InspectableProperty
public int getFirstDayOfWeek() {
return mDelegate.getFirstDayOfWeek();
}
@@ -426,6 +437,7 @@
* @see #getCalendarView()
* @deprecated Not supported by Material-style {@code calendar} mode
*/
+ @InspectableProperty
@Deprecated
public boolean getCalendarViewShown() {
return mDelegate.getCalendarViewShown();
@@ -476,6 +488,7 @@
* @return {@code true} if the spinners are shown
* @deprecated Not supported by Material-style {@code calendar} mode
*/
+ @InspectableProperty
@Deprecated
public boolean getSpinnersShown() {
return mDelegate.getSpinnersShown();
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index bf2762a..0469dbd 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -35,6 +35,7 @@
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -142,6 +143,16 @@
update();
}
+ /**
+ * Returns whether this view shows relative time
+ *
+ * @return True if it shows relative time, false otherwise
+ */
+ @InspectableProperty(name = "showReleative", hasAttributeId = false)
+ public boolean isShowRelativeTime() {
+ return mShowRelativeTime;
+ }
+
@Override
@android.view.RemotableViewMethod
public void setVisibility(@Visibility int visibility) {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index c821774..9c21ba6 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -273,7 +273,11 @@
boolean mDiscardNextActionUp;
boolean mIgnoreActionUpEvent;
- @UnsupportedAppUsage
+ /**
+ * To set a custom cursor, you should use {@link TextView#setTextCursorDrawable(Drawable)}
+ * or {@link TextView#setTextCursorDrawable(int)}.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private long mShowCursor;
private boolean mRenderCursorRegardlessTiming;
private Blink mBlink;
@@ -3656,7 +3660,7 @@
intent.putExtra(USER_DICTIONARY_EXTRA_LOCALE,
mTextView.getTextServicesLocale().toString());
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
- mTextView.getContext().startActivity(intent);
+ mTextView.startActivityAsTextOperationUserIfNecessary(intent);
// There is no way to know if the word was indeed added. Re-check.
// TODO The ExtractEditText should remove the span in the original text instead
editable.removeSpan(mMisspelledSpanInfo.mSuggestionSpan);
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 865f520..5723b94 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -31,6 +31,7 @@
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewHierarchyEncoder;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -367,6 +368,7 @@
*
* @return Whether all children are considered when measuring.
*/
+ @InspectableProperty
public boolean getMeasureAllChildren() {
return mMeasureAllChildren;
}
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 13c086c..c8abf18 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -46,6 +46,7 @@
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -327,6 +328,10 @@
* @attr ref android.R.styleable#GridLayout_orientation
*/
@Orientation
+ @InspectableProperty(enumMapping = {
+ @InspectableProperty.EnumMap(value = HORIZONTAL, name = "horizontal"),
+ @InspectableProperty.EnumMap(value = VERTICAL, name = "vertical")
+ })
public int getOrientation() {
return mOrientation;
}
@@ -387,6 +392,7 @@
*
* @attr ref android.R.styleable#GridLayout_rowCount
*/
+ @InspectableProperty
public int getRowCount() {
return mVerticalAxis.getCount();
}
@@ -420,6 +426,7 @@
*
* @attr ref android.R.styleable#GridLayout_columnCount
*/
+ @InspectableProperty
public int getColumnCount() {
return mHorizontalAxis.getCount();
}
@@ -451,6 +458,7 @@
*
* @attr ref android.R.styleable#GridLayout_useDefaultMargins
*/
+ @InspectableProperty
public boolean getUseDefaultMargins() {
return mUseDefaultMargins;
}
@@ -499,6 +507,10 @@
* @attr ref android.R.styleable#GridLayout_alignmentMode
*/
@AlignmentMode
+ @InspectableProperty(enumMapping = {
+ @InspectableProperty.EnumMap(value = ALIGN_BOUNDS, name = "alignBounds"),
+ @InspectableProperty.EnumMap(value = ALIGN_MARGINS, name = "alignMargins"),
+ })
public int getAlignmentMode() {
return mAlignmentMode;
}
@@ -533,6 +545,7 @@
*
* @attr ref android.R.styleable#GridLayout_rowOrderPreserved
*/
+ @InspectableProperty
public boolean isRowOrderPreserved() {
return mVerticalAxis.isOrderPreserved();
}
@@ -569,6 +582,7 @@
*
* @attr ref android.R.styleable#GridLayout_columnOrderPreserved
*/
+ @InspectableProperty
public boolean isColumnOrderPreserved() {
return mHorizontalAxis.isOrderPreserved();
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index f781802..bbbe369 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -42,6 +42,7 @@
import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.animation.GridLayoutAnimationController;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -122,7 +123,7 @@
private int mColumnWidth;
@UnsupportedAppUsage
private int mRequestedColumnWidth;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769395)
private int mRequestedNumColumns;
private View mReferenceView = null;
@@ -2061,6 +2062,7 @@
*
* @attr ref android.R.styleable#GridView_gravity
*/
+ @InspectableProperty(valueType = InspectableProperty.ValueType.GRAVITY)
public int getGravity() {
return mGravity;
}
@@ -2096,6 +2098,7 @@
*
* @attr ref android.R.styleable#GridView_horizontalSpacing
*/
+ @InspectableProperty
public int getHorizontalSpacing() {
return mHorizontalSpacing;
}
@@ -2147,6 +2150,7 @@
*
* @attr ref android.R.styleable#GridView_verticalSpacing
*/
+ @InspectableProperty
public int getVerticalSpacing() {
return mVerticalSpacing;
}
@@ -2167,6 +2171,13 @@
}
@StretchMode
+ @InspectableProperty(enumMapping = {
+ @InspectableProperty.EnumMap(value = NO_STRETCH, name = "none"),
+ @InspectableProperty.EnumMap(value = STRETCH_SPACING, name = "spacingWidth"),
+ @InspectableProperty.EnumMap(
+ value = STRETCH_SPACING_UNIFORM, name = "spacingWidthUniform"),
+ @InspectableProperty.EnumMap(value = STRETCH_COLUMN_WIDTH, name = "columnWidth"),
+ })
public int getStretchMode() {
return mStretchMode;
}
@@ -2197,6 +2208,7 @@
*
* @attr ref android.R.styleable#GridView_columnWidth
*/
+ @InspectableProperty
public int getColumnWidth() {
return mColumnWidth;
}
@@ -2241,6 +2253,7 @@
* @see #setNumColumns(int)
*/
@ViewDebug.ExportedProperty
+ @InspectableProperty
public int getNumColumns() {
return mNumColumns;
}
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index bf9dffd..1c5f837 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -43,6 +43,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -293,6 +294,7 @@
*
* @attr ref android.R.styleable#HorizontalScrollView_fillViewport
*/
+ @InspectableProperty
public boolean isFillViewport() {
return mFillViewport;
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index c21182c..e9c31db 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -51,6 +51,7 @@
import android.view.ViewDebug;
import android.view.ViewHierarchyEncoder;
import android.view.accessibility.AccessibilityEvent;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -326,6 +327,7 @@
*
* @attr ref android.R.styleable#ImageView_adjustViewBounds
*/
+ @InspectableProperty
public boolean getAdjustViewBounds() {
return mAdjustViewBounds;
}
@@ -364,6 +366,7 @@
*
* @attr ref android.R.styleable#ImageView_maxWidth
*/
+ @InspectableProperty
public int getMaxWidth() {
return mMaxWidth;
}
@@ -402,6 +405,7 @@
*
* @attr ref android.R.styleable#ImageView_maxHeight
*/
+ @InspectableProperty
public int getMaxHeight() {
return mMaxHeight;
}
@@ -438,6 +442,7 @@
* @return the view's drawable, or null if no drawable has been
* assigned.
*/
+ @InspectableProperty(name = "src")
public Drawable getDrawable() {
if (mDrawable == mRecycleableBitmapDrawable) {
// Consider our cached version dirty since app code now has a reference to it
@@ -650,6 +655,7 @@
* @see #setImageTintList(ColorStateList)
*/
@Nullable
+ @InspectableProperty(name = "tint")
public ColorStateList getImageTintList() {
return mDrawableTintList;
}
@@ -679,6 +685,7 @@
* @see #setImageTintMode(PorterDuff.Mode)
*/
@Nullable
+ @InspectableProperty(name = "tintMode")
public PorterDuff.Mode getImageTintMode() {
return mDrawableTintMode;
}
@@ -844,6 +851,7 @@
* @see ImageView.ScaleType
* @attr ref android.R.styleable#ImageView_scaleType
*/
+ @InspectableProperty
public ScaleType getScaleType() {
return mScaleType;
}
@@ -893,6 +901,7 @@
*
* @attr ref android.R.styleable#ImageView_cropToPadding
*/
+ @InspectableProperty
public boolean getCropToPadding() {
return mCropToPadding;
}
@@ -1404,6 +1413,7 @@
* if baseline alignment is not supported.
*/
@Override
+ @InspectableProperty
@ViewDebug.ExportedProperty(category = "layout")
public int getBaseline() {
if (mBaselineAlignBottom) {
@@ -1451,6 +1461,7 @@
* @return True if the ImageView's baseline is considered the bottom of the view, false if otherwise.
* @see #setBaselineAlignBottom(boolean)
*/
+ @InspectableProperty
public boolean getBaselineAlignBottom() {
return mBaselineAlignBottom;
}
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 15910bb..64769b5 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -31,6 +31,7 @@
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewHierarchyEncoder;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -342,6 +343,7 @@
*
* @attr ref android.R.styleable#LinearLayout_divider
*/
+ @InspectableProperty(name = "divider")
public Drawable getDividerDrawable() {
return mDivider;
}
@@ -526,6 +528,7 @@
*
* @return true when widgets are baseline-aligned, false otherwise
*/
+ @InspectableProperty
public boolean isBaselineAligned() {
return mBaselineAligned;
}
@@ -554,6 +557,7 @@
*
* @attr ref android.R.styleable#LinearLayout_measureWithLargestChild
*/
+ @InspectableProperty(name = "measureWithLargestChild")
public boolean isMeasureWithLargestChildEnabled() {
return mUseLargestChild;
}
@@ -633,6 +637,7 @@
* part of a larger layout that is baseline aligned, or -1 if none has
* been set.
*/
+ @InspectableProperty
public int getBaselineAlignedChildIndex() {
return mBaselineAlignedChildIndex;
}
@@ -686,6 +691,7 @@
* a number lower than or equals to 0.0f if not weight sum is
* to be used.
*/
+ @InspectableProperty
public float getWeightSum() {
return mWeightSum;
}
@@ -1841,6 +1847,10 @@
* @return either {@link #HORIZONTAL} or {@link #VERTICAL}
*/
@OrientationMode
+ @InspectableProperty(enumMapping = {
+ @InspectableProperty.EnumMap(value = HORIZONTAL, name = "horizontal"),
+ @InspectableProperty.EnumMap(value = VERTICAL, name = "vertical")
+ })
public int getOrientation() {
return mOrientation;
}
@@ -1877,6 +1887,7 @@
* @return the current gravity.
* @see #setGravity
*/
+ @InspectableProperty(valueType = InspectableProperty.ValueType.GRAVITY)
public int getGravity() {
return mGravity;
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 9b49786..311f896 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -49,6 +49,7 @@
import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -3637,6 +3638,7 @@
* @return the current drawable drawn between list elements
* @attr ref R.styleable#ListView_divider
*/
+ @InspectableProperty
@Nullable
public Drawable getDivider() {
return mDivider;
@@ -3666,6 +3668,7 @@
/**
* @return Returns the height of the divider that will be drawn between each item in the list.
*/
+ @InspectableProperty
public int getDividerHeight() {
return mDividerHeight;
}
@@ -3701,6 +3704,7 @@
*
* @see #setHeaderDividersEnabled(boolean)
*/
+ @InspectableProperty(name = "headerDividersEnabled")
public boolean areHeaderDividersEnabled() {
return mHeaderDividersEnabled;
}
@@ -3724,6 +3728,7 @@
*
* @see #setFooterDividersEnabled(boolean)
*/
+ @InspectableProperty(name = "footerDividersEnabled")
public boolean areFooterDividersEnabled() {
return mFooterDividersEnabled;
}
diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java
index d82e56c..b0c0c12 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -259,6 +259,19 @@
}
/**
+ * Sets whether the popup menu's adapter is forced to show icons in the
+ * menu item views.
+ * <p>
+ * Changes take effect on the next call to show().
+ *
+ * @param forceShowIcon {@code true} to force icons to be shown, or
+ * {@code false} for icons to be optionally shown
+ */
+ public void setForceShowIcon(boolean forceShowIcon) {
+ mPopup.setForceShowIcon(forceShowIcon);
+ }
+
+ /**
* Interface responsible for receiving menu item click events if the items
* themselves do not have individual item click listeners.
*/
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index ed6f0d6..705a371 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -273,7 +273,7 @@
private int mAnchorXoff;
private int mAnchorYoff;
private int mAnchoredGravity;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private boolean mOverlapAnchor;
private boolean mPopupViewInitialLayoutDirectionInherited;
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 1fc72f5..6b48c65 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -20,6 +20,7 @@
import android.annotation.InterpolatorRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.Px;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -37,6 +38,7 @@
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.graphics.drawable.shapes.Shape;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
@@ -58,6 +60,7 @@
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -168,12 +171,24 @@
/** Duration of smooth progress animations. */
private static final int PROGRESS_ANIM_DURATION = 80;
- @UnsupportedAppUsage
+ /**
+ * Outside the framework, please use {@link ProgressBar#getMinWidth()} and
+ * {@link ProgressBar#setMinWidth(int)} instead of accessing these directly.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
int mMinWidth;
int mMaxWidth;
- @UnsupportedAppUsage
+ /**
+ * Outside the framework, please use {@link ProgressBar#getMinHeight()} and
+ * {@link ProgressBar#setMinHeight(int)} instead of accessing these directly.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
int mMinHeight;
- @UnsupportedAppUsage
+ /**
+ * Outside the framework, please use {@link ProgressBar#getMaxHeight()} ()} and
+ * {@link ProgressBar#setMaxHeight(int)} (int)} instead of accessing these directly.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
int mMaxHeight;
private int mProgress;
@@ -186,7 +201,7 @@
private int mBehavior;
@UnsupportedAppUsage
private int mDuration;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private boolean mIndeterminate;
@UnsupportedAppUsage
private boolean mOnlyIndeterminate;
@@ -391,6 +406,74 @@
}
/**
+ * Sets the minimum width the progress bar can have.
+ * @param minWidth the minimum width to be set, in pixels
+ * @attr ref android.R.styleable#ProgressBar_minWidth
+ */
+ public void setMinWidth(@Px int minWidth) {
+ mMinWidth = minWidth;
+ requestLayout();
+ }
+
+ /**
+ * @return the minimum width the progress bar can have, in pixels
+ */
+ @Px public int getMinWidth() {
+ return mMinWidth;
+ }
+
+ /**
+ * Sets the maximum width the progress bar can have.
+ * @param maxWidth the maximum width to be set, in pixels
+ * @attr ref android.R.styleable#ProgressBar_maxWidth
+ */
+ public void setMaxWidth(@Px int maxWidth) {
+ mMaxWidth = maxWidth;
+ requestLayout();
+ }
+
+ /**
+ * @return the maximum width the progress bar can have, in pixels
+ */
+ @Px public int getMaxWidth() {
+ return mMaxWidth;
+ }
+
+ /**
+ * Sets the minimum height the progress bar can have.
+ * @param minHeight the minimum height to be set, in pixels
+ * @attr ref android.R.styleable#ProgressBar_minHeight
+ */
+ public void setMinHeight(@Px int minHeight) {
+ mMinHeight = minHeight;
+ requestLayout();
+ }
+
+ /**
+ * @return the minimum height the progress bar can have, in pixels
+ */
+ @Px public int getMinHeight() {
+ return mMinHeight;
+ }
+
+ /**
+ * Sets the maximum height the progress bar can have.
+ * @param maxHeight the maximum height to be set, in pixels
+ * @attr ref android.R.styleable#ProgressBar_maxHeight
+ */
+ public void setMaxHeight(@Px int maxHeight) {
+ mMaxHeight = maxHeight;
+ requestLayout();
+ }
+
+ /**
+ * @return the maximum height the progress bar can have, in pixels
+ */
+ @Px public int getMaxHeight() {
+ return mMaxHeight;
+ }
+
+ /**
* Returns {@code true} if the target drawable needs to be tileified.
*
* @param dr the drawable to check
@@ -556,6 +639,7 @@
*
* @return true if the progress bar is in indeterminate mode
*/
+ @InspectableProperty
@ViewDebug.ExportedProperty(category = "progress")
public synchronized boolean isIndeterminate() {
return mIndeterminate;
@@ -610,6 +694,7 @@
* @see #setIndeterminateDrawable(android.graphics.drawable.Drawable)
* @see #setIndeterminate(boolean)
*/
+ @InspectableProperty
public Drawable getIndeterminateDrawable() {
return mIndeterminateDrawable;
}
@@ -677,6 +762,7 @@
* @attr ref android.R.styleable#ProgressBar_indeterminateTint
* @see #setIndeterminateTintList(ColorStateList)
*/
+ @InspectableProperty(name = "indeterminateTint")
@Nullable
public ColorStateList getIndeterminateTintList() {
return mProgressTintInfo != null ? mProgressTintInfo.mIndeterminateTintList : null;
@@ -712,6 +798,7 @@
* @attr ref android.R.styleable#ProgressBar_indeterminateTintMode
* @see #setIndeterminateTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getIndeterminateTintMode() {
return mProgressTintInfo != null ? mProgressTintInfo.mIndeterminateTintMode : null;
@@ -768,6 +855,7 @@
* @see #setProgressDrawable(android.graphics.drawable.Drawable)
* @see #setIndeterminate(boolean)
*/
+ @InspectableProperty
public Drawable getProgressDrawable() {
return mProgressDrawable;
}
@@ -821,6 +909,7 @@
/**
* @hide
*/
+ @InspectableProperty
public boolean getMirrorForRtl() {
return mMirrorForRtl;
}
@@ -951,6 +1040,7 @@
* @attr ref android.R.styleable#ProgressBar_progressTint
* @see #setProgressTintList(ColorStateList)
*/
+ @InspectableProperty(name = "progressTint")
@Nullable
public ColorStateList getProgressTintList() {
return mProgressTintInfo != null ? mProgressTintInfo.mProgressTintList : null;
@@ -988,6 +1078,7 @@
* @attr ref android.R.styleable#ProgressBar_progressTintMode
* @see #setProgressTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getProgressTintMode() {
return mProgressTintInfo != null ? mProgressTintInfo.mProgressTintMode : null;
@@ -1033,6 +1124,7 @@
* @attr ref android.R.styleable#ProgressBar_progressBackgroundTint
* @see #setProgressBackgroundTintList(ColorStateList)
*/
+ @InspectableProperty(name = "progressBackgroundTint")
@Nullable
public ColorStateList getProgressBackgroundTintList() {
return mProgressTintInfo != null ? mProgressTintInfo.mProgressBackgroundTintList : null;
@@ -1067,6 +1159,7 @@
* @attr ref android.R.styleable#ProgressBar_progressBackgroundTintMode
* @see #setProgressBackgroundTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getProgressBackgroundTintMode() {
return mProgressTintInfo != null ? mProgressTintInfo.mProgressBackgroundTintMode : null;
@@ -1112,6 +1205,7 @@
* @attr ref android.R.styleable#ProgressBar_secondaryProgressTint
* @see #setSecondaryProgressTintList(ColorStateList)
*/
+ @InspectableProperty(name = "secondaryProgressTint")
@Nullable
public ColorStateList getSecondaryProgressTintList() {
return mProgressTintInfo != null ? mProgressTintInfo.mSecondaryProgressTintList : null;
@@ -1150,6 +1244,7 @@
* @attr ref android.R.styleable#ProgressBar_secondaryProgressTintMode
* @see #setSecondaryProgressTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getSecondaryProgressTintMode() {
return mProgressTintInfo != null ? mProgressTintInfo.mSecondaryProgressTintMode : null;
@@ -1477,6 +1572,7 @@
* @see #getMax()
*/
@ViewDebug.ExportedProperty(category = "progress")
+ @InspectableProperty
public synchronized int getProgress() {
return mIndeterminate ? 0 : mProgress;
}
@@ -1494,6 +1590,7 @@
* @see #getMax()
*/
@ViewDebug.ExportedProperty(category = "progress")
+ @InspectableProperty
public synchronized int getSecondaryProgress() {
return mIndeterminate ? 0 : mSecondaryProgress;
}
@@ -1508,6 +1605,7 @@
* @see #getSecondaryProgress()
*/
@ViewDebug.ExportedProperty(category = "progress")
+ @InspectableProperty
public synchronized int getMin() {
return mMin;
}
@@ -1522,6 +1620,7 @@
* @see #getSecondaryProgress()
*/
@ViewDebug.ExportedProperty(category = "progress")
+ @InspectableProperty
public synchronized int getMax() {
return mMax;
}
@@ -1687,6 +1786,7 @@
*
* @return the {@link Interpolator} associated to this animation
*/
+ @InspectableProperty
public Interpolator getInterpolator() {
return mInterpolator;
}
diff --git a/core/java/android/widget/RatingBar.java b/core/java/android/widget/RatingBar.java
index d343d49..9f9fdee 100644
--- a/core/java/android/widget/RatingBar.java
+++ b/core/java/android/widget/RatingBar.java
@@ -23,6 +23,7 @@
import android.graphics.drawable.shapes.Shape;
import android.util.AttributeSet;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -164,6 +165,7 @@
*
* @attr ref android.R.styleable#RatingBar_isIndicator
*/
+ @InspectableProperty(name = "isIndicator")
public boolean isIndicator() {
return !mIsUserSeekable;
}
@@ -190,6 +192,7 @@
* Returns the number of stars shown.
* @return The number of stars shown.
*/
+ @InspectableProperty
public int getNumStars() {
return mNumStars;
}
@@ -208,6 +211,7 @@
*
* @return The current rating.
*/
+ @InspectableProperty
public float getRating() {
return getProgress() / getProgressPerStar();
}
@@ -234,6 +238,7 @@
*
* @return The step size.
*/
+ @InspectableProperty
public float getStepSize() {
return (float) getNumStars() / getMax();
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 506d615..556bfd1 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -34,6 +34,7 @@
import android.view.ViewGroup;
import android.view.ViewHierarchyEncoder;
import android.view.accessibility.AccessibilityEvent;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
@@ -289,6 +290,16 @@
}
/**
+ * Get the id of the View to be ignored by gravity
+ *
+ * @attr ref android.R.styleable#RelativeLayout_ignoreGravity
+ */
+ @InspectableProperty
+ public int getIgnoreGravity() {
+ return mIgnoreGravity;
+ }
+
+ /**
* Describes how the child views are positioned.
*
* @return the gravity.
@@ -298,6 +309,7 @@
*
* @attr ref android.R.styleable#RelativeLayout_gravity
*/
+ @InspectableProperty(valueType = InspectableProperty.ValueType.GRAVITY)
public int getGravity() {
return mGravity;
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 2dec4e8..8514b85 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -206,13 +206,13 @@
*
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public ApplicationInfo mApplication;
/**
* The resource ID of the layout file. (Added to the parcel)
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private final int mLayoutId;
/**
@@ -224,13 +224,13 @@
* An array of actions to perform on the view tree once it has been
* inflated
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private ArrayList<Action> mActions;
/**
* Maps bitmaps to unique indicies to avoid Bitmap duplication.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private BitmapCache mBitmapCache;
/**
@@ -252,7 +252,7 @@
* RemoteViews.
*/
private RemoteViews mLandscape = null;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private RemoteViews mPortrait = null;
@ApplyFlags
@@ -430,7 +430,7 @@
// Do nothing
}
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public int mergeBehavior() {
return MERGE_REPLACE;
}
@@ -466,7 +466,7 @@
// Nothing to visit by default
}
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
int viewId;
}
@@ -499,7 +499,7 @@
*
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public void mergeRemoteViews(RemoteViews newRv) {
if (newRv == null) return;
// We first copy the new RemoteViews, as the process of merging modifies the way the actions
@@ -690,7 +690,7 @@
return SET_PENDING_INTENT_TEMPLATE_TAG;
}
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
PendingIntent pendingIntentTemplate;
}
@@ -1138,7 +1138,7 @@
private static class BitmapCache {
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
ArrayList<Bitmap> mBitmaps;
int mBitmapMemory = -1;
@@ -1190,9 +1190,9 @@
private class BitmapReflectionAction extends Action {
int bitmapId;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Bitmap bitmap;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
String methodName;
BitmapReflectionAction(int viewId, String methodName, Bitmap bitmap) {
@@ -1258,10 +1258,10 @@
static final int COLOR_STATE_LIST = 15;
static final int ICON = 16;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
String methodName;
int type;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Object value;
ReflectionAction(int viewId, String methodName, int type, Object value) {
@@ -1554,7 +1554,7 @@
* ViewGroup methods that are related to adding Views.
*/
private class ViewGroupActionAdd extends Action {
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private RemoteViews mNestedViews;
private int mIndex;
@@ -2469,7 +2469,7 @@
* Returns an estimate of the bitmap heap memory usage for this RemoteViews.
*/
/** @hide */
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public int estimateMemoryUsage() {
return mBitmapCache.getBitmapMemory();
}
@@ -2517,7 +2517,7 @@
*
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public void addView(int viewId, RemoteViews nestedView, int index) {
addAction(new ViewGroupActionAdd(viewId, nestedView, index));
}
@@ -2992,8 +2992,9 @@
* See {@link Adapter#getViewTypeCount()}.
*
* @hide
+ * @deprecated this appears to have no users outside of UnsupportedAppUsage?
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public void setRemoteAdapter(int viewId, ArrayList<RemoteViews> list, int viewTypeCount) {
addAction(new SetRemoteViewsAdapterList(viewId, list, viewTypeCount));
}
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 4658d73..24bc9f1 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -45,6 +45,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -110,7 +111,7 @@
* layout is dirty. This prevents the scroll from being wrong if the child has not been
* laid out before requesting focus.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769715)
private View mChildToScrollTo = null;
/**
@@ -324,6 +325,7 @@
*
* @attr ref android.R.styleable#ScrollView_fillViewport
*/
+ @InspectableProperty
public boolean isFillViewport() {
return mFillViewport;
}
@@ -1382,16 +1384,20 @@
*
* @param child the View to scroll to
*/
- private void scrollToChild(View child) {
- child.getDrawingRect(mTempRect);
+ public void scrollToDescendant(View child) {
+ if (!mIsLayoutDirty) {
+ child.getDrawingRect(mTempRect);
- /* Offset from child's local coordinates to ScrollView coordinates */
- offsetDescendantRectToMyCoords(child, mTempRect);
+ /* Offset from child's local coordinates to ScrollView coordinates */
+ offsetDescendantRectToMyCoords(child, mTempRect);
- int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+ int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
- if (scrollDelta != 0) {
- scrollBy(0, scrollDelta);
+ if (scrollDelta != 0) {
+ scrollBy(0, scrollDelta);
+ }
+ } else {
+ mChildToScrollTo = child;
}
}
@@ -1486,7 +1492,7 @@
public void requestChildFocus(View child, View focused) {
if (focused != null && focused.getRevealOnFocusHint()) {
if (!mIsLayoutDirty) {
- scrollToChild(focused);
+ scrollToDescendant(focused);
} else {
// The child may not be laid out yet, we can't compute the scroll yet
mChildToScrollTo = focused;
@@ -1567,7 +1573,7 @@
mIsLayoutDirty = false;
// Give a child focus if it needs it
if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
- scrollToChild(mChildToScrollTo);
+ scrollToDescendant(mChildToScrollTo);
}
mChildToScrollTo = null;
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 10e1dfb..af3b8c0 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -62,6 +62,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.view.inspector.InspectableProperty;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.TextView.OnEditorActionListener;
@@ -563,6 +564,7 @@
*
* @return the query string
*/
+ @InspectableProperty(hasAttributeId = false)
public CharSequence getQuery() {
return mSearchSrcTextView.getText();
}
@@ -620,6 +622,7 @@
* @return the displayed query hint text, or {@code null} if none set
* @attr ref android.R.styleable#SearchView_queryHint
*/
+ @InspectableProperty
@Nullable
public CharSequence getQueryHint() {
final CharSequence hint;
@@ -656,13 +659,25 @@
* Returns the default iconified state of the search field.
* @return
*
+ * @deprecated use {@link #isIconifiedByDefault()}
* @attr ref android.R.styleable#SearchView_iconifiedByDefault
*/
+ @Deprecated
public boolean isIconfiedByDefault() {
return mIconifiedByDefault;
}
/**
+ * Returns the default iconified state of the search field.
+ *
+ * @attr ref android.R.styleable#SearchView_iconifiedByDefault
+ */
+ @InspectableProperty
+ public boolean isIconifiedByDefault() {
+ return mIconifiedByDefault;
+ }
+
+ /**
* Iconifies or expands the SearchView. Any query text is cleared when iconified. This is
* a temporary state and does not override the default iconified state set by
* {@link #setIconifiedByDefault(boolean)}. If the default state is iconified, then
@@ -686,6 +701,7 @@
* @return true if the SearchView is currently iconified, false if the search field is
* fully visible.
*/
+ @InspectableProperty(hasAttributeId = false)
public boolean isIconified() {
return mIconified;
}
@@ -780,6 +796,7 @@
*
* @attr ref android.R.styleable#SearchView_maxWidth
*/
+ @InspectableProperty
public int getMaxWidth() {
return mMaxWidth;
}
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 1705ba8..fb56d97 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -45,6 +45,7 @@
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inspector.InspectableProperty;
import android.widget.PopupWindow.OnDismissListener;
import com.android.internal.R;
@@ -360,6 +361,7 @@
*
* @attr ref android.R.styleable#Spinner_popupBackground
*/
+ @InspectableProperty
public Drawable getPopupBackground() {
return mPopup.getBackground();
}
@@ -392,6 +394,7 @@
*
* @attr ref android.R.styleable#ListPopupWindow_dropDownVerticalOffset
*/
+ @InspectableProperty
public int getDropDownVerticalOffset() {
return mPopup.getVerticalOffset();
}
@@ -416,6 +419,7 @@
*
* @attr ref android.R.styleable#ListPopupWindow_dropDownHorizontalOffset
*/
+ @InspectableProperty
public int getDropDownHorizontalOffset() {
return mPopup.getHorizontalOffset();
}
@@ -452,6 +456,7 @@
*
* @attr ref android.R.styleable#Spinner_dropDownWidth
*/
+ @InspectableProperty
public int getDropDownWidth() {
return mDropDownWidth;
}
@@ -491,6 +496,7 @@
*
* @return A {@link android.view.Gravity Gravity} value
*/
+ @InspectableProperty(valueType = InspectableProperty.ValueType.GRAVITY)
public int getGravity() {
return mGravity;
}
@@ -828,6 +834,7 @@
/**
* @return The prompt to display when the dialog is shown
*/
+ @InspectableProperty
public CharSequence getPrompt() {
return mPopup.getHintText();
}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 79dc670..af4f0202 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -52,6 +52,7 @@
import android.view.ViewStructure;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -444,6 +445,7 @@
*
* @attr ref android.R.styleable#Switch_switchPadding
*/
+ @InspectableProperty
public int getSwitchPadding() {
return mSwitchPadding;
}
@@ -469,6 +471,7 @@
*
* @attr ref android.R.styleable#Switch_switchMinWidth
*/
+ @InspectableProperty
public int getSwitchMinWidth() {
return mSwitchMinWidth;
}
@@ -492,6 +495,7 @@
*
* @attr ref android.R.styleable#Switch_thumbTextPadding
*/
+ @InspectableProperty
public int getThumbTextPadding() {
return mThumbTextPadding;
}
@@ -532,6 +536,7 @@
*
* @attr ref android.R.styleable#Switch_track
*/
+ @InspectableProperty(name = "track")
public Drawable getTrackDrawable() {
return mTrackDrawable;
}
@@ -562,6 +567,7 @@
* @attr ref android.R.styleable#Switch_trackTint
* @see #setTrackTintList(ColorStateList)
*/
+ @InspectableProperty(name = "trackTint")
@Nullable
public ColorStateList getTrackTintList() {
return mTrackTintList;
@@ -591,6 +597,7 @@
* @attr ref android.R.styleable#Switch_trackTintMode
* @see #setTrackTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getTrackTintMode() {
return mTrackTintMode;
@@ -655,6 +662,7 @@
*
* @attr ref android.R.styleable#Switch_thumb
*/
+ @InspectableProperty(name = "thumb")
public Drawable getThumbDrawable() {
return mThumbDrawable;
}
@@ -685,6 +693,7 @@
* @attr ref android.R.styleable#Switch_thumbTint
* @see #setThumbTintList(ColorStateList)
*/
+ @InspectableProperty(name = "thumbTint")
@Nullable
public ColorStateList getThumbTintList() {
return mThumbTintList;
@@ -714,6 +723,7 @@
* @attr ref android.R.styleable#Switch_thumbTintMode
* @see #setThumbTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty
@Nullable
public PorterDuff.Mode getThumbTintMode() {
return mThumbTintMode;
@@ -758,6 +768,7 @@
*
* @attr ref android.R.styleable#Switch_splitTrack
*/
+ @InspectableProperty
public boolean getSplitTrack() {
return mSplitTrack;
}
@@ -767,6 +778,7 @@
*
* @attr ref android.R.styleable#Switch_textOn
*/
+ @InspectableProperty
public CharSequence getTextOn() {
return mTextOn;
}
@@ -786,6 +798,7 @@
*
* @attr ref android.R.styleable#Switch_textOff
*/
+ @InspectableProperty
public CharSequence getTextOff() {
return mTextOff;
}
@@ -817,6 +830,7 @@
* @return whether the on/off text should be displayed
* @attr ref android.R.styleable#Switch_showText
*/
+ @InspectableProperty
public boolean getShowText() {
return mShowText;
}
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index 4865808..7f462cb 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -39,6 +39,7 @@
import android.util.AttributeSet;
import android.view.RemotableViewMethod;
import android.view.ViewHierarchyEncoder;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -285,6 +286,7 @@
* @see #setFormat12Hour(CharSequence)
* @see #is24HourModeEnabled()
*/
+ @InspectableProperty
@ExportedProperty
public CharSequence getFormat12Hour() {
return mFormat12;
@@ -344,6 +346,7 @@
* @see #setFormat24Hour(CharSequence)
* @see #is24HourModeEnabled()
*/
+ @InspectableProperty
@ExportedProperty
public CharSequence getFormat24Hour() {
return mFormat24;
@@ -435,6 +438,7 @@
* @see #setFormat24Hour(CharSequence)
* @see #getFormat24Hour()
*/
+ @InspectableProperty(hasAttributeId = false)
public boolean is24HourModeEnabled() {
if (mShowCurrentUserTime) {
return DateFormat.is24HourFormat(getContext(), ActivityManager.getCurrentUser());
@@ -453,6 +457,7 @@
* @see java.util.TimeZone#getAvailableIDs()
* @see #setTimeZone(String)
*/
+ @InspectableProperty
public String getTimeZone() {
return mTimeZone;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 8029cf0..0f4e23d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -172,6 +172,9 @@
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.view.inspector.InspectableProperty;
+import android.view.inspector.InspectableProperty.EnumMap;
+import android.view.inspector.InspectableProperty.FlagMap;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassificationContext;
import android.view.textclassifier.TextClassificationManager;
@@ -432,8 +435,13 @@
private ColorStateList mHintTextColor;
private ColorStateList mLinkTextColor;
@ViewDebug.ExportedProperty(category = "text")
- @UnsupportedAppUsage
+
+ /**
+ * {@link #setTextColor(int)} or {@link #getCurrentTextColor()} should be used instead.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private int mCurTextColor;
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private int mCurHintTextColor;
private boolean mFreezesText;
@@ -704,7 +712,7 @@
@UnsupportedAppUsage
private ChangeWatcher mChangeWatcher;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123769451)
private ArrayList<TextWatcher> mListeners;
// display attributes
@@ -1889,6 +1897,10 @@
* @see #setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int)
* @see #setAutoSizeTextTypeUniformWithPresetSizes(int[], int)
*/
+ @InspectableProperty(enumMapping = {
+ @EnumMap(name = "none", value = AUTO_SIZE_TEXT_TYPE_NONE),
+ @EnumMap(name = "uniform", value = AUTO_SIZE_TEXT_TYPE_UNIFORM)
+ })
@AutoSizeTextType
public int getAutoSizeTextType() {
return mAutoSizeTextType;
@@ -1901,6 +1913,7 @@
*
* @see #setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int)
*/
+ @InspectableProperty
public int getAutoSizeStepGranularity() {
return Math.round(mAutoSizeStepGranularityInPx);
}
@@ -1914,6 +1927,7 @@
* @see #setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int)
* @see #setAutoSizeTextTypeUniformWithPresetSizes(int[], int)
*/
+ @InspectableProperty
public int getAutoSizeMinTextSize() {
return Math.round(mAutoSizeMinTextSizeInPx);
}
@@ -1927,6 +1941,7 @@
* @see #setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int)
* @see #setAutoSizeTextTypeUniformWithPresetSizes(int[], int)
*/
+ @InspectableProperty
public int getAutoSizeMaxTextSize() {
return Math.round(mAutoSizeMaxTextSizeInPx);
}
@@ -2271,6 +2286,7 @@
* @attr ref android.R.styleable#TextView_text
*/
@ViewDebug.CapturedViewProperty
+ @InspectableProperty
public CharSequence getText() {
return mText;
}
@@ -2308,6 +2324,7 @@
* contain additional first-or last-line padding.
* @return The height of one standard line in pixels.
*/
+ @InspectableProperty
public int getLineHeight() {
return FastMath.round(mTextPaint.getFontMetricsInt(null) * mSpacingMult + mSpacingAdd);
}
@@ -3231,6 +3248,7 @@
*
* @attr ref android.R.styleable#TextView_drawablePadding
*/
+ @InspectableProperty(name = "drawablePadding")
public int getCompoundDrawablePadding() {
final Drawables dr = mDrawables;
return dr != null ? dr.mDrawablePadding : 0;
@@ -3267,6 +3285,7 @@
* @attr ref android.R.styleable#TextView_drawableTint
* @see #setCompoundDrawableTintList(ColorStateList)
*/
+ @InspectableProperty(name = "drawableTint")
public ColorStateList getCompoundDrawableTintList() {
return mDrawables != null ? mDrawables.mTintList : null;
}
@@ -3301,6 +3320,7 @@
* @attr ref android.R.styleable#TextView_drawableTintMode
* @see #setCompoundDrawableTintMode(PorterDuff.Mode)
*/
+ @InspectableProperty(name = "drawableTintMode")
public PorterDuff.Mode getCompoundDrawableTintMode() {
return mDrawables != null ? mDrawables.mTintMode : null;
}
@@ -3481,6 +3501,7 @@
* @see #setFirstBaselineToTopHeight(int)
* @attr ref android.R.styleable#TextView_firstBaselineToTopHeight
*/
+ @InspectableProperty
public int getFirstBaselineToTopHeight() {
return getPaddingTop() - getPaint().getFontMetricsInt().top;
}
@@ -3491,17 +3512,24 @@
* @see #setLastBaselineToBottomHeight(int)
* @attr ref android.R.styleable#TextView_lastBaselineToBottomHeight
*/
+ @InspectableProperty
public int getLastBaselineToBottomHeight() {
return getPaddingBottom() + getPaint().getFontMetricsInt().bottom;
}
/**
- * Gets the autolink mask of the text. See {@link
- * android.text.util.Linkify#ALL Linkify.ALL} and peers for
- * possible values.
+ * Gets the autolink mask of the text.
+ *
+ * See {@link Linkify#ALL} and peers for possible values.
*
* @attr ref android.R.styleable#TextView_autoLink
*/
+ @InspectableProperty(name = "autoLink", flagMapping = {
+ @FlagMap(name = "web", target = Linkify.WEB_URLS),
+ @FlagMap(name = "email", target = Linkify.EMAIL_ADDRESSES),
+ @FlagMap(name = "phone", target = Linkify.PHONE_NUMBERS),
+ @FlagMap(name = "map", target = Linkify.MAP_ADDRESSES)
+ })
public final int getAutoLinkMask() {
return mAutoLinkMask;
}
@@ -4150,6 +4178,7 @@
/**
* @return the size (in pixels) of the default text size in this TextView.
*/
+ @InspectableProperty
@ViewDebug.ExportedProperty(category = "text")
public float getTextSize() {
return mTextPaint.getTextSize();
@@ -4243,6 +4272,7 @@
* This will usually be 1.0.
* @return The horizontal scale factor.
*/
+ @InspectableProperty
public float getTextScaleX() {
return mTextPaint.getTextScaleX();
}
@@ -4303,6 +4333,7 @@
* @attr ref android.R.styleable#TextView_typeface
* @attr ref android.R.styleable#TextView_textStyle
*/
+ @InspectableProperty
public Typeface getTypeface() {
return mTextPaint.getTypeface();
}
@@ -4363,6 +4394,7 @@
*
* @attr ref android.R.styleable#TextView_fallbackLineSpacing
*/
+ @InspectableProperty
public boolean isFallbackLineSpacing() {
return mUseFallbackLineSpacing;
}
@@ -4376,6 +4408,7 @@
* @see #setElegantTextHeight(boolean)
* @see Paint#setElegantTextHeight(boolean)
*/
+ @InspectableProperty
public boolean isElegantTextHeight() {
return mTextPaint.isElegantTextHeight();
}
@@ -4388,6 +4421,7 @@
* @see #setLetterSpacing(float)
* @see Paint#setLetterSpacing
*/
+ @InspectableProperty
public float getLetterSpacing() {
return mTextPaint.getLetterSpacing();
}
@@ -4426,6 +4460,7 @@
* @see #setFontFeatureSettings(String)
* @see Paint#setFontFeatureSettings(String) Paint.setFontFeatureSettings(String)
*/
+ @InspectableProperty
@Nullable
public String getFontFeatureSettings() {
return mTextPaint.getFontFeatureSettings();
@@ -4477,6 +4512,11 @@
* @attr ref android.R.styleable#TextView_breakStrategy
* @see #setBreakStrategy(int)
*/
+ @InspectableProperty(enumMapping = {
+ @EnumMap(name = "simple", value = Layout.BREAK_STRATEGY_SIMPLE),
+ @EnumMap(name = "high_quality", value = Layout.BREAK_STRATEGY_HIGH_QUALITY),
+ @EnumMap(name = "balanced", value = Layout.BREAK_STRATEGY_BALANCED)
+ })
@Layout.BreakStrategy
public int getBreakStrategy() {
return mBreakStrategy;
@@ -4523,6 +4563,11 @@
* @attr ref android.R.styleable#TextView_hyphenationFrequency
* @see #setHyphenationFrequency(int)
*/
+ @InspectableProperty(enumMapping = {
+ @EnumMap(name = "none", value = Layout.HYPHENATION_FREQUENCY_NONE),
+ @EnumMap(name = "normal", value = Layout.HYPHENATION_FREQUENCY_NORMAL),
+ @EnumMap(name = "full", value = Layout.HYPHENATION_FREQUENCY_FULL)
+ })
@Layout.HyphenationFrequency
public int getHyphenationFrequency() {
return mHyphenationFrequency;
@@ -4580,6 +4625,10 @@
*
* @see #setJustificationMode(int)
*/
+ @InspectableProperty(enumMapping = {
+ @EnumMap(name = "none", value = Layout.JUSTIFICATION_MODE_NONE),
+ @EnumMap(name = "inter_word", value = Layout.JUSTIFICATION_MODE_INTER_WORD)
+ })
public @Layout.JustificationMode int getJustificationMode() {
return mJustificationMode;
}
@@ -4720,6 +4769,7 @@
*
* @attr ref android.R.styleable#TextView_textColor
*/
+ @InspectableProperty(name = "textColor")
public final ColorStateList getTextColors() {
return mTextColor;
}
@@ -4754,6 +4804,7 @@
*
* @attr ref android.R.styleable#TextView_textColorHighlight
*/
+ @InspectableProperty(name = "textColorHighlight")
@ColorInt
public int getHighlightColor() {
return mHighlightColor;
@@ -4819,6 +4870,7 @@
*
* @attr ref android.R.styleable#TextView_shadowRadius
*/
+ @InspectableProperty
public float getShadowRadius() {
return mShadowRadius;
}
@@ -4830,6 +4882,7 @@
*
* @attr ref android.R.styleable#TextView_shadowDx
*/
+ @InspectableProperty
public float getShadowDx() {
return mShadowDx;
}
@@ -4842,6 +4895,7 @@
*
* @attr ref android.R.styleable#TextView_shadowDy
*/
+ @InspectableProperty
public float getShadowDy() {
return mShadowDy;
}
@@ -4854,6 +4908,7 @@
*
* @attr ref android.R.styleable#TextView_shadowColor
*/
+ @InspectableProperty
@ColorInt
public int getShadowColor() {
return mShadowColor;
@@ -4901,6 +4956,7 @@
*
* @attr ref android.R.styleable#TextView_linksClickable
*/
+ @InspectableProperty
public final boolean getLinksClickable() {
return mLinksClickable;
}
@@ -4961,6 +5017,7 @@
*
* @attr ref android.R.styleable#TextView_textColorHint
*/
+ @InspectableProperty(name = "textColorHint")
public final ColorStateList getHintTextColors() {
return mHintTextColor;
}
@@ -5013,6 +5070,7 @@
*
* @attr ref android.R.styleable#TextView_textColorLink
*/
+ @InspectableProperty(name = "textColorLink")
public final ColorStateList getLinkTextColors() {
return mLinkTextColor;
}
@@ -5062,6 +5120,7 @@
* @see android.view.Gravity
* @attr ref android.R.styleable#TextView_gravity
*/
+ @InspectableProperty(valueType = InspectableProperty.ValueType.GRAVITY)
public int getGravity() {
return mGravity;
}
@@ -5118,6 +5177,7 @@
* @attr ref android.R.styleable#TextView_scrollHorizontally
* @see #setHorizontallyScrolling(boolean)
*/
+ @InspectableProperty(name = "scrollHorizontally")
public final boolean isHorizontallyScrollable() {
return mHorizontallyScrolling;
}
@@ -5170,6 +5230,7 @@
*
* @attr ref android.R.styleable#TextView_minLines
*/
+ @InspectableProperty
public int getMinLines() {
return mMinMode == LINES ? mMinimum : -1;
}
@@ -5252,6 +5313,7 @@
*
* @attr ref android.R.styleable#TextView_maxLines
*/
+ @InspectableProperty
public int getMaxLines() {
return mMaxMode == LINES ? mMaximum : -1;
}
@@ -5291,6 +5353,7 @@
*
* @attr ref android.R.styleable#TextView_maxHeight
*/
+ @InspectableProperty
public int getMaxHeight() {
return mMaxMode == PIXELS ? mMaximum : -1;
}
@@ -5375,6 +5438,7 @@
*
* @attr ref android.R.styleable#TextView_minEms
*/
+ @InspectableProperty
public int getMinEms() {
return mMinWidthMode == EMS ? mMinWidth : -1;
}
@@ -5418,6 +5482,7 @@
*
* @attr ref android.R.styleable#TextView_minWidth
*/
+ @InspectableProperty
public int getMinWidth() {
return mMinWidthMode == PIXELS ? mMinWidth : -1;
}
@@ -5457,6 +5522,7 @@
*
* @attr ref android.R.styleable#TextView_maxEms
*/
+ @InspectableProperty
public int getMaxEms() {
return mMaxWidthMode == EMS ? mMaxWidth : -1;
}
@@ -5496,6 +5562,7 @@
*
* @attr ref android.R.styleable#TextView_maxWidth
*/
+ @InspectableProperty
public int getMaxWidth() {
return mMaxWidthMode == PIXELS ? mMaxWidth : -1;
}
@@ -5579,6 +5646,7 @@
*
* @attr ref android.R.styleable#TextView_lineSpacingMultiplier
*/
+ @InspectableProperty
public float getLineSpacingMultiplier() {
return mSpacingMult;
}
@@ -5593,6 +5661,7 @@
*
* @attr ref android.R.styleable#TextView_lineSpacingExtra
*/
+ @InspectableProperty
public float getLineSpacingExtra() {
return mSpacingAdd;
}
@@ -5877,6 +5946,7 @@
*
* @see #setFreezesText
*/
+ @InspectableProperty
public boolean getFreezesText() {
return mFreezesText;
}
@@ -6340,6 +6410,7 @@
*
* @attr ref android.R.styleable#TextView_hint
*/
+ @InspectableProperty
@ViewDebug.CapturedViewProperty
public CharSequence getHint() {
return mHint;
@@ -6351,6 +6422,7 @@
*
* @attr ref android.R.styleable#TextView_singleLine
*/
+ @InspectableProperty
public boolean isSingleLine() {
return mSingleLine;
}
@@ -6592,6 +6664,147 @@
* @see #setInputType(int)
* @see android.text.InputType
*/
+ @InspectableProperty(flagMapping = {
+ @FlagMap(name = "none", mask = 0xffffffff, target = InputType.TYPE_NULL),
+ @FlagMap(
+ name = "text",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL),
+ @FlagMap(
+ name = "textUri",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI),
+ @FlagMap(
+ name = "textEmailAddress",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS),
+ @FlagMap(
+ name = "textEmailSubject",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT),
+ @FlagMap(
+ name = "textShortMessage",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE),
+ @FlagMap(
+ name = "textLongMessage",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE),
+ @FlagMap(
+ name = "textPersonName",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_PERSON_NAME),
+ @FlagMap(
+ name = "textPostalAddress",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS),
+ @FlagMap(
+ name = "textPassword",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD),
+ @FlagMap(
+ name = "textVisiblePassword",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD),
+ @FlagMap(
+ name = "textWebEditText",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT),
+ @FlagMap(
+ name = "textFilter",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_FILTER),
+ @FlagMap(
+ name = "textPhonetic",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PHONETIC),
+ @FlagMap(
+ name = "textWebEmailAddress",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS),
+ @FlagMap(
+ name = "textWebPassword",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD),
+ @FlagMap(
+ name = "number",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_NORMAL),
+ @FlagMap(
+ name = "numberPassword",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_NUMBER
+ | InputType.TYPE_NUMBER_VARIATION_PASSWORD),
+ @FlagMap(
+ name = "phone",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_PHONE),
+ @FlagMap(
+ name = "datetime",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_DATETIME
+ | InputType.TYPE_DATETIME_VARIATION_NORMAL),
+ @FlagMap(
+ name = "date",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_DATETIME
+ | InputType.TYPE_DATETIME_VARIATION_DATE),
+ @FlagMap(
+ name = "time",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION,
+ target = InputType.TYPE_CLASS_DATETIME
+ | InputType.TYPE_DATETIME_VARIATION_TIME),
+ @FlagMap(
+ name = "textCapCharacters",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS),
+ @FlagMap(
+ name = "textCapWords",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_WORDS),
+ @FlagMap(
+ name = "textCapSentences",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES),
+ @FlagMap(
+ name = "textAutoCorrect",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT),
+ @FlagMap(
+ name = "textAutoComplete",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE),
+ @FlagMap(
+ name = "textMultiLine",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE),
+ @FlagMap(
+ name = "textImeMultiLine",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE),
+ @FlagMap(
+ name = "textNoSuggestions",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS),
+ @FlagMap(
+ name = "numberSigned",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED),
+ @FlagMap(
+ name = "numberDecimal",
+ mask = InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_FLAGS,
+ target = InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL),
+ })
public int getInputType() {
return mEditor == null ? EditorInfo.TYPE_NULL : mEditor.mInputType;
}
@@ -6614,8 +6827,55 @@
* Get the type of the Input Method Editor (IME).
* @return the type of the IME
* @see #setImeOptions(int)
- * @see android.view.inputmethod.EditorInfo
+ * @see EditorInfo
*/
+ @InspectableProperty(flagMapping = {
+ @FlagMap(name = "normal", mask = 0xffffffff, target = EditorInfo.IME_NULL),
+ @FlagMap(
+ name = "actionUnspecified",
+ mask = EditorInfo.IME_MASK_ACTION,
+ target = EditorInfo.IME_ACTION_UNSPECIFIED),
+ @FlagMap(
+ name = "actionNone",
+ mask = EditorInfo.IME_MASK_ACTION,
+ target = EditorInfo.IME_ACTION_NONE),
+ @FlagMap(
+ name = "actionGo",
+ mask = EditorInfo.IME_MASK_ACTION,
+ target = EditorInfo.IME_ACTION_GO),
+ @FlagMap(
+ name = "actionSearch",
+ mask = EditorInfo.IME_MASK_ACTION,
+ target = EditorInfo.IME_ACTION_SEARCH),
+ @FlagMap(
+ name = "actionSend",
+ mask = EditorInfo.IME_MASK_ACTION,
+ target = EditorInfo.IME_ACTION_SEND),
+ @FlagMap(
+ name = "actionNext",
+ mask = EditorInfo.IME_MASK_ACTION,
+ target = EditorInfo.IME_ACTION_NEXT),
+ @FlagMap(
+ name = "actionDone",
+ mask = EditorInfo.IME_MASK_ACTION,
+ target = EditorInfo.IME_ACTION_DONE),
+ @FlagMap(
+ name = "actionPrevious",
+ mask = EditorInfo.IME_MASK_ACTION,
+ target = EditorInfo.IME_ACTION_PREVIOUS),
+ @FlagMap(name = "flagForceAscii", target = EditorInfo.IME_FLAG_FORCE_ASCII),
+ @FlagMap(name = "flagNavigateNext", target = EditorInfo.IME_FLAG_NAVIGATE_NEXT),
+ @FlagMap(name = "flagNavigatePrevious", target = EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS),
+ @FlagMap(
+ name = "flagNoAccessoryAction",
+ target = EditorInfo.IME_FLAG_NO_ACCESSORY_ACTION),
+ @FlagMap(name = "flagNoEnterAction", target = EditorInfo.IME_FLAG_NO_ENTER_ACTION),
+ @FlagMap(name = "flagNoExtractUi", target = EditorInfo.IME_FLAG_NO_EXTRACT_UI),
+ @FlagMap(name = "flagNoFullscreen", target = EditorInfo.IME_FLAG_NO_FULLSCREEN),
+ @FlagMap(
+ name = "flagNoPersonalizedLearning",
+ target = EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING),
+ })
public int getImeOptions() {
return mEditor != null && mEditor.mInputContentType != null
? mEditor.mInputContentType.imeOptions : EditorInfo.IME_NULL;
@@ -6644,6 +6904,7 @@
* @see #setImeActionLabel
* @see android.view.inputmethod.EditorInfo
*/
+ @InspectableProperty
public CharSequence getImeActionLabel() {
return mEditor != null && mEditor.mInputContentType != null
? mEditor.mInputContentType.imeActionLabel : null;
@@ -6655,6 +6916,7 @@
* @see #setImeActionLabel
* @see android.view.inputmethod.EditorInfo
*/
+ @InspectableProperty
public int getImeActionId() {
return mEditor != null && mEditor.mInputContentType != null
? mEditor.mInputContentType.imeActionId : 0;
@@ -6777,6 +7039,7 @@
* @see #setPrivateImeOptions(String)
* @see EditorInfo#privateImeOptions
*/
+ @InspectableProperty
public String getPrivateImeOptions() {
return mEditor != null && mEditor.mInputContentType != null
? mEditor.mInputContentType.privateImeOptions : null;
@@ -7385,6 +7648,7 @@
*
* @attr ref android.R.styleable#TextView_textIsSelectable
*/
+ @InspectableProperty(name = "textIsSelectable")
public boolean isTextSelectable() {
return mEditor == null ? false : mEditor.mTextIsSelectable;
}
@@ -8924,6 +9188,7 @@
*
* @attr ref android.R.styleable#TextView_includeFontPadding
*/
+ @InspectableProperty
public boolean getIncludeFontPadding() {
return mIncludePad;
}
@@ -9870,6 +10135,7 @@
* @see #setAllCaps(boolean)
* @see #setTransformationMethod(TransformationMethod)
*/
+ @InspectableProperty(name = "textAllCaps")
public boolean isAllCaps() {
final TransformationMethod method = getTransformationMethod();
return method != null && method instanceof AllCapsTransformationMethod;
@@ -9979,6 +10245,7 @@
*
* @attr ref android.R.styleable#TextView_marqueeRepeatLimit
*/
+ @InspectableProperty
public int getMarqueeRepeatLimit() {
return mMarqueeRepeatLimit;
}
@@ -9987,6 +10254,7 @@
* Returns where, if anywhere, words that are longer than the view
* is wide should be ellipsized.
*/
+ @InspectableProperty
@ViewDebug.ExportedProperty
public TextUtils.TruncateAt getEllipsize() {
return mEllipsize;
@@ -10038,6 +10306,7 @@
*
* @attr ref android.R.styleable#TextView_cursorVisible
*/
+ @InspectableProperty
public boolean isCursorVisible() {
// true is the default value
return mEditor == null ? true : mEditor.mCursorVisible;
@@ -10971,6 +11240,22 @@
}
/**
+ * Starts {@link Activity} as a text-operation user if it is specified with
+ * {@link #setTextOperationUser(UserHandle)}.
+ *
+ * <p>Otherwise, just starts {@link Activity} with {@link Context#startActivity(Intent)}.</p>
+ *
+ * @param intent The description of the activity to start.
+ */
+ void startActivityAsTextOperationUserIfNecessary(@NonNull Intent intent) {
+ if (mTextOperationUser != null) {
+ getContext().startActivityAsUser(intent, mTextOperationUser);
+ } else {
+ getContext().startActivity(intent);
+ }
+ }
+
+ /**
* This is a temporary method. Future versions may support multi-locale text.
* Caveat: This method may not return the latest text services locale, but this should be
* acceptable and it's more important to make this method asynchronous.
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 6a5c8cc..b239ce6 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -35,6 +35,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
@@ -165,6 +166,10 @@
*/
@TimePickerMode
@TestApi
+ @InspectableProperty(name = "timePickerMode", enumMapping = {
+ @InspectableProperty.EnumMap(name = "clock", value = MODE_CLOCK),
+ @InspectableProperty.EnumMap(name = "spinner", value = MODE_SPINNER)
+ })
public int getMode() {
return mMode;
}
@@ -185,6 +190,7 @@
* @return the currently selected hour, in the range (0-23)
* @see #setHour(int)
*/
+ @InspectableProperty(hasAttributeId = false)
public int getHour() {
return mDelegate.getHour();
}
@@ -205,6 +211,7 @@
* @return the currently selected minute, in the range (0-59)
* @see #setMinute(int)
*/
+ @InspectableProperty(hasAttributeId = false)
public int getMinute() {
return mDelegate.getMinute();
}
@@ -272,6 +279,7 @@
* {@code false} otherwise}
* @see #setIs24HourView(Boolean)
*/
+ @InspectableProperty(hasAttributeId = false, name = "24Hour")
public boolean is24HourView() {
return mDelegate.is24Hour();
}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index c256d57..eef40e1 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -341,10 +341,10 @@
// the proper ordering of these system-wide.
// =======================================================================================
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static INotificationManager sService;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
static private INotificationManager getService() {
if (sService != null) {
return sService;
diff --git a/core/java/android/widget/ToggleButton.java b/core/java/android/widget/ToggleButton.java
index 6a8449e..bba6da6 100644
--- a/core/java/android/widget/ToggleButton.java
+++ b/core/java/android/widget/ToggleButton.java
@@ -21,6 +21,7 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.AttributeSet;
+import android.view.inspector.InspectableProperty;
/**
* Displays checked/unchecked states as a button
@@ -87,6 +88,7 @@
*
* @return The text.
*/
+ @InspectableProperty
public CharSequence getTextOn() {
return mTextOn;
}
@@ -105,6 +107,7 @@
*
* @return The text.
*/
+ @InspectableProperty
public CharSequence getTextOff() {
return mTextOff;
}
@@ -118,6 +121,16 @@
mTextOff = textOff;
}
+ /**
+ * Returns the alpha value of the button when it is disabled
+ *
+ * @return the alpha value, 0.0-1.0
+ */
+ @InspectableProperty
+ public float getDisabledAlpha() {
+ return mDisabledAlpha;
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index adb7f2f..a33c47d8 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -45,6 +45,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.view.inspector.InspectableProperty;
import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;
@@ -383,6 +384,7 @@
* 0 if menus are inflated against the toolbar theme
* @see #setPopupTheme(int)
*/
+ @InspectableProperty
public int getPopupTheme() {
return mPopupTheme;
}
@@ -414,6 +416,7 @@
* @see #setTitleMarginStart(int)
* @attr ref android.R.styleable#Toolbar_titleMarginStart
*/
+ @InspectableProperty
public int getTitleMarginStart() {
return mTitleMarginStart;
}
@@ -436,6 +439,7 @@
* @see #setTitleMarginTop(int)
* @attr ref android.R.styleable#Toolbar_titleMarginTop
*/
+ @InspectableProperty
public int getTitleMarginTop() {
return mTitleMarginTop;
}
@@ -458,6 +462,7 @@
* @see #setTitleMarginEnd(int)
* @attr ref android.R.styleable#Toolbar_titleMarginEnd
*/
+ @InspectableProperty
public int getTitleMarginEnd() {
return mTitleMarginEnd;
}
@@ -480,6 +485,7 @@
* @see #setTitleMarginBottom(int)
* @attr ref android.R.styleable#Toolbar_titleMarginBottom
*/
+ @InspectableProperty
public int getTitleMarginBottom() {
return mTitleMarginBottom;
}
@@ -650,6 +656,7 @@
* @see #setLogo(int)
* @see #setLogo(android.graphics.drawable.Drawable)
*/
+ @InspectableProperty
public Drawable getLogo() {
return mLogoView != null ? mLogoView.getDrawable() : null;
}
@@ -688,6 +695,7 @@
*
* @return A description of the logo
*/
+ @InspectableProperty
public CharSequence getLogoDescription() {
return mLogoView != null ? mLogoView.getContentDescription() : null;
}
@@ -735,6 +743,7 @@
*
* @return The current title.
*/
+ @InspectableProperty
public CharSequence getTitle() {
return mTitleText;
}
@@ -791,6 +800,7 @@
*
* @return The current subtitle
*/
+ @InspectableProperty
public CharSequence getSubtitle() {
return mSubtitleText;
}
@@ -895,6 +905,7 @@
*
* @attr ref android.R.styleable#Toolbar_navigationContentDescription
*/
+ @InspectableProperty
@Nullable
public CharSequence getNavigationContentDescription() {
return mNavButtonView != null ? mNavButtonView.getContentDescription() : null;
@@ -987,6 +998,7 @@
*
* @attr ref android.R.styleable#Toolbar_navigationIcon
*/
+ @InspectableProperty
@Nullable
public Drawable getNavigationIcon() {
return mNavButtonView != null ? mNavButtonView.getDrawable() : null;
@@ -1024,6 +1036,7 @@
*
* @attr ref android.R.styleable#Toolbar_collapseContentDescription
*/
+ @InspectableProperty
@Nullable
public CharSequence getCollapseContentDescription() {
return mCollapseButtonView != null ? mCollapseButtonView.getContentDescription() : null;
@@ -1069,6 +1082,7 @@
*
* @attr ref android.R.styleable#Toolbar_collapseIcon
*/
+ @InspectableProperty
@Nullable
public Drawable getCollapseIcon() {
return mCollapseButtonView != null ? mCollapseButtonView.getDrawable() : null;
@@ -1234,6 +1248,7 @@
* @see #getContentInsetRight()
* @attr ref android.R.styleable#Toolbar_contentInsetStart
*/
+ @InspectableProperty
public int getContentInsetStart() {
return mContentInsets != null ? mContentInsets.getStart() : 0;
}
@@ -1254,6 +1269,7 @@
* @see #getContentInsetRight()
* @attr ref android.R.styleable#Toolbar_contentInsetEnd
*/
+ @InspectableProperty
public int getContentInsetEnd() {
return mContentInsets != null ? mContentInsets.getEnd() : 0;
}
@@ -1297,6 +1313,7 @@
* @see #getContentInsetRight()
* @attr ref android.R.styleable#Toolbar_contentInsetLeft
*/
+ @InspectableProperty
public int getContentInsetLeft() {
return mContentInsets != null ? mContentInsets.getLeft() : 0;
}
@@ -1317,6 +1334,7 @@
* @see #getContentInsetLeft()
* @attr ref android.R.styleable#Toolbar_contentInsetRight
*/
+ @InspectableProperty
public int getContentInsetRight() {
return mContentInsets != null ? mContentInsets.getRight() : 0;
}
@@ -1333,6 +1351,7 @@
* @see #setContentInsetStartWithNavigation(int)
* @attr ref android.R.styleable#Toolbar_contentInsetStartWithNavigation
*/
+ @InspectableProperty
public int getContentInsetStartWithNavigation() {
return mContentInsetStartWithNavigation != RtlSpacingHelper.UNDEFINED
? mContentInsetStartWithNavigation
@@ -1376,6 +1395,7 @@
* @see #setContentInsetEndWithActions(int)
* @attr ref android.R.styleable#Toolbar_contentInsetEndWithActions
*/
+ @InspectableProperty
public int getContentInsetEndWithActions() {
return mContentInsetEndWithActions != RtlSpacingHelper.UNDEFINED
? mContentInsetEndWithActions
diff --git a/core/java/android/widget/ViewAnimator.java b/core/java/android/widget/ViewAnimator.java
index 598a407..80ea363 100644
--- a/core/java/android/widget/ViewAnimator.java
+++ b/core/java/android/widget/ViewAnimator.java
@@ -26,6 +26,7 @@
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import android.view.inspector.InspectableProperty;
/**
* Base class for a {@link FrameLayout} container that will perform animations
@@ -265,6 +266,7 @@
* @see #setInAnimation(android.view.animation.Animation)
* @see #setInAnimation(android.content.Context, int)
*/
+ @InspectableProperty
public Animation getInAnimation() {
return mInAnimation;
}
@@ -289,6 +291,7 @@
* @see #setOutAnimation(android.view.animation.Animation)
* @see #setOutAnimation(android.content.Context, int)
*/
+ @InspectableProperty
public Animation getOutAnimation() {
return mOutAnimation;
}
@@ -340,6 +343,7 @@
*
* @see #setAnimateFirstView(boolean)
*/
+ @InspectableProperty
public boolean getAnimateFirstView() {
return mAnimateFirstTime;
}
diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java
index 5e72b2e..414b136 100644
--- a/core/java/android/widget/ViewFlipper.java
+++ b/core/java/android/widget/ViewFlipper.java
@@ -25,6 +25,7 @@
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
/**
@@ -134,6 +135,16 @@
}
/**
+ * Get the delay before flipping to the next view.
+ *
+ * @return delay time in milliseconds
+ */
+ @InspectableProperty
+ public int getFlipInterval() {
+ return mFlipInterval;
+ }
+
+ /**
* Start a timer to cycle through child views
*/
public void startFlipping() {
@@ -191,6 +202,7 @@
/**
* Returns true if the child views are flipping.
*/
+ @InspectableProperty(hasAttributeId = false)
public boolean isFlipping() {
return mStarted;
}
@@ -207,6 +219,7 @@
* Returns true if this view automatically calls {@link #startFlipping()}
* when it becomes attached to a window.
*/
+ @InspectableProperty
public boolean isAutoStart() {
return mAutoStart;
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index cfe2939..119a015 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -16,6 +16,9 @@
package com.android.internal.app;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.prediction.AppPredictionContext;
@@ -27,6 +30,7 @@
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -46,9 +50,11 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
+import android.metrics.LogMaker;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -93,11 +99,13 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.ImageUtils;
import com.google.android.collect.Lists;
import java.io.File;
import java.io.IOException;
+import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -174,6 +182,18 @@
private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT = 3;
private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 4;
+ @Retention(SOURCE)
+ @IntDef({CONTENT_PREVIEW_FILE, CONTENT_PREVIEW_IMAGE, CONTENT_PREVIEW_TEXT})
+ private @interface ContentPreviewType {
+ }
+
+ // Starting at 1 since 0 is considered "undefined" for some of the database transformations
+ // of tron logs.
+ private static final int CONTENT_PREVIEW_IMAGE = 1;
+ private static final int CONTENT_PREVIEW_FILE = 2;
+ private static final int CONTENT_PREVIEW_TEXT = 3;
+ protected MetricsLogger mMetricsLogger;
+
private final Handler mChooserHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -397,11 +417,12 @@
}
});
- MetricsLogger.action(this, MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN);
-
mChooserShownTime = System.currentTimeMillis();
final long systemCost = mChooserShownTime - intentReceivedTime;
- MetricsLogger.histogram(null, "system_cost_for_smart_sharing", (int) systemCost);
+
+ getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN)
+ .addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, target.getType())
+ .addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost));
if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
final IntentFilter filter = getTargetIntentFilter();
@@ -448,18 +469,38 @@
return;
}
- ViewGroup contentPreviewLayout = findViewById(R.id.content_preview);
String action = targetIntent.getAction();
if (!(Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action))) {
- contentPreviewLayout.setVisibility(View.GONE);
return;
}
- showDefaultContentPreview(contentPreviewLayout, targetIntent);
+ int previewType = findPreferredContentPreview(targetIntent, getContentResolver());
+
+ getMetricsLogger().write(new LogMaker(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)
+ .setSubtype(previewType));
+ displayContentPreview(previewType, targetIntent);
}
- private void showDefaultContentPreview(final ViewGroup parentLayout,
- final Intent targetIntent) {
+ private void displayContentPreview(@ContentPreviewType int previewType, Intent targetIntent) {
+ switch (previewType) {
+ case CONTENT_PREVIEW_TEXT:
+ displayTextContentPreview(targetIntent);
+ break;
+ case CONTENT_PREVIEW_IMAGE:
+ displayImageContentPreview(targetIntent);
+ break;
+ case CONTENT_PREVIEW_FILE:
+ displayFileContentPreview(targetIntent);
+ break;
+ default:
+ Log.e(TAG, "Unexpected content preview type: " + previewType);
+ }
+ }
+
+ private void displayTextContentPreview(Intent targetIntent) {
+ ViewGroup contentPreviewLayout = findViewById(R.id.content_preview_text_area);
+ contentPreviewLayout.setVisibility(View.VISIBLE);
+
CharSequence sharingText = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
if (sharingText == null) {
findViewById(R.id.content_preview_text_layout).setVisibility(View.GONE);
@@ -498,6 +539,105 @@
}
}
+ private void displayImageContentPreview(Intent targetIntent) {
+ ViewGroup contentPreviewLayout = findViewById(R.id.content_preview_image_area);
+ contentPreviewLayout.setVisibility(View.VISIBLE);
+
+ String action = targetIntent.getAction();
+ if (Intent.ACTION_SEND.equals(action)) {
+ Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+ loadUriIntoView(R.id.content_preview_image_1_large, uri);
+ } else {
+ ContentResolver resolver = getContentResolver();
+
+ List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+ List<Uri> imageUris = new ArrayList<>();
+ for (Uri uri : uris) {
+ if (isImageType(resolver.getType(uri))) {
+ imageUris.add(uri);
+ }
+ }
+
+ if (imageUris.size() == 0) {
+ Log.i(TAG, "Attempted to display image preview area with zero"
+ + " available images detected in EXTRA_STREAM list");
+ return;
+ }
+
+ loadUriIntoView(R.id.content_preview_image_1_large, imageUris.get(0));
+
+ if (imageUris.size() == 2) {
+ loadUriIntoView(R.id.content_preview_image_2_large, imageUris.get(1));
+ } else if (imageUris.size() > 2) {
+ loadUriIntoView(R.id.content_preview_image_2_small, imageUris.get(1));
+ RoundedRectImageView imageView = loadUriIntoView(
+ R.id.content_preview_image_3_small, imageUris.get(2));
+
+ if (imageUris.size() > 3) {
+ imageView.setExtraImageCount(imageUris.size() - 3);
+ }
+ }
+ }
+ }
+
+ private void displayFileContentPreview(Intent targetIntent) {
+ // support coming
+ }
+
+ private RoundedRectImageView loadUriIntoView(int imageResourceId, Uri uri) {
+ RoundedRectImageView imageView = findViewById(imageResourceId);
+ imageView.setVisibility(View.VISIBLE);
+ Bitmap bmp = loadThumbnail(uri, new Size(200, 200));
+ imageView.setImageBitmap(bmp);
+
+ return imageView;
+ }
+
+ @VisibleForTesting
+ protected boolean isImageType(String mimeType) {
+ return mimeType != null && mimeType.startsWith("image/");
+ }
+
+ @ContentPreviewType
+ private int findPreferredContentPreview(Uri uri, ContentResolver resolver) {
+ if (uri == null) {
+ return CONTENT_PREVIEW_TEXT;
+ }
+
+ String mimeType = resolver.getType(uri);
+ return isImageType(mimeType) ? CONTENT_PREVIEW_IMAGE : CONTENT_PREVIEW_FILE;
+ }
+
+ /**
+ * In {@link android.content.Intent#getType}, the app may specify a very general
+ * mime-type that broadly covers all data being shared, such as {@literal *}/*
+ * when sending an image and text. We therefore should inspect each item for the
+ * the preferred type, in order of IMAGE, FILE, TEXT.
+ */
+ @ContentPreviewType
+ private int findPreferredContentPreview(Intent targetIntent, ContentResolver resolver) {
+ String action = targetIntent.getAction();
+ if (Intent.ACTION_SEND.equals(action)) {
+ Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+ return findPreferredContentPreview(uri, resolver);
+ } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) {
+ List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+ if (uris == null || uris.isEmpty()) {
+ return CONTENT_PREVIEW_TEXT;
+ }
+
+ for (Uri uri : uris) {
+ if (findPreferredContentPreview(uri, resolver) == CONTENT_PREVIEW_IMAGE) {
+ return CONTENT_PREVIEW_IMAGE;
+ }
+ }
+
+ return CONTENT_PREVIEW_FILE;
+ }
+
+ return CONTENT_PREVIEW_TEXT;
+ }
+
static SharedPreferences getPinnedSharedPrefs(Context context) {
// The code below is because in the android:ui process, no one can hear you scream.
// The package info in the context isn't initialized in the way it is for normal apps,
@@ -1048,6 +1188,13 @@
}
}
+ protected MetricsLogger getMetricsLogger() {
+ if (mMetricsLogger == null) {
+ mMetricsLogger = new MetricsLogger();
+ }
+ return mMetricsLogger;
+ }
+
public class ChooserListController extends ResolverListController {
public ChooserListController(Context context,
PackageManager pm,
@@ -1114,7 +1261,8 @@
}
try {
- return getContentResolver().loadThumbnail(uri, size, null);
+ return ImageUtils.decodeSampledBitmapFromStream(getContentResolver(),
+ uri, size.getWidth(), size.getHeight());
} catch (IOException | NullPointerException ex) {
Log.w(TAG, "Error loading preview thumbnail for uri: " + uri.toString(), ex);
}
@@ -1593,6 +1741,8 @@
if (show != mShowServiceTargets) {
mShowServiceTargets = show;
notifyDataSetChanged();
+ getMetricsLogger().write(
+ new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN_DIRECT_TARGET));
}
}
@@ -1751,8 +1901,6 @@
}
if (startType == ChooserListAdapter.TARGET_SERVICE) {
- holder.row.setBackgroundColor(
- getColor(R.color.chooser_service_row_background_color));
int nextStartType = mChooserListAdapter.getPositionTargetType(
getFirstRowPosition(rowPosition + 1));
int serviceSpacing = holder.row.getContext().getResources()
@@ -2045,6 +2193,9 @@
public static class RoundedRectImageView extends ImageView {
private int mRadius = 0;
private Path mPath = new Path();
+ private Paint mOverlayPaint = new Paint(0);
+ private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private String mExtraImageCount = null;
public RoundedRectImageView(Context context) {
super(context);
@@ -2062,6 +2213,14 @@
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mRadius = context.getResources().getDimensionPixelSize(R.dimen.chooser_corner_radius);
+
+ mOverlayPaint.setColor(0x99000000);
+ mOverlayPaint.setStyle(Paint.Style.FILL);
+
+ mTextPaint.setColor(Color.WHITE);
+ mTextPaint.setTextSize(context.getResources()
+ .getDimensionPixelSize(R.dimen.chooser_preview_image_font_size));
+ mTextPaint.setTextAlign(Paint.Align.CENTER);
}
private void updatePath(int width, int height) {
@@ -2083,12 +2242,24 @@
updatePath(getWidth(), getHeight());
}
+ /**
+ * Display an overlay with extra image count on 3rd image
+ */
+ public void setExtraImageCount(int count) {
+ if (count > 0) {
+ this.mExtraImageCount = "+" + count;
+ } else {
+ this.mExtraImageCount = null;
+ }
+ }
+
@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
super.onSizeChanged(width, height, oldWidth, oldHeight);
updatePath(width, height);
}
+
@Override
protected void onDraw(Canvas canvas) {
if (mRadius != 0) {
@@ -2096,6 +2267,16 @@
}
super.onDraw(canvas);
+
+ if (mExtraImageCount != null) {
+ canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), mOverlayPaint);
+
+ int xPos = canvas.getWidth() / 2;
+ int yPos = (int) ((canvas.getHeight() / 2.0f)
+ - ((mTextPaint.descent() + mTextPaint.ascent()) / 2.0f));
+
+ canvas.drawText(mExtraImageCount, xPos, yPos, mTextPaint);
+ }
}
}
}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index b881aef..8b669d5 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -99,6 +99,11 @@
*/
public static final int PROFILE_FROM_SHELL = 1 << 15;
+ /*
+ * Enable using the ART app image startup cache
+ */
+ public static final int USE_APP_IMAGE_STARTUP_CACHE = 1 << 16;
+
/** No external storage should be mounted. */
public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
/** Default external storage should be mounted. */
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 9f23797..e132abd 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -41,6 +41,7 @@
import android.system.StructCapUserData;
import android.system.StructCapUserHeader;
import android.text.Hyphenator;
+import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -84,6 +85,8 @@
private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+ private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
+ "persist.device_config.runtime_native.use_app_image_startup_cache";
private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
@@ -705,6 +708,13 @@
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
+ String use_app_image_cache = SystemProperties.get(
+ PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
+ // Property defaults to true currently.
+ if (!TextUtils.isEmpty(use_app_image_cache) && !use_app_image_cache.equals("false")) {
+ parsedArgs.mRuntimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
+ }
+
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
diff --git a/core/java/com/android/internal/policy/DecorContext.java b/core/java/com/android/internal/policy/DecorContext.java
index cd80d53..429c618 100644
--- a/core/java/com/android/internal/policy/DecorContext.java
+++ b/core/java/com/android/internal/policy/DecorContext.java
@@ -22,6 +22,7 @@
import android.view.ContextThemeWrapper;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
+import android.view.contentcapture.ContentCaptureManager;
import java.lang.ref.WeakReference;
@@ -36,6 +37,7 @@
private PhoneWindow mPhoneWindow;
private WindowManager mWindowManager;
private Resources mActivityResources;
+ private ContentCaptureManager mContentCaptureManager;
private WeakReference<Context> mActivityContext;
@@ -60,6 +62,16 @@
}
return mWindowManager;
}
+ if (Context.CONTENT_CAPTURE_MANAGER_SERVICE.equals(name)) {
+ if (mContentCaptureManager == null) {
+ Context activityContext = mActivityContext.get();
+ if (activityContext != null) {
+ mContentCaptureManager = (ContentCaptureManager) activityContext
+ .getSystemService(name);
+ }
+ }
+ return mContentCaptureManager;
+ }
return super.getSystemService(name);
}
@@ -79,4 +91,9 @@
public AssetManager getAssets() {
return mActivityResources.getAssets();
}
+
+ @Override
+ public boolean isContentCaptureSupported() {
+ return true;
+ }
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 9df37ad..bfb5084 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -69,8 +69,9 @@
void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded, in int notificationLocation);
void onNotificationDirectReplied(String key);
void onNotificationSmartSuggestionsAdded(String key, int smartReplyCount, int smartActionCount,
- boolean generatedByAsssistant);
- void onNotificationSmartReplySent(in String key, in int replyIndex, in CharSequence reply, boolean generatedByAssistant, in int notificationLocation);
+ boolean generatedByAsssistant, boolean editBeforeSending);
+ void onNotificationSmartReplySent(in String key, in int replyIndex, in CharSequence reply,
+ in int notificationLocation, boolean modifiedBeforeSending);
void onNotificationSettingsViewed(String key);
void setSystemUiVisibility(int displayId, int vis, int mask, String cause);
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 226b8db..b04ebec 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -690,4 +690,26 @@
}
return result;
}
+
+ public static boolean startsWith(byte[] cur, byte[] val) {
+ if (cur == null || val == null) return false;
+ if (cur.length < val.length) return false;
+ for (int i = 0; i < val.length; i++) {
+ if (cur[i] != val[i]) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns the first element from the array for which
+ * condition {@code predicate} is true, or null if there is no such element
+ */
+ public static @Nullable <T> T find(@Nullable T[] items,
+ @NonNull java.util.function.Predicate<T> predicate) {
+ if (isEmpty(items)) return null;
+ for (final T item : items) {
+ if (predicate.test(item)) return item;
+ }
+ return null;
+ }
}
diff --git a/core/java/com/android/internal/util/CollectionUtils.java b/core/java/com/android/internal/util/CollectionUtils.java
index f91b837..78fdfe4 100644
--- a/core/java/com/android/internal/util/CollectionUtils.java
+++ b/core/java/com/android/internal/util/CollectionUtils.java
@@ -335,6 +335,13 @@
}
/**
+ * @return the first element if not empty/null, null otherwise
+ */
+ public static @Nullable <T> T firstOrNull(@Nullable Collection<T> cur) {
+ return isEmpty(cur) ? null : cur.iterator().next();
+ }
+
+ /**
* @return list of single given element if it's not null, empty list otherwise
*/
public static @NonNull <T> List<T> singletonOrEmpty(@Nullable T item) {
diff --git a/core/java/com/android/internal/util/ImageUtils.java b/core/java/com/android/internal/util/ImageUtils.java
index 7d56e9e..195ae52 100644
--- a/core/java/com/android/internal/util/ImageUtils.java
+++ b/core/java/com/android/internal/util/ImageUtils.java
@@ -16,14 +16,20 @@
package com.android.internal.util;
+import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
+
+import java.io.IOException;
+import java.io.InputStream;
/**
* Utility class for image analysis and processing.
@@ -80,7 +86,7 @@
width = height = COMPACT_BITMAP_SIZE;
}
- final int size = height*width;
+ final int size = height * width;
ensureBufferSize(size);
bitmap.getPixels(mTempBuffer, 0, width, 0, 0, width, height);
for (int i = 0; i < size; i++) {
@@ -156,4 +162,55 @@
return result;
}
+
+ /**
+ * @see https://developer.android.com/topic/performance/graphics/load-bitmap
+ */
+ public static int calculateInSampleSize(BitmapFactory.Options options,
+ int reqWidth, int reqHeight) {
+ // Raw height and width of image
+ final int height = options.outHeight;
+ final int width = options.outWidth;
+ int inSampleSize = 1;
+
+ if (height > reqHeight || width > reqWidth) {
+ final int halfHeight = height / 2;
+ final int halfWidth = width / 2;
+
+ // Calculate the largest inSampleSize value that is a power of 2 and keeps both
+ // height and width larger than the requested height and width.
+ while ((halfHeight / inSampleSize) >= reqHeight
+ && (halfWidth / inSampleSize) >= reqWidth) {
+ inSampleSize *= 2;
+ }
+ }
+
+ return inSampleSize;
+ }
+
+ /**
+ * Load a bitmap, and attempt to downscale to the required size, to save
+ * on memory.
+ *
+ * @see https://developer.android.com/topic/performance/graphics/load-bitmap
+ */
+ public static Bitmap decodeSampledBitmapFromStream(ContentResolver resolver,
+ Uri uri, int reqWidth, int reqHeight) throws IOException {
+
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ try (InputStream is = resolver.openInputStream(uri)) {
+ // First decode with inJustDecodeBounds=true to check dimensions
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(is, null, options);
+
+ options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
+ }
+
+ // need to do this twice as the InputStream is consumed in the first call,
+ // and not all InputStreams support marks
+ try (InputStream is = resolver.openInputStream(uri)) {
+ options.inJustDecodeBounds = false;
+ return BitmapFactory.decodeStream(is, null, options);
+ }
+ }
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 0752efe..cb18ca1 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -34,9 +34,9 @@
int untrustedDisplayId);
// TODO: Use ParceledListSlice instead
- List<InputMethodInfo> getInputMethodList();
+ List<InputMethodInfo> getInputMethodList(int userId);
// TODO: Use ParceledListSlice instead
- List<InputMethodInfo> getEnabledInputMethodList();
+ List<InputMethodInfo> getEnabledInputMethodList(int userId);
List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,
boolean allowsImplicitlySelectedSubtypes);
InputMethodSubtype getLastInputMethodSubtype();
diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl
index 794238a..664643c 100644
--- a/core/java/com/android/internal/view/IInputMethodSession.aidl
+++ b/core/java/com/android/internal/view/IInputMethodSession.aidl
@@ -48,4 +48,6 @@
void finishSession();
void updateCursorAnchorInfo(in CursorAnchorInfo cursorAnchorInfo);
+
+ void notifyImeHidden();
}
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index e6d3460..64291de 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
+import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
@@ -107,10 +108,13 @@
* <p>
* Changes take effect on the next call to show().
*
+ * This method should not be accessed directly outside the framework, please use
+ * {@link android.widget.PopupMenu#setForceShowIcon(boolean)} instead.
+ *
* @param forceShowIcon {@code true} to force icons to be shown, or
* {@code false} for icons to be optionally shown
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public void setForceShowIcon(boolean forceShowIcon) {
mForceShowIcon = forceShowIcon;
if (mPopup != null) {
diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java
index 7609b67..498bc5a 100644
--- a/core/java/com/android/internal/widget/MediaNotificationView.java
+++ b/core/java/com/android/internal/widget/MediaNotificationView.java
@@ -39,6 +39,7 @@
private View mActions;
private View mHeader;
private View mMainColumn;
+ private View mMediaContent;
private int mImagePushIn;
public MediaNotificationView(Context context) {
@@ -70,7 +71,7 @@
(MarginLayoutParams) mRightIcon.getLayoutParams();
int imageEndMargin = layoutParams.getMarginEnd();
size -= imageEndMargin;
- int fullHeight = getMeasuredHeight();
+ int fullHeight = mMediaContent.getMeasuredHeight();
if (size > fullHeight) {
size = fullHeight;
} else if (size < fullHeight) {
@@ -154,5 +155,6 @@
mActions = findViewById(com.android.internal.R.id.media_actions);
mHeader = findViewById(com.android.internal.R.id.notification_header);
mMainColumn = findViewById(com.android.internal.R.id.notification_main_column);
+ mMediaContent = findViewById(com.android.internal.R.id.notification_media_content);
}
}
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index b7e656b..ee8637d8 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -17,15 +17,12 @@
package com.android.internal.widget;
-import com.android.internal.R;
-
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.metrics.LogMaker;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -45,8 +42,13 @@
import android.widget.AbsListView;
import android.widget.OverScroller;
+import com.android.internal.R;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
public class ResolverDrawerLayout extends ViewGroup {
private static final String TAG = "ResolverDrawerLayout";
+ private MetricsLogger mMetricsLogger;
/**
* Max width of the whole drawer layout
@@ -496,6 +498,9 @@
final boolean isCollapsedNew = newPos != 0;
if (isCollapsedOld != isCollapsedNew) {
onCollapsedChanged(isCollapsedNew);
+ getMetricsLogger().write(
+ new LogMaker(MetricsEvent.ACTION_SHARESHEET_COLLAPSED_CHANGED)
+ .setSubtype(isCollapsedNew ? 1 : 0));
}
postInvalidateOnAnimation();
return dy;
@@ -1037,4 +1042,11 @@
dispatchOnDismissed();
}
}
+
+ private MetricsLogger getMetricsLogger() {
+ if (mMetricsLogger == null) {
+ mMetricsLogger = new MetricsLogger();
+ }
+ return mMetricsLogger;
+ }
}
diff --git a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
index 1b40492..b4610bd 100644
--- a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
+++ b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
@@ -26,6 +26,7 @@
import android.content.SyncAdapterType;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
import android.util.Log;
import org.json.JSONArray;
@@ -48,6 +49,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* Helper for backing up account sync settings (whether or not a service should be synced). The
@@ -76,15 +78,17 @@
private static final String KEY_AUTHORITY_NAME = "name";
private static final String KEY_AUTHORITY_SYNC_STATE = "syncState";
private static final String KEY_AUTHORITY_SYNC_ENABLED = "syncEnabled";
- private static final String STASH_FILE = Environment.getDataDirectory()
- + "/backup/unadded_account_syncsettings.json";
+ private static final String STASH_FILE = "/backup/unadded_account_syncsettings.json";
private Context mContext;
private AccountManager mAccountManager;
+ private final int mUserId;
- public AccountSyncSettingsBackupHelper(Context context) {
+ public AccountSyncSettingsBackupHelper(Context context, int userId) {
mContext = context;
mAccountManager = AccountManager.get(mContext);
+
+ mUserId = userId;
}
/**
@@ -94,7 +98,7 @@
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput output,
ParcelFileDescriptor newState) {
try {
- JSONObject dataJSON = serializeAccountSyncSettingsToJSON();
+ JSONObject dataJSON = serializeAccountSyncSettingsToJSON(mUserId);
if (DEBUG) {
Log.d(TAG, "Account sync settings JSON: " + dataJSON);
@@ -123,10 +127,9 @@
/**
* Fetch and serialize Account and authority information as a JSON Array.
*/
- private JSONObject serializeAccountSyncSettingsToJSON() throws JSONException {
- Account[] accounts = mAccountManager.getAccounts();
- SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(
- mContext.getUserId());
+ private JSONObject serializeAccountSyncSettingsToJSON(int userId) throws JSONException {
+ Account[] accounts = mAccountManager.getAccountsAsUser(userId);
+ SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(userId);
// Create a map of Account types to authorities. Later this will make it easier for us to
// generate our JSON.
@@ -146,7 +149,8 @@
// Generate JSON.
JSONObject backupJSON = new JSONObject();
backupJSON.put(KEY_VERSION, JSON_FORMAT_VERSION);
- backupJSON.put(KEY_MASTER_SYNC_ENABLED, ContentResolver.getMasterSyncAutomatically());
+ backupJSON.put(KEY_MASTER_SYNC_ENABLED, ContentResolver.getMasterSyncAutomaticallyAsUser(
+ userId));
JSONArray accountJSONArray = new JSONArray();
for (Account account : accounts) {
@@ -165,8 +169,9 @@
// Add authorities for this Account type and check whether or not sync is enabled.
JSONArray authoritiesJSONArray = new JSONArray();
for (String authority : authorities) {
- int syncState = ContentResolver.getIsSyncable(account, authority);
- boolean syncEnabled = ContentResolver.getSyncAutomatically(account, authority);
+ int syncState = ContentResolver.getIsSyncableAsUser(account, authority, userId);
+ boolean syncEnabled = ContentResolver.getSyncAutomaticallyAsUser(account, authority,
+ userId);
JSONObject authorityJSON = new JSONObject();
authorityJSON.put(KEY_AUTHORITY_NAME, authority);
@@ -254,17 +259,18 @@
boolean masterSyncEnabled = dataJSON.getBoolean(KEY_MASTER_SYNC_ENABLED);
JSONArray accountJSONArray = dataJSON.getJSONArray(KEY_ACCOUNTS);
- boolean currentMasterSyncEnabled = ContentResolver.getMasterSyncAutomatically();
+ boolean currentMasterSyncEnabled = ContentResolver.getMasterSyncAutomaticallyAsUser(
+ mUserId);
if (currentMasterSyncEnabled) {
// Disable master sync to prevent any syncs from running.
- ContentResolver.setMasterSyncAutomatically(false);
+ ContentResolver.setMasterSyncAutomaticallyAsUser(false, mUserId);
}
try {
- restoreFromJsonArray(accountJSONArray);
+ restoreFromJsonArray(accountJSONArray, mUserId);
} finally {
// Set the master sync preference to the value from the backup set.
- ContentResolver.setMasterSyncAutomatically(masterSyncEnabled);
+ ContentResolver.setMasterSyncAutomaticallyAsUser(masterSyncEnabled, mUserId);
}
Log.i(TAG, "Restore successful.");
} catch (IOException | JSONException e) {
@@ -272,9 +278,9 @@
}
}
- private void restoreFromJsonArray(JSONArray accountJSONArray)
+ private void restoreFromJsonArray(JSONArray accountJSONArray, int userId)
throws JSONException {
- HashSet<Account> currentAccounts = getAccounts();
+ Set<Account> currentAccounts = getAccounts(userId);
JSONArray unaddedAccountsJSONArray = new JSONArray();
for (int i = 0; i < accountJSONArray.length(); i++) {
JSONObject accountJSON = (JSONObject) accountJSONArray.get(i);
@@ -292,14 +298,14 @@
// yet won't be restored.
if (currentAccounts.contains(account)) {
if (DEBUG) Log.i(TAG, "Restoring Sync Settings for" + accountName);
- restoreExistingAccountSyncSettingsFromJSON(accountJSON);
+ restoreExistingAccountSyncSettingsFromJSON(accountJSON, userId);
} else {
unaddedAccountsJSONArray.put(accountJSON);
}
}
if (unaddedAccountsJSONArray.length() > 0) {
- try (FileOutputStream fOutput = new FileOutputStream(STASH_FILE)) {
+ try (FileOutputStream fOutput = new FileOutputStream(getStashFile(userId))) {
String jsonString = unaddedAccountsJSONArray.toString();
DataOutputStream out = new DataOutputStream(fOutput);
out.writeUTF(jsonString);
@@ -308,18 +314,20 @@
Log.e(TAG, "unable to write the sync settings to the stash file", ioe);
}
} else {
- File stashFile = new File(STASH_FILE);
- if (stashFile.exists()) stashFile.delete();
+ File stashFile = getStashFile(userId);
+ if (stashFile.exists()) {
+ stashFile.delete();
+ }
}
}
/**
* Restore SyncSettings for all existing accounts from a stashed backup-set
*/
- private void accountAddedInternal() {
+ private void accountAddedInternal(int userId) {
String jsonString;
- try (FileInputStream fIn = new FileInputStream(new File(STASH_FILE))) {
+ try (FileInputStream fIn = new FileInputStream(getStashFile(userId))) {
DataInputStream in = new DataInputStream(fIn);
jsonString = in.readUTF();
} catch (FileNotFoundException fnfe) {
@@ -333,7 +341,7 @@
try {
JSONArray unaddedAccountsJSONArray = new JSONArray(jsonString);
- restoreFromJsonArray(unaddedAccountsJSONArray);
+ restoreFromJsonArray(unaddedAccountsJSONArray, userId);
} catch (JSONException jse) {
// Malformed jsonString
Log.e(TAG, "there was an error with the stashed sync settings", jse);
@@ -343,9 +351,10 @@
/**
* Restore SyncSettings for all existing accounts from a stashed backup-set
*/
- public static void accountAdded(Context context) {
- AccountSyncSettingsBackupHelper helper = new AccountSyncSettingsBackupHelper(context);
- helper.accountAddedInternal();
+ public static void accountAdded(Context context, int userId) {
+ AccountSyncSettingsBackupHelper helper = new AccountSyncSettingsBackupHelper(context,
+ userId);
+ helper.accountAddedInternal(userId);
}
/**
@@ -353,9 +362,9 @@
*
* @return Accounts in a HashSet.
*/
- private HashSet<Account> getAccounts() {
- Account[] accounts = mAccountManager.getAccounts();
- HashSet<Account> accountHashSet = new HashSet<Account>();
+ private Set<Account> getAccounts(int userId) {
+ Account[] accounts = mAccountManager.getAccountsAsUser(userId);
+ Set<Account> accountHashSet = new HashSet<Account>();
for (Account account : accounts) {
accountHashSet.add(account);
}
@@ -391,7 +400,7 @@
* initialization sync, while an adapter that the user had off will be off until the user
* enables it on this device at which point it will get an initialization sync.
*/
- private void restoreExistingAccountSyncSettingsFromJSON(JSONObject accountJSON)
+ private void restoreExistingAccountSyncSettingsFromJSON(JSONObject accountJSON, int userId)
throws JSONException {
// Restore authorities.
JSONArray authorities = accountJSON.getJSONArray(KEY_ACCOUNT_AUTHORITIES);
@@ -406,14 +415,15 @@
int wasSyncable = authority.getInt(KEY_AUTHORITY_SYNC_STATE);
ContentResolver.setSyncAutomaticallyAsUser(
- account, authorityName, wasSyncEnabled, 0 /* user Id */);
+ account, authorityName, wasSyncEnabled, userId);
if (!wasSyncEnabled) {
- ContentResolver.setIsSyncable(
+ ContentResolver.setIsSyncableAsUser(
account,
authorityName,
wasSyncable == 0 ?
- 0 /* not syncable */ : 2 /* syncable but needs initialization */);
+ 0 /* not syncable */ : 2 /* syncable but needs initialization */,
+ userId);
}
}
}
@@ -422,4 +432,10 @@
public void writeNewStateDescription(ParcelFileDescriptor newState) {
}
-}
\ No newline at end of file
+
+ private static File getStashFile(int userId) {
+ File baseDir = userId == UserHandle.USER_SYSTEM ? Environment.getDataDirectory()
+ : Environment.getDataSystemCeDirectory(userId);
+ return new File(baseDir, STASH_FILE);
+ }
+}
diff --git a/core/java/com/android/server/backup/NotificationBackupHelper.java b/core/java/com/android/server/backup/NotificationBackupHelper.java
index 0d225e8..7d4f8f7 100644
--- a/core/java/com/android/server/backup/NotificationBackupHelper.java
+++ b/core/java/com/android/server/backup/NotificationBackupHelper.java
@@ -18,9 +18,7 @@
import android.app.INotificationManager;
import android.app.backup.BlobBackupHelper;
-import android.content.Context;
import android.os.ServiceManager;
-import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
@@ -34,9 +32,11 @@
// Key under which the payload blob is stored
static final String KEY_NOTIFICATIONS = "notifications";
- public NotificationBackupHelper(Context context) {
+ private final int mUserId;
+
+ public NotificationBackupHelper(int userId) {
super(BLOB_VERSION, KEY_NOTIFICATIONS);
- // context is currently unused
+ mUserId = userId;
}
@Override
@@ -46,8 +46,7 @@
try {
INotificationManager nm = INotificationManager.Stub.asInterface(
ServiceManager.getService("notification"));
- // TODO: http://b/22388012
- newPayload = nm.getBackupPayload(UserHandle.USER_SYSTEM);
+ newPayload = nm.getBackupPayload(mUserId);
} catch (Exception e) {
// Treat as no data
Slog.e(TAG, "Couldn't communicate with notification manager");
@@ -67,8 +66,7 @@
try {
INotificationManager nm = INotificationManager.Stub.asInterface(
ServiceManager.getService("notification"));
- // TODO: http://b/22388012
- nm.applyRestore(payload, UserHandle.USER_SYSTEM);
+ nm.applyRestore(payload, mUserId);
} catch (Exception e) {
Slog.e(TAG, "Couldn't communicate with notification manager");
}
diff --git a/core/java/com/android/server/backup/PermissionBackupHelper.java b/core/java/com/android/server/backup/PermissionBackupHelper.java
index ff0e63d..c0ba181 100644
--- a/core/java/com/android/server/backup/PermissionBackupHelper.java
+++ b/core/java/com/android/server/backup/PermissionBackupHelper.java
@@ -19,7 +19,6 @@
import android.app.AppGlobals;
import android.app.backup.BlobBackupHelper;
import android.content.pm.IPackageManager;
-import android.os.UserHandle;
import android.util.Slog;
public class PermissionBackupHelper extends BlobBackupHelper {
@@ -32,8 +31,12 @@
// key under which the permission-grant state blob is committed to backup
private static final String KEY_PERMISSIONS = "permissions";
- public PermissionBackupHelper() {
+ private final int mUserId;
+
+ public PermissionBackupHelper(int userId) {
super(STATE_VERSION, KEY_PERMISSIONS);
+
+ mUserId = userId;
}
@Override
@@ -45,7 +48,7 @@
try {
switch (key) {
case KEY_PERMISSIONS:
- return pm.getPermissionGrantBackup(UserHandle.USER_SYSTEM);
+ return pm.getPermissionGrantBackup(mUserId);
default:
Slog.w(TAG, "Unexpected backup key " + key);
@@ -65,7 +68,7 @@
try {
switch (key) {
case KEY_PERMISSIONS:
- pm.restorePermissionGrants(payload, UserHandle.USER_SYSTEM);
+ pm.restorePermissionGrants(payload, mUserId);
break;
default:
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java
index 47e7a0e7..35e8f56 100644
--- a/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -19,7 +19,7 @@
import android.app.IWallpaperManager;
import android.app.backup.BackupAgentHelper;
import android.app.backup.BackupDataInput;
-import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupHelper;
import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput;
import android.app.backup.WallpaperBackupHelper;
@@ -31,8 +31,11 @@
import android.os.UserHandle;
import android.util.Slog;
+import com.google.android.collect.Sets;
+
import java.io.File;
import java.io.IOException;
+import java.util.Set;
/**
* Backup agent for various system-managed data. Wallpapers are now handled by a
@@ -77,20 +80,25 @@
// Use old keys to keep legacy data compatibility and avoid writing two wallpapers
private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY;
- private WallpaperBackupHelper mWallpaperHelper = null;
+ private static final Set<String> sEligibleForMultiUser = Sets.newArraySet(
+ PERMISSION_HELPER, NOTIFICATION_HELPER, SYNC_SETTINGS_HELPER);
+
+ private int mUserId = UserHandle.USER_SYSTEM;
@Override
- public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
- ParcelFileDescriptor newState) throws IOException {
- addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
+ public void onCreate(UserHandle user) {
+ super.onCreate(user);
+
+ mUserId = user.getIdentifier();
+
+ addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this, mUserId));
addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
- addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
- addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
+ addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(mUserId));
+ addHelper(PERMISSION_HELPER, new PermissionBackupHelper(mUserId));
addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper());
addHelper(SLICES_HELPER, new SliceBackupHelper(this));
- super.onBackup(oldState, data, newState);
}
@Override
@@ -103,26 +111,25 @@
throws IOException {
// Slot in a restore helper for the older wallpaper backup schema to support restore
// from devices still generating data in that format.
- mWallpaperHelper = new WallpaperBackupHelper(this,
- new String[] { WALLPAPER_IMAGE_KEY} );
- addHelper(WALLPAPER_HELPER, mWallpaperHelper);
+ addHelper(WALLPAPER_HELPER, new WallpaperBackupHelper(this,
+ new String[] { WALLPAPER_IMAGE_KEY}));
// On restore, we also support a long-ago wallpaper data schema "system_files"
addHelper("system_files", new WallpaperBackupHelper(this,
new String[] { WALLPAPER_IMAGE_KEY} ));
- addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
- addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
- addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
- addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
- addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
- addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
- addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper());
- addHelper(SLICES_HELPER, new SliceBackupHelper(this));
-
super.onRestore(data, appVersionCode, newState);
}
+ @Override
+ public void addHelper(String keyPrefix, BackupHelper helper) {
+ if (mUserId != UserHandle.USER_SYSTEM && !sEligibleForMultiUser.contains(keyPrefix)) {
+ return;
+ }
+
+ super.addHelper(keyPrefix, helper);
+ }
+
/**
* Support for 'adb restore' of legacy archives
*/
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index e7a1c49..345058b 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -276,6 +276,7 @@
"libmediametrics",
"libmeminfo",
"libaudioclient",
+ "libaudiopolicy",
"libjpeg",
"libusbhost",
"libharfbuzz_ng",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 49598bb..d69d416 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -230,6 +230,11 @@
extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
+// Namespace for Android Runtime flags applied during boot time.
+static const char* RUNTIME_NATIVE_BOOT_NAMESPACE = "runtime_native_boot";
+// Feature flag name for Garbage Collector type.
+static const char* GCTYPE = "gctype";
+
static AndroidRuntime* gCurRuntime = NULL;
/*
@@ -776,7 +781,9 @@
}
std::string gc_type_override =
- server_configurable_flags::GetServerConfigurableFlag("runtime_native", "gctype", "");
+ server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
+ GCTYPE,
+ /*default_value=*/ "");
std::string gc_type_override_temp;
if (gc_type_override.empty()) {
parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:");
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 86342c4..774c224 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -3,7 +3,7 @@
per-file *Camera*,*camera* = shuzhenwang@google.com, yinchiayeh@google.com, zhijunhe@google.com
# Connectivity
-per-file android_net_* = ek@google.com, lorenzo@google.com, satk@google.com
+per-file android_net_* = codewiz@google.com, jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com
# Zygote
per-file com_android_inernal_os_Zygote.*,fd_utils.* = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 79bfa17..70e6604f 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -507,9 +507,18 @@
ninePatchChunk, ninePatchInsets, -1);
}
+ // Speculative fix for b/112551574. It doesn't seem like |b| can be null. If it is, print some
+ // info that might be helpful to diagnose.
+ Bitmap* b = defaultAllocator.getStorageObjAndReset();
+ if (!b) {
+ ALOGW("defaultAllocator has no storage object!");
+ ALOGW("\tjavaBitmap: %s", (javaBitmap == nullptr ? "null" : "present"));
+ ALOGW("\tisHardware: %s", (isHardware ? "true" : "false"));
+ ALOGW("\twillScale: %s", (willScale ? "true" : "false"));
+ return nullptr;
+ }
// now create the java bitmap
- return bitmap::createBitmap(env, defaultAllocator.getStorageObjAndReset(),
- bitmapCreateFlags, ninePatchChunk, ninePatchInsets, -1);
+ return bitmap::createBitmap(env, b, bitmapCreateFlags, ninePatchChunk, ninePatchInsets, -1);
}
static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 7eddcfe..cfb2dd1 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -29,6 +29,7 @@
#include <net/if.h>
#include <linux/filter.h>
#include <linux/if_arp.h>
+#include <linux/tcp.h>
#include <netinet/ether.h>
#include <netinet/icmp6.h>
#include <netinet/ip.h>
@@ -226,6 +227,34 @@
}
}
+static void android_net_utils_attachDropAllBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd)
+{
+ struct sock_filter filter_code[] = {
+ // Reject all.
+ BPF_STMT(BPF_RET | BPF_K, 0)
+ };
+ struct sock_fprog filter = {
+ sizeof(filter_code) / sizeof(filter_code[0]),
+ filter_code,
+ };
+
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
+ jniThrowExceptionFmt(env, "java/net/SocketException",
+ "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
+ }
+}
+
+static void android_net_utils_detachBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd)
+{
+ int dummy = 0;
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ if (setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)) != 0) {
+ jniThrowExceptionFmt(env, "java/net/SocketException",
+ "setsockopt(SO_DETACH_FILTER): %s", strerror(errno));
+ }
+
+}
static void android_net_utils_setupRaSocket(JNIEnv *env, jobject clazz, jobject javaFd,
jint ifIndex)
{
@@ -458,6 +487,41 @@
return answer;
}
+static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
+ if (javaFd == NULL) {
+ jniThrowNullPointerException(env, NULL);
+ return NULL;
+ }
+
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ struct tcp_repair_window trw = {};
+ socklen_t size = sizeof(trw);
+
+ // Obtain the parameters of the TCP repair window.
+ int rc = getsockopt(fd, IPPROTO_TCP, TCP_REPAIR_WINDOW, &trw, &size);
+ if (rc == -1) {
+ throwErrnoException(env, "getsockopt : TCP_REPAIR_WINDOW", errno);
+ return NULL;
+ }
+
+ struct tcp_info tcpinfo = {};
+ socklen_t tcpinfo_size = sizeof(tcp_info);
+
+ // Obtain the window scale from the tcp info structure. This contains a scale factor that
+ // should be applied to the window size.
+ rc = getsockopt(fd, IPPROTO_TCP, TCP_INFO, &tcpinfo, &tcpinfo_size);
+ if (rc == -1) {
+ throwErrnoException(env, "getsockopt : TCP_INFO", errno);
+ return NULL;
+ }
+
+ jclass class_TcpRepairWindow = env->FindClass("android/net/TcpRepairWindow");
+ jmethodID ctor = env->GetMethodID(class_TcpRepairWindow, "<init>", "(IIIIII)V");
+
+ return env->NewObject(class_TcpRepairWindow, ctor, trw.snd_wl1, trw.snd_wnd, trw.max_window,
+ trw.rcv_wnd, trw.rcv_wup, tcpinfo.tcpi_rcv_wscale);
+}
+
// ----------------------------------------------------------------------------
/*
@@ -475,6 +539,9 @@
{ "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter },
{ "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachRaFilter },
{ "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachControlPacketFilter },
+ { "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter },
+ { "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter },
+ { "getTcpRepairWindow", "(Ljava/io/FileDescriptor;)Landroid/net/TcpRepairWindow;", (void*) android_net_utils_getTcpRepairWindow },
{ "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_setupRaSocket },
{ "resNetworkSend", "(I[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
{ "resNetworkQuery", "(ILjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index c1b5aae..191472d 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -59,8 +59,8 @@
sp<MessageQueue> mMessageQueue;
DisplayEventReceiver mReceiver;
- virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
- virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
+ void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
+ void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
};
@@ -84,28 +84,30 @@
DisplayEventDispatcher::dispose();
}
-void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) {
+void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
+ uint32_t count) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
ALOGV("receiver %p ~ Invoking vsync handler.", this);
env->CallVoidMethod(receiverObj.get(),
- gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count);
+ gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, displayId, count);
ALOGV("receiver %p ~ Returned from vsync handler.", this);
}
mMessageQueue->raiseAndClearException(env, "dispatchVsync");
}
-void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) {
+void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId,
+ bool connected) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
ALOGV("receiver %p ~ Invoking hotplug handler.", this);
env->CallVoidMethod(receiverObj.get(),
- gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, id, connected);
+ gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, displayId, connected);
ALOGV("receiver %p ~ Returned from hotplug handler.", this);
}
@@ -175,9 +177,9 @@
gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env,
- gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JII)V");
+ gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V");
gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
- gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JIZ)V");
+ gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
return res;
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index fad2fe0..68be005 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -483,8 +483,29 @@
transaction->setLayerStack(ctrl, layerStack);
}
-static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
- sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
+static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) {
+ const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
+ jlongArray array = env->NewLongArray(displayIds.size());
+ if (array == nullptr) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
+ return nullptr;
+ }
+
+ if (displayIds.empty()) {
+ return array;
+ }
+
+ jlong* values = env->GetLongArrayElements(array, 0);
+ for (size_t i = 0; i < displayIds.size(); ++i) {
+ values[i] = static_cast<jlong>(displayIds[i]);
+ }
+
+ env->ReleaseLongArrayElements(array, values, 0);
+ return array;
+}
+
+static jobject nativeGetPhysicalDisplayToken(JNIEnv* env, jclass clazz, jlong physicalDisplayId) {
+ sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(physicalDisplayId);
return javaObjectForIBinder(env, token);
}
@@ -1145,8 +1166,10 @@
(void*)nativeSetCornerRadius },
{"nativeSetLayerStack", "(JJI)V",
(void*)nativeSetLayerStack },
- {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
- (void*)nativeGetBuiltInDisplay },
+ {"nativeGetPhysicalDisplayIds", "()[J",
+ (void*)nativeGetPhysicalDisplayIds },
+ {"nativeGetPhysicalDisplayToken", "(J)Landroid/os/IBinder;",
+ (void*)nativeGetPhysicalDisplayToken },
{"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
(void*)nativeCreateDisplay },
{"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
@@ -1314,4 +1337,4 @@
return err;
}
-};
+} // namespace android
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 4052919..8c73630 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -1202,12 +1202,12 @@
static JavaVM* mJvm = nullptr;
-static void attachRenderThreadToJvm() {
+static void attachRenderThreadToJvm(const char* name) {
LOG_ALWAYS_FATAL_IF(!mJvm, "No jvm but we set the hook??");
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_4;
- args.name = (char*) "RenderThread";
+ args.name = name;
args.group = NULL;
JNIEnv* env;
mJvm->AttachCurrentThreadAsDaemon(&env, (void*) &args);
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 5a65028..0ef4f87 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -647,6 +647,23 @@
static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames,
const std::vector<std::string>& volumeLabels,
bool mountAllObbs, userid_t userId, fail_fn_t fail_fn) {
+ if (volumeLabels.size() > 0) {
+ std::string sandboxDataDir = StringPrintf("/storage/%s", volumeLabels[0].c_str());
+ if (volumeLabels[0] == "emulated") {
+ StringAppendF(&sandboxDataDir, "/%d", userId);
+ }
+ StringAppendF(&sandboxDataDir, "/Android/data/%s", packageNames[0].c_str());
+ struct stat sb;
+ if (TEMP_FAILURE_RETRY(lstat(sandboxDataDir.c_str(), &sb)) == -1) {
+ if (errno == ENOENT) {
+ ALOGD("Sandbox not fully prepared for %s", sandboxDataDir.c_str());
+ return;
+ } else {
+ fail_fn(CREATE_ERROR("Failed to lstat %s: %s",
+ sandboxDataDir.c_str(), strerror(errno)));
+ }
+ }
+ }
for (auto& label : volumeLabels) {
std::string mntSource = StringPrintf("/mnt/runtime/write/%s", label.c_str());
std::string mntTarget = StringPrintf("/storage/%s", label.c_str());
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index f3733fd..6360a5f 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -321,6 +321,7 @@
optional SettingProto badging = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto show_note_about_notification_hiding = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto in_call_notification_enabled = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto bubbles = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Notification notification = 41;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 840291d..60b04cf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4409,10 +4409,10 @@
{@link android.provider.Telephony.Intents#ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL}
broadcast -->
<permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|privileged" />
- <!-- A subclass of {@link android.app.SmsAppService} must be protected with this permission. -->
- <permission android:name="android.permission.BIND_SMS_APP_SERVICE"
+ <!-- A subclass of {@link android.service.carrier.CarrierMessagingClientService} must be protected with this permission. -->
+ <permission android:name="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE"
android:protectionLevel="signature" />
<!-- @hide Permission that allows configuring appops.
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index 0fde2cc..6839e39 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -1,11 +1,11 @@
<!--
-Copyright (C) 2018 The Android Open Source Project
+Copyright (C) 2019 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
+ Licensed under the Apache License, Version 2 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/licenses/LICENSE-2
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,24 +13,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<vector
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:name="vector"
- android:width="48dp"
- android:height="48dp"
- android:viewportWidth="48"
- android:viewportHeight="48">
- <group android:name="stat_sys_adb">
- <path
- android:name="outer"
- android:pathData="M 18 30 L 24 30 C 29.523 30 34 25.523 34 20 C 34 14.477 29.523 10 24 10 C 18.477 10 14 14.477 14 20 L 14 44"
- android:strokeColor="#000000"
- android:strokeWidth="10"/>
- <path
- android:name="inner"
- android:pathData="M 19 30 L 24 30 C 29.523 30 34 25.523 34 20 C 34 14.477 29.523 10 24 10 C 18.477 10 14 14.477 14 20 L 14 44"
- android:strokeColor="#000000"
- android:strokeAlpha="0"
- android:strokeWidth="6"/>
- </group>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M12,12m-7,0a7,7,0,1,1,14,0a7,7,0,1,1,-14,0"
+ android:strokeColor="#FF0000"
+ android:strokeWidth="4"/>
+ <path
+ android:pathData="M19,19 L12,12"
+ android:strokeLineCap="round"
+ android:strokeColor="#FF0000"
+ android:strokeWidth="4"
+ android:strokeAlpha=".5"/>
+ <path
+ android:pathData="M12,12m-2,0a2,2,0,1,1,4,0a2,2,0,1,1,-4,0"
+ android:fillColor="#FF0000"/>
</vector>
diff --git a/core/res/res/drawable/autofill_dataset_picker_background.xml b/core/res/res/drawable/autofill_dataset_picker_background.xml
index b5617e1..d574970 100644
--- a/core/res/res/drawable/autofill_dataset_picker_background.xml
+++ b/core/res/res/drawable/autofill_dataset_picker_background.xml
@@ -16,7 +16,7 @@
<inset xmlns:android="http://schemas.android.com/apk/res/android">
<shape android:shape="rectangle">
- <corners android:radius="2dp" />
+ <corners android:radius="@dimen/config_bottomDialogCornerRadius" />
<solid android:color="?attr/colorBackground" />
</shape>
</inset>
diff --git a/core/res/res/drawable/bottomsheet_background.xml b/core/res/res/drawable/bottomsheet_background.xml
new file mode 100644
index 0000000..bc32ba6
--- /dev/null
+++ b/core/res/res/drawable/bottomsheet_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners
+ android:topLeftRadius="?attr/dialogCornerRadius"
+ android:topRightRadius="?attr/dialogCornerRadius" />
+ <solid android:color="?attr/colorBackgroundFloating" />
+</shape>
diff --git a/core/res/res/drawable/ic_drag_handle.xml b/core/res/res/drawable/ic_drag_handle.xml
new file mode 100644
index 0000000..67ab84d
--- /dev/null
+++ b/core/res/res/drawable/ic_drag_handle.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M20.0,9.0L4.0,9.0l0.0,2.0l16.0,0.0L20.0,9.0zM4.0,15.0l16.0,0.0l0.0,-2.0L4.0,13.0l0.0,2.0z"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index a24f920..14a5310 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -25,11 +25,24 @@
android:maxCollapsedHeightSmall="56dp"
android:id="@id/contentPanel">
+
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alwaysShow="true"
- android:background="?attr/colorBackgroundFloating">
+ android:background="@drawable/bottomsheet_background">
+
+ <ImageView
+ android:id="@+id/drag"
+ android:layout_width="48dp"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_drag_handle"
+ android:clickable="true"
+ android:paddingTop="@dimen/chooser_edge_margin_normal"
+ android:tint="?android:attr/textColorSecondary"
+ android:layout_centerHorizontal="true"
+ android:layout_alignParentTop="true" />
+
<TextView android:id="@+id/profile_button"
android:layout_width="wrap_content"
android:layout_height="48dp"
@@ -41,7 +54,7 @@
android:textAppearance="?attr/textAppearanceButton"
android:textColor="?attr/colorAccent"
android:gravity="center_vertical"
- android:layout_alignParentTop="true"
+ android:layout_below="@id/drag"
android:layout_alignParentRight="true"
android:singleLine="true"/>
@@ -59,12 +72,84 @@
android:layout_centerHorizontal="true"/>
</RelativeLayout>
+ <!-- The following 3 layouts are mutually exclusive. One of them will be
+ set VISIBLE programatically, when the optimal preview type can be
+ determined by inspecting the data being shared. This path was chosen
+ b/c inflating layouts in code had sizing problems with this widget. -->
+
+ <!-- Layout Option 1: Supporting up to 3 images for preview -->
<LinearLayout
- android:id="@+id/content_preview"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:background="?attr/colorBackgroundFloating">
+ <RelativeLayout
+ android:id="@+id/content_preview_image_area"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:paddingBottom="@dimen/chooser_view_spacing"
+ android:visibility="gone"
+ android:background="?attr/colorBackgroundFloating">
+
+ <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+ android:id="@+id/content_preview_image_1_large"
+ android:visibility="gone"
+ android:layout_width="120dp"
+ android:layout_height="140dp"
+ android:layout_alignParentTop="true"
+ android:adjustViewBounds="true"
+ android:gravity="center"
+ android:scaleType="centerCrop"/>
+
+ <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+ android:id="@+id/content_preview_image_2_large"
+ android:visibility="gone"
+ android:layout_width="120dp"
+ android:layout_height="140dp"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@id/content_preview_image_1_large"
+ android:layout_marginLeft="10dp"
+ android:adjustViewBounds="true"
+ android:gravity="center"
+ android:scaleType="centerCrop"/>
+
+ <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+ android:id="@+id/content_preview_image_2_small"
+ android:visibility="gone"
+ android:layout_width="120dp"
+ android:layout_height="65dp"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@id/content_preview_image_1_large"
+ android:layout_marginLeft="10dp"
+ android:adjustViewBounds="true"
+ android:gravity="center"
+ android:scaleType="centerCrop"/>
+
+ <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
+ android:id="@+id/content_preview_image_3_small"
+ android:visibility="gone"
+ android:layout_width="120dp"
+ android:layout_height="65dp"
+ android:layout_below="@id/content_preview_image_2_small"
+ android:layout_toRightOf="@id/content_preview_image_1_large"
+ android:layout_marginLeft="10dp"
+ android:layout_marginTop="10dp"
+ android:adjustViewBounds="true"
+ android:gravity="center"
+ android:scaleType="centerCrop"/>
+
+ </RelativeLayout>
+ </LinearLayout>
+
+ <!-- Layout Option 2: Text preview, with optional title and thumbnail -->
+ <LinearLayout
+ android:id="@+id/content_preview_text_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/chooser_view_spacing"
+ android:visibility="gone"
android:background="?attr/colorBackgroundFloating">
<LinearLayout
@@ -108,15 +193,12 @@
<view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
android:id="@+id/content_preview_thumbnail"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:layout_marginRight="12dp"
+ android:layout_width="75dp"
+ android:layout_height="75dp"
+ android:layout_marginRight="16dp"
android:adjustViewBounds="true"
android:layout_gravity="center_vertical"
android:gravity="center"
- android:maxWidth="70dp"
- android:maxHeight="70dp"
- android:padding="5dp"
android:scaleType="centerCrop"/>
<TextView
@@ -138,7 +220,6 @@
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
android:background="?attr/colorBackgroundFloating"
- android:elevation="8dp"
android:listSelector="@color/transparent"
android:divider="@null"
android:scrollIndicators="top"
@@ -150,7 +231,7 @@
android:layout_alwaysShow="true"
android:background="?attr/colorBackgroundFloating"
android:text="@string/noApplications"
- android:padding="32dp"
+ android:padding="@dimen/chooser_edge_margin_normal"
android:gravity="center"
android:visibility="gone"/>
diff --git a/core/res/res/layout/notification_material_media_seekbar.xml b/core/res/res/layout/notification_material_media_seekbar.xml
new file mode 100644
index 0000000..1b691d6
--- /dev/null
+++ b/core/res/res/layout/notification_material_media_seekbar.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/notification_media_progress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_alignParentBottom="true"
+ >
+ <SeekBar android:id="@+id/notification_media_progress_bar"
+ style="@style/Widget.ProgressBar.Horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:maxHeight="3dp"
+ android:paddingTop="24dp"
+ android:paddingBottom="24dp"
+ android:layout_marginBottom="-24dp"
+ android:layout_marginTop="-12dp"
+ android:splitTrack="false"
+ />
+ <FrameLayout
+ android:id="@+id/notification_media_progress_time"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginBottom="11dp"
+ >
+
+ <!-- width is set to "match_parent" to avoid extra layout calls -->
+ <TextView android:id="@+id/notification_media_elapsed_time"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_marginStart="@dimen/notification_content_margin_start"
+ android:gravity="left"
+ />
+
+ <TextView android:id="@+id/notification_media_total_time"
+ style="@style/Widget.DeviceDefault.Notification.Text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:gravity="right"
+ />
+ </FrameLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index 56f7a59..3267f72 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -39,6 +39,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
+ android:id="@+id/notification_media_content"
>
<LinearLayout
android:id="@+id/notification_main_column"
@@ -84,5 +85,9 @@
android:id="@+id/media_seamless"
/>
</LinearLayout>
+ <ViewStub android:id="@+id/notification_media_seekbar_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
</LinearLayout>
</com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 01b0866..64d91ad 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -34,49 +34,61 @@
android:layout_width="match_parent"
android:layout_height="@dimen/media_notification_header_height" />
<LinearLayout
- android:id="@+id/notification_main_column"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginStart="@dimen/notification_content_margin_start"
- android:layout_marginTop="@dimen/notification_content_margin_top"
- android:tag="media"
+ android:orientation="vertical"
+ android:id="@+id/notification_media_content"
>
<LinearLayout
- android:id="@+id/notification_content_container"
+ android:id="@+id/notification_main_column"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="fill_vertical"
- android:layout_weight="1"
- android:minHeight="@dimen/notification_min_content_height"
- android:paddingBottom="@dimen/notification_content_margin"
- android:orientation="vertical"
- >
- <include layout="@layout/notification_template_part_line1"/>
- <include layout="@layout/notification_template_text"/>
- </LinearLayout>
- <LinearLayout
- android:id="@+id/media_actions"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|end"
- android:layout_marginStart="10dp"
- android:layout_marginBottom="@dimen/media_notification_actions_padding_bottom"
- android:layoutDirection="ltr"
android:orientation="horizontal"
+ android:layout_marginStart="@dimen/notification_content_margin_start"
+ android:layout_marginTop="@dimen/notification_content_margin_top"
+ android:layout_alignParentTop="true"
+ android:tag="media"
>
- <include
- layout="@layout/notification_material_media_action"
- android:id="@+id/action0"
- />
- <include
- layout="@layout/notification_material_media_action"
- android:id="@+id/action1"
- />
- <include
- layout="@layout/notification_material_media_action"
- android:id="@+id/action2"
- />
+ <LinearLayout
+ android:id="@+id/notification_content_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="fill_vertical"
+ android:layout_weight="1"
+ android:minHeight="@dimen/notification_min_content_height"
+ android:paddingBottom="@dimen/notification_content_margin"
+ android:orientation="vertical"
+ >
+ <include layout="@layout/notification_template_part_line1"/>
+ <include layout="@layout/notification_template_text"/>
+ </LinearLayout>
+ <LinearLayout
+ android:id="@+id/media_actions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|end"
+ android:layout_marginStart="10dp"
+ android:layoutDirection="ltr"
+ android:orientation="horizontal"
+ >
+ <include
+ layout="@layout/notification_material_media_action"
+ android:id="@+id/action0"
+ />
+ <include
+ layout="@layout/notification_material_media_action"
+ android:id="@+id/action1"
+ />
+ <include
+ layout="@layout/notification_material_media_action"
+ android:id="@+id/action2"
+ />
+ </LinearLayout>
</LinearLayout>
+ <ViewStub android:id="@+id/notification_media_seekbar_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ />
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 759fc12..881688b 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -164,6 +164,15 @@
provider.-->
<attr name="grantUriPermissions" format="boolean" />
+ <!-- If true, the system will always create URI permission grants
+ in the cases where {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}
+ or {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} would apply.
+ This is useful for a content provider that dynamically enforces permissions
+ on calls in to the provider, instead of through the manifest: the system
+ needs to know that it should always apply permission grants, even if it
+ looks like the target of the grant would already have access to the URI. -->
+ <attr name="forceUriPermissions" format="boolean" />
+
<!-- Characterizes the potential risk implied in a permission and
indicates the procedure the system should follow when determining
whether to grant the permission to an application requesting it. {@link
@@ -2199,6 +2208,7 @@
<attr name="readPermission" />
<attr name="writePermission" />
<attr name="grantUriPermissions" />
+ <attr name="forceUriPermissions" />
<attr name="permission" />
<attr name="multiprocess" />
<attr name="initOrder" />
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 16c0744..02fae4a 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -199,8 +199,6 @@
<color name="Red_700">#ffc53929</color>
<color name="Red_800">#ffb93221</color>
- <color name="chooser_service_row_background_color">#fff5f5f5</color>
-
<!-- Status bar color for semi transparent mode. -->
<color name="system_bar_background_semi_transparent">#66000000</color> <!-- 40% black -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 38c257e..ec53811 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1594,7 +1594,7 @@
<integer-array name="config_screenBrighteningThresholds">
<item>100</item>
</integer-array>
-
+
<!-- Array of hysteresis constraint values for darkening, represented as tenths of a
percent. The length of this array is assumed to be one greater than
config_screenThresholdLevels. The darkening threshold is calculated as
@@ -1933,18 +1933,11 @@
the platform will search for an SMS app and use that (if there is one)-->
<string name="default_sms_application" translatable="false">com.android.messaging</string>
- <!-- Default web browser. This is the package name of the application that will
- be the default browser when the device first boots. Afterwards the user
- can select whatever browser app they wish to use as the default.
-
- If this string is empty or the specified package does not exist, then
- the behavior will be as though no app was named as an explicit default. -->
- <string name="default_browser" translatable="false"></string>
-
<!-- Default role holders. This will be an array of roles and package names of their default
holders, with each item in the format of "ROLE_NAME: PACKAGE_NAME_1, PACKAGE_NAME_2". -->
<string-array name="config_defaultRoleHolders" translatable="false">
<item>android.app.role.SMS: com.android.messaging</item>
+ <item>android.app.role.DIALER: com.android.phone</item>
</string-array>
<!-- Enable/disable default bluetooth profiles:
@@ -2639,6 +2632,7 @@
extractor must come first -->
<item>com.android.server.notification.NotificationChannelExtractor</item>
<item>com.android.server.notification.NotificationAdjustmentExtractor</item>
+ <item>com.android.server.notification.BubbleExtractor</item>
<!-- depends on AdjustmentExtractor-->
<item>com.android.server.notification.ValidateNotificationPeople</item>
<item>com.android.server.notification.PriorityExtractor</item>
@@ -3431,8 +3425,10 @@
<!-- Flag indicates that whether non-system apps can be installed on internal storage. -->
<bool name="config_allow3rdPartyAppOnInternal">true</bool>
- <!-- Package name of the default cell broadcast receiver -->
- <string name="config_defaultCellBroadcastReceiverPkg" translatable="false">com.android.cellbroadcastreceiver</string>
+ <!-- Package names of the default cell broadcast receivers -->
+ <string-array name="config_defaultCellBroadcastReceiverPkgs" translatable="false">
+ <item>com.android.cellbroadcastreceiver</item>
+ </string-array>
<!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. -->
<string name="config_icon_mask" translatable="false">"M50,0L92,0C96.42,0 100,4.58 100 8L100,92C100, 96.42 96.42 100 92 100L8 100C4.58, 100 0 96.42 0 92L0 8 C 0 4.42 4.42 0 8 0L50 0Z"</string>
@@ -3667,6 +3663,8 @@
<dimen name="config_dialogCornerRadius">2dp</dimen>
<!-- Corner radius of system buttons -->
<dimen name="config_buttonCornerRadius">@dimen/control_corner_material</dimen>
+ <!-- Corner radius for bottom sheet system dialogs -->
+ <dimen name="config_bottomDialogCornerRadius">@dimen/config_dialogCornerRadius</dimen>
<!-- Corner radius of system progress bars -->
<dimen name="config_progressBarCornerRadius">@dimen/progress_bar_corner_material</dimen>
<!-- Controls whether system buttons use all caps for text -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 38367fb..9f86f84 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -720,4 +720,5 @@
<dimen name="chooser_view_spacing">18dp</dimen>
<dimen name="chooser_edge_margin_thin">16dp</dimen>
<dimen name="chooser_edge_margin_normal">24dp</dimen>
+ <dimen name="chooser_preview_image_font_size">20sp</dimen>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e7d8102..f84f1f1 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2938,6 +2938,7 @@
<public name="inheritShowWhenLocked" />
<public name="zygotePreloadName" />
<public name="useEmbeddedDex" />
+ <public name="forceUriPermissions" />
</public-group>
<public-group type="drawable" first-id="0x010800b4">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c9098736..1da9149 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -50,9 +50,14 @@
<java-symbol type="id" name="characterPicker" />
<java-symbol type="id" name="clearDefaultHint" />
<java-symbol type="id" name="contentPanel" />
- <java-symbol type="id" name="content_preview" />
+ <java-symbol type="id" name="content_preview_image_area" />
+ <java-symbol type="id" name="content_preview_image_1_large" />
+ <java-symbol type="id" name="content_preview_image_2_large" />
+ <java-symbol type="id" name="content_preview_image_2_small" />
+ <java-symbol type="id" name="content_preview_image_3_small" />
<java-symbol type="id" name="content_preview_thumbnail" />
<java-symbol type="id" name="content_preview_text" />
+ <java-symbol type="id" name="content_preview_text_area" />
<java-symbol type="id" name="content_preview_text_layout" />
<java-symbol type="id" name="content_preview_title" />
<java-symbol type="id" name="content_preview_title_layout" />
@@ -195,6 +200,12 @@
<java-symbol type="id" name="action3" />
<java-symbol type="id" name="action4" />
<java-symbol type="id" name="media_seamless" />
+ <java-symbol type="id" name="notification_media_seekbar_container" />
+ <java-symbol type="id" name="notification_media_content" />
+ <java-symbol type="id" name="notification_media_progress" />
+ <java-symbol type="id" name="notification_media_progress_bar" />
+ <java-symbol type="id" name="notification_media_elapsed_time" />
+ <java-symbol type="id" name="notification_media_total_time" />
<java-symbol type="id" name="big_picture" />
<java-symbol type="id" name="big_text" />
<java-symbol type="id" name="chronometer" />
@@ -1023,7 +1034,6 @@
<java-symbol type="string" name="sipAddressTypeOther" />
<java-symbol type="string" name="sipAddressTypeWork" />
<java-symbol type="string" name="default_sms_application" />
- <java-symbol type="string" name="default_browser" />
<java-symbol type="string" name="sms_control_message" />
<java-symbol type="string" name="sms_control_title" />
<java-symbol type="string" name="sms_control_no" />
@@ -1573,6 +1583,7 @@
<java-symbol type="layout" name="immersive_mode_cling" />
<java-symbol type="layout" name="user_switching_dialog" />
<java-symbol type="layout" name="common_tab_settings" />
+ <java-symbol type="layout" name="notification_material_media_seekbar" />
<java-symbol type="anim" name="slide_in_child_bottom" />
<java-symbol type="anim" name="slide_in_right" />
@@ -2725,6 +2736,7 @@
<java-symbol type="dimen" name="chooser_view_spacing" />
<java-symbol type="dimen" name="chooser_edge_margin_thin" />
<java-symbol type="dimen" name="chooser_edge_margin_normal" />
+ <java-symbol type="dimen" name="chooser_preview_image_font_size"/>
<java-symbol type="layout" name="chooser_grid" />
<java-symbol type="layout" name="resolve_grid_item" />
<java-symbol type="id" name="day_picker_view_pager" />
@@ -2732,7 +2744,6 @@
<java-symbol type="drawable" name="scroll_indicator_material" />
<java-symbol type="layout" name="chooser_row" />
- <java-symbol type="color" name="chooser_service_row_background_color" />
<java-symbol type="id" name="target_badge" />
<java-symbol type="bool" name="config_supportDoubleTapWake" />
<java-symbol type="drawable" name="ic_perm_device_info" />
@@ -3140,7 +3151,7 @@
<java-symbol type="drawable" name="lockscreen_selected" />
<java-symbol type="string" name="notification_header_divider_symbol_with_spaces" />
- <java-symbol type="string" name="config_defaultCellBroadcastReceiverPkg" />
+ <java-symbol type="array" name="config_defaultCellBroadcastReceiverPkgs" />
<java-symbol type="color" name="notification_primary_text_color_light" />
<java-symbol type="color" name="notification_primary_text_color_dark" />
@@ -3584,7 +3595,7 @@
<!-- For Secondary Launcher -->
<java-symbol type="string" name="config_secondaryHomeComponent" />
-
+
<java-symbol type="string" name="dynamic_mode_notification_channel_name" />
<java-symbol type="string" name="dynamic_mode_notification_title" />
<java-symbol type="string" name="dynamic_mode_notification_summary" />
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 6a81050..40ebd44 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -36,12 +36,11 @@
frameworks-core-util-lib \
mockwebserver \
guava \
- androidx.test.runner \
- androidx.test.ext.junit \
- androidx.test.rules \
androidx.test.espresso.core \
+ androidx.test.ext.junit \
+ androidx.test.runner \
+ androidx.test.rules \
mockito-target-minus-junit4 \
- espresso-core \
ub-uiautomator \
platform-test-annotations \
truth-prebuilt \
diff --git a/core/tests/coretests/src/android/animation/AnimatorInflaterTest.java b/core/tests/coretests/src/android/animation/AnimatorInflaterTest.java
index be1d44c..c71bc73 100644
--- a/core/tests/coretests/src/android/animation/AnimatorInflaterTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorInflaterTest.java
@@ -16,22 +16,28 @@
package android.animation;
-import android.test.ActivityInstrumentationTestCase2;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import androidx.test.filters.LargeTest;
+import androidx.test.rule.ActivityTestRule;
import com.android.frameworks.coretests.R;
+import org.junit.Rule;
+import org.junit.Test;
+
import java.util.HashSet;
import java.util.Set;
@LargeTest
-public class AnimatorInflaterTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
- Set<Integer> identityHashes = new HashSet<Integer>();
+public class AnimatorInflaterTest {
+ @Rule
+ public final ActivityTestRule<BasicAnimatorActivity> mActivityRule =
+ new ActivityTestRule<>(BasicAnimatorActivity.class);
- public AnimatorInflaterTest() {
- super(BasicAnimatorActivity.class);
- }
+ private final Set<Integer> mIdentityHashes = new HashSet<>();
private void assertUnique(Object object) {
assertUnique(object, "");
@@ -39,15 +45,16 @@
private void assertUnique(Object object, String msg) {
final int code = System.identityHashCode(object);
- assertTrue("object should be unique " + msg + ", obj:" + object, identityHashes.add(code));
-
+ assertTrue("object should be unique " + msg + ", obj:" + object, mIdentityHashes.add(code));
}
+ @Test
public void testLoadStateListAnimator() {
- StateListAnimator sla1 = AnimatorInflater.loadStateListAnimator(getActivity(),
+ final BasicAnimatorActivity activity = mActivityRule.getActivity();
+ StateListAnimator sla1 = AnimatorInflater.loadStateListAnimator(activity,
R.anim.test_state_anim);
- sla1.setTarget(getActivity().mAnimatingButton);
- StateListAnimator sla2 = AnimatorInflater.loadStateListAnimator(getActivity(),
+ sla1.setTarget(activity.mAnimatingButton);
+ StateListAnimator sla2 = AnimatorInflater.loadStateListAnimator(activity,
R.anim.test_state_anim);
assertNull(sla2.getTarget());
for (StateListAnimator sla : new StateListAnimator[]{sla1, sla2}) {
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
index 55837ba..7a1de0c 100644
--- a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
@@ -16,27 +16,38 @@
package android.animation;
-import android.test.ActivityInstrumentationTestCase2;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import android.view.View;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
import com.android.frameworks.coretests.R;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
import java.util.ArrayList;
-public class AnimatorSetActivityTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {
+@SmallTest
+public class AnimatorSetActivityTest {
+
+ @Rule
+ public final ActivityTestRule<AnimatorSetActivity> mActivityRule =
+ new ActivityTestRule<>(AnimatorSetActivity.class);
private static final long POLL_INTERVAL = 100; // ms
private AnimatorSetActivity mActivity;
private ObjectAnimator a1,a2,a3;
private ValueAnimator a4,a5;
- public AnimatorSetActivityTest() {
- super(AnimatorSetActivity.class);
- }
-
static class MyListener implements Animator.AnimatorListener {
boolean startIsCalled = false;
boolean endIsCalled = false;
@@ -63,10 +74,9 @@
}
}
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
- mActivity = getActivity();
+ mActivity = mActivityRule.getActivity();
View square1 = mActivity.findViewById(R.id.square1);
View square2 = mActivity.findViewById(R.id.square2);
@@ -78,7 +88,7 @@
a5 = ValueAnimator.ofFloat(10f, 5f).setDuration(850);
}
- @Override
+ @After
public void tearDown() throws Exception {
mActivity = null;
a1 = null;
@@ -86,10 +96,9 @@
a3 = null;
a4 = null;
a5 = null;
- super.tearDown();
}
- @SmallTest
+ @Test
public void testGetChildAnimations() {
AnimatorSet s1 = new AnimatorSet();
s1.playTogether(a1, a2, a3);
@@ -129,7 +138,7 @@
}
}
- @SmallTest
+ @Test
public void testTotalDuration() {
ArrayList<Animator> list = getAnimatorList();
@@ -192,7 +201,7 @@
}
- @SmallTest
+ @Test
public void testGetDuration() {
AnimatorSet s = new AnimatorSet();
assertTrue(s.getDuration() < 0);
@@ -205,8 +214,8 @@
}
- @SmallTest
@UiThreadTest
+ @Test
public void testSetDuration() {
AnimatorSet s = getSequentialSet();
assertTrue(s.getDuration() < 0);
@@ -224,7 +233,7 @@
assertEquals(duration, a5.getDuration());
}
- @SmallTest
+ @Test
public void testAddListener() throws InterruptedException {
// Verify that the listener is added to the list of listeners in the AnimatorSet
// and that newly added listener gets callback for lifecycle events of the animator
@@ -241,13 +250,10 @@
assertFalse(listener.endIsCalled);
try {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s.start();
- assertTrue(listener.startIsCalled);
- assertFalse(listener.endIsCalled);
- }
+ mActivityRule.runOnUiThread(() -> {
+ s.start();
+ assertTrue(listener.startIsCalled);
+ assertFalse(listener.endIsCalled);
});
} catch (Throwable throwable) {
throwable.printStackTrace();
@@ -258,18 +264,13 @@
assertTrue(listener.endIsCalled);
}
- @SmallTest
+ @Test
public void testRemoveListener() throws Throwable {
final AnimatorSet s = new AnimatorSet();
s.playTogether(a1, a2, a3, a4);
MyListener listener = new MyListener();
s.addListener(listener);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s.start();
- }
- });
+ mActivityRule.runOnUiThread(s::start);
Thread.sleep(s.getTotalDuration() + 100);
assertTrue(listener.startIsCalled);
@@ -282,18 +283,13 @@
listener.startIsCalled = false;
listener.endIsCalled = false;
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s.start();
- }
- });
+ mActivityRule.runOnUiThread(s::start);
Thread.sleep(s.getTotalDuration() + 100);
assertFalse(listener.startIsCalled);
assertFalse(listener.endIsCalled);
}
- @SmallTest
+ @Test
public void testEnd() throws Throwable {
// End animator set
final AnimatorSet s = new AnimatorSet();
@@ -301,37 +297,30 @@
final MyListener listener = new MyListener();
s.addListener(listener);
assertFalse(listener.endIsCalled);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s.start();
- assertTrue(s.isStarted());
- assertTrue(listener.startIsCalled);
- assertFalse(listener.endIsCalled);
- }
+ mActivityRule.runOnUiThread(() -> {
+ s.start();
+ assertTrue(s.isStarted());
+ assertTrue(listener.startIsCalled);
+ assertFalse(listener.endIsCalled);
});
Thread.sleep(a2.getTotalDuration());
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s.end();
- assertTrue(listener.startIsCalled);
- assertTrue(listener.endIsCalled);
- assertFalse(s.isRunning());
- assertFalse(s.isStarted());
+ mActivityRule.runOnUiThread(() -> {
+ s.end();
+ assertTrue(listener.startIsCalled);
+ assertTrue(listener.endIsCalled);
+ assertFalse(s.isRunning());
+ assertFalse(s.isStarted());
- assertFalse(a1.isStarted());
- assertFalse(a2.isStarted());
- assertFalse(a3.isStarted());
- assertFalse(a4.isStarted());
- }
+ assertFalse(a1.isStarted());
+ assertFalse(a2.isStarted());
+ assertFalse(a3.isStarted());
+ assertFalse(a4.isStarted());
});
-
}
- @SmallTest
+ @Test
public void testStart() throws Throwable {
final AnimatorSet s = new AnimatorSet();
ArrayList<Animator> animators = getAnimatorList();
@@ -355,12 +344,9 @@
assertFalse(l.endIsCalled);
}
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s.start();
- assertTrue(l.startIsCalled);
- }
+ mActivityRule.runOnUiThread(() -> {
+ s.start();
+ assertTrue(l.startIsCalled);
});
long timeout = s.getTotalDuration() * 2;
@@ -383,7 +369,7 @@
}
}
- @SmallTest
+ @Test
public void testCancel() throws Throwable {
// Check whether cancel would trigger onAnimationCanceled and cancel all the unfinished
// animations
@@ -411,42 +397,33 @@
assertFalse(l.endIsCalled);
}
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s.start();
- }
- });
+ mActivityRule.runOnUiThread(s::start);
Thread.sleep(a1.getTotalDuration());
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertTrue(s.isStarted());
- ArrayList<Integer> runningAnimIds = new ArrayList<Integer>();
- for (int i = 0; i < animators.size(); i++) {
- if (animators.get(i).isStarted()) {
- runningAnimIds.add(i);
- }
- }
- s.cancel();
- assertTrue(l.startIsCalled);
- assertTrue(l.cancelIsCalled);
- assertTrue(l.endIsCalled);
-
- for (int i = 0; i < listeners.size(); i++) {
- assertTrue(listeners.get(i).startIsCalled);
- if (runningAnimIds.contains(i)) {
- assertTrue(listeners.get(i).cancelIsCalled);
- }
- assertTrue(listeners.get(i).endIsCalled);
+ mActivityRule.runOnUiThread(() -> {
+ assertTrue(s.isStarted());
+ ArrayList<Integer> runningAnimIds = new ArrayList<>();
+ for (int i = 0; i < animators.size(); i++) {
+ if (animators.get(i).isStarted()) {
+ runningAnimIds.add(i);
}
}
- });
+ s.cancel();
+ assertTrue(l.startIsCalled);
+ assertTrue(l.cancelIsCalled);
+ assertTrue(l.endIsCalled);
+ for (int i = 0; i < listeners.size(); i++) {
+ assertTrue(listeners.get(i).startIsCalled);
+ if (runningAnimIds.contains(i)) {
+ assertTrue(listeners.get(i).cancelIsCalled);
+ }
+ assertTrue(listeners.get(i).endIsCalled);
+ }
+ });
}
- @SmallTest
+ @Test
public void testIsRunning() throws Throwable {
final AnimatorSet s = new AnimatorSet();
final long startDelay = 500;
@@ -455,12 +432,7 @@
s.setStartDelay(startDelay);
MyListener listener = new MyListener();
s.addListener(listener);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s.start();
- }
- });
+ mActivityRule.runOnUiThread(s::start);
while (!listener.endIsCalled) {
boolean passedStartDelay = a1.isStarted() || a2.isStarted() || a3.isStarted() ||
@@ -471,35 +443,29 @@
assertFalse(s.isRunning());
}
- @SmallTest
+ @Test
public void testPauseAndResume() throws Throwable {
final AnimatorSet set = getSequentialSet();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- // Calling pause before start should have no effect, per documentation
- set.pause();
- set.start();
- assertFalse(set.isPaused());
- }
+ mActivityRule.runOnUiThread(() -> {
+ // Calling pause before start should have no effect, per documentation
+ set.pause();
+ set.start();
+ assertFalse(set.isPaused());
});
while (!a2.isStarted()) {
Thread.sleep(50);
}
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertFalse(set.isPaused());
- set.pause();
- assertTrue(set.isPaused());
- set.resume();
- assertFalse(set.isPaused());
- }
+ mActivityRule.runOnUiThread(() -> {
+ assertFalse(set.isPaused());
+ set.pause();
+ assertTrue(set.isPaused());
+ set.resume();
+ assertFalse(set.isPaused());
});
}
- @SmallTest
+ @Test
public void testClone() throws Throwable {
// Set up an AnimatorSet and two clones, add one listener to each. When the clones animate,
// listeners of both the clone and the animator being cloned should receive animation
@@ -535,14 +501,11 @@
// Start the animation, and make the first clone during its run and the second clone once
// it ends.
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertFalse(l1.startIsCalled);
- assertFalse(l1.endIsCalled);
+ mActivityRule.runOnUiThread(() -> {
+ assertFalse(l1.startIsCalled);
+ assertFalse(l1.endIsCalled);
- s1.start();
- }
+ s1.start();
});
// Make the first clone, during the animation's run.
@@ -552,20 +515,12 @@
s2.addListener(l2);
Thread.sleep(POLL_INTERVAL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- s1.end();
- }
- });
+ mActivityRule.runOnUiThread(s1::end);
Thread.sleep(POLL_INTERVAL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertTrue(l1.startIsCalled);
- assertTrue(l1.endIsCalled);
- }
+ mActivityRule.runOnUiThread(() -> {
+ assertTrue(l1.startIsCalled);
+ assertTrue(l1.endIsCalled);
});
Thread.sleep(POLL_INTERVAL);
@@ -574,59 +529,49 @@
final MyListener l3 = new MyListener();
s3.addListener(l3);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- // Checking the fields before animations start.
- assertFalse(l2.startIsCalled);
- assertFalse(l2.cancelIsCalled);
- assertFalse(l2.endIsCalled);
- assertFalse(l3.startIsCalled);
- assertFalse(l3.cancelIsCalled);
- assertFalse(l3.endIsCalled);
+ mActivityRule.runOnUiThread(() -> {
+ // Checking the fields before animations start.
+ assertFalse(l2.startIsCalled);
+ assertFalse(l2.cancelIsCalled);
+ assertFalse(l2.endIsCalled);
+ assertFalse(l3.startIsCalled);
+ assertFalse(l3.cancelIsCalled);
+ assertFalse(l3.endIsCalled);
- s2.start();
- s3.start();
- }
+ s2.start();
+ s3.start();
});
Thread.sleep(POLL_INTERVAL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- // Make sure the listeners receive the callbacks
- // At this time only onAnimationStart() should be called.
- assertTrue(l2.startIsCalled);
- assertTrue(l3.startIsCalled);
- assertFalse(l2.endIsCalled);
- assertFalse(l3.endIsCalled);
- assertFalse(l2.cancelIsCalled);
- assertFalse(l3.cancelIsCalled);
+ mActivityRule.runOnUiThread(() -> {
+ // Make sure the listeners receive the callbacks
+ // At this time only onAnimationStart() should be called.
+ assertTrue(l2.startIsCalled);
+ assertTrue(l3.startIsCalled);
+ assertFalse(l2.endIsCalled);
+ assertFalse(l3.endIsCalled);
+ assertFalse(l2.cancelIsCalled);
+ assertFalse(l3.cancelIsCalled);
- s2.end();
- s3.cancel();
- }
+ s2.end();
+ s3.cancel();
});
Thread.sleep(POLL_INTERVAL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- // Check that the new listeners for the new animations gets called for the events.
- assertTrue(l2.startIsCalled);
- assertFalse(l2.cancelIsCalled);
- assertTrue(l2.endIsCalled);
- assertTrue(l3.startIsCalled);
- assertTrue(l3.cancelIsCalled);
- assertTrue(l3.endIsCalled);
+ mActivityRule.runOnUiThread(() -> {
+ // Check that the new listeners for the new animations gets called for the events.
+ assertTrue(l2.startIsCalled);
+ assertFalse(l2.cancelIsCalled);
+ assertTrue(l2.endIsCalled);
+ assertTrue(l3.startIsCalled);
+ assertTrue(l3.cancelIsCalled);
+ assertTrue(l3.endIsCalled);
- // Check that the listener on the animation that was being clone receive the
- // animation lifecycle events for the clones.
- assertTrue(onlyContains(startedAnimators, s1, s2, s3));
- assertTrue(onlyContains(canceledAnimators, s3));
- assertTrue(onlyContains(endedAnimators, s1, s2, s3));
- }
+ // Check that the listener on the animation that was being clone receive the
+ // animation lifecycle events for the clones.
+ assertTrue(onlyContains(startedAnimators, s1, s2, s3));
+ assertTrue(onlyContains(canceledAnimators, s3));
+ assertTrue(onlyContains(endedAnimators, s1, s2, s3));
});
-
}
/**
@@ -663,5 +608,4 @@
list.add(a5);
return list;
}
-
}
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetEventsTest.java b/core/tests/coretests/src/android/animation/AnimatorSetEventsTest.java
index 4e90d1a..94c90aa 100644
--- a/core/tests/coretests/src/android/animation/AnimatorSetEventsTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorSetEventsTest.java
@@ -23,6 +23,8 @@
import com.android.frameworks.coretests.R;
+import org.junit.Test;
+
import java.util.concurrent.TimeUnit;
/**
@@ -36,7 +38,7 @@
@Override
public void setUp() throws Exception {
- button = (Button) getActivity().findViewById(R.id.animatingButton);
+ button = mActivityRule.getActivity().findViewById(R.id.animatingButton);
mAnimator = new AnimatorSet();
((AnimatorSet)mAnimator).playSequentially(xAnim, yAnim);
super.setUp();
@@ -53,23 +55,21 @@
* its children
*/
@MediumTest
- public void testPlayingCancelDuringChildDelay() throws Exception {
+ @Test
+ public void testPlayingCancelDuringChildDelay() throws Throwable {
yAnim.setStartDelay(500);
final AnimatorSet animSet = new AnimatorSet();
animSet.playSequentially(xAnim, yAnim);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- animSet.addListener(mFutureListener);
- mRunning = true;
- animSet.start();
- handler.postDelayed(new Canceler(animSet, mFuture), ANIM_DURATION + 250);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ animSet.addListener(mFutureListener);
+ mRunning = true;
+ animSet.start();
+ handler.postDelayed(new Canceler(animSet, mFuture), ANIM_DURATION + 250);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
diff --git a/core/tests/coretests/src/android/animation/AutoCancelTest.java b/core/tests/coretests/src/android/animation/AutoCancelTest.java
index b3ec92c..7df7336 100644
--- a/core/tests/coretests/src/android/animation/AutoCancelTest.java
+++ b/core/tests/coretests/src/android/animation/AutoCancelTest.java
@@ -16,15 +16,24 @@
package android.animation;
+import static org.junit.Assert.assertTrue;
+
import android.os.Handler;
-import android.test.ActivityInstrumentationTestCase2;
import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Rule;
+import org.junit.Test;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
-public class AutoCancelTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
+public class AutoCancelTest {
+
+ @Rule
+ public final ActivityTestRule<BasicAnimatorActivity> mActivityRule =
+ new ActivityTestRule<>(BasicAnimatorActivity.class);
boolean mAnimX1Canceled = false;
boolean mAnimXY1Canceled = false;
@@ -37,10 +46,6 @@
HashMap<Animator, Boolean> mCanceledMap = new HashMap<Animator, Boolean>();
- public AutoCancelTest() {
- super(BasicAnimatorActivity.class);
- }
-
ObjectAnimator setupAnimator(long startDelay, String... properties) {
ObjectAnimator returnVal;
if (properties.length == 1) {
@@ -58,8 +63,7 @@
return returnVal;
}
- private void setupAnimators(long startDelay, boolean startLater, final FutureWaiter future)
- throws Exception {
+ private void setupAnimators(long startDelay, boolean startLater, final FutureWaiter future) {
// Animators to be auto-canceled
final ObjectAnimator animX1 = setupAnimator(startDelay, "x");
final ObjectAnimator animY1 = setupAnimator(startDelay, "y");
@@ -123,64 +127,56 @@
}
@SmallTest
- public void testAutoCancel() throws Exception {
+ @Test
+ public void testAutoCancel() throws Throwable {
final FutureWaiter future = new FutureWaiter();
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- setupAnimators(0, false, future);
- } catch (Exception e) {
- future.setException(e);
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ setupAnimators(0, false, future);
+ } catch (Exception e) {
+ future.setException(e);
}
});
assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS));
}
@SmallTest
- public void testAutoCancelDelayed() throws Exception {
+ @Test
+ public void testAutoCancelDelayed() throws Throwable {
final FutureWaiter future = new FutureWaiter();
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- setupAnimators(START_DELAY, false, future);
- } catch (Exception e) {
- future.setException(e);
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ setupAnimators(START_DELAY, false, future);
+ } catch (Exception e) {
+ future.setException(e);
}
});
assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS));
}
@SmallTest
- public void testAutoCancelTestLater() throws Exception {
+ @Test
+ public void testAutoCancelTestLater() throws Throwable {
final FutureWaiter future = new FutureWaiter();
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- setupAnimators(0, true, future);
- } catch (Exception e) {
- future.setException(e);
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ setupAnimators(0, true, future);
+ } catch (Exception e) {
+ future.setException(e);
}
});
assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS));
}
@SmallTest
- public void testAutoCancelDelayedTestLater() throws Exception {
+ @Test
+ public void testAutoCancelDelayedTestLater() throws Throwable {
final FutureWaiter future = new FutureWaiter();
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- setupAnimators(START_DELAY, true, future);
- } catch (Exception e) {
- future.setException(e);
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ setupAnimators(START_DELAY, true, future);
+ } catch (Exception e) {
+ future.setException(e);
}
});
assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS));
diff --git a/core/tests/coretests/src/android/animation/EventsTest.java b/core/tests/coretests/src/android/animation/EventsTest.java
index ba7413a..0c40a95 100644
--- a/core/tests/coretests/src/android/animation/EventsTest.java
+++ b/core/tests/coretests/src/android/animation/EventsTest.java
@@ -16,12 +16,20 @@
package android.animation;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.CallSuper;
import android.os.Handler;
-import android.test.ActivityInstrumentationTestCase2;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -38,8 +46,11 @@
* wait for some later event to occur before ending. These tests use a combination of an
* AbstractFuture mechanism and a delayed action to release that Future later.
*/
-public abstract class EventsTest
- extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
+public abstract class EventsTest {
+
+ @Rule
+ public final ActivityTestRule<BasicAnimatorActivity> mActivityRule =
+ new ActivityTestRule<>(BasicAnimatorActivity.class);
protected static final int ANIM_DURATION = 400;
protected static final int ANIM_DELAY = 100;
@@ -55,7 +66,6 @@
private boolean mCanceled; // tracks whether we've canceled the animator
protected Animator.AnimatorListener mFutureListener; // mechanism for delaying end of the test
protected FutureWaiter mFuture; // Mechanism for waiting for the UI test to complete
- private Animator.AnimatorListener mListener; // Listener that handles/tests the events
protected Animator mAnimator; // The animator used in the tests. Must be set in subclass
// setup() method prior to calling the superclass setup()
@@ -67,10 +77,12 @@
protected static class Canceler implements Runnable {
Animator mAnim;
FutureWaiter mFuture;
+
public Canceler(Animator anim, FutureWaiter future) {
mAnim = anim;
mFuture = future;
}
+
@Override
public void run() {
try {
@@ -79,7 +91,7 @@
mFuture.setException(new RuntimeException(e));
}
}
- };
+ }
/**
* Timeout length, based on when the animation should reasonably be complete.
@@ -95,10 +107,12 @@
static class Ender implements Runnable {
Animator mAnim;
FutureWaiter mFuture;
+
public Ender(Animator anim, FutureWaiter future) {
mAnim = anim;
mFuture = future;
}
+
@Override
public void run() {
try {
@@ -107,7 +121,7 @@
mFuture.setException(new RuntimeException(e));
}
}
- };
+ }
/**
* Pauses the given animator. Used to delay pausing until some later time (after the
@@ -116,10 +130,12 @@
static class Pauser implements Runnable {
Animator mAnim;
FutureWaiter mFuture;
+
public Pauser(Animator anim, FutureWaiter future) {
mAnim = anim;
mFuture = future;
}
+
@Override
public void run() {
try {
@@ -128,7 +144,7 @@
mFuture.setException(new RuntimeException(e));
}
}
- };
+ }
/**
* Resumes the given animator. Used to delay resuming until some later time (after the
@@ -137,10 +153,12 @@
static class Resumer implements Runnable {
Animator mAnim;
FutureWaiter mFuture;
+
public Resumer(Animator anim, FutureWaiter future) {
mAnim = anim;
mFuture = future;
}
+
@Override
public void run() {
try {
@@ -149,7 +167,7 @@
mFuture.setException(new RuntimeException(e));
}
}
- };
+ }
/**
* Releases the given Future object when the listener's end() event is called. Specifically,
@@ -171,28 +189,14 @@
public FutureReleaseListener(FutureWaiter future, long timeout) {
mFuture = future;
Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mFuture.release();
- }
- }, timeout);
+ handler.postDelayed(mFuture::release, timeout);
}
@Override
public void onAnimationEnd(Animator animation) {
Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mFuture.release();
- }
- }, FUTURE_RELEASE_DELAY);
+ handler.postDelayed(mFuture::release, FUTURE_RELEASE_DELAY);
}
- };
-
- public EventsTest() {
- super(BasicAnimatorActivity.class);
}
/**
@@ -201,13 +205,12 @@
* and then call super.setup(), where further properties are set on that animator.
* @throws Exception
*/
- @Override
+ @CallSuper
+ @Before
public void setUp() throws Exception {
- super.setUp();
-
// mListener is the main testing mechanism of this file. The asserts of each test
// are embedded in the listener callbacks that it implements.
- mListener = new AnimatorListenerAdapter() {
+ final Animator.AnimatorListener listener = new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
// This should only be called on an animation that has not yet been started
@@ -236,9 +239,8 @@
}
};
- mAnimator.addListener(mListener);
+ mAnimator.addListener(listener);
mAnimator.setDuration(ANIM_DURATION);
-
mFuture = new FutureWaiter();
mRunning = false;
@@ -251,6 +253,7 @@
*/
@UiThreadTest
@SmallTest
+ @Test
public void testCancel() throws Exception {
mAnimator.cancel();
}
@@ -260,6 +263,7 @@
*/
@UiThreadTest
@SmallTest
+ @Test
public void testEnd() throws Exception {
mRunning = true; // end() implicitly starts an unstarted animator
mAnimator.end();
@@ -270,19 +274,17 @@
*/
@UiThreadTest
@SmallTest
- public void testStartCancel() throws Exception {
+ @Test
+ public void testStartCancel() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -293,19 +295,17 @@
*/
@UiThreadTest
@SmallTest
- public void testStartEnd() throws Exception {
+ @Test
+ public void testStartEnd() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.end();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.end();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -315,20 +315,18 @@
* Same as testStartCancel, but with a startDelayed animator
*/
@SmallTest
- public void testStartDelayedCancel() throws Exception {
+ @Test
+ public void testStartDelayedCancel() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
mAnimator.setStartDelay(ANIM_DELAY);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -338,20 +336,18 @@
* Same as testStartEnd, but with a startDelayed animator
*/
@SmallTest
- public void testStartDelayedEnd() throws Exception {
+ @Test
+ public void testStartDelayedEnd() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
mAnimator.setStartDelay(ANIM_DELAY);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.end();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.end();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -361,20 +357,18 @@
* Verify that canceling an animator that is playing does the right thing.
*/
@MediumTest
- public void testPlayingCancel() throws Exception {
+ @Test
+ public void testPlayingCancel() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.addListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -384,20 +378,18 @@
* Verify that ending an animator that is playing does the right thing.
*/
@MediumTest
- public void testPlayingEnd() throws Exception {
+ @Test
+ public void testPlayingEnd() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.addListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -407,21 +399,19 @@
* Same as testPlayingCancel, but with a startDelayed animator
*/
@MediumTest
- public void testPlayingDelayedCancel() throws Exception {
+ @Test
+ public void testPlayingDelayedCancel() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.addListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -431,21 +421,19 @@
* Same as testPlayingEnd, but with a startDelayed animator
*/
@MediumTest
- public void testPlayingDelayedEnd() throws Exception {
+ @Test
+ public void testPlayingDelayedEnd() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.addListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -455,24 +443,21 @@
* Same as testPlayingDelayedCancel, but cancel during the startDelay period
*/
@MediumTest
- public void testPlayingDelayedCancelMidDelay() throws Exception {
+ @Test
+ public void testPlayingDelayedCancelMidDelay() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- // Set the listener to automatically timeout after an uncanceled animation
- // would have finished. This tests to make sure that we're not calling
- // the listeners with cancel/end callbacks since they won't be called
- // with the start event.
- mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
- Handler handler = new Handler();
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DELAY);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ // Set the listener to automatically timeout after an uncanceled animation would
+ // have finished. This tests to make sure that we're not calling the listeners with
+ // cancel/end callbacks since they won't be called with the start event.
+ mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
+ Handler handler = new Handler();
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DELAY);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout() + 100, TimeUnit.MILLISECONDS);
@@ -482,24 +467,21 @@
* Same as testPlayingDelayedEnd, but end during the startDelay period
*/
@MediumTest
- public void testPlayingDelayedEndMidDelay() throws Exception {
+ @Test
+ public void testPlayingDelayedEndMidDelay() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- // Set the listener to automatically timeout after an uncanceled animation
- // would have finished. This tests to make sure that we're not calling
- // the listeners with cancel/end callbacks since they won't be called
- // with the start event.
- mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
- Handler handler = new Handler();
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DELAY);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ // Set the listener to automatically timeout after an uncanceled animation would
+ // have finished. This tests to make sure that we're not calling the listeners with
+ // cancel/end callbacks since they won't be called with the start event.
+ mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
+ Handler handler = new Handler();
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DELAY);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout() + 100, TimeUnit.MILLISECONDS);
@@ -510,20 +492,18 @@
* does nothing.
*/
@MediumTest
- public void testStartDoubleCancel() throws Exception {
+ @Test
+ public void testStartDoubleCancel() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
- mAnimator.cancel();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -534,21 +514,19 @@
* does nothing.
*/
@MediumTest
- public void testStartDoubleEnd() throws Exception {
+ @Test
+ public void testStartDoubleEnd() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.end();
- mRunning = true; // end() implicitly starts an unstarted animator
- mAnimator.end();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.end();
+ mRunning = true; // end() implicitly starts an unstarted animator
+ mAnimator.end();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -558,21 +536,19 @@
* Same as testStartDoubleCancel, but with a startDelayed animator
*/
@MediumTest
- public void testStartDelayedDoubleCancel() throws Exception {
+ @Test
+ public void testStartDelayedDoubleCancel() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
- mAnimator.cancel();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -582,22 +558,20 @@
* Same as testStartDoubleEnd, but with a startDelayed animator
*/
@MediumTest
- public void testStartDelayedDoubleEnd() throws Exception {
+ @Test
+ public void testStartDelayedDoubleEnd() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.end();
- mRunning = true; // end() implicitly starts an unstarted animator
- mAnimator.end();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.end();
+ mRunning = true; // end() implicitly starts an unstarted animator
+ mAnimator.end();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -608,22 +582,20 @@
* the appropriate timeout duration.
*/
@MediumTest
- public void testPauseResume() throws Exception {
+ @Test
+ public void testPauseResume() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.addListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
- handler.postDelayed(new Resumer(mAnimator, mFuture),
- ANIM_PAUSE_DELAY + ANIM_PAUSE_DURATION);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
+ handler.postDelayed(new Resumer(mAnimator, mFuture),
+ ANIM_PAUSE_DELAY + ANIM_PAUSE_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout() + ANIM_PAUSE_DURATION, TimeUnit.MILLISECONDS);
@@ -634,23 +606,21 @@
* the appropriate timeout duration.
*/
@MediumTest
- public void testPauseResumeDelayed() throws Exception {
+ @Test
+ public void testPauseResumeDelayed() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.addListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
- handler.postDelayed(new Resumer(mAnimator, mFuture),
- ANIM_PAUSE_DELAY + ANIM_PAUSE_DURATION);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
+ handler.postDelayed(new Resumer(mAnimator, mFuture),
+ ANIM_PAUSE_DELAY + ANIM_PAUSE_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout() + ANIM_PAUSE_DURATION + ANIM_FULL_DURATION_SLOP,
@@ -661,20 +631,18 @@
* Verify that pausing an animator without resuming it causes a timeout.
*/
@MediumTest
- public void testPauseTimeout() throws Exception {
+ @Test
+ public void testPauseTimeout() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.addListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
try {
@@ -689,21 +657,19 @@
* Verify that pausing a startDelayed animator without resuming it causes a timeout.
*/
@MediumTest
- public void testPauseTimeoutDelayed() throws Exception {
+ @Test
+ public void testPauseTimeoutDelayed() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.addListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.addListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
try {
diff --git a/core/tests/coretests/src/android/animation/ObjectAnimatorEventsTest.java b/core/tests/coretests/src/android/animation/ObjectAnimatorEventsTest.java
index 53f9472..63ad061 100644
--- a/core/tests/coretests/src/android/animation/ObjectAnimatorEventsTest.java
+++ b/core/tests/coretests/src/android/animation/ObjectAnimatorEventsTest.java
@@ -27,11 +27,10 @@
@Override
public void setUp() throws Exception {
- final BasicAnimatorActivity activity = getActivity();
- Button button = (Button) activity.findViewById(R.id.animatingButton);
+ final BasicAnimatorActivity activity = mActivityRule.getActivity();
+ Button button = activity.findViewById(R.id.animatingButton);
mAnimator = ObjectAnimator.ofFloat(button, "translationX", 0, 100);
super.setUp();
}
-
}
diff --git a/core/tests/coretests/src/android/animation/StateListAnimatorTest.java b/core/tests/coretests/src/android/animation/StateListAnimatorTest.java
index e755b89..12f1977 100644
--- a/core/tests/coretests/src/android/animation/StateListAnimatorTest.java
+++ b/core/tests/coretests/src/android/animation/StateListAnimatorTest.java
@@ -16,41 +16,47 @@
package android.animation;
-import android.test.ActivityInstrumentationTestCase2;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
import android.util.StateSet;
import android.view.View;
import android.view.ViewGroup;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.LargeTest;
+import androidx.test.rule.ActivityTestRule;
import com.android.frameworks.coretests.R;
+import org.junit.Rule;
+import org.junit.Test;
+
import java.util.concurrent.atomic.AtomicInteger;
@LargeTest
-public class StateListAnimatorTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
+public class StateListAnimatorTest {
- public StateListAnimatorTest() {
- super(BasicAnimatorActivity.class);
- }
+ @Rule
+ public final ActivityTestRule<BasicAnimatorActivity> mActivityRule =
+ new ActivityTestRule<>(BasicAnimatorActivity.class);
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
+ @Test
public void testInflateFromAnimator() throws Exception {
StateListAnimator stateListAnimator = AnimatorInflater
- .loadStateListAnimator(getActivity(), R.anim.test_state_anim);
+ .loadStateListAnimator(mActivityRule.getActivity(), R.anim.test_state_anim);
assertNotNull("A state list animator should be returned", stateListAnimator);
assertEquals("State list animator should have three items", 3,
stateListAnimator.getTuples().size());
}
@UiThreadTest
+ @Test
public void testAttachDetach() throws Exception {
- View view = new View(getActivity());
+ final BasicAnimatorActivity activity = mActivityRule.getActivity();
+ View view = new View(activity);
final AtomicInteger setStateCount = new AtomicInteger(0);
StateListAnimator stateListAnimator = new StateListAnimator() {
@Override
@@ -62,7 +68,7 @@
view.setStateListAnimator(stateListAnimator);
assertNotNull("State list animator should have a reference to view even if it is detached",
stateListAnimator.getTarget());
- ViewGroup viewGroup = (ViewGroup) getActivity().findViewById(android.R.id.content);
+ ViewGroup viewGroup = activity.findViewById(android.R.id.content);
int preSetStateCount = setStateCount.get();
viewGroup.addView(view);
assertTrue("When view is attached, state list drawable's setState should be called",
@@ -82,9 +88,10 @@
stateListAnimator2.getTarget());
}
+ @Test
public void testStateListLoading() throws InterruptedException {
StateListAnimator stateListAnimator = AnimatorInflater
- .loadStateListAnimator(getActivity(), R.anim.test_state_anim);
+ .loadStateListAnimator(mActivityRule.getActivity(), R.anim.test_state_anim);
assertNotNull("A state list animator should be returned", stateListAnimator);
assertEquals("Steate list animator should have two items", 3,
stateListAnimator.getTuples().size());
diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorEventsTest.java b/core/tests/coretests/src/android/animation/ValueAnimatorEventsTest.java
index f6d71b8..ba9aef8 100644
--- a/core/tests/coretests/src/android/animation/ValueAnimatorEventsTest.java
+++ b/core/tests/coretests/src/android/animation/ValueAnimatorEventsTest.java
@@ -26,5 +26,4 @@
mAnimator = ValueAnimator.ofFloat(0, 1);
super.setUp();
}
-
}
diff --git a/core/tests/coretests/src/android/animation/ViewPropertyAnimatorTest.java b/core/tests/coretests/src/android/animation/ViewPropertyAnimatorTest.java
index 997af00..81cd4da 100644
--- a/core/tests/coretests/src/android/animation/ViewPropertyAnimatorTest.java
+++ b/core/tests/coretests/src/android/animation/ViewPropertyAnimatorTest.java
@@ -16,17 +16,24 @@
package android.animation;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.os.Handler;
-import android.test.ActivityInstrumentationTestCase2;
import android.view.ViewPropertyAnimator;
import android.widget.Button;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
import com.android.frameworks.coretests.R;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
import java.util.concurrent.TimeUnit;
/**
@@ -41,8 +48,11 @@
* wait for some later event to occur before ending. These tests use a combination of an
* AbstractFuture mechanism and a delayed action to release that Future later.
*/
-public abstract class ViewPropertyAnimatorTest
- extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
+public class ViewPropertyAnimatorTest {
+
+ @Rule
+ public final ActivityTestRule<BasicAnimatorActivity> mActivityRule =
+ new ActivityTestRule<>(BasicAnimatorActivity.class);
protected static final int ANIM_DURATION = 400;
protected static final int ANIM_DELAY = 100;
@@ -79,7 +89,7 @@
mFuture.setException(new RuntimeException(e));
}
}
- };
+ }
/**
* Timeout length, based on when the animation should reasonably be complete.
@@ -108,28 +118,14 @@
public FutureReleaseListener(FutureWaiter future, long timeout) {
mFuture = future;
Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mFuture.release();
- }
- }, timeout);
+ handler.postDelayed(mFuture::release, timeout);
}
@Override
public void onAnimationEnd(Animator animation) {
Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mFuture.release();
- }
- }, FUTURE_RELEASE_DELAY);
+ handler.postDelayed(mFuture::release, FUTURE_RELEASE_DELAY);
}
- };
-
- public ViewPropertyAnimatorTest() {
- super(BasicAnimatorActivity.class);
}
/**
@@ -138,15 +134,13 @@
* and then call super.setup(), where further properties are set on that animator.
* @throws Exception
*/
- @Override
+ @Before
public void setUp() throws Exception {
- final BasicAnimatorActivity activity = getActivity();
- Button button = (Button) activity.findViewById(R.id.animatingButton);
+ final BasicAnimatorActivity activity = mActivityRule.getActivity();
+ Button button = activity.findViewById(R.id.animatingButton);
mAnimator = button.animate().x(100).y(100);
- super.setUp();
-
// mListener is the main testing mechanism of this file. The asserts of each test
// are embedded in the listener callbacks that it implements.
mListener = new AnimatorListenerAdapter() {
@@ -195,6 +189,7 @@
*/
@UiThreadTest
@SmallTest
+ @Test
public void testCancel() throws Exception {
mAnimator.cancel();
}
@@ -204,19 +199,17 @@
*/
@UiThreadTest
@SmallTest
- public void testStartCancel() throws Exception {
+ @Test
+ public void testStartCancel() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -226,20 +219,18 @@
* Same as testStartCancel, but with a startDelayed animator
*/
@SmallTest
- public void testStartDelayedCancel() throws Exception {
+ @Test
+ public void testStartDelayedCancel() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
mAnimator.setStartDelay(ANIM_DELAY);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -249,20 +240,18 @@
* Verify that canceling an animator that is playing does the right thing.
*/
@MediumTest
- public void testPlayingCancel() throws Exception {
+ @Test
+ public void testPlayingCancel() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.setListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.setListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -272,21 +261,19 @@
* Same as testPlayingCancel, but with a startDelayed animator
*/
@MediumTest
- public void testPlayingDelayedCancel() throws Exception {
+ @Test
+ public void testPlayingDelayedCancel() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- Handler handler = new Handler();
- mAnimator.setListener(mFutureListener);
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ Handler handler = new Handler();
+ mAnimator.setListener(mFutureListener);
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -296,24 +283,21 @@
* Same as testPlayingDelayedCancel, but cancel during the startDelay period
*/
@MediumTest
- public void testPlayingDelayedCancelMidDelay() throws Exception {
+ @Test
+ public void testPlayingDelayedCancelMidDelay() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- // Set the listener to automatically timeout after an uncanceled animation
- // would have finished. This tests to make sure that we're not calling
- // the listeners with cancel/end callbacks since they won't be called
- // with the start event.
- mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
- Handler handler = new Handler();
- mRunning = true;
- mAnimator.start();
- handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DELAY);
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ // Set the listener to automatically timeout after an uncanceled animation would
+ // have finished. This tests to make sure that we're not calling the listeners with
+ // cancel/end callbacks since they won't be called with the start event.
+ mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
+ Handler handler = new Handler();
+ mRunning = true;
+ mAnimator.start();
+ handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DELAY);
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout() + 100, TimeUnit.MILLISECONDS);
@@ -324,20 +308,18 @@
* does nothing.
*/
@MediumTest
- public void testStartDoubleCancel() throws Exception {
+ @Test
+ public void testStartDoubleCancel() throws Throwable {
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
- mAnimator.cancel();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
@@ -347,24 +329,21 @@
* Same as testStartDoubleCancel, but with a startDelayed animator
*/
@MediumTest
- public void testStartDelayedDoubleCancel() throws Exception {
+ @Test
+ public void testStartDelayedDoubleCancel() throws Throwable {
mAnimator.setStartDelay(ANIM_DELAY);
mFutureListener = new FutureReleaseListener(mFuture);
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- try {
- mRunning = true;
- mAnimator.start();
- mAnimator.cancel();
- mAnimator.cancel();
- mFuture.release();
- } catch (junit.framework.AssertionFailedError e) {
- mFuture.setException(new RuntimeException(e));
- }
+ mActivityRule.runOnUiThread(() -> {
+ try {
+ mRunning = true;
+ mAnimator.start();
+ mAnimator.cancel();
+ mAnimator.cancel();
+ mFuture.release();
+ } catch (junit.framework.AssertionFailedError e) {
+ mFuture.setException(new RuntimeException(e));
}
});
mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
}
-
}
diff --git a/core/tests/coretests/src/android/hardware/hdmi/HdmiUtilsTest.java b/core/tests/coretests/src/android/hardware/hdmi/HdmiUtilsTest.java
index 16be0b0..d8799cb 100644
--- a/core/tests/coretests/src/android/hardware/hdmi/HdmiUtilsTest.java
+++ b/core/tests/coretests/src/android/hardware/hdmi/HdmiUtilsTest.java
@@ -17,7 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
-import android.support.test.filters.SmallTest;
+import androidx.test.filters.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/core/tests/coretests/src/android/view/AccessibilityInteractionControllerTest.java b/core/tests/coretests/src/android/view/AccessibilityInteractionControllerTest.java
index d0719cb..7855ef9 100644
--- a/core/tests/coretests/src/android/view/AccessibilityInteractionControllerTest.java
+++ b/core/tests/coretests/src/android/view/AccessibilityInteractionControllerTest.java
@@ -26,9 +26,6 @@
import android.app.UiAutomation;
import android.graphics.Rect;
import android.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -36,6 +33,10 @@
import android.view.accessibility.AccessibilityTestActivity;
import android.view.accessibility.AccessibilityWindowInfo;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.rule.ActivityTestRule;
+
import com.android.compatibility.common.util.TestUtils;
import com.android.frameworks.coretests.R;
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index b07cb99..da81d17 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.graphics.Insets;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
@@ -80,7 +81,7 @@
@Test
public void testImeVisibility() {
- final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash);
+ final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
mController.onControlsChanged(new InsetsSourceControl[] { ime });
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 7cd3c44..71ce02d 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -19,13 +19,23 @@
import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.WindowInsets.Type.sideBars;
+import static android.view.WindowInsets.Type.systemBars;
+import static android.view.WindowInsets.Type.topBar;
import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.graphics.Insets;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.platform.test.annotations.Presubmit;
@@ -55,6 +65,7 @@
private SurfaceSession mSession = new SurfaceSession();
private SurfaceControl mTopLeash;
private SurfaceControl mNavLeash;
+ private InsetsState mInsetsState;
@Mock Transaction mMockTransaction;
@Mock InsetsController mMockController;
@@ -63,6 +74,7 @@
@Before
public void setup() {
+ ViewRootImpl.sNewInsetsMode = NEW_INSETS_MODE_FULL;
MockitoAnnotations.initMocks(this);
mTopLeash = new SurfaceControl.Builder(mSession)
.setName("testSurface")
@@ -70,24 +82,25 @@
mNavLeash = new SurfaceControl.Builder(mSession)
.setName("testSurface")
.build();
- InsetsState state = new InsetsState();
- state.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 500, 100));
- state.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(400, 0, 500, 500));
- InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, state,
+ mInsetsState = new InsetsState();
+ mInsetsState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 500, 100));
+ mInsetsState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(400, 0, 500, 500));
+ InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, mInsetsState,
() -> mMockTransaction, mMockController);
- topConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mTopLeash));
+ topConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mTopLeash, new Point(0, 0)));
- InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(TYPE_NAVIGATION_BAR, state,
- () -> mMockTransaction, mMockController);
+ InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(TYPE_NAVIGATION_BAR,
+ mInsetsState, () -> mMockTransaction, mMockController);
navConsumer.hide();
- navConsumer.setControl(new InsetsSourceControl(TYPE_NAVIGATION_BAR, mNavLeash));
+ navConsumer.setControl(new InsetsSourceControl(TYPE_NAVIGATION_BAR, mNavLeash,
+ new Point(400, 0)));
SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();
consumers.put(TYPE_TOP_BAR, topConsumer);
consumers.put(TYPE_NAVIGATION_BAR, navConsumer);
mController = new InsetsAnimationControlImpl(consumers,
- new Rect(0, 0, 500, 500), state, mMockListener, WindowInsets.Type.systemBars(),
- () -> mMockTransactionApplier, mock(InsetsController.class));
+ new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(),
+ () -> mMockTransactionApplier, mMockController);
}
@Test
@@ -95,7 +108,7 @@
assertEquals(Insets.of(0, 100, 100, 0), mController.getShownStateInsets());
assertEquals(Insets.of(0, 0, 0, 0), mController.getHiddenStateInsets());
assertEquals(Insets.of(0, 100, 0, 0), mController.getCurrentInsets());
- assertEquals(WindowInsets.Type.systemBars(), mController.getTypes());
+ assertEquals(systemBars(), mController.getTypes());
}
@Test
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 8f21096..6dad6a2 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -27,6 +27,7 @@
import android.content.Context;
import android.graphics.Insets;
+import android.graphics.Point;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.WindowInsets.Type;
@@ -74,11 +75,12 @@
Insets.of(10, 10, 10, 10), rect, rect, rect, rect),
rect, rect);
});
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
@Test
public void testControlsChanged() {
- InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+ InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point());
mController.onControlsChanged(new InsetsSourceControl[] { control });
assertEquals(mLeash,
mController.getSourceConsumer(TYPE_TOP_BAR).getControl().getLeash());
@@ -86,7 +88,7 @@
@Test
public void testControlsRevoked() {
- InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+ InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point());
mController.onControlsChanged(new InsetsSourceControl[] { control });
mController.onControlsChanged(new InsetsSourceControl[0]);
assertNull(mController.getSourceConsumer(TYPE_TOP_BAR).getControl());
@@ -94,22 +96,19 @@
@Test
public void testAnimationEndState() {
- final InsetsSourceControl navBar = new InsetsSourceControl(TYPE_NAVIGATION_BAR, mLeash);
- final InsetsSourceControl topBar = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
- final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash);
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
- InsetsSourceControl[] controls = new InsetsSourceControl[3];
- controls[0] = navBar;
- controls[1] = topBar;
- controls[2] = ime;
- mController.onControlsChanged(controls);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mController.show(Type.all());
// quickly jump to final state by cancelling it.
mController.cancelExistingAnimation();
assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
- assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
+ // no focused view, no IME.
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
mController.hide(Type.all());
mController.cancelExistingAnimation();
@@ -119,11 +118,175 @@
mController.show(Type.ime());
mController.cancelExistingAnimation();
- assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
+ // no focused view, no IME.
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
- mController.hide(Type.ime());
+ @Test
+ public void testApplyImeVisibility() {
+ final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
+
+ InsetsSourceControl[] controls = new InsetsSourceControl[3];
+ controls[0] = ime;
+ mController.onControlsChanged(controls);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mController.applyImeVisibility(true);
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
+ mController.applyImeVisibility(false);
mController.cancelExistingAnimation();
assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
});
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Test
+ public void testShowHideSelectively() {
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ int types = Type.sideBars() | Type.systemBars();
+ // test show select types.
+ mController.show(types);
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ // test hide all
+ mController.hide(types);
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Test
+ public void testShowHideSingle() {
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ int types = Type.sideBars() | Type.systemBars();
+ // test show select types.
+ mController.show(types);
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ // test hide all
+ mController.hide(Type.all());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ // test single show
+ mController.show(Type.sideBars());
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ // test single hide
+ mController.hide(Type.sideBars());
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Test
+ public void testShowHideMultiple() {
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ // start two animations and see if previous is cancelled and final state is reached.
+ mController.show(Type.sideBars());
+ mController.show(Type.systemBars());
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ mController.hide(Type.sideBars());
+ mController.hide(Type.systemBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ int types = Type.sideBars() | Type.systemBars();
+ // show two at a time and hide one by one.
+ mController.show(types);
+ mController.hide(Type.sideBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ mController.hide(Type.systemBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Test
+ public void testShowMultipleHideOneByOne() {
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ int types = Type.sideBars() | Type.systemBars();
+ // show two at a time and hide one by one.
+ mController.show(types);
+ mController.hide(Type.sideBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ mController.hide(Type.systemBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ private InsetsSourceControl[] prepareControls() {
+ final InsetsSourceControl navBar = new InsetsSourceControl(TYPE_NAVIGATION_BAR, mLeash,
+ new Point());
+ final InsetsSourceControl topBar = new InsetsSourceControl(TYPE_TOP_BAR, mLeash,
+ new Point());
+ final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
+
+ InsetsSourceControl[] controls = new InsetsSourceControl[3];
+ controls[0] = navBar;
+ controls[1] = topBar;
+ controls[2] = ime;
+ mController.onControlsChanged(controls);
+ return controls;
}
}
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 82cd213..66146c9 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import android.graphics.Point;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl.Transaction;
@@ -56,7 +57,7 @@
.build();
mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(),
() -> mMockTransaction, mMockController);
- mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+ mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point()));
}
@Test
@@ -78,7 +79,7 @@
reset(mMockTransaction);
mConsumer.hide();
verifyZeroInteractions(mMockTransaction);
- mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+ mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point()));
verify(mMockTransaction).hide(eq(mLeash));
}
}
diff --git a/core/tests/coretests/src/android/view/PinchZoomAction.java b/core/tests/coretests/src/android/view/PinchZoomAction.java
index bec9b55..cfdec4d 100644
--- a/core/tests/coretests/src/android/view/PinchZoomAction.java
+++ b/core/tests/coretests/src/android/view/PinchZoomAction.java
@@ -16,20 +16,21 @@
package android.view;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.hamcrest.Matchers.allOf;
import android.os.SystemClock;
-import android.support.test.espresso.InjectEventSecurityException;
-import android.support.test.espresso.PerformException;
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.action.Swiper;
-import android.support.test.espresso.util.HumanReadables;
+
+import androidx.test.espresso.InjectEventSecurityException;
+import androidx.test.espresso.PerformException;
+import androidx.test.espresso.UiController;
+import androidx.test.espresso.ViewAction;
+import androidx.test.espresso.action.Swiper;
+import androidx.test.espresso.util.HumanReadables;
import org.hamcrest.Matcher;
diff --git a/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java b/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java
index 1990135..f63a454 100644
--- a/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java
+++ b/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java
@@ -16,48 +16,43 @@
package android.view;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import android.content.Context;
-import android.test.ActivityInstrumentationTestCase2;
import android.util.DisplayMetrics;
import android.widget.TextView;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
+import androidx.test.rule.ActivityTestRule;
import com.android.frameworks.coretests.R;
-import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
@LargeTest
-public class ScaleGestureDetectorTest extends ActivityInstrumentationTestCase2<ScaleGesture> {
- private ScaleGesture mScaleGestureActivity;
+public class ScaleGestureDetectorTest {
- public ScaleGestureDetectorTest() {
- super("com.android.frameworks.coretests", ScaleGesture.class);
- }
+ @Rule
+ public final ActivityTestRule<ScaleGesture> mActivityRule =
+ new ActivityTestRule<>(ScaleGesture.class);
+ private ScaleGesture mScaleGestureActivity;
@Before
public void setUp() throws Exception {
- super.setUp();
- injectInstrumentation(InstrumentationRegistry.getInstrumentation());
- mScaleGestureActivity = getActivity();
- }
-
- @After
- public void tearDown() throws Exception {
- super.tearDown();
+ mScaleGestureActivity = mActivityRule.getActivity();
}
@Test
public void testScaleGestureDetector() {
// No scaling should have occurred prior to performing pinch zoom action.
final float initialScaleFactor = 1.0f;
- assertEquals(initialScaleFactor, mScaleGestureActivity.getScaleFactor());
+ assertEquals(initialScaleFactor, mScaleGestureActivity.getScaleFactor(), 0f);
// Specify start and end coordinates, irrespective of device display size.
final DisplayMetrics dm = new DisplayMetrics();
diff --git a/core/tests/coretests/src/android/view/accessibility/FindViewByIdTest.java b/core/tests/coretests/src/android/view/accessibility/FindViewByIdTest.java
new file mode 100644
index 0000000..da6ecb4
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/FindViewByIdTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.filters.MediumTest;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+@MediumTest
+public class FindViewByIdTest {
+
+ @Rule
+ public ActivityTestRule<Activity> mActivityRule = new ActivityTestRule<>(Activity.class);
+
+ private Context getContext() {
+ return InstrumentationRegistry.getTargetContext();
+ }
+
+ private Activity getActivity() {
+ return mActivityRule.getActivity();
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFindViewById() {
+ LinearLayout contentView = new LinearLayout(getContext());
+ getActivity().setContentView(contentView);
+ View child1 = new View(getContext());
+ View child2 = new View(getContext());
+ child1.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ child2.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+
+ contentView.addView(child1);
+ contentView.addView(child2);
+ View result = AccessibilityNodeIdManager.getInstance().findView(
+ child2.getAccessibilityViewId());
+ assertEquals(result, child2);
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFindViewByIdReturnNullIfRemovedFromHierarchy() {
+ LinearLayout contentView = new LinearLayout(getContext());
+ getActivity().setContentView(contentView);
+ View child1 = new View(getContext());
+ View child2 = new View(getContext());
+ contentView.addView(child1);
+ contentView.addView(child2);
+ child1.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ child2.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+
+ contentView.removeView(child1);
+ View result = AccessibilityNodeIdManager.getInstance().findView(
+ child1.getAccessibilityViewId());
+ assertNull(result);
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFindViewByIdReturnNullIfNotImportant() {
+ LinearLayout contentView = new LinearLayout(getContext());
+ getActivity().setContentView(contentView);
+ View child1 = new View(getContext());
+ View child2 = new View(getContext());
+ child2.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+
+ contentView.addView(child1);
+ contentView.addView(child2);
+
+ View result = AccessibilityNodeIdManager.getInstance().findView(
+ child1.getAccessibilityViewId());
+ assertNull(result);
+ }
+}
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
new file mode 100644
index 0000000..f325d89
--- /dev/null
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.contentcapture;
+
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_FINISHED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.os.Parcel;
+import android.os.SystemClock;
+import android.view.autofill.AutofillId;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.ArrayList;
+
+/**
+ * Unit test for {@link ContentCaptureEvent}.
+ *
+ * <p>To run it:
+ * {@code atest FrameworksCoreTests:android.view.contentcapture.ContentCaptureEventTest}
+ */
+@RunWith(JUnit4.class)
+public class ContentCaptureEventTest {
+
+ private static final long MY_EPOCH = SystemClock.uptimeMillis();
+
+ // Not using @Mock because it's final - no need to be fancy here....
+ private final ContentCaptureContext mClientContext = new ContentCaptureContext.Builder()
+ .setAction("WHATEVER").build();
+
+ @Test
+ public void testSetAutofillId_null() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ assertThrows(NullPointerException.class, () -> event.setAutofillId(null));
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ }
+
+ @Test
+ public void testSetAutofillIds_null() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ assertThrows(NullPointerException.class, () -> event.setAutofillIds(null));
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ }
+
+ @Test
+ public void testAddAutofillId_null() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ assertThrows(NullPointerException.class, () -> event.addAutofillId(null));
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ }
+
+ @Test
+ public void testSetAutofillId() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id = new AutofillId(108);
+ event.setAutofillId(id);
+ assertThat(event.getId()).isEqualTo(id);
+ assertThat(event.getIds()).isNull();
+ }
+
+ @Test
+ public void testSetAutofillIds() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id = new AutofillId(108);
+ final ArrayList<AutofillId> ids = new ArrayList<>(1);
+ ids.add(id);
+ event.setAutofillIds(ids);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id);
+ }
+
+ @Test
+ public void testAddAutofillId() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id1 = new AutofillId(108);
+ event.addAutofillId(id1);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1);
+
+ final AutofillId id2 = new AutofillId(666);
+ event.addAutofillId(id2);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1, id2).inOrder();
+ }
+
+ @Test
+ public void testAddAutofillId_afterSetId() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id1 = new AutofillId(108);
+ event.setAutofillId(id1);
+ assertThat(event.getId()).isEqualTo(id1);
+ assertThat(event.getIds()).isNull();
+
+ final AutofillId id2 = new AutofillId(666);
+ event.addAutofillId(id2);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1, id2).inOrder();
+ }
+
+ @Test
+ public void testAddAutofillId_afterSetIds() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id1 = new AutofillId(108);
+ final ArrayList<AutofillId> ids = new ArrayList<>(1);
+ ids.add(id1);
+ event.setAutofillIds(ids);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1);
+
+ final AutofillId id2 = new AutofillId(666);
+ event.addAutofillId(id2);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1, id2).inOrder();
+ }
+
+ @Test
+ public void testSessionStarted_directly() {
+ final ContentCaptureEvent event = newEventForSessionStarted();
+ assertSessionStartedEvent(event);
+ }
+
+ @Test
+ public void testSessionStarted_throughParcel() {
+ final ContentCaptureEvent event = newEventForSessionStarted();
+ final ContentCaptureEvent clone = cloneThroughParcel(event);
+ assertSessionStartedEvent(clone);
+ }
+
+ private ContentCaptureEvent newEventForSessionStarted() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_STARTED)
+ .setClientContext(mClientContext)
+ .setParentSessionId("108");
+ assertThat(event).isNotNull();
+ return event;
+ }
+
+ private void assertSessionStartedEvent(ContentCaptureEvent event) {
+ assertThat(event.getType()).isEqualTo(TYPE_SESSION_STARTED);
+ assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);
+ assertThat(event.getSessionId()).isEqualTo("42");
+ assertThat(event.getParentSessionId()).isEqualTo("108");
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ assertThat(event.getText()).isNull();
+ assertThat(event.getViewNode()).isNull();
+ final ContentCaptureContext clientContext = event.getClientContext();
+ assertThat(clientContext.getAction()).isEqualTo("WHATEVER");
+ }
+
+ @Test
+ public void testSessionFinished_directly() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_FINISHED)
+ .setParentSessionId("108");
+ assertThat(event).isNotNull();
+ assertSessionFinishedEvent(event);
+ }
+
+ @Test
+ public void testSessionFinished_throughParcel() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_FINISHED)
+ .setClientContext(mClientContext) // should not be writting to parcel
+ .setParentSessionId("108");
+ assertThat(event).isNotNull();
+ final ContentCaptureEvent clone = cloneThroughParcel(event);
+ assertSessionFinishedEvent(clone);
+ }
+
+ private void assertSessionFinishedEvent(ContentCaptureEvent event) {
+ assertThat(event.getType()).isEqualTo(TYPE_SESSION_FINISHED);
+ assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);
+ assertThat(event.getSessionId()).isEqualTo("42");
+ assertThat(event.getParentSessionId()).isEqualTo("108");
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ assertThat(event.getText()).isNull();
+ assertThat(event.getViewNode()).isNull();
+ assertThat(event.getClientContext()).isNull();
+ }
+
+ private ContentCaptureEvent cloneThroughParcel(ContentCaptureEvent event) {
+ Parcel parcel = Parcel.obtain();
+
+ try {
+ // Write to parcel
+ parcel.setDataPosition(0); // Sanity / paranoid check
+ event.writeToParcel(parcel, 0);
+
+ // Read from parcel
+ parcel.setDataPosition(0);
+ ContentCaptureEvent clone = ContentCaptureEvent.CREATOR.createFromParcel(parcel);
+ assertThat(clone).isNotNull();
+ return clone;
+ } finally {
+ parcel.recycle();
+ }
+ }
+
+}
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
index 71612e6..34fdebf 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
@@ -155,5 +155,10 @@
void internalNotifyViewTextChanged(AutofillId id, CharSequence text) {
throw new UnsupportedOperationException("should not have been called");
}
+
+ @Override
+ public void internalNotifyViewHierarchyEvent(boolean started) {
+ throw new UnsupportedOperationException("should not have been called");
+ }
}
}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java
new file mode 100644
index 0000000..08ad62a
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/TemplateClassificationIntentFactoryTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.textclassifier;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Intent;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.google.android.textclassifier.AnnotatorModel;
+import com.google.android.textclassifier.RemoteActionTemplate;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TemplateClassificationIntentFactoryTest {
+
+ private static final String TEXT = "text";
+ private static final String TITLE = "Map";
+ private static final String ACTION = Intent.ACTION_VIEW;
+
+ @Mock
+ private IntentFactory mFallback;
+ private TemplateClassificationIntentFactory mTemplateClassificationIntentFactory;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mTemplateClassificationIntentFactory = new TemplateClassificationIntentFactory(
+ new TemplateIntentFactory(),
+ mFallback);
+ }
+
+ @Test
+ public void create_foreignText() {
+ RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate(
+ TITLE,
+ null,
+ ACTION,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ );
+
+ AnnotatorModel.ClassificationResult classificationResult =
+ new AnnotatorModel.ClassificationResult(
+ TextClassifier.TYPE_ADDRESS,
+ 1.0f,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ new RemoteActionTemplate[]{remoteActionTemplate});
+
+ List<TextClassifierImpl.LabeledIntent> intents =
+ mTemplateClassificationIntentFactory.create(
+ InstrumentationRegistry.getContext(),
+ TEXT,
+ /* foreignText */ true,
+ null,
+ classificationResult);
+
+ assertThat(intents).hasSize(2);
+ TextClassifierImpl.LabeledIntent labeledIntent = intents.get(0);
+ assertThat(labeledIntent.getTitle()).isEqualTo(TITLE);
+ Intent intent = labeledIntent.getIntent();
+ assertThat(intent.getAction()).isEqualTo(ACTION);
+ assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue();
+
+ labeledIntent = intents.get(1);
+ intent = labeledIntent.getIntent();
+ assertThat(intent.getAction()).isEqualTo(Intent.ACTION_TRANSLATE);
+ assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue();
+ }
+
+ @Test
+ public void create_notForeignText() {
+ RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate(
+ TITLE,
+ null,
+ ACTION,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ );
+
+ AnnotatorModel.ClassificationResult classificationResult =
+ new AnnotatorModel.ClassificationResult(
+ TextClassifier.TYPE_ADDRESS,
+ 1.0f,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ new RemoteActionTemplate[]{remoteActionTemplate});
+
+ List<TextClassifierImpl.LabeledIntent> intents =
+ mTemplateClassificationIntentFactory.create(
+ InstrumentationRegistry.getContext(),
+ TEXT,
+ /* foreignText */ false,
+ null,
+ classificationResult);
+
+ assertThat(intents).hasSize(1);
+ TextClassifierImpl.LabeledIntent labeledIntent = intents.get(0);
+ assertThat(labeledIntent.getTitle()).isEqualTo(TITLE);
+ Intent intent = labeledIntent.getIntent();
+ assertThat(intent.getAction()).isEqualTo(ACTION);
+ assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue();
+ }
+}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TemplateIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/TemplateIntentFactoryTest.java
index 0fcf359..0d364a3 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TemplateIntentFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TemplateIntentFactoryTest.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package android.view.textclassifier;
import static com.google.common.truth.Truth.assertThat;
@@ -21,18 +20,15 @@
import android.content.Intent;
import android.net.Uri;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.google.android.textclassifier.AnnotatorModel;
import com.google.android.textclassifier.NamedVariant;
import com.google.android.textclassifier.RemoteActionTemplate;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
@@ -62,14 +58,12 @@
};
private static final Integer REQUEST_CODE = 10;
- @Mock
- private IntentFactory mFallback;
private TemplateIntentFactory mTemplateIntentFactory;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mTemplateIntentFactory = new TemplateIntentFactory(mFallback);
+ mTemplateIntentFactory = new TemplateIntentFactory();
}
@Test
@@ -87,25 +81,9 @@
REQUEST_CODE
);
- AnnotatorModel.ClassificationResult classificationResult =
- new AnnotatorModel.ClassificationResult(
- TextClassifier.TYPE_ADDRESS,
- 1.0f,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- new RemoteActionTemplate[]{remoteActionTemplate});
- List<TextClassifierImpl.LabeledIntent> intents = mTemplateIntentFactory.create(
- InstrumentationRegistry.getContext(),
- TEXT,
- false,
- null,
- classificationResult);
+ List<TextClassifierImpl.LabeledIntent> intents =
+ mTemplateIntentFactory.create(new RemoteActionTemplate[]{remoteActionTemplate});
assertThat(intents).hasSize(1);
TextClassifierImpl.LabeledIntent labeledIntent = intents.get(0);
@@ -122,12 +100,11 @@
assertThat(
intent.getStringExtra(KEY_ONE)).isEqualTo(VALUE_ONE);
assertThat(intent.getIntExtra(KEY_TWO, 0)).isEqualTo(VALUE_TWO);
- assertThat(
- intent.getBooleanExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER, false)).isTrue();
+ assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue();
}
@Test
- public void create_pacakgeIsNotNull() {
+ public void create_packageIsNotNull() {
RemoteActionTemplate remoteActionTemplate = new RemoteActionTemplate(
TITLE,
DESCRIPTION,
@@ -141,25 +118,8 @@
REQUEST_CODE
);
- AnnotatorModel.ClassificationResult classificationResult =
- new AnnotatorModel.ClassificationResult(
- TextClassifier.TYPE_ADDRESS,
- 1.0f,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- new RemoteActionTemplate[]{remoteActionTemplate});
-
- List<TextClassifierImpl.LabeledIntent> intents = mTemplateIntentFactory.create(
- InstrumentationRegistry.getContext(),
- TEXT,
- false,
- null,
- classificationResult);
+ List<TextClassifierImpl.LabeledIntent> intents =
+ mTemplateIntentFactory.create(new RemoteActionTemplate[] {remoteActionTemplate});
assertThat(intents).hasSize(0);
}
@@ -179,25 +139,9 @@
null
);
- AnnotatorModel.ClassificationResult classificationResult =
- new AnnotatorModel.ClassificationResult(
- TextClassifier.TYPE_ADDRESS,
- 1.0f,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- new RemoteActionTemplate[]{remoteActionTemplate});
+ List<TextClassifierImpl.LabeledIntent> intents =
+ mTemplateIntentFactory.create(new RemoteActionTemplate[]{remoteActionTemplate});
- List<TextClassifierImpl.LabeledIntent> intents = mTemplateIntentFactory.create(
- InstrumentationRegistry.getContext(),
- TEXT,
- false,
- null,
- classificationResult);
assertThat(intents).hasSize(1);
TextClassifierImpl.LabeledIntent labeledIntent = intents.get(0);
@@ -212,7 +156,6 @@
assertThat(intent.getFlags()).isEqualTo(0);
assertThat(intent.getCategories()).isNull();
assertThat(intent.getPackage()).isNull();
- assertThat(
- intent.getBooleanExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER, false)).isTrue();
+ assertThat(intent.hasExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER)).isTrue();
}
}
diff --git a/core/tests/coretests/src/android/widget/EditorCursorTest.java b/core/tests/coretests/src/android/widget/EditorCursorTest.java
index e4f55df..585c601 100644
--- a/core/tests/coretests/src/android/widget/EditorCursorTest.java
+++ b/core/tests/coretests/src/android/widget/EditorCursorTest.java
@@ -16,11 +16,12 @@
package android.widget;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerOnLeft;
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerOnRight;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+
import static junit.framework.Assert.fail;
import static org.hamcrest.MatcherAssert.assertThat;
diff --git a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
index 483270e..f6e02bc 100644
--- a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
+++ b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java
@@ -16,15 +16,6 @@
package android.widget;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.Espresso.pressBack;
-import static android.support.test.espresso.action.ViewActions.clearText;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.action.ViewActions.replaceText;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static android.widget.espresso.DragHandleUtils.onHandleView;
import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem;
import static android.widget.espresso.FloatingToolbarEspressoUtils.clickFloatingToolbarItem;
@@ -37,43 +28,55 @@
import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.Espresso.pressBack;
+import static androidx.test.espresso.action.ViewActions.clearText;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.action.ViewActions.replaceText;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import android.content.res.TypedArray;
-import android.support.test.espresso.NoMatchingViewException;
-import android.support.test.espresso.ViewAssertion;
-import android.test.ActivityInstrumentationTestCase2;
import android.text.Selection;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.SuggestionSpan;
import android.text.style.TextAppearanceSpan;
-import android.view.View;
import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
import com.android.frameworks.coretests.R;
+import org.junit.Rule;
+import org.junit.Test;
+
/**
* SuggestionsPopupWindowTest tests.
*
* TODO: Add tests for when there are no suggestions
*/
-public class SuggestionsPopupWindowTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
+@SmallTest
+public class SuggestionsPopupWindowTest {
- public SuggestionsPopupWindowTest() {
- super(TextViewActivity.class);
- }
+ @Rule
+ public final ActivityTestRule<TextViewActivity> mActivityRule =
+ new ActivityTestRule<>(TextViewActivity.class);
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- getActivity();
+ private TextViewActivity getActivity() {
+ return mActivityRule.getActivity();
}
private void setSuggestionSpan(SuggestionSpan span, int start, int end) {
- final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+ final TextView textView = getActivity().findViewById(R.id.textview);
textView.post(
() -> {
final Spannable text = (Spannable) textView.getText();
@@ -83,7 +86,7 @@
getInstrumentation().waitForIdleSync();
}
- @SmallTest
+ @Test
public void testOnTextContextMenuItem() {
final String text = "abc def ghi";
@@ -94,14 +97,14 @@
new String[]{"DEF", "Def"}, SuggestionSpan.FLAG_AUTO_CORRECTION);
setSuggestionSpan(suggestionSpan, text.indexOf('d'), text.indexOf('f') + 1);
- final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+ final TextView textView = getActivity().findViewById(R.id.textview);
textView.post(() -> textView.onTextContextMenuItem(TextView.ID_REPLACE));
getInstrumentation().waitForIdleSync();
assertSuggestionsPopupIsDisplayed();
}
- @SmallTest
+ @Test
public void testSelectionActionMode() {
final String text = "abc def ghi";
@@ -123,7 +126,7 @@
assertSuggestionsPopupIsDisplayed();
}
- @SmallTest
+ @Test
public void testInsertionActionMode() {
final String text = "abc def ghi";
@@ -146,13 +149,13 @@
}
private void showSuggestionsPopup() {
- final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+ final TextView textView = getActivity().findViewById(R.id.textview);
textView.post(() -> textView.onTextContextMenuItem(TextView.ID_REPLACE));
getInstrumentation().waitForIdleSync();
assertSuggestionsPopupIsDisplayed();
}
- @SmallTest
+ @Test
public void testSuggestionItems() {
final String text = "abc def ghi";
@@ -190,7 +193,7 @@
onView(withId(R.id.textview)).check(matches(withText("abc ghi")));
}
- @SmallTest
+ @Test
public void testMisspelled() {
final String text = "abc def ghi";
@@ -217,7 +220,7 @@
// TODO: Check if add to dictionary dialog is displayed.
}
- @SmallTest
+ @Test
public void testEasyCorrect() {
final String text = "abc def ghi";
@@ -253,7 +256,7 @@
getActivity().getString(com.android.internal.R.string.delete));
}
- @SmallTest
+ @Test
public void testTextAppearanceInSuggestionsPopup() {
final String text = "abc def ghi";
@@ -302,53 +305,49 @@
assertSuggestionsPopupContainsItem(
getActivity().getString(com.android.internal.R.string.delete));
- onSuggestionsPopup().check(new ViewAssertion() {
- @Override
- public void check(View view, NoMatchingViewException e) {
- final ListView listView = (ListView) view.findViewById(
- com.android.internal.R.id.suggestionContainer);
- assertNotNull(listView);
- final int childNum = listView.getChildCount();
- assertEquals(singleWordCandidates.length + multiWordCandidates.length,
- childNum);
+ onSuggestionsPopup().check((view, e) -> {
+ final ListView listView = view.findViewById(
+ com.android.internal.R.id.suggestionContainer);
+ assertNotNull(listView);
+ final int childNum = listView.getChildCount();
+ assertEquals(singleWordCandidates.length + multiWordCandidates.length, childNum);
- for (int j = 0; j < childNum; j++) {
- final TextView suggestion = (TextView) listView.getChildAt(j);
- assertNotNull(suggestion);
- final Spanned spanned = (Spanned) suggestion.getText();
- assertNotNull(spanned);
+ for (int j = 0; j < childNum; j++) {
+ final TextView suggestion = (TextView) listView.getChildAt(j);
+ assertNotNull(suggestion);
+ final Spanned spanned = (Spanned) suggestion.getText();
+ assertNotNull(spanned);
- // Check that the suggestion item order is kept.
- final String expectedText;
- if (j < singleWordCandidates.length) {
- expectedText = "abc " + singleWordCandidates[j] + " ghi";
- } else {
- expectedText = multiWordCandidates[j - singleWordCandidates.length];
- }
- assertEquals(expectedText, spanned.toString());
-
- // Check that the text is highlighted with correct color and text size.
- final TextAppearanceSpan[] taSpan = spanned.getSpans(
- text.indexOf('d'), text.indexOf('f') + 1, TextAppearanceSpan.class);
- assertEquals(1, taSpan.length);
- TextPaint tp = new TextPaint();
- taSpan[0].updateDrawState(tp);
- assertEquals(expectedHighlightTextColor, tp.getColor());
- assertEquals(expectedHighlightTextSize, tp.getTextSize());
-
- // Check the correct part of the text is highlighted.
- final int expectedStart;
- final int expectedEnd;
- if (j < singleWordCandidates.length) {
- expectedStart = text.indexOf('d');
- expectedEnd = text.indexOf('f') + 1;
- } else {
- expectedStart = 0;
- expectedEnd = text.length();
- }
- assertEquals(expectedStart, spanned.getSpanStart(taSpan[0]));
- assertEquals(expectedEnd, spanned.getSpanEnd(taSpan[0]));
+ // Check that the suggestion item order is kept.
+ final String expectedText;
+ if (j < singleWordCandidates.length) {
+ expectedText = "abc " + singleWordCandidates[j] + " ghi";
+ } else {
+ expectedText = multiWordCandidates[j - singleWordCandidates.length];
}
+ assertEquals(expectedText, spanned.toString());
+
+ // Check that the text is highlighted with correct color and text size.
+ final TextAppearanceSpan[] taSpan = spanned.getSpans(
+ text.indexOf('d'), text.indexOf('f') + 1, TextAppearanceSpan.class);
+ assertEquals(1, taSpan.length);
+ TextPaint tp = new TextPaint();
+ taSpan[0].updateDrawState(tp);
+ assertEquals(expectedHighlightTextColor, tp.getColor());
+ assertEquals(expectedHighlightTextSize, tp.getTextSize(), 0f);
+
+ // Check the correct part of the text is highlighted.
+ final int expectedStart;
+ final int expectedEnd;
+ if (j < singleWordCandidates.length) {
+ expectedStart = text.indexOf('d');
+ expectedEnd = text.indexOf('f') + 1;
+ } else {
+ expectedStart = 0;
+ expectedEnd = text.length();
+ }
+ assertEquals(expectedStart, spanned.getSpanStart(taSpan[0]));
+ assertEquals(expectedEnd, spanned.getSpanEnd(taSpan[0]));
}
});
pressBack();
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
index 41fa08b..b411668 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
@@ -16,15 +16,6 @@
package android.widget;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.Espresso.pressBack;
-import static android.support.test.espresso.action.ViewActions.replaceText;
-import static android.support.test.espresso.action.ViewActions.typeText;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static android.widget.espresso.ContextMenuUtils.assertContextMenuContainsItemDisabled;
import static android.widget.espresso.ContextMenuUtils.assertContextMenuContainsItemEnabled;
import static android.widget.espresso.ContextMenuUtils.assertContextMenuIsNotDisplayed;
@@ -42,6 +33,15 @@
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
import static android.widget.espresso.TextViewAssertions.hasSelection;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.Espresso.pressBack;
+import static androidx.test.espresso.action.ViewActions.replaceText;
+import static androidx.test.espresso.action.ViewActions.typeText;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
import android.app.Activity;
import android.view.MotionEvent;
import android.view.textclassifier.TextClassificationManager;
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 9d93421..267a9c8 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -16,15 +16,6 @@
package android.widget;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.action.ViewActions.longClick;
-import static android.support.test.espresso.action.ViewActions.pressKey;
-import static android.support.test.espresso.action.ViewActions.replaceText;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static android.widget.espresso.CustomViewActions.longPressAtRelativeCoordinates;
import static android.widget.espresso.DragHandleUtils.onHandleView;
import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem;
@@ -44,6 +35,16 @@
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
import static android.widget.espresso.TextViewAssertions.hasSelection;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.action.ViewActions.longClick;
+import static androidx.test.espresso.action.ViewActions.pressKey;
+import static androidx.test.espresso.action.ViewActions.replaceText;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -60,7 +61,6 @@
import android.app.Instrumentation;
import android.content.ClipData;
import android.content.ClipboardManager;
-import android.support.test.espresso.action.EspressoKey;
import android.support.test.uiautomator.UiDevice;
import android.text.InputType;
import android.text.Selection;
@@ -79,6 +79,7 @@
import android.widget.espresso.CustomViewActions.RelativeCoordinatesProvider;
import androidx.test.InstrumentationRegistry;
+import androidx.test.espresso.action.EspressoKey;
import androidx.test.filters.MediumTest;
import androidx.test.filters.Suppress;
import androidx.test.rule.ActivityTestRule;
diff --git a/core/tests/coretests/src/android/widget/espresso/ContextMenuUtils.java b/core/tests/coretests/src/android/widget/espresso/ContextMenuUtils.java
index 02ee9be..0f8faa8 100644
--- a/core/tests/coretests/src/android/widget/espresso/ContextMenuUtils.java
+++ b/core/tests/coretests/src/android/widget/espresso/ContextMenuUtils.java
@@ -16,28 +16,29 @@
package android.widget.espresso;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
-import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static android.support.test.espresso.matcher.ViewMatchers.hasFocus;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
-import static android.support.test.espresso.matcher.ViewMatchers.isEnabled;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
+import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static androidx.test.espresso.matcher.ViewMatchers.hasFocus;
+import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
+import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.not;
-import android.support.test.espresso.NoMatchingRootException;
-import android.support.test.espresso.NoMatchingViewException;
-import android.support.test.espresso.ViewInteraction;
-import android.support.test.espresso.matcher.ViewMatchers;
import android.view.View;
import android.widget.MenuPopupWindow.MenuDropDownListView;
+import androidx.test.espresso.NoMatchingRootException;
+import androidx.test.espresso.NoMatchingViewException;
+import androidx.test.espresso.ViewInteraction;
+import androidx.test.espresso.matcher.ViewMatchers;
+
import com.android.internal.view.menu.ListMenuItemView;
import org.hamcrest.Description;
diff --git a/core/tests/coretests/src/android/widget/espresso/CustomViewActions.java b/core/tests/coretests/src/android/widget/espresso/CustomViewActions.java
index daf9e78..217553e 100644
--- a/core/tests/coretests/src/android/widget/espresso/CustomViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/CustomViewActions.java
@@ -16,15 +16,15 @@
package android.widget.espresso;
-import static android.support.test.espresso.action.ViewActions.actionWithAssertions;
+import static androidx.test.espresso.action.ViewActions.actionWithAssertions;
import android.view.View;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.action.CoordinatesProvider;
-import android.support.test.espresso.action.GeneralClickAction;
-import android.support.test.espresso.action.Press;
-import android.support.test.espresso.action.Tap;
+import androidx.test.espresso.ViewAction;
+import androidx.test.espresso.action.CoordinatesProvider;
+import androidx.test.espresso.action.GeneralClickAction;
+import androidx.test.espresso.action.Press;
+import androidx.test.espresso.action.Tap;
import com.android.internal.util.Preconditions;
diff --git a/core/tests/coretests/src/android/widget/espresso/DragAction.java b/core/tests/coretests/src/android/widget/espresso/DragAction.java
index b2c8e38..afdc4d3 100644
--- a/core/tests/coretests/src/android/widget/espresso/DragAction.java
+++ b/core/tests/coretests/src/android/widget/espresso/DragAction.java
@@ -16,27 +16,30 @@
package android.widget.espresso;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
+
import static com.android.internal.util.Preconditions.checkNotNull;
+
import static org.hamcrest.Matchers.allOf;
+
import android.annotation.Nullable;
import android.os.SystemClock;
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.PerformException;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.action.CoordinatesProvider;
-import android.support.test.espresso.action.MotionEvents;
-import android.support.test.espresso.action.PrecisionDescriber;
-import android.support.test.espresso.action.Swiper;
-import android.support.test.espresso.util.HumanReadables;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
-import org.hamcrest.Matcher;
+import androidx.test.espresso.PerformException;
+import androidx.test.espresso.UiController;
+import androidx.test.espresso.ViewAction;
+import androidx.test.espresso.action.CoordinatesProvider;
+import androidx.test.espresso.action.MotionEvents;
+import androidx.test.espresso.action.PrecisionDescriber;
+import androidx.test.espresso.action.Swiper;
+import androidx.test.espresso.util.HumanReadables;
+import org.hamcrest.Matcher;
/**
* Drags on a View using touch events.<br>
diff --git a/core/tests/coretests/src/android/widget/espresso/DragHandleUtils.java b/core/tests/coretests/src/android/widget/espresso/DragHandleUtils.java
index 1693e54..1b849b5 100644
--- a/core/tests/coretests/src/android/widget/espresso/DragHandleUtils.java
+++ b/core/tests/coretests/src/android/widget/espresso/DragHandleUtils.java
@@ -16,22 +16,23 @@
package android.widget.espresso;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.RootMatchers.isPlatformPopup;
-import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
-import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.RootMatchers.isPlatformPopup;
+import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
+import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.Matchers.allOf;
-import android.support.test.espresso.NoMatchingRootException;
-import android.support.test.espresso.NoMatchingViewException;
-import android.support.test.espresso.ViewInteraction;
import android.widget.Editor;
+import androidx.test.espresso.NoMatchingRootException;
+import androidx.test.espresso.NoMatchingViewException;
+import androidx.test.espresso.ViewInteraction;
+
public final class DragHandleUtils {
private DragHandleUtils() {}
diff --git a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
index 0355f82..d45d4b0 100644
--- a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
+++ b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
@@ -16,30 +16,31 @@
package android.widget.espresso;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.RootMatchers.isPlatformPopup;
-import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
-import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.RootMatchers.isPlatformPopup;
+import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
+import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
-import android.support.test.espresso.NoMatchingRootException;
-import android.support.test.espresso.NoMatchingViewException;
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.ViewInteraction;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import androidx.test.espresso.NoMatchingRootException;
+import androidx.test.espresso.NoMatchingViewException;
+import androidx.test.espresso.UiController;
+import androidx.test.espresso.ViewAction;
+import androidx.test.espresso.ViewInteraction;
+
import com.android.internal.widget.FloatingToolbar;
import org.hamcrest.Description;
diff --git a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
index b50d6f4..f56af5a 100644
--- a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
+++ b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
@@ -16,18 +16,19 @@
package android.widget.espresso;
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.action.CoordinatesProvider;
-import android.support.test.espresso.action.MotionEvents;
-import android.support.test.espresso.action.MotionEvents.DownResultHolder;
-import android.support.test.espresso.action.Press;
-import android.support.test.espresso.action.Tapper;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import androidx.test.espresso.UiController;
+import androidx.test.espresso.ViewAction;
+import androidx.test.espresso.action.CoordinatesProvider;
+import androidx.test.espresso.action.MotionEvents;
+import androidx.test.espresso.action.MotionEvents.DownResultHolder;
+import androidx.test.espresso.action.Press;
+import androidx.test.espresso.action.Tapper;
+
import org.hamcrest.Matcher;
/**
diff --git a/core/tests/coretests/src/android/widget/espresso/MouseUiController.java b/core/tests/coretests/src/android/widget/espresso/MouseUiController.java
index 022be76..abee736 100644
--- a/core/tests/coretests/src/android/widget/espresso/MouseUiController.java
+++ b/core/tests/coretests/src/android/widget/espresso/MouseUiController.java
@@ -18,16 +18,19 @@
import static com.android.internal.util.Preconditions.checkNotNull;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
import android.annotation.IntDef;
-import android.support.test.espresso.InjectEventSecurityException;
-import android.support.test.espresso.UiController;
+import android.os.SystemClock;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import androidx.test.espresso.InjectEventSecurityException;
+import androidx.test.espresso.UiController;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Iterator;
+
/**
* Class to wrap an UiController to overwrite source of motion events to SOURCE_MOUSE.
* Note that this doesn't change the tool type.
@@ -71,6 +74,32 @@
return mUiController.injectMotionEvent(event);
}
+ /**
+ * Copied from latest {@link androidx.test.espresso.UiController}, since current
+ * {@link androidx.test.espresso.UiController#injectMotionEventSequence(Iterable)} seems not a
+ * default method.
+ */
+ @Override
+ public boolean injectMotionEventSequence(Iterable<MotionEvent> events)
+ throws InjectEventSecurityException {
+ android.util.Log.w(
+ "UIC",
+ "Using default injectMotionEventSeq() - this may not inject a sequence properly. "
+ + "If wrapping UIController please override this method and delegate.");
+ Iterator<MotionEvent> mei = events.iterator();
+ boolean success = true;
+ while (mei.hasNext()) {
+ MotionEvent me = mei.next();
+ if (me.getEventTime() - SystemClock.uptimeMillis() > 10) {
+ // Because the loopMainThreadForAtLeast is overkill for waiting, intentially only
+ // call it with a smaller amount of milliseconds as best effort
+ loopMainThreadForAtLeast(10);
+ }
+ success &= injectMotionEvent(me);
+ }
+ return success;
+ }
+
@Override
public boolean injectString(String str) throws InjectEventSecurityException {
return mUiController.injectString(str);
diff --git a/core/tests/coretests/src/android/widget/espresso/SuggestionsPopupwindowUtils.java b/core/tests/coretests/src/android/widget/espresso/SuggestionsPopupwindowUtils.java
index b5a96ae..32c02403 100644
--- a/core/tests/coretests/src/android/widget/espresso/SuggestionsPopupwindowUtils.java
+++ b/core/tests/coretests/src/android/widget/espresso/SuggestionsPopupwindowUtils.java
@@ -16,36 +16,40 @@
package android.widget.espresso;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
-import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
+import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.view.View;
+
+import androidx.test.espresso.NoMatchingRootException;
+import androidx.test.espresso.NoMatchingViewException;
+import androidx.test.espresso.UiController;
+import androidx.test.espresso.ViewAction;
+import androidx.test.espresso.ViewInteraction;
+import androidx.test.espresso.action.GeneralLocation;
+import androidx.test.espresso.action.Press;
+import androidx.test.espresso.action.Tap;
import org.hamcrest.Matcher;
-import android.support.test.espresso.NoMatchingRootException;
-import android.support.test.espresso.NoMatchingViewException;
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.ViewInteraction;
-import android.support.test.espresso.action.GeneralLocation;
-import android.support.test.espresso.action.Press;
-import android.support.test.espresso.action.Tap;
-import android.view.View;
-
public final class SuggestionsPopupwindowUtils {
private static final int id = com.android.internal.R.id.suggestionWindowContainer;
private SuggestionsPopupwindowUtils() {};
public static ViewInteraction onSuggestionsPopup() {
+ getInstrumentation().waitForIdleSync();
return onView(withId(id)).inRoot(withDecorView(hasDescendant(withId(id))));
}
private static ViewInteraction onSuggestionsPopupItem(Matcher<View> matcher) {
+ getInstrumentation().waitForIdleSync();
return onView(matcher).inRoot(withDecorView(hasDescendant(withId(id))));
}
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
index b4c547e..83ce67b 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
@@ -16,16 +16,9 @@
package android.widget.espresso;
-import static android.support.test.espresso.action.ViewActions.actionWithAssertions;
+import static androidx.test.espresso.action.ViewActions.actionWithAssertions;
import android.graphics.Rect;
-import android.support.test.espresso.PerformException;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.action.CoordinatesProvider;
-import android.support.test.espresso.action.GeneralLocation;
-import android.support.test.espresso.action.Press;
-import android.support.test.espresso.action.Tap;
-import android.support.test.espresso.util.HumanReadables;
import android.text.Layout;
import android.view.MotionEvent;
import android.view.View;
@@ -33,6 +26,14 @@
import android.widget.Editor.HandleView;
import android.widget.TextView;
+import androidx.test.espresso.PerformException;
+import androidx.test.espresso.ViewAction;
+import androidx.test.espresso.action.CoordinatesProvider;
+import androidx.test.espresso.action.GeneralLocation;
+import androidx.test.espresso.action.Press;
+import androidx.test.espresso.action.Tap;
+import androidx.test.espresso.util.HumanReadables;
+
/**
* A collection of actions on a {@link android.widget.TextView}.
*/
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java b/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
index 5ed69e0..d638da5 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
@@ -16,7 +16,7 @@
package android.widget.espresso;
-import static android.support.test.espresso.matcher.ViewMatchers.assertThat;
+import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
import static com.android.internal.util.Preconditions.checkNotNull;
@@ -26,14 +26,15 @@
import android.annotation.IntDef;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.support.test.espresso.NoMatchingViewException;
-import android.support.test.espresso.ViewAssertion;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
+import androidx.test.espresso.NoMatchingViewException;
+import androidx.test.espresso.ViewAssertion;
+
import junit.framework.AssertionFailedError;
import org.hamcrest.Matcher;
diff --git a/core/tests/coretests/src/android/widget/espresso/ViewClickAction.java b/core/tests/coretests/src/android/widget/espresso/ViewClickAction.java
index 8bce1b0..1e6447d 100644
--- a/core/tests/coretests/src/android/widget/espresso/ViewClickAction.java
+++ b/core/tests/coretests/src/android/widget/espresso/ViewClickAction.java
@@ -16,17 +16,18 @@
package android.widget.espresso;
-import org.hamcrest.Matcher;
-
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.support.test.espresso.action.CoordinatesProvider;
-import android.support.test.espresso.action.GeneralClickAction;
-import android.support.test.espresso.action.PrecisionDescriber;
-import android.support.test.espresso.action.Tapper;
import android.view.View;
import android.view.ViewConfiguration;
+import androidx.test.espresso.UiController;
+import androidx.test.espresso.ViewAction;
+import androidx.test.espresso.action.CoordinatesProvider;
+import androidx.test.espresso.action.GeneralClickAction;
+import androidx.test.espresso.action.PrecisionDescriber;
+import androidx.test.espresso.action.Tapper;
+
+import org.hamcrest.Matcher;
+
public final class ViewClickAction implements ViewAction {
private final GeneralClickAction mGeneralClickAction;
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 6b9e69c..3d59835a 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -27,7 +27,9 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -43,6 +45,7 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.metrics.LogMaker;
import android.net.Uri;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -51,11 +54,14 @@
import com.android.internal.R;
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.util.ArrayList;
@@ -66,6 +72,11 @@
*/
@RunWith(AndroidJUnit4.class)
public class ChooserActivityTest {
+
+ private static final int CONTENT_PREVIEW_IMAGE = 1;
+ private static final int CONTENT_PREVIEW_FILE = 2;
+ private static final int CONTENT_PREVIEW_TEXT = 3;
+
@Rule
public ActivityTestRule<ChooserWrapperActivity> mActivityRule =
new ActivityTestRule<>(ChooserWrapperActivity.class, false,
@@ -402,16 +413,15 @@
createResolvedComponentsForTestWithOtherProfile(1);
when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
- Mockito.anyBoolean(),
- Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+ Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
final ChooserWrapperActivity activity = mActivityRule
.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
onView(withId(R.id.copy_button)).perform(click());
-
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(
Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboard.getPrimaryClip();
@@ -421,6 +431,170 @@
assertThat("text/plain", is(clipDescription.getMimeType(0)));
}
+ @Test
+ public void oneVisibleImagePreview() throws InterruptedException {
+ Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
+ + com.android.frameworks.coretests.R.drawable.test320x240);
+
+ ArrayList<Uri> uris = new ArrayList<>();
+ uris.add(uri);
+
+ Intent sendIntent = createSendImageIntentWithPreview(uris);
+ sOverrides.previewThumbnail = createBitmap();
+
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ waitForIdle();
+ onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
+ onView(withId(R.id.content_preview_image_2_large)).check(matches(not(isDisplayed())));
+ onView(withId(R.id.content_preview_image_2_small)).check(matches(not(isDisplayed())));
+ onView(withId(R.id.content_preview_image_3_small)).check(matches(not(isDisplayed())));
+ }
+
+ @Test
+ public void twoVisibleImagePreview() throws InterruptedException {
+ Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
+ + com.android.frameworks.coretests.R.drawable.test320x240);
+
+ ArrayList<Uri> uris = new ArrayList<>();
+ uris.add(uri);
+ uris.add(uri);
+
+ Intent sendIntent = createSendImageIntentWithPreview(uris);
+ sOverrides.previewThumbnail = createBitmap();
+
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ waitForIdle();
+ onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
+ onView(withId(R.id.content_preview_image_2_large)).check(matches(isDisplayed()));
+ onView(withId(R.id.content_preview_image_2_small)).check(matches(not(isDisplayed())));
+ onView(withId(R.id.content_preview_image_3_small)).check(matches(not(isDisplayed())));
+ }
+
+ @Test
+ public void threeOrMoreVisibleImagePreview() throws InterruptedException {
+ Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
+ + com.android.frameworks.coretests.R.drawable.test320x240);
+
+ ArrayList<Uri> uris = new ArrayList<>();
+ uris.add(uri);
+ uris.add(uri);
+ uris.add(uri);
+ uris.add(uri);
+ uris.add(uri);
+
+ Intent sendIntent = createSendImageIntentWithPreview(uris);
+ sOverrides.previewThumbnail = createBitmap();
+
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ waitForIdle();
+ onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed()));
+ onView(withId(R.id.content_preview_image_2_large)).check(matches(not(isDisplayed())));
+ onView(withId(R.id.content_preview_image_2_small)).check(matches(isDisplayed()));
+ onView(withId(R.id.content_preview_image_3_small)).check(matches(isDisplayed()));
+ }
+
+ @Test
+ public void testOnCreateLogging() {
+ Intent sendIntent = createSendTextIntent();
+ sendIntent.setType("TestType");
+
+ MetricsLogger mockLogger = sOverrides.metricsLogger;
+ ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test"));
+ waitForIdle();
+ verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
+ assertThat(logMakerCaptor.getAllValues().get(0).getCategory(),
+ is(MetricsProto.MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN));
+ assertThat(logMakerCaptor
+ .getAllValues().get(0)
+ .getTaggedData(MetricsProto.MetricsEvent.FIELD_TIME_TO_APP_TARGETS),
+ is(notNullValue()));
+ assertThat(logMakerCaptor
+ .getAllValues().get(0)
+ .getTaggedData(MetricsProto.MetricsEvent.FIELD_SHARESHEET_MIMETYPE),
+ is("TestType"));
+ }
+
+ @Test
+ public void testEmptyPreviewLogging() {
+ Intent sendIntent = createSendTextIntentWithPreview(null, null);
+
+ MetricsLogger mockLogger = sOverrides.metricsLogger;
+ ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, "empty preview logger test"));
+ waitForIdle();
+ verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
+ // First invocation is from onCreate
+ assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
+ is(MetricsProto.MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
+ assertThat(logMakerCaptor.getAllValues().get(1).getSubtype(),
+ is(CONTENT_PREVIEW_TEXT));
+ }
+
+ @Test
+ public void testTitlePreviewLogging() {
+ Intent sendIntent = createSendTextIntentWithPreview("TestTitle", null);
+
+ MetricsLogger mockLogger = sOverrides.metricsLogger;
+ ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ waitForIdle();
+ verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
+ // First invocation is from onCreate
+ assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
+ is(MetricsProto.MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
+ assertThat(logMakerCaptor.getAllValues().get(1).getSubtype(),
+ is(CONTENT_PREVIEW_TEXT));
+ }
+
+ @Test
+ public void testImagePreviewLogging() {
+ Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
+ + com.android.frameworks.coretests.R.drawable.test320x240);
+
+ ArrayList<Uri> uris = new ArrayList<>();
+ uris.add(uri);
+
+ Intent sendIntent = createSendImageIntentWithPreview(uris);
+ sOverrides.previewThumbnail = createBitmap();
+
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+
+ MetricsLogger mockLogger = sOverrides.metricsLogger;
+ ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ waitForIdle();
+ verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
+ // First invocation is from onCreate
+ assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
+ is(MetricsProto.MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
+ assertThat(logMakerCaptor.getAllValues().get(1).getSubtype(),
+ is(CONTENT_PREVIEW_IMAGE));
+ assertThat(logMakerCaptor.getAllValues().get(2).getCategory(),
+ is(MetricsProto.MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
+ assertThat(logMakerCaptor.getAllValues().get(2).getSubtype(),
+ is(CONTENT_PREVIEW_IMAGE));
+ }
+
private Intent createSendTextIntent() {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
@@ -441,6 +615,20 @@
return sendIntent;
}
+ private Intent createSendImageIntentWithPreview(ArrayList<Uri> uris) {
+ Intent sendIntent = new Intent();
+
+ if (uris.size() > 1) {
+ sendIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
+ sendIntent.putExtra(Intent.EXTRA_STREAM, uris);
+ } else {
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
+ }
+
+ return sendIntent;
+ }
+
private Intent createViewTextIntent() {
Intent viewIntent = new Intent();
viewIntent.setAction(Intent.ACTION_VIEW);
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index 637d2ea..f60467b 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -25,6 +25,8 @@
import android.net.Uri;
import android.util.Size;
+import com.android.internal.logging.MetricsLogger;
+
import java.util.function.Function;
public class ChooserWrapperActivity extends ChooserActivity {
@@ -85,6 +87,20 @@
return super.loadThumbnail(uri, size);
}
+ @Override
+ protected boolean isImageType(String mimeType) {
+ if (sOverrides.previewThumbnail != null) {
+ return true;
+ }
+
+ return super.isImageType(mimeType);
+ }
+
+ @Override
+ protected MetricsLogger getMetricsLogger() {
+ return sOverrides.metricsLogger;
+ }
+
/**
* We cannot directly mock the activity created since instrumentation creates it.
* <p>
@@ -97,6 +113,7 @@
public ResolverListController resolverListController;
public Boolean isVoiceInteraction;
public Bitmap previewThumbnail;
+ public MetricsLogger metricsLogger;
public void reset() {
onSafelyStartCallback = null;
@@ -104,6 +121,7 @@
createPackageManager = null;
previewThumbnail = null;
resolverListController = mock(ResolverListController.class);
+ metricsLogger = mock(MetricsLogger.class);
}
}
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index fe2fb85..7430c7a 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -16,12 +16,12 @@
package com.android.internal.app;
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isEnabled;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.android.internal.app.ResolverWrapperActivity.sOverrides;
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
index 3ddd8aa..64b7c2cc 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
@@ -22,8 +22,9 @@
import android.os.Process;
import android.os.SystemClock;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
import com.android.internal.os.KernelCpuThreadReader.ProcessCpuUsage;
import com.android.internal.os.KernelCpuThreadReader.ThreadCpuUsage;
diff --git a/core/tests/coretests/src/com/android/internal/statusbar/NotificationVisibilityTest.java b/core/tests/coretests/src/com/android/internal/statusbar/NotificationVisibilityTest.java
index b740ecc..22432a8 100644
--- a/core/tests/coretests/src/com/android/internal/statusbar/NotificationVisibilityTest.java
+++ b/core/tests/coretests/src/com/android/internal/statusbar/NotificationVisibilityTest.java
@@ -19,8 +19,8 @@
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
diff --git a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
index 28a8afe..0a729a9 100644
--- a/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
+++ b/core/tests/hdmitests/src/android/hardware/hdmi/HdmiAudioSystemClientTest.java
@@ -181,6 +181,11 @@
}
@Override
+ public void sendVolumeKeyEvent(
+ final int deviceType, final int keyCode, final boolean isPressed) {
+ }
+
+ @Override
public void oneTouchPlay(final IHdmiControlCallback callback) {
}
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 035ee10..bb47658 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -58,6 +58,14 @@
}
prebuilt_etc {
+ name: "privapp_whitelist_com.android.dialer",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.dialer.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
name: "privapp_whitelist_com.android.launcher3",
product_specific: true,
sub_dir: "permissions",
diff --git a/data/etc/com.android.dialer.xml b/data/etc/com.android.dialer.xml
new file mode 100644
index 0000000..ccdb21f
--- /dev/null
+++ b/data/etc/com.android.dialer.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.dialer">
+ <permission name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"/>
+ <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+ <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+ <permission name="android.permission.MODIFY_PHONE_STATE"/>
+ <permission name="android.permission.STATUS_BAR"/>
+ <permission name="android.permission.STOP_APP_SWITCHES"/>
+ <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+ <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index bcac5fd..6770ae1 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -22,6 +22,7 @@
<permissions>
<privapp-permissions package="android.ext.services">
<permission name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
+ <permission name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
</privapp-permissions>
<privapp-permissions package="com.android.apps.tag">
@@ -48,17 +49,6 @@
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
</privapp-permissions>
- <privapp-permissions package="com.android.dialer">
- <permission name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"/>
- <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
- <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.STATUS_BAR"/>
- <permission name="android.permission.STOP_APP_SWITCHES"/>
- <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
- <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.emergency">
<!-- Required to place emergency calls from emergency info screen. -->
<permission name="android.permission.CALL_PRIVILEGED"/>
@@ -114,16 +104,6 @@
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
</privapp-permissions>
- <privapp-permissions package="com.android.omadm.service">
- <permission name="android.permission.CHANGE_CONFIGURATION"/>
- <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
- <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
- <permission name="android.permission.WRITE_APN_SETTINGS"/>
- <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.packageinstaller">
<permission name="android.permission.DELETE_PACKAGES"/>
<permission name="android.permission.INSTALL_PACKAGES"/>
@@ -300,6 +280,7 @@
<permission name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/>
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<permission name="android.permission.MOVE_PACKAGE"/>
+ <permission name="android.permission.OBSERVE_APP_USAGE"/>
<permission name="android.permission.PACKAGE_USAGE_STATS" />
<permission name="android.permission.POWER_SAVER" />
<permission name="android.permission.READ_FRAME_BUFFER"/>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 080c5d5..18f0cae 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -25,6 +25,7 @@
import android.annotation.WorkerThread;
import android.content.res.ResourcesImpl;
import android.hardware.HardwareBuffer;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.StrictMode;
@@ -77,7 +78,7 @@
*/
private boolean mRequestPremultiplied;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769491)
private byte[] mNinePatchChunk; // may be null
@UnsupportedAppUsage
private NinePatch.InsetStruct mNinePatchInsets; // may be null
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index 229923c..5d8ba93 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -36,7 +36,10 @@
* A family of typefaces with different styles.
*
* @hide
+ *
+ * @deprecated Use {@link android.graphics.fonts.FontFamily} instead.
*/
+@Deprecated
public class FontFamily {
private static String TAG = "FontFamily";
@@ -51,20 +54,28 @@
/**
* @hide
+ *
+ * This cannot be deleted because it's in use by AndroidX.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768928)
public long mNativePtr;
// Points native font family builder. Must be zero after freezing this family.
private long mBuilderPtr;
- @UnsupportedAppUsage
+ /**
+ * This cannot be deleted because it's in use by AndroidX.
+ */
+ @UnsupportedAppUsage(trackingBug = 123768928)
public FontFamily() {
mBuilderPtr = nInitBuilder(null, 0);
mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr);
}
- @UnsupportedAppUsage
+ /**
+ * This cannot be deleted because it's in use by AndroidX.
+ */
+ @UnsupportedAppUsage(trackingBug = 123768928)
public FontFamily(@Nullable String[] langs, int variant) {
final String langsString;
if (langs == null || langs.length == 0) {
@@ -83,8 +94,10 @@
*
* @return boolean returns false if some error happens in native code, e.g. broken font file is
* passed, etc.
+ *
+ * This cannot be deleted because it's in use by AndroidX.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768928)
public boolean freeze() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen");
@@ -98,7 +111,10 @@
return mNativePtr != 0;
}
- @UnsupportedAppUsage
+ /**
+ * This cannot be deleted because it's in use by AndroidX.
+ */
+ @UnsupportedAppUsage(trackingBug = 123768928)
public void abortCreation() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen or abandoned");
@@ -107,6 +123,10 @@
mBuilderPtr = 0;
}
+ /**
+ * This cannot be deleted because it's in use by AndroidX.
+ */
+ @UnsupportedAppUsage(trackingBug = 123768928)
public boolean addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight,
int italic) {
if (mBuilderPtr == 0) {
@@ -128,7 +148,10 @@
}
}
- @UnsupportedAppUsage
+ /**
+ * This cannot be deleted because it's in use by AndroidX.
+ */
+ @UnsupportedAppUsage(trackingBug = 123768928)
public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes,
int weight, int italic) {
if (mBuilderPtr == 0) {
@@ -153,8 +176,10 @@
* @param isItalic Whether this font is italic. If the weight is set to 0, this will be resolved
* using the OS/2 table in the font.
* @return
+ *
+ * This cannot be deleted because it's in use by AndroidX.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768928)
public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie,
boolean isAsset, int ttcIndex, int weight, int isItalic,
FontVariationAxis[] axes) {
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index cb1f69c..7c9529b 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -92,7 +92,13 @@
/** The NORMAL style of the default monospace typeface. */
public static final Typeface MONOSPACE;
- @UnsupportedAppUsage
+ /**
+ * The default {@link Typeface}s for different text styles.
+ * Call {@link #defaultFromStyle(int)} to get the default typeface for the given text style.
+ * It shouldn't be changed for app wide typeface settings. Please use theme and font XML for
+ * the same purpose.
+ */
+ @UnsupportedAppUsage(trackingBug = 123769446)
static Typeface[] sDefaults;
/**
@@ -125,7 +131,11 @@
static final Map<String, Typeface> sSystemFontMap;
// We cannot support sSystemFallbackMap since we will migrate to public FontFamily API.
- @UnsupportedAppUsage
+ /**
+ * @deprecated Use {@link android.graphics.fonts.FontFamily} instead.
+ */
+ @UnsupportedAppUsage(trackingBug = 123768928)
+ @Deprecated
static final Map<String, android.graphics.FontFamily[]> sSystemFallbackMap =
Collections.emptyMap();
@@ -993,7 +1003,7 @@
* @deprecated
*/
@Deprecated
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768928)
private static Typeface createFromFamilies(android.graphics.FontFamily[] families) {
long[] ptrArray = new long[families.length];
for (int i = 0; i < families.length; i++) {
@@ -1019,9 +1029,11 @@
/**
* This method is used by supportlib-v27.
- * TODO: Remove private API use in supportlib: http://b/72665240
+ *
+ * @deprecated Use {@link android.graphics.fonts.FontFamily} instead.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768395)
+ @Deprecated
private static Typeface createFromFamiliesWithDefault(
android.graphics.FontFamily[] families, int weight, int italic) {
return createFromFamiliesWithDefault(families, DEFAULT_FAMILY, weight, italic);
@@ -1039,8 +1051,11 @@
* the first family's font is used. If the first family has multiple fonts, the
* closest to the regular weight and upright font is used.
* @param families array of font families
+ *
+ * @deprecated Use {@link android.graphics.fonts.FontFamily} instead.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768928)
+ @Deprecated
private static Typeface createFromFamiliesWithDefault(android.graphics.FontFamily[] families,
String fallbackName, int weight, int italic) {
android.graphics.fonts.FontFamily[] fallback = SystemFonts.getSystemFallback(fallbackName);
diff --git a/libs/androidfw/DisplayEventDispatcher.cpp b/libs/androidfw/DisplayEventDispatcher.cpp
index 7708e43..3b9a348 100644
--- a/libs/androidfw/DisplayEventDispatcher.cpp
+++ b/libs/androidfw/DisplayEventDispatcher.cpp
@@ -68,7 +68,7 @@
// Drain all pending events.
nsecs_t vsyncTimestamp;
- int32_t vsyncDisplayId;
+ PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "",
@@ -101,10 +101,11 @@
// Drain all pending events, keep the last vsync.
nsecs_t vsyncTimestamp;
- int32_t vsyncDisplayId;
+ PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
- ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d",
+ ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%"
+ ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%d",
this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);
mWaitingForVsync = false;
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
@@ -114,7 +115,7 @@
}
bool DisplayEventDispatcher::processPendingEvents(
- nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) {
+ nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount) {
bool gotVsync = false;
DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
ssize_t n;
@@ -128,11 +129,11 @@
// ones. That's fine, we only care about the most recent.
gotVsync = true;
*outTimestamp = ev.header.timestamp;
- *outId = ev.header.id;
+ *outDisplayId = ev.header.displayId;
*outCount = ev.vsync.count;
break;
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
- dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected);
+ dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected);
break;
default:
ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 70ce9bc..bdd4706 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -633,6 +633,7 @@
overlayable_info.actor = actor;
overlayable_info.policy_flags = policy_header->policy_flags;
loaded_package->overlayable_infos_.push_back(std::make_pair(overlayable_info, ids));
+ loaded_package->defines_overlayable_ = true;
break;
}
diff --git a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
index bf35aa3..d2addba 100644
--- a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
+++ b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
@@ -37,10 +37,12 @@
DisplayEventReceiver mReceiver;
bool mWaitingForVsync;
- virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) = 0;
- virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) = 0;
+ virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) = 0;
+ virtual void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId,
+ bool connected) = 0;
virtual int handleEvent(int receiveFd, int events, void* data);
- bool processPendingEvents(nsecs_t* outTimestamp, int32_t* id, uint32_t* outCount);
+ bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
+ uint32_t* outCount);
};
}
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index be62f30..b5f4006 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -223,7 +223,7 @@
}
}
- // Retrieve the overlayable properties of the specified resource. If the resource is not
+ // Retrieves the overlayable properties of the specified resource. If the resource is not
// overlayable, this will return a null pointer.
const OverlayableInfo* GetOverlayableInfo(uint32_t resid) const {
for (const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>& overlayable_info_ids
@@ -235,6 +235,13 @@
return nullptr;
}
+ // Retrieves whether or not the package defines overlayable resources.
+ // TODO(123905379): Remove this when the enforcement of overlayable is turned on for all APK and
+ // not just those that defined overlayable resources.
+ bool DefinesOverlayable() const {
+ return defines_overlayable_;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(LoadedPackage);
@@ -248,6 +255,7 @@
bool dynamic_ = false;
bool system_ = false;
bool overlay_ = false;
+ bool defines_overlayable_ = false;
ByteBucketArray<TypeSpecPtr> type_specs_;
ByteBucketArray<uint32_t> resource_ids_;
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index 4c67513..cf5d7ce 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -55,9 +55,12 @@
return sDummyDisplay;
}
+ const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
+ LOG_ALWAYS_FATAL_IF(token == nullptr,
+ "Failed to get display info because internal display is disconnected");
+
DisplayInfo displayInfo;
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
- status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &displayInfo);
+ status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo);
LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
return displayInfo;
}
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 2a48837..76c56609 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -164,14 +164,15 @@
* with reading incorrect data from EGLImage backed SkImage (likely a driver bug).
*/
sk_sp<SkSurface> tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(),
- SkBudgeted::kYes, bitmap->info());
+ SkBudgeted::kYes, bitmap->info(), 0,
+ kTopLeft_GrSurfaceOrigin, nullptr);
// if we can't generate a GPU surface that matches the destination bitmap (e.g. 565) then we
// attempt to do the intermediate rendering step in 8888
if (!tmpSurface.get()) {
SkImageInfo tmpInfo = bitmap->info().makeColorType(SkColorType::kN32_SkColorType);
tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
- tmpInfo);
+ tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr);
if (!tmpSurface.get()) {
ALOGW("Unable to generate GPU buffer in a format compatible with the provided bitmap");
return false;
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index 375f5bc..6a12a20 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -65,6 +65,15 @@
return skWidth;
}
+void MinikinFontSkia::GetHorizontalAdvances(uint16_t* glyph_ids, uint32_t count,
+ const minikin::MinikinPaint& paint,
+ const minikin::FontFakery& fakery,
+ float* outAdvances) const {
+ SkFont skFont;
+ MinikinFontSkia_SetSkiaFont(this, &skFont, paint, fakery);
+ skFont.getWidths(glyph_ids, count, outAdvances);
+}
+
void MinikinFontSkia::GetBounds(minikin::MinikinRect* bounds, uint32_t glyph_id,
const minikin::MinikinPaint& paint,
const minikin::FontFakery& fakery) const {
diff --git a/libs/hwui/hwui/MinikinSkia.h b/libs/hwui/hwui/MinikinSkia.h
index ad46b23..90f7d48 100644
--- a/libs/hwui/hwui/MinikinSkia.h
+++ b/libs/hwui/hwui/MinikinSkia.h
@@ -35,6 +35,11 @@
float GetHorizontalAdvance(uint32_t glyph_id, const minikin::MinikinPaint& paint,
const minikin::FontFakery& fakery) const override;
+ void GetHorizontalAdvances(uint16_t* glyph_ids, uint32_t count,
+ const minikin::MinikinPaint& paint,
+ const minikin::FontFakery& fakery,
+ float* outAdvances) const override;
+
void GetBounds(minikin::MinikinRect* bounds, uint32_t glyph_id,
const minikin::MinikinPaint& paint,
const minikin::FontFakery& fakery) const override;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index d0fe022..15f53f2 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -42,7 +42,13 @@
namespace skiapipeline {
SkiaVulkanPipeline::SkiaVulkanPipeline(renderthread::RenderThread& thread)
- : SkiaPipeline(thread), mVkManager(thread.vulkanManager()) {}
+ : SkiaPipeline(thread), mVkManager(thread.vulkanManager()) {
+ thread.renderState().registerContextCallback(this);
+}
+
+SkiaVulkanPipeline::~SkiaVulkanPipeline() {
+ mRenderThread.renderState().removeContextCallback(this);
+}
MakeCurrentResult SkiaVulkanPipeline::makeCurrent() {
return MakeCurrentResult::AlreadyCurrent;
@@ -53,6 +59,8 @@
"drawRenderNode called on a context with no surface!");
SkSurface* backBuffer = mVkManager.getBackbufferSurface(&mVkSurface);
+ LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr,
+ "drawRenderNode called on a context with an invalid surface");
if (backBuffer == nullptr) {
SkDebugf("failed to get backbuffer");
return Frame(-1, -1, 0);
@@ -153,6 +161,13 @@
return nullptr;
}
+void SkiaVulkanPipeline::onContextDestroyed() {
+ if (mVkSurface) {
+ mVkManager.destroySurface(mVkSurface);
+ mVkSurface = nullptr;
+ }
+}
+
} /* namespace skiapipeline */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 9343076..2c24edd 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -19,14 +19,16 @@
#include "SkiaPipeline.h"
#include "renderthread/VulkanManager.h"
+#include "renderstate/RenderState.h"
+
namespace android {
namespace uirenderer {
namespace skiapipeline {
-class SkiaVulkanPipeline : public SkiaPipeline {
+class SkiaVulkanPipeline : public SkiaPipeline, public IGpuContextCallback {
public:
explicit SkiaVulkanPipeline(renderthread::RenderThread& thread);
- virtual ~SkiaVulkanPipeline() {}
+ virtual ~SkiaVulkanPipeline();
renderthread::MakeCurrentResult makeCurrent() override;
renderthread::Frame getFrame() override;
@@ -49,6 +51,9 @@
static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
SkBitmap& skBitmap);
+protected:
+ void onContextDestroyed() override;
+
private:
renderthread::VulkanManager& mVkManager;
renderthread::VulkanSurface* mVkSurface = nullptr;
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index 2f8d381..fe2d41e 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -43,7 +43,9 @@
, mImageInfo(image_info) {}
VkFunctorDrawHandler::~VkFunctorDrawHandler() {
- mFunctorHandle->postDrawVk();
+ if (mDrawn) {
+ mFunctorHandle->postDrawVk();
+ }
}
void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) {
@@ -77,6 +79,7 @@
params.format = vulkan_info.fFormat;
mFunctorHandle->drawVk(params);
+ mDrawn = true;
vulkan_info.fDrawBounds->offset.x = mClip.fLeft;
vulkan_info.fDrawBounds->offset.y = mClip.fTop;
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.h b/libs/hwui/pipeline/skia/VkFunctorDrawable.h
index 1a53c8f..d3f9777 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.h
@@ -44,6 +44,8 @@
const SkMatrix mMatrix;
const SkIRect mClip;
const SkImageInfo mImageInfo;
+
+ bool mDrawn = false;
};
/**
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index 6c04232..6da8062 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -117,7 +117,6 @@
auto& cache = skiapipeline::ShaderCache::get();
cache.initShaderDiskCache(identity, size);
contextOptions->fPersistentCache = &cache;
- contextOptions->fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
}
void CacheManager::trimMemory(TrimMemoryMode mode) {
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 8bef359..3904ed2 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -56,7 +56,7 @@
static bool gHasRenderThreadInstance = false;
-static void (*gOnStartHook)() = nullptr;
+static JVMAttachHook gOnStartHook = nullptr;
class DisplayEventReceiverWrapper : public VsyncSource {
public:
@@ -111,11 +111,15 @@
return gHasRenderThreadInstance;
}
-void RenderThread::setOnStartHook(void (*onStartHook)()) {
+void RenderThread::setOnStartHook(JVMAttachHook onStartHook) {
LOG_ALWAYS_FATAL_IF(hasInstance(), "can't set an onStartHook after we've started...");
gOnStartHook = onStartHook;
}
+JVMAttachHook RenderThread::getOnStartHook() {
+ return gOnStartHook;
+}
+
RenderThread& RenderThread::getInstance() {
// This is a pointer because otherwise __cxa_finalize
// will try to delete it like a Good Citizen but that causes us to crash
@@ -203,11 +207,17 @@
void RenderThread::destroyRenderingContext() {
mFunctorManager.onContextDestroyed();
- if (mEglManager->hasEglContext()) {
- setGrContext(nullptr);
- mEglManager->destroy();
+ if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
+ if (mEglManager->hasEglContext()) {
+ setGrContext(nullptr);
+ mEglManager->destroy();
+ }
+ } else {
+ if (vulkanManager().hasVkContext()) {
+ setGrContext(nullptr);
+ vulkanManager().destroy();
+ }
}
- vulkanManager().destroy();
}
void RenderThread::dumpGraphicsMemory(int fd) {
@@ -319,7 +329,7 @@
bool RenderThread::threadLoop() {
setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);
if (gOnStartHook) {
- gOnStartHook();
+ gOnStartHook("RenderThread");
}
initThreadLocals();
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 1ef83fb..b182928 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -75,12 +75,15 @@
class DummyVsyncSource;
+typedef void (*JVMAttachHook)(const char* name);
+
class RenderThread : private ThreadBase {
PREVENT_COPY_AND_ASSIGN(RenderThread);
public:
// Sets a callback that fires before any RenderThread setup has occurred.
- ANDROID_API static void setOnStartHook(void (*onStartHook)());
+ ANDROID_API static void setOnStartHook(JVMAttachHook onStartHook);
+ static JVMAttachHook getOnStartHook();
WorkQueue& queue() { return ThreadBase::queue(); }
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 582d51e..90397fd 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -89,7 +89,7 @@
mPhysicalDeviceFeatures2 = {};
}
-bool VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFeatures2& features) {
+void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFeatures2& features) {
VkResult err;
constexpr VkApplicationInfo app_info = {
@@ -107,15 +107,11 @@
uint32_t extensionCount = 0;
err = mEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
- if (VK_SUCCESS != err) {
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
std::unique_ptr<VkExtensionProperties[]> extensions(
new VkExtensionProperties[extensionCount]);
err = mEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.get());
- if (VK_SUCCESS != err) {
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
bool hasKHRSurfaceExtension = false;
bool hasKHRAndroidSurfaceExtension = false;
for (uint32_t i = 0; i < extensionCount; ++i) {
@@ -127,10 +123,7 @@
hasKHRAndroidSurfaceExtension = true;
}
}
- if (!hasKHRSurfaceExtension || !hasKHRAndroidSurfaceExtension) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(!hasKHRSurfaceExtension || !hasKHRAndroidSurfaceExtension);
}
const VkInstanceCreateInfo instance_create = {
@@ -146,10 +139,7 @@
GET_PROC(CreateInstance);
err = mCreateInstance(&instance_create, nullptr, &mInstance);
- if (err < 0) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(err < 0);
GET_INST_PROC(DestroyInstance);
GET_INST_PROC(EnumeratePhysicalDevices);
@@ -166,39 +156,23 @@
GET_INST_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
uint32_t gpuCount;
- err = mEnumeratePhysicalDevices(mInstance, &gpuCount, nullptr);
- if (err) {
- this->destroy();
- return false;
- }
- if (!gpuCount) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(mEnumeratePhysicalDevices(mInstance, &gpuCount, nullptr));
+ LOG_ALWAYS_FATAL_IF(!gpuCount);
// Just returning the first physical device instead of getting the whole array. Since there
// should only be one device on android.
gpuCount = 1;
err = mEnumeratePhysicalDevices(mInstance, &gpuCount, &mPhysicalDevice);
// VK_INCOMPLETE is returned when the count we provide is less than the total device count.
- if (err && VK_INCOMPLETE != err) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(err && VK_INCOMPLETE != err);
VkPhysicalDeviceProperties physDeviceProperties;
mGetPhysicalDeviceProperties(mPhysicalDevice, &physDeviceProperties);
- if (physDeviceProperties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(physDeviceProperties.apiVersion < VK_MAKE_VERSION(1, 1, 0));
// query to get the initial queue props size
uint32_t queueCount;
mGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, nullptr);
- if (!queueCount) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(!queueCount);
// now get the actual queue props
std::unique_ptr<VkQueueFamilyProperties[]> queueProps(new VkQueueFamilyProperties[queueCount]);
@@ -212,10 +186,7 @@
break;
}
}
- if (mGraphicsQueueIndex == queueCount) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(mGraphicsQueueIndex == queueCount);
// All physical devices and queue families on Android must be capable of
// presentation with any native window. So just use the first one.
@@ -225,18 +196,12 @@
uint32_t extensionCount = 0;
err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
nullptr);
- if (VK_SUCCESS != err) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
std::unique_ptr<VkExtensionProperties[]> extensions(
new VkExtensionProperties[extensionCount]);
err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
extensions.get());
- if (VK_SUCCESS != err) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
bool hasKHRSwapchainExtension = false;
for (uint32_t i = 0; i < extensionCount; ++i) {
mDeviceExtensions.push_back(extensions[i].extensionName);
@@ -244,10 +209,7 @@
hasKHRSwapchainExtension = true;
}
}
- if (!hasKHRSwapchainExtension) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension);
}
auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) {
@@ -259,10 +221,7 @@
grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(),
mInstanceExtensions.data(), mDeviceExtensions.size(), mDeviceExtensions.data());
- if (!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1));
memset(&features, 0, sizeof(VkPhysicalDeviceFeatures2));
features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
@@ -332,11 +291,7 @@
nullptr, // ppEnabledFeatures
};
- err = mCreateDevice(mPhysicalDevice, &deviceInfo, nullptr, &mDevice);
- if (err) {
- this->destroy();
- return false;
- }
+ LOG_ALWAYS_FATAL_IF(mCreateDevice(mPhysicalDevice, &deviceInfo, nullptr, &mDevice));
GET_DEV_PROC(GetDeviceQueue);
GET_DEV_PROC(DeviceWaitIdle);
@@ -366,8 +321,6 @@
GET_DEV_PROC(DestroyFence);
GET_DEV_PROC(WaitForFences);
GET_DEV_PROC(ResetFences);
-
- return true;
}
void VulkanManager::initialize() {
@@ -381,7 +334,7 @@
LOG_ALWAYS_FATAL_IF(instanceVersion < VK_MAKE_VERSION(1, 1, 0));
GrVkExtensions extensions;
- LOG_ALWAYS_FATAL_IF(!this->setupDevice(extensions, mPhysicalDeviceFeatures2));
+ this->setupDevice(extensions, mPhysicalDeviceFeatures2);
mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue);
@@ -419,7 +372,7 @@
if (!setupDummyCommandBuffer()) {
this->destroy();
- return;
+ // Pass through will crash on next line.
}
LOG_ALWAYS_FATAL_IF(mDummyCB == VK_NULL_HANDLE);
@@ -520,6 +473,9 @@
destroySurface(surface);
*surfaceOut = createSurface(window, colorMode, colorSpace, colorType);
surface = *surfaceOut;
+ if (!surface) {
+ return nullptr;
+ }
}
VulkanSurface::BackbufferInfo* backbuffer = getAvailableBackbuffer(surface);
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 6426fe2..1fe6c65 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -151,7 +151,7 @@
// Sets up the VkInstance and VkDevice objects. Also fills out the passed in
// VkPhysicalDeviceFeatures struct.
- bool setupDevice(GrVkExtensions&, VkPhysicalDeviceFeatures2&);
+ void setupDevice(GrVkExtensions&, VkPhysicalDeviceFeatures2&);
void destroyBuffers(VulkanSurface* surface);
diff --git a/libs/hwui/tests/common/TestContext.cpp b/libs/hwui/tests/common/TestContext.cpp
index 92b6cbd..0a54aca 100644
--- a/libs/hwui/tests/common/TestContext.cpp
+++ b/libs/hwui/tests/common/TestContext.cpp
@@ -37,11 +37,13 @@
0, // presentationDeadline
};
-DisplayInfo getBuiltInDisplay() {
+DisplayInfo getInternalDisplay() {
#if !HWUI_NULL_GPU
DisplayInfo display;
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
- status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &display);
+ const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
+ LOG_ALWAYS_FATAL_IF(token == nullptr,
+ "Failed to get display info because internal display is disconnected\n");
+ status_t status = SurfaceComposerClient::getDisplayInfo(token, &display);
LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n");
return display;
#else
diff --git a/libs/hwui/tests/common/TestContext.h b/libs/hwui/tests/common/TestContext.h
index 0996f4d..116d4de 100644
--- a/libs/hwui/tests/common/TestContext.h
+++ b/libs/hwui/tests/common/TestContext.h
@@ -36,7 +36,7 @@
extern DisplayInfo gDisplay;
#define dp(x) ((x)*android::uirenderer::test::gDisplay.density)
-DisplayInfo getBuiltInDisplay();
+DisplayInfo getInternalDisplay();
class TestContext {
public:
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 5fa008b..0e61899e 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -109,7 +109,7 @@
void run(const TestScene::Info& info, const TestScene::Options& opts,
benchmark::BenchmarkReporter* reporter) {
// Switch to the real display
- gDisplay = getBuiltInDisplay();
+ gDisplay = getInternalDisplay();
Properties::forceDrawFrame = true;
TestContext testContext;
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index 26ff6eb..de10ff1 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -21,6 +21,7 @@
#include "TaskManager.h"
#include "TaskProcessor.h"
#include "utils/MathUtils.h"
+#include "renderthread/RenderThread.h"
namespace android {
namespace uirenderer {
@@ -84,6 +85,11 @@
status_t TaskManager::WorkerThread::readyToRun() {
setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
+ auto onStartHook = renderthread::RenderThread::getOnStartHook();
+ if (onStartHook) {
+ onStartHook(mName.c_str());
+ }
+
return NO_ERROR;
}
diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h
index c4c1291..6c67222 100644
--- a/libs/hwui/thread/TaskManager.h
+++ b/libs/hwui/thread/TaskManager.h
@@ -77,7 +77,8 @@
class WorkerThread : public Thread {
public:
- explicit WorkerThread(const String8& name) : mSignal(Condition::WAKE_UP_ONE), mName(name) {}
+ explicit WorkerThread(const String8& name)
+ : Thread(false), mSignal(Condition::WAKE_UP_ONE), mName(name) {}
bool addTask(const TaskWrapper& task);
size_t getTaskCount() const;
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index e795b81..1aeefb8 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -85,12 +85,12 @@
boolean stopGnssBatch();
boolean injectLocation(in Location location);
- // --- deprecated ---
List<String> getAllProviders();
List<String> getProviders(in Criteria criteria, boolean enabledOnly);
String getBestProvider(in Criteria criteria, boolean enabledOnly);
ProviderProperties getProviderProperties(String provider);
- String getNetworkProviderPackage();
+ boolean isProviderPackage(String packageName);
+
void setLocationControllerExtraPackage(String packageName);
String getLocationControllerExtraPackage();
void setLocationControllerExtraPackageEnabled(boolean enabled);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 63b57d1..c027fd4 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -934,6 +934,7 @@
* @hide
*/
@SystemApi
+ @TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestLocationUpdates(LocationRequest request, LocationListener listener,
Looper looper) {
@@ -963,6 +964,7 @@
* @hide
*/
@SystemApi
+ @TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestLocationUpdates(LocationRequest request, PendingIntent intent) {
checkPendingIntent(intent);
@@ -1293,6 +1295,7 @@
* @hide
*/
@SystemApi
+ @TestApi
@RequiresPermission(WRITE_SECURE_SETTINGS)
public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
Settings.Secure.putIntForUser(
@@ -2410,17 +2413,18 @@
}
/**
- * Return the package that implements the {@link #NETWORK_PROVIDER} functionality.
+ * Returns true if the given package name matches a location provider package, and false
+ * otherwise.
*
* @hide
*/
@SystemApi
- public @Nullable String getNetworkProviderPackage() {
+ public boolean isProviderPackage(String packageName) {
try {
- return mService.getNetworkProviderPackage();
+ return mService.isProviderPackage(packageName);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
- return null;
+ return false;
}
}
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 0480eab..0caa0c5 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -90,6 +91,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class LocationRequest implements Parcelable {
/**
* Used with {@link #setQuality} to request the most accurate locations available.
diff --git a/location/java/com/android/internal/location/ILocationProviderManager.aidl b/location/java/com/android/internal/location/ILocationProviderManager.aidl
index b1b8f0c..79166ae 100644
--- a/location/java/com/android/internal/location/ILocationProviderManager.aidl
+++ b/location/java/com/android/internal/location/ILocationProviderManager.aidl
@@ -26,6 +26,8 @@
*/
interface ILocationProviderManager {
+ void onSetAdditionalProviderPackages(in List<String> packageNames);
+
void onSetEnabled(boolean enabled);
void onSetProperties(in ProviderProperties properties);
diff --git a/location/lib/api/current.txt b/location/lib/api/current.txt
index c721218..67d6496 100644
--- a/location/lib/api/current.txt
+++ b/location/lib/api/current.txt
@@ -19,6 +19,7 @@
method protected boolean onSendExtraCommand(@Nullable String, @Nullable android.os.Bundle);
method protected abstract void onSetRequest(com.android.location.provider.ProviderRequestUnbundled, android.os.WorkSource);
method public void reportLocation(android.location.Location);
+ method public void setAdditionalProviderPackages(java.util.List<java.lang.String>);
method public void setEnabled(boolean);
method public void setProperties(com.android.location.provider.ProviderPropertiesUnbundled);
field public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index 5bcec92..7cd7207 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -36,6 +36,8 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
/**
* Base class for location providers implemented as unbundled services.
@@ -88,6 +90,7 @@
@Nullable private volatile ILocationProviderManager mManager;
private volatile ProviderProperties mProperties;
private volatile boolean mEnabled;
+ private final ArrayList<String> mAdditionalProviderPackages;
public LocationProviderBase(String tag, ProviderPropertiesUnbundled properties) {
mTag = tag;
@@ -99,6 +102,7 @@
mManager = null;
mProperties = properties.getProviderProperties();
mEnabled = true;
+ mAdditionalProviderPackages = new ArrayList<>(0);
}
public IBinder getBinder() {
@@ -160,6 +164,29 @@
}
/**
+ * Sets a list of additional packages that should be considered as part of this location
+ * provider for the purposes of generating locations. This should generally only be used when
+ * another package may issue location requests on behalf of this package in the course of
+ * providing location. This will inform location services to treat the other packages as
+ * location providers as well.
+ */
+ public void setAdditionalProviderPackages(List<String> packageNames) {
+ synchronized (mBinder) {
+ mAdditionalProviderPackages.clear();
+ mAdditionalProviderPackages.addAll(packageNames);
+ }
+
+ ILocationProviderManager manager = mManager;
+ if (manager != null) {
+ try {
+ manager.onSetAdditionalProviderPackages(mAdditionalProviderPackages);
+ } catch (RemoteException | RuntimeException e) {
+ Log.w(mTag, e);
+ }
+ }
+ }
+
+ /**
* Returns true if this provider has been set as enabled. This will be true unless explicitly
* set otherwise.
*/
@@ -275,6 +302,9 @@
public void setLocationProviderManager(ILocationProviderManager manager) {
synchronized (mBinder) {
try {
+ if (!mAdditionalProviderPackages.isEmpty()) {
+ manager.onSetAdditionalProviderPackages(mAdditionalProviderPackages);
+ }
manager.onSetProperties(mProperties);
manager.onSetEnabled(mEnabled);
} catch (RemoteException e) {
diff --git a/media/Android.bp b/media/Android.bp
index 1aefebe..141d415c 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -102,7 +102,8 @@
"--hide MissingPermission --hide BroadcastBehavior " +
"--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
"--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo " +
- "--hide HiddenTypedefConstant "
+ "--hide HiddenTypedefConstant --show-annotation android.annotation.SystemApi " +
+ " --show-annotation android.annotation.TestApi "
droidstubs {
name: "updatable-media-stubs",
@@ -110,8 +111,7 @@
":updatable-media-srcs-without-aidls",
":framework-media-annotation-srcs",
],
- args: metalava_updatable_media_args + " --show-annotation android.annotation.SystemApi " +
- " --show-annotation android.annotation.TestApi ",
+ args: metalava_updatable_media_args,
// Ideally, sdk_version here should be "current_system", but "current - 1" is used
// to avoid dependency cycle with framework.
sdk_version: "28",
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index 925ca0d..c38a831 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -63,6 +63,8 @@
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -86,6 +88,12 @@
/**
* MediaPlayer2 class can be used to control playback of audio/video files and streams.
*
+ * <p>
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
+ * for consistent behavior across all devices.
+ *
* <p>Topics covered here are:
* <ol>
* <li><a href="#PlayerStates">Player states</a>
@@ -408,6 +416,7 @@
synchronized (mDrmEventCallbackLock) {
mDrmEventCallback = null;
}
+ clearMediaDrmObjects();
native_release();
@@ -418,6 +427,16 @@
mReleased = true;
}
+ void clearMediaDrmObjects() {
+ Collection<MediaDrm> drmObjs = mDrmObjs.values();
+ synchronized (mDrmObjs) {
+ for (MediaDrm drmObj : drmObjs) {
+ drmObj.close();
+ }
+ mDrmObjs.clear();
+ }
+ }
+
private native void native_release();
// Have to declare protected for finalize() since it is protected
@@ -442,6 +461,7 @@
// This is a synchronous call.
public void reset() {
clearSourceInfos();
+ clearMediaDrmObjects();
stayAwake(false);
native_reset();
@@ -4504,7 +4524,7 @@
};
// Modular DRM
- private final Map<UUID, MediaDrm> mDrmObjs = new HashMap<>();
+ private final Map<UUID, MediaDrm> mDrmObjs = Collections.synchronizedMap(new HashMap<>());
private class DrmHandle {
static final int PROVISION_TIMEOUT_MS = 60000;
@@ -4891,10 +4911,6 @@
mDrmObj.closeSession(mDrmSessionId);
mDrmSessionId = null;
}
- if (mDrmObj != null) {
- mDrmObj.close();
- mDrmObj = null;
- }
}
void release() throws NoDrmSchemeException {
diff --git a/media/java/android/media/AudioRecordingConfiguration.java b/media/java/android/media/AudioRecordingConfiguration.java
index 1d763ce..0af47e8 100644
--- a/media/java/android/media/AudioRecordingConfiguration.java
+++ b/media/java/android/media/AudioRecordingConfiguration.java
@@ -402,7 +402,7 @@
&& (mClientPortId == that.mClientPortId)
&& (mClientSilenced == that.mClientSilenced)
&& (mDeviceSource == that.mDeviceSource)
- && (mClientEffects.equals(that.mClientEffects))
- && (mDeviceEffects.equals(that.mDeviceEffects)));
+ && (Arrays.equals(mClientEffects, that.mClientEffects))
+ && (Arrays.equals(mDeviceEffects, that.mDeviceEffects)));
}
}
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index 4f74ec9..963b1d1 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -97,9 +97,33 @@
*/
public static final int QUALITY_2160P = 8;
+ /**
+ * Quality level corresponding to the VGA (640 x 480) resolution.
+ * @hide
+ */
+ public static final int QUALITY_VGA = 9;
+
+ /**
+ * Quality level corresponding to 4k-DCI (4096 x 2160) resolution.
+ * @hide
+ */
+ public static final int QUALITY_4KDCI = 10;
+
+ /**
+ * Quality level corresponding to QHD (2560 x 1440) resolution
+ * @hide
+ */
+ public static final int QUALITY_QHD = 11;
+
+ /**
+ * Quality level corresponding to 2K (2048 x 1080) resolution
+ * @hide
+ */
+ public static final int QUALITY_2K = 12;
+
// Start and end of quality list
private static final int QUALITY_LIST_START = QUALITY_LOW;
- private static final int QUALITY_LIST_END = QUALITY_2160P;
+ private static final int QUALITY_LIST_END = QUALITY_2K;
/**
* Time lapse quality level corresponding to the lowest available resolution.
@@ -146,9 +170,34 @@
*/
public static final int QUALITY_TIME_LAPSE_2160P = 1008;
+ /**
+ * Time lapse quality level corresponding to the VGA (640 x 480) resolution.
+ * @hide
+ */
+ public static final int QUALITY_TIME_LAPSE_VGA = 1009;
+
+ /**
+ * Time lapse quality level corresponding to the 4k-DCI (4096 x 2160) resolution.
+ * @hide
+ */
+ public static final int QUALITY_TIME_LAPSE_4KDCI = 1010;
+
+ /**
+ * Time lapse quality level corresponding to the QHD (2560 x 1440) resolution.
+ * @hide
+ */
+ public static final int QUALITY_TIME_LAPSE_QHD = 1011;
+
+ /**
+ * Time lapse quality level corresponding to the 2K (2048 x 1080) resolution.
+ * @hide
+ */
+ public static final int QUALITY_TIME_LAPSE_2K = 1012;
+
+
// Start and end of timelapse quality list
private static final int QUALITY_TIME_LAPSE_LIST_START = QUALITY_TIME_LAPSE_LOW;
- private static final int QUALITY_TIME_LAPSE_LIST_END = QUALITY_TIME_LAPSE_2160P;
+ private static final int QUALITY_TIME_LAPSE_LIST_END = QUALITY_TIME_LAPSE_2K;
/**
* High speed ( >= 100fps) quality level corresponding to the lowest available resolution.
@@ -204,9 +253,27 @@
*/
public static final int QUALITY_HIGH_SPEED_2160P = 2005;
+ /**
+ * High speed ( >= 100fps) quality level corresponding to the CIF (352 x 288)
+ * @hide
+ */
+ public static final int QUALITY_HIGH_SPEED_CIF = 2006;
+
+ /**
+ * High speed ( >= 100fps) quality level corresponding to the VGA (640 x 480)
+ * @hide
+ */
+ public static final int QUALITY_HIGH_SPEED_VGA = 2007;
+
+ /**
+ * High speed ( >= 100fps) quality level corresponding to the 4K-DCI (4096 x 2160)
+ * @hide
+ */
+ public static final int QUALITY_HIGH_SPEED_4KDCI = 2008;
+
// Start and end of high speed quality list
private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW;
- private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_2160P;
+ private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_4KDCI;
/**
* Default recording duration in seconds before the session is terminated.
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index b9088d4..31d2232 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -31,6 +31,8 @@
import android.util.Log;
import android.util.Pair;
+import com.android.internal.util.ArrayUtils;
+
import libcore.io.IoUtils;
import libcore.io.Streams;
@@ -395,6 +397,12 @@
* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
*/
public static final String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw";
+ /**
+ * Type is byte[]. See <a href=
+ * "https://en.wikipedia.org/wiki/Extensible_Metadata_Platform">Extensible
+ * Metadata Platform (XMP)</a> for details on contents.
+ */
+ public static final String TAG_XMP = "Xmp";
/**
* Private tags used for pointing the other IFD offsets.
@@ -1012,7 +1020,8 @@
new ExifTag(TAG_RW2_SENSOR_BOTTOM_BORDER, 6, IFD_FORMAT_ULONG),
new ExifTag(TAG_RW2_SENSOR_RIGHT_BORDER, 7, IFD_FORMAT_ULONG),
new ExifTag(TAG_RW2_ISO, 23, IFD_FORMAT_USHORT),
- new ExifTag(TAG_RW2_JPG_FROM_RAW, 46, IFD_FORMAT_UNDEFINED)
+ new ExifTag(TAG_RW2_JPG_FROM_RAW, 46, IFD_FORMAT_UNDEFINED),
+ new ExifTag(TAG_XMP, 700, IFD_FORMAT_BYTE),
};
// Primary image IFD Exif Private tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
@@ -1243,6 +1252,8 @@
private static final Charset ASCII = Charset.forName("US-ASCII");
// Identifier for EXIF APP1 segment in JPEG
private static final byte[] IDENTIFIER_EXIF_APP1 = "Exif\0\0".getBytes(ASCII);
+ // Identifier for XMP APP1 segment in JPEG
+ private static final byte[] IDENTIFIER_XMP_APP1 = "http://ns.adobe.com/xap/1.0/\0".getBytes(ASCII);
// JPEG segment markers, that each marker consumes two bytes beginning with 0xff and ending with
// the indicator. There is no SOF4, SOF8, SOF16 markers in JPEG and SOFx markers indicates start
// of frame(baseline DCT) and the image size info exists in its beginning part.
@@ -2046,6 +2057,22 @@
}
/**
+ * Returns the raw bytes for the value of the requested tag inside the image
+ * file, or {@code null} if the tag is not contained.
+ *
+ * @return raw bytes for the value of the requested tag, or {@code null} if
+ * no tag was found.
+ */
+ public @Nullable byte[] getAttributeBytes(@NonNull String tag) {
+ final ExifAttribute attribute = getExifAttribute(tag);
+ if (attribute != null) {
+ return attribute.bytes;
+ } else {
+ return null;
+ }
+ }
+
+ /**
* Stores the latitude and longitude value in a float array. The first element is
* the latitude, and the second element is the longitude. Returns false if the
* Exif tags are not available.
@@ -2432,40 +2459,32 @@
}
switch (marker) {
case MARKER_APP1: {
- if (DEBUG) {
- Log.d(TAG, "MARKER_APP1");
- }
- if (length < 6) {
- // Skip if it's not an EXIF APP1 segment.
- break;
- }
- byte[] identifier = new byte[6];
- if (in.read(identifier) != 6) {
- throw new IOException("Invalid exif");
- }
- bytesRead += 6;
- length -= 6;
- if (!Arrays.equals(identifier, IDENTIFIER_EXIF_APP1)) {
- // Skip if it's not an EXIF APP1 segment.
- break;
- }
- if (length <= 0) {
- throw new IOException("Invalid exif");
- }
- if (DEBUG) {
- Log.d(TAG, "readExifSegment with a byte array (length: " + length + ")");
- }
- // Save offset values for createJpegThumbnailBitmap() function
- mExifOffset = bytesRead;
-
- byte[] bytes = new byte[length];
- if (in.read(bytes) != length) {
- throw new IOException("Invalid exif");
- }
+ final int start = bytesRead;
+ final byte[] bytes = new byte[length];
+ in.readFully(bytes);
bytesRead += length;
length = 0;
- readExifSegment(bytes, imageType);
+ if (ArrayUtils.startsWith(bytes, IDENTIFIER_EXIF_APP1)) {
+ final long offset = start + IDENTIFIER_EXIF_APP1.length;
+ final byte[] value = Arrays.copyOfRange(bytes,
+ IDENTIFIER_EXIF_APP1.length, bytes.length);
+
+ readExifSegment(value, imageType);
+
+ // Save offset values for createJpegThumbnailBitmap() function
+ mExifOffset = (int) offset;
+ } else if (ArrayUtils.startsWith(bytes, IDENTIFIER_XMP_APP1)) {
+ // See XMP Specification Part 3: Storage in Files, 1.1.3 JPEG, Table 6
+ final long offset = start + IDENTIFIER_XMP_APP1.length;
+ final byte[] value = Arrays.copyOfRange(bytes,
+ IDENTIFIER_XMP_APP1.length, bytes.length);
+
+ if (getAttribute(TAG_XMP) == null) {
+ mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, new ExifAttribute(
+ IFD_FORMAT_BYTE, value.length, offset, value));
+ }
+ }
break;
}
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index ce631a433..cf5711d 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -18,8 +18,12 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.cas.V1_0.*;
+import android.hardware.cas.V1_0.HidlCasPluginDescriptor;
+import android.hardware.cas.V1_1.ICas;
+import android.hardware.cas.V1_1.ICasListener;
+import android.hardware.cas.V1_1.IMediaCasService;
import android.media.MediaCasException.*;
+import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IHwBinder;
@@ -128,6 +132,9 @@
private class EventHandler extends Handler
{
private static final int MSG_CAS_EVENT = 0;
+ private static final int MSG_CAS_SESSION_EVENT = 1;
+ private static final String SESSION_KEY = "sessionId";
+ private static final String DATA_KEY = "data";
public EventHandler(Looper looper) {
super(looper);
@@ -138,6 +145,12 @@
if (msg.what == MSG_CAS_EVENT) {
mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2,
toBytes((ArrayList<Byte>) msg.obj));
+ } else if (msg.what == MSG_CAS_SESSION_EVENT) {
+ Bundle bundle = msg.getData();
+ ArrayList<Byte> sessionId = toByteArray(bundle.getByteArray(SESSION_KEY));
+ mListener.onSessionEvent(MediaCas.this,
+ createFromSessionId(sessionId), msg.arg1, msg.arg2,
+ bundle.getByteArray(DATA_KEY));
}
}
}
@@ -149,6 +162,20 @@
mEventHandler.sendMessage(mEventHandler.obtainMessage(
EventHandler.MSG_CAS_EVENT, event, arg, data));
}
+ @Override
+ public void onSessionEvent(@NonNull ArrayList<Byte> sessionId,
+ int event, int arg, @Nullable ArrayList<Byte> data)
+ throws RemoteException {
+ Message msg = mEventHandler.obtainMessage();
+ msg.what = EventHandler.MSG_CAS_SESSION_EVENT;
+ msg.arg1 = event;
+ msg.arg2 = arg;
+ Bundle bundle = new Bundle();
+ bundle.putByteArray(EventHandler.SESSION_KEY, toBytes(sessionId));
+ bundle.putByteArray(EventHandler.DATA_KEY, toBytes(data));
+ msg.setData(bundle);
+ mEventHandler.sendMessage(msg);
+ }
};
/**
@@ -222,6 +249,20 @@
}
/**
+ * Query if an object equal current Session object.
+ *
+ * @param obj an object to compare to current Session object.
+ *
+ * @return Whether input object equal current Session object.
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof Session) {
+ return mSessionId.equals(((Session) obj).mSessionId);
+ }
+ return false;
+ }
+
+ /**
* Set the private data for a session.
*
* @param data byte array of the private data.
@@ -282,6 +323,30 @@
}
/**
+ * Send a session event to a CA system. The format of the event is
+ * scheme-specific and is opaque to the framework.
+ *
+ * @param event an integer denoting a scheme-specific event to be sent.
+ * @param arg a scheme-specific integer argument for the event.
+ * @param data a byte array containing scheme-specific data for the event.
+ *
+ * @throws IllegalStateException if the MediaCas instance is not valid.
+ * @throws MediaCasException for CAS-specific errors.
+ * @throws MediaCasStateException for CAS-specific state exceptions.
+ */
+ public void sendSessionEvent(int event, int arg, @Nullable byte[] data)
+ throws MediaCasException {
+ validateInternalStates();
+
+ try {
+ MediaCasException.throwExceptionIfNeeded(
+ mICas.sendSessionEvent(mSessionId, event, arg, toByteArray(data)));
+ } catch (RemoteException e) {
+ cleanupAndRethrowIllegalState();
+ }
+ }
+
+ /**
* Close the session.
*
* @throws IllegalStateException if the MediaCas instance is not valid.
@@ -362,7 +427,7 @@
*/
public MediaCas(int CA_system_id) throws UnsupportedCasException {
try {
- mICas = getService().createPlugin(CA_system_id, mBinder);
+ mICas = getService().createPluginExt(CA_system_id, mBinder);
} catch(Exception e) {
Log.e(TAG, "Failed to create plugin: " + e);
mICas = null;
@@ -388,13 +453,28 @@
/**
* Notify the listener of a scheme-specific event from the CA system.
*
- * @param MediaCas the MediaCas object to receive this event.
+ * @param mediaCas the MediaCas object to receive this event.
* @param event an integer whose meaning is scheme-specific.
* @param arg an integer whose meaning is scheme-specific.
* @param data a byte array of data whose format and meaning are
* scheme-specific.
*/
- void onEvent(MediaCas MediaCas, int event, int arg, @Nullable byte[] data);
+ void onEvent(@NonNull MediaCas mediaCas, int event, int arg, @Nullable byte[] data);
+
+ /**
+ * Notify the listener of a scheme-specific session event from CA system.
+ *
+ * @param mediaCas the MediaCas object to receive this event.
+ * @param session session object which the event is for.
+ * @param event an integer whose meaning is scheme-specific.
+ * @param arg an integer whose meaning is scheme-specific.
+ * @param data a byte array of data whose format and meaning are
+ * scheme-specific.
+ */
+ default void onSessionEvent(@NonNull MediaCas mediaCas, @NonNull Session session,
+ int event, int arg, @Nullable byte[] data) {
+ Log.d(TAG, "Received MediaCas Session event");
+ }
}
/**
@@ -543,7 +623,7 @@
}
}
- /**
+ /**
* Initiate a provisioning operation for a CA system.
*
* @param provisionString string containing information needed for the
@@ -603,4 +683,4 @@
protected void finalize() {
close();
}
-}
\ No newline at end of file
+}
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 0c3d625..c6c2fdd 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -3373,6 +3373,8 @@
/**
* Change a video encoder's target bitrate on the fly. The value is an
* Integer object containing the new bitrate in bps.
+ *
+ * @see #setParameters(Bundle)
*/
public static final String PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";
@@ -3384,12 +3386,43 @@
* input-side of the encoder in that case.
* The value is an Integer object containing the value 1 to suspend
* or the value 0 to resume.
+ *
+ * @see #setParameters(Bundle)
*/
public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";
/**
+ * When {@link #PARAMETER_KEY_SUSPEND} is present, the client can also
+ * optionally use this key to specify the timestamp (in micro-second)
+ * at which the suspend/resume operation takes effect.
+ *
+ * Note that the specified timestamp must be greater than or equal to the
+ * timestamp of any previously queued suspend/resume operations.
+ *
+ * The value is a long int, indicating the timestamp to suspend/resume.
+ *
+ * @see #setParameters(Bundle)
+ */
+ public static final String PARAMETER_KEY_SUSPEND_TIME = "drop-start-time-us";
+
+ /**
+ * Specify an offset (in micro-second) to be added on top of the timestamps
+ * onward. A typical use case is to apply an adjust to the timestamps after
+ * a period of pause by the user.
+ *
+ * This parameter can only be used on an encoder in "surface-input" mode.
+ *
+ * The value is a long int, indicating the timestamp offset to be applied.
+ *
+ * @see #setParameters(Bundle)
+ */
+ public static final String PARAMETER_KEY_OFFSET_TIME = "time-offset-us";
+
+ /**
* Request that the encoder produce a sync frame "soon".
* Provide an Integer with the value 0.
+ *
+ * @see #setParameters(Bundle)
*/
public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index c82b5f6..a76cf1f 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -463,6 +463,61 @@
= "repeat-previous-frame-after";
/**
+ * Instruct the video encoder in "surface-input" mode to drop excessive
+ * frames from the source, so that the input frame rate to the encoder
+ * does not exceed the specified fps.
+ *
+ * The associated value is a float, representing the max frame rate to
+ * feed the encoder at.
+ *
+ */
+ public static final String KEY_MAX_FPS_TO_ENCODER
+ = "max-fps-to-encoder";
+
+ /**
+ * Instruct the video encoder in "surface-input" mode to limit the gap of
+ * timestamp between any two adjacent frames fed to the encoder to the
+ * specified amount (in micro-second).
+ *
+ * The associated value is a long int. When positive, it represents the max
+ * timestamp gap between two adjacent frames fed to the encoder. When negative,
+ * the absolute value represents a fixed timestamp gap between any two adjacent
+ * frames fed to the encoder. Note that this will also apply even when the
+ * original timestamp goes backward in time. Under normal conditions, such frames
+ * would be dropped and not sent to the encoder.
+ *
+ * The output timestamp will be restored to the original timestamp and will
+ * not be affected.
+ *
+ * This is used in some special scenarios where input frames arrive sparingly
+ * but it's undesirable to allocate more bits to any single frame, or when it's
+ * important to ensure all frames are captured (rather than captured in the
+ * correct order).
+ *
+ */
+ public static final String KEY_MAX_PTS_GAP_TO_ENCODER
+ = "max-pts-gap-to-encoder";
+
+ /**
+ * If specified when configuring a video encoder that's in "surface-input"
+ * mode, it will instruct the encoder to put the surface source in suspended
+ * state when it's connected. No video frames will be accepted until a resume
+ * operation (see {@link MediaCodec#PARAMETER_KEY_SUSPEND}), optionally with
+ * timestamp specified via {@link MediaCodec#PARAMETER_KEY_SUSPEND_TIME}, is
+ * received.
+ *
+ * The value is an integer, with 1 indicating to create with the surface
+ * source suspended, or 0 otherwise. The default value is 0.
+ *
+ * If this key is not set or set to 0, the surface source will accept buffers
+ * as soon as it's connected to the encoder (although they may not be encoded
+ * immediately). This key can be used when the client wants to prepare the
+ * encoder session in advance, but do not want to accept buffers immediately.
+ */
+ public static final String KEY_CREATE_INPUT_SURFACE_SUSPENDED
+ = "create-input-buffers-suspended";
+
+ /**
* If specified when configuring a video decoder rendering to a surface,
* causes the decoder to output "blank", i.e. black frames to the surface
* when stopped to clear out any previously displayed contents.
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 1c6210e..761b625 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -353,11 +353,6 @@
// no route flags set, use default as described in Builder.setRouteFlags(int)
mRouteFlags = ROUTE_FLAG_LOOP_BACK;
}
- // can't do loop back AND render at same time in this implementation
- if (mRouteFlags == (ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK)) {
- throw new IllegalArgumentException("Unsupported route behavior combination 0x" +
- Integer.toHexString(mRouteFlags));
- }
if (mFormat == null) {
// FIXME Can we eliminate this? Will AudioMix work with an unspecified sample rate?
int rate = AudioSystem.getPrimaryOutputSamplingRate();
@@ -377,11 +372,11 @@
throw new IllegalArgumentException("Unsupported device on non-playback mix");
}
} else {
- if ((mRouteFlags & ROUTE_FLAG_RENDER) == ROUTE_FLAG_RENDER) {
+ if ((mRouteFlags & ROUTE_FLAG_SUPPORTED) == ROUTE_FLAG_RENDER) {
throw new IllegalArgumentException(
"Can't have flag ROUTE_FLAG_RENDER without an audio device");
}
- if ((mRouteFlags & ROUTE_FLAG_SUPPORTED) == ROUTE_FLAG_LOOP_BACK) {
+ if ((mRouteFlags & ROUTE_FLAG_LOOP_BACK) == ROUTE_FLAG_LOOP_BACK) {
if (mRule.getTargetMixType() == MIX_TYPE_PLAYERS) {
mDeviceSystemType = AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
} else if (mRule.getTargetMixType() == MIX_TYPE_RECORDERS) {
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 406f9dd..f07f1e8 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -153,8 +153,12 @@
if (nameIsType) {
mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus);
+ if (mCodec == nullptr || mCodec->getName(&mNameAtCreation) != OK) {
+ mNameAtCreation = "(null)";
+ }
} else {
mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus);
+ mNameAtCreation = name;
}
CHECK((mCodec != NULL) != (mInitStatus != OK));
}
@@ -699,9 +703,8 @@
return err;
}
- // TODO: get alias
ScopedLocalRef<jstring> nameObject(env,
- env->NewStringUTF(codecInfo->getCodecName()));
+ env->NewStringUTF(mNameAtCreation.c_str()));
ScopedLocalRef<jstring> canonicalNameObject(env,
env->NewStringUTF(codecInfo->getCodecName()));
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 0a53f1a..de08550 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -155,6 +155,7 @@
sp<ALooper> mLooper;
sp<MediaCodec> mCodec;
+ AString mNameAtCreation;
sp<AMessage> mCallbackNotification;
sp<AMessage> mOnFrameRenderedNotification;
diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp
index cf14942..6b8f745 100644
--- a/media/jni/android_media_MediaCodecList.cpp
+++ b/media/jni/android_media_MediaCodecList.cpp
@@ -24,6 +24,10 @@
#include <media/IMediaCodecList.h>
#include <media/MediaCodecInfo.h>
+#include <utils/Vector.h>
+
+#include <vector>
+
#include "android_runtime/AndroidRuntime.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>
@@ -31,25 +35,91 @@
using namespace android;
-static sp<IMediaCodecList> getCodecList(JNIEnv *env) {
- sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
- if (mcl == NULL) {
- // This should never happen unless something is really wrong
- jniThrowException(
- env, "java/lang/RuntimeException", "cannot get MediaCodecList");
+/**
+ * This object unwraps codec aliases into individual codec infos as the Java interface handles
+ * aliases in this way.
+ */
+class JavaMediaCodecListWrapper {
+public:
+ struct Info {
+ sp<MediaCodecInfo> info;
+ AString alias;
+ };
+
+ const Info getCodecInfo(size_t index) const {
+ if (index < mInfoList.size()) {
+ return mInfoList[index];
+ }
+ // return
+ return Info { nullptr /* info */, "(none)" /* alias */ };
}
- return mcl;
+
+ size_t countCodecs() const {
+ return mInfoList.size();
+ }
+
+ sp<IMediaCodecList> getCodecList() const {
+ return mCodecList;
+ }
+
+ size_t findCodecByName(AString name) const {
+ auto it = mInfoIndex.find(name);
+ return it == mInfoIndex.end() ? -ENOENT : it->second;
+ }
+
+ JavaMediaCodecListWrapper(sp<IMediaCodecList> mcl)
+ : mCodecList(mcl) {
+ size_t numCodecs = mcl->countCodecs();
+ for (size_t ix = 0; ix < numCodecs; ++ix) {
+ sp<MediaCodecInfo> info = mcl->getCodecInfo(ix);
+ Vector<AString> namesAndAliases;
+ info->getAliases(&namesAndAliases);
+ namesAndAliases.insertAt(0);
+ namesAndAliases.editItemAt(0) = info->getCodecName();
+ for (const AString &nameOrAlias : namesAndAliases) {
+ if (mInfoIndex.count(nameOrAlias) > 0) {
+ // skip duplicate names or aliases
+ continue;
+ }
+ mInfoIndex.emplace(nameOrAlias, mInfoList.size());
+ mInfoList.emplace_back(Info { info, nameOrAlias });
+ }
+ }
+ }
+
+private:
+ sp<IMediaCodecList> mCodecList;
+ std::vector<Info> mInfoList;
+ std::map<AString, size_t> mInfoIndex;
+};
+
+static std::mutex sMutex;
+static std::unique_ptr<JavaMediaCodecListWrapper> sListWrapper;
+
+static const JavaMediaCodecListWrapper *getCodecList(JNIEnv *env) {
+ std::lock_guard<std::mutex> lock(sMutex);
+ if (sListWrapper == nullptr) {
+ sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
+ if (mcl == NULL) {
+ // This should never happen unless something is really wrong
+ jniThrowException(
+ env, "java/lang/RuntimeException", "cannot get MediaCodecList");
+ }
+
+ sListWrapper.reset(new JavaMediaCodecListWrapper(mcl));
+ }
+ return sListWrapper.get();
}
-static sp<MediaCodecInfo> getCodecInfo(JNIEnv *env, jint index) {
- sp<IMediaCodecList> mcl = getCodecList(env);
- if (mcl == NULL) {
+static JavaMediaCodecListWrapper::Info getCodecInfo(JNIEnv *env, jint index) {
+ const JavaMediaCodecListWrapper *mcl = getCodecList(env);
+ if (mcl == nullptr) {
// Runtime exception already pending.
- return NULL;
+ return JavaMediaCodecListWrapper::Info { nullptr /* info */, "(none)" /* alias */ };
}
- sp<MediaCodecInfo> info = mcl->getCodecInfo(index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = mcl->getCodecInfo(index);
+ if (info.info == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
}
@@ -58,36 +128,36 @@
static jint android_media_MediaCodecList_getCodecCount(
JNIEnv *env, jobject /* thiz */) {
- sp<IMediaCodecList> mcl = getCodecList(env);
+ const JavaMediaCodecListWrapper *mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
return 0;
}
+
return mcl->countCodecs();
}
static jstring android_media_MediaCodecList_getCodecName(
JNIEnv *env, jobject /* thiz */, jint index) {
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return NULL;
}
- // TODO: support aliases
- const char *name = info->getCodecName();
+ const char *name = info.alias.c_str();
return env->NewStringUTF(name);
}
static jstring android_media_MediaCodecList_getCanonicalName(
JNIEnv *env, jobject /* thiz */, jint index) {
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return NULL;
}
- const char *name = info->getCodecName();
+ const char *name = info.info->getCodecName();
return env->NewStringUTF(name);
}
@@ -104,7 +174,7 @@
return -ENOENT;
}
- sp<IMediaCodecList> mcl = getCodecList(env);
+ const JavaMediaCodecListWrapper *mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
env->ReleaseStringUTFChars(name, nameStr);
@@ -118,25 +188,25 @@
static jboolean android_media_MediaCodecList_getAttributes(
JNIEnv *env, jobject /* thiz */, jint index) {
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return 0;
}
- return info->getAttributes();
+ return info.info->getAttributes();
}
static jarray android_media_MediaCodecList_getSupportedTypes(
JNIEnv *env, jobject /* thiz */, jint index) {
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return NULL;
}
Vector<AString> types;
- info->getSupportedMediaTypes(&types);
+ info.info->getSupportedMediaTypes(&types);
jclass clazz = env->FindClass("java/lang/String");
CHECK(clazz != NULL);
@@ -160,8 +230,8 @@
return NULL;
}
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return NULL;
}
@@ -181,7 +251,7 @@
// TODO query default-format also from codec/codec list
const sp<MediaCodecInfo::Capabilities> &capabilities =
- info->getCapabilitiesFor(typeStr);
+ info.info->getCapabilitiesFor(typeStr);
env->ReleaseStringUTFChars(type, typeStr);
typeStr = NULL;
if (capabilities == NULL) {
@@ -192,7 +262,7 @@
capabilities->getSupportedColorFormats(&colorFormats);
capabilities->getSupportedProfileLevels(&profileLevels);
sp<AMessage> details = capabilities->getDetails();
- bool isEncoder = info->isEncoder();
+ bool isEncoder = info.info->isEncoder();
jobject defaultFormatObj = NULL;
if (ConvertMessageToMap(env, defaultFormat, &defaultFormatObj)) {
@@ -267,13 +337,13 @@
}
static jobject android_media_MediaCodecList_getGlobalSettings(JNIEnv *env, jobject /* thiz */) {
- sp<IMediaCodecList> mcl = getCodecList(env);
+ const JavaMediaCodecListWrapper *mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
return NULL;
}
- const sp<AMessage> settings = mcl->getGlobalSettings();
+ const sp<AMessage> settings = mcl->getCodecList()->getGlobalSettings();
if (settings == NULL) {
jniThrowException(env, "java/lang/RuntimeException", "cannot get global settings");
return NULL;
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 5f51320..e08dab4 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -26,7 +26,6 @@
#include <media/AudioTrack.h>
#include "SoundPool.h"
#include "SoundPoolThread.h"
-#include <media/AudioPolicyHelper.h>
#include <media/NdkMediaCodec.h>
#include <media/NdkMediaExtractor.h>
#include <media/NdkMediaFormat.h>
@@ -746,7 +745,8 @@
// initialize track
size_t afFrameCount;
uint32_t afSampleRate;
- audio_stream_type_t streamType = audio_attributes_to_stream_type(mSoundPool->attributes());
+ audio_stream_type_t streamType =
+ AudioSystem::attributesToStreamType(*mSoundPool->attributes());
if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
afFrameCount = kDefaultFrameCount;
}
diff --git a/native/android/choreographer.cpp b/native/android/choreographer.cpp
index c3629da..2db575b 100644
--- a/native/android/choreographer.cpp
+++ b/native/android/choreographer.cpp
@@ -24,6 +24,7 @@
#include <android/choreographer.h>
#include <androidfw/DisplayEventDispatcher.h>
#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
#include <utils/Looper.h>
#include <utils/Mutex.h>
#include <utils/Timers.h>
@@ -67,8 +68,8 @@
explicit Choreographer(const sp<Looper>& looper);
Choreographer(const Choreographer&) = delete;
- virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
- virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
+ void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
+ void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
void scheduleCallbacks();
@@ -139,13 +140,10 @@
}
}
-
-void Choreographer::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t) {
- if (id != ISurfaceComposer::eDisplayIdMain) {
- ALOGV("choreographer %p ~ ignoring vsync signal for non-main display (id=%d)", this, id);
- scheduleVsync();
- return;
- }
+// TODO(b/74619554): The PhysicalDisplayId is ignored because SF only emits VSYNC events for the
+// internal display and DisplayEventReceiver::requestNextVsync only allows requesting VSYNC for
+// the internal display implicitly.
+void Choreographer::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId, uint32_t) {
std::vector<FrameCallback> callbacks{};
{
AutoMutex _l{mLock};
@@ -160,9 +158,10 @@
}
}
-void Choreographer::dispatchHotplug(nsecs_t, int32_t id, bool connected) {
- ALOGV("choreographer %p ~ received hotplug event (id=%" PRId32 ", connected=%s), ignoring.",
- this, id, toString(connected));
+void Choreographer::dispatchHotplug(nsecs_t, PhysicalDisplayId displayId, bool connected) {
+ ALOGV("choreographer %p ~ received hotplug event (displayId=%"
+ ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", connected=%s), ignoring.",
+ this, displayId, toString(connected));
}
void Choreographer::handleMessage(const Message& message) {
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 3156732..7d2934b 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -46,7 +46,13 @@
static bool getWideColorSupport(const sp<SurfaceControl>& surfaceControl) {
sp<SurfaceComposerClient> client = surfaceControl->getClient();
- sp<IBinder> display(client->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
+
+ const sp<IBinder> display = client->getInternalDisplayToken();
+ if (display == nullptr) {
+ ALOGE("unable to get wide color support for disconnected internal display");
+ return false;
+ }
+
bool isWideColorDisplay = false;
status_t err = client->isWideColorDisplay(display, &isWideColorDisplay);
if (err) {
@@ -58,7 +64,12 @@
static bool getHdrSupport(const sp<SurfaceControl>& surfaceControl) {
sp<SurfaceComposerClient> client = surfaceControl->getClient();
- sp<IBinder> display(client->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
+
+ const sp<IBinder> display = client->getInternalDisplayToken();
+ if (display == nullptr) {
+ ALOGE("unable to get hdr capabilities for disconnected internal display");
+ return false;
+ }
HdrCapabilities hdrCapabilities;
status_t err = client->getHdrCapabilities(display, &hdrCapabilities);
@@ -499,7 +510,5 @@
color.g = g;
color.b = b;
- transaction->setColor(surfaceControl, color)
- .setColorAlpha(surfaceControl, alpha)
- .setColorDataspace(surfaceControl, static_cast<ui::Dataspace>(dataspace));
+ transaction->setBackgroundColor(surfaceControl, color, alpha, static_cast<ui::Dataspace>(dataspace));
}
diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml
index 1e38f26..7b4e32b 100644
--- a/packages/CarSystemUI/res/values/colors.xml
+++ b/packages/CarSystemUI/res/values/colors.xml
@@ -16,22 +16,18 @@
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<color name="nav_bar_ripple_background_color">#40ffffff</color>
- <color name="car_accent">#356FE5</color>
<!-- colors for user switcher -->
<color name="car_user_switcher_background_color">#000000</color>
- <color name="car_user_switcher_name_text_color">@color/car_body1_light</color>
+ <color name="car_user_switcher_name_text_color">@*android:color/car_body1_light</color>
<color name="car_user_switcher_add_user_background_color">#131313</color>
- <color name="car_nav_icon_fill_color">@color/car_grey_50</color>
+ <color name="car_nav_icon_fill_color">@*android:color/car_grey_50</color>
<!-- colors for seekbar -->
<color name="car_seekbar_track_background">#131315</color>
- <color name="car_seekbar_track_secondary_progress">@color/car_accent</color>
+ <color name="car_seekbar_track_secondary_progress">@*android:color/car_accent</color>
<!-- colors for volume dialog tint -->
- <color name="car_volume_dialog_tint">@color/car_tint_light</color>
+ <color name="car_volume_dialog_tint">@*android:color/car_tint</color>
- <!-- System ui can't depend on car libs so redefine. -->
- <color name="car_grey_50">#fffafafa</color>
-
- <color name="docked_divider_background">@color/car_grey_50</color>
+ <color name="docked_divider_background">@*android:color/car_grey_50</color>
<color name="system_bar_background_opaque">#ff172026</color>
<color name="status_bar_background_color">#33000000</color>
@@ -46,10 +42,6 @@
<!-- The color of the ripples on the untinted notifications -->
<color name="notification_ripple_untinted_color">@color/ripple_material_light</color>
- <color name="car_teal_700">#ff00796b</color>
- <color name="car_grey_300">#ffe0e0e0</color>
- <color name="car_grey_900">#ff212121</color>
-
<color name="keyguard_button_text_color">@android:color/black</color>
<color name="list_divider_color">@*android:color/car_list_divider_light</color>
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index e66a4624..2dba1d5b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -105,8 +105,6 @@
mHvacController.connectToCarService();
CarSystemUIFactory factory = SystemUIFactory.getInstance();
- mCarFacetButtonController = factory.getCarDependencyComponent()
- .getCarFacetButtonController();
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
mDeviceIsProvisioned = mDeviceProvisionedController.isDeviceProvisioned();
if (!mDeviceIsProvisioned) {
@@ -137,7 +135,7 @@
/**
* Remove all content from navbars and rebuild them. Used to allow for different nav bars
- * before and after the device is provisioned
+ * before and after the device is provisioned. . Also for change of density and font size.
*/
private void restartNavBars() {
// remove and reattach all hvac components such that we don't keep a reference to unused
@@ -253,6 +251,9 @@
super.makeStatusBarView();
mHvacController = new HvacController(mContext);
+ CarSystemUIFactory factory = SystemUIFactory.getInstance();
+ mCarFacetButtonController = factory.getCarDependencyComponent()
+ .getCarFacetButtonController();
mNotificationPanelBackground = getDefaultWallpaper();
mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
@@ -589,6 +590,7 @@
@Override
public void onDensityOrFontScaleChanged() {
super.onDensityOrFontScaleChanged();
+ restartNavBars();
// Need to update the background on density changed in case the change was due to night
// mode.
mNotificationPanelBackground = getDefaultWallpaper();
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
index 7fb51b9..fe6581b 100644
--- a/packages/ExtServices/AndroidManifest.xml
+++ b/packages/ExtServices/AndroidManifest.xml
@@ -24,6 +24,8 @@
<uses-permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
+ <uses-permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
+
<application android:label="@string/app_name"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index fe931ff..b6b229c 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -105,6 +105,7 @@
protected AssistantSettings.Factory mSettingsFactory = AssistantSettings.FACTORY;
@VisibleForTesting
protected AssistantSettings mSettings;
+ private SmsHelper mSmsHelper;
public Assistant() {
}
@@ -122,6 +123,18 @@
mAgingHelper = new AgingHelper(getContext(),
mNotificationCategorizer,
new AgingCallback());
+ mSmsHelper = new SmsHelper(this);
+ mSmsHelper.initialize();
+ }
+
+ @Override
+ public void onDestroy() {
+ // This null check is only for the unit tests as ServiceTestCase.tearDown calls onDestroy
+ // without having first called onCreate.
+ if (mSmsHelper != null) {
+ mSmsHelper.destroy();
+ }
+ super.onDestroy();
}
private void loadFile() {
@@ -214,7 +227,8 @@
if (!isForCurrentUser(sbn)) {
return null;
}
- NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
+ NotificationEntry entry =
+ new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry);
return createEnqueuedNotificationAdjustment(
entry, suggestions.actions, suggestions.replies);
@@ -261,7 +275,7 @@
Ranking ranking = getRanking(sbn.getKey(), rankingMap);
if (ranking != null && ranking.getChannel() != null) {
NotificationEntry entry = new NotificationEntry(mPackageManager,
- sbn, ranking.getChannel());
+ sbn, ranking.getChannel(), mSmsHelper);
String key = getKey(
sbn.getPackageName(), sbn.getUserId(), ranking.getChannel().getId());
ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
diff --git a/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java b/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
index d99c356..6cf72a4 100644
--- a/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
+++ b/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
@@ -23,7 +23,6 @@
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
-import android.util.KeyValueListParser;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -37,6 +36,9 @@
private static final boolean DEFAULT_GENERATE_REPLIES = true;
private static final boolean DEFAULT_GENERATE_ACTIONS = true;
private static final int DEFAULT_NEW_INTERRUPTION_MODEL_INT = 1;
+ private static final int DEFAULT_MAX_MESSAGES_TO_EXTRACT = 5;
+ @VisibleForTesting
+ static final int DEFAULT_MAX_SUGGESTIONS = 3;
private static final Uri STREAK_LIMIT_URI =
Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT);
@@ -46,7 +48,6 @@
private static final Uri NOTIFICATION_NEW_INTERRUPTION_MODEL_URI =
Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL);
- private final KeyValueListParser mParser = new KeyValueListParser(',');
private final ContentResolver mResolver;
private final int mUserId;
@@ -55,12 +56,14 @@
@VisibleForTesting
protected final Runnable mOnUpdateRunnable;
- // Actuall configuration settings.
+ // Actual configuration settings.
float mDismissToViewRatioLimit;
int mStreakLimit;
boolean mGenerateReplies = DEFAULT_GENERATE_REPLIES;
boolean mGenerateActions = DEFAULT_GENERATE_ACTIONS;
boolean mNewInterruptionModel;
+ int mMaxMessagesToExtract = DEFAULT_MAX_MESSAGES_TO_EXTRACT;
+ int mMaxSuggestions = DEFAULT_MAX_SUGGESTIONS;
private AssistantSettings(Handler handler, ContentResolver resolver, int userId,
Runnable onUpdateRunnable) {
@@ -124,27 +127,18 @@
}
private void updateFromDeviceConfigFlags() {
- String generateRepliesFlag = DeviceConfig.getProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES);
- if (TextUtils.isEmpty(generateRepliesFlag)) {
- mGenerateReplies = DEFAULT_GENERATE_REPLIES;
- } else {
- // parseBoolean returns false for everything that isn't 'true' so there's no need to
- // sanitise the flag string here.
- mGenerateReplies = Boolean.parseBoolean(generateRepliesFlag);
- }
+ mGenerateReplies = DeviceConfigHelper.getBoolean(
+ DeviceConfig.NotificationAssistant.GENERATE_REPLIES, DEFAULT_GENERATE_REPLIES);
- String generateActionsFlag = DeviceConfig.getProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS);
- if (TextUtils.isEmpty(generateActionsFlag)) {
- mGenerateActions = DEFAULT_GENERATE_ACTIONS;
- } else {
- // parseBoolean returns false for everything that isn't 'true' so there's no need to
- // sanitise the flag string here.
- mGenerateActions = Boolean.parseBoolean(generateActionsFlag);
- }
+ mGenerateActions = DeviceConfigHelper.getBoolean(
+ DeviceConfig.NotificationAssistant.GENERATE_ACTIONS, DEFAULT_GENERATE_ACTIONS);
+
+ mMaxMessagesToExtract = DeviceConfigHelper.getInteger(
+ DeviceConfig.NotificationAssistant.MAX_MESSAGES_TO_EXTRACT,
+ DEFAULT_MAX_MESSAGES_TO_EXTRACT);
+
+ mMaxSuggestions = DeviceConfigHelper.getInteger(
+ DeviceConfig.NotificationAssistant.MAX_SUGGESTIONS, DEFAULT_MAX_SUGGESTIONS);
mOnUpdateRunnable.run();
}
@@ -175,8 +169,37 @@
mOnUpdateRunnable.run();
}
+ static class DeviceConfigHelper {
+
+ static int getInteger(String key, int defaultValue) {
+ String value = getValue(key);
+ if (TextUtils.isEmpty(value)) {
+ return defaultValue;
+ }
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException ex) {
+ return defaultValue;
+ }
+ }
+
+ static boolean getBoolean(String key, boolean defaultValue) {
+ String value = getValue(key);
+ if (TextUtils.isEmpty(value)) {
+ return defaultValue;
+ }
+ return Boolean.parseBoolean(value);
+ }
+
+ private static String getValue(String key) {
+ return DeviceConfig.getProperty(
+ DeviceConfig.NotificationAssistant.NAMESPACE,
+ key);
+ }
+ }
+
public interface Factory {
AssistantSettings createAndRegister(Handler handler, ContentResolver resolver, int userId,
Runnable onUpdateRunnable);
}
-}
+}
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java b/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java
index 7ba0f7a..f95891c 100644
--- a/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java
+++ b/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java
@@ -15,6 +15,7 @@
*/
package android.ext.services.notification;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_MIN;
@@ -91,7 +92,7 @@
}
// TODO: is from signature app
if (entry.getSbn().getUid() < Process.FIRST_APPLICATION_UID) {
- if (entry.getImportance() >= IMPORTANCE_HIGH) {
+ if (entry.getImportance() >= IMPORTANCE_DEFAULT) {
return CATEGORY_SYSTEM;
} else {
return CATEGORY_SYSTEM_LOW;
diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
index ce2c409..546bec2 100644
--- a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
+++ b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
@@ -27,6 +27,7 @@
import android.app.NotificationChannel;
import android.app.Person;
import android.app.RemoteInput;
+import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -56,15 +57,17 @@
private boolean mSeen;
private boolean mExpanded;
private boolean mIsShowActionEventLogged;
+ private SmsHelper mSmsHelper;
public NotificationEntry(IPackageManager packageManager, StatusBarNotification sbn,
- NotificationChannel channel) {
+ NotificationChannel channel, SmsHelper smsHelper) {
mSbn = sbn;
mChannel = channel;
mPackageManager = packageManager;
mPreChannelsNotification = isPreChannelsNotification();
mAttributes = calculateAudioAttributes();
mImportance = calculateInitialImportance();
+ mSmsHelper = smsHelper;
}
private boolean isPreChannelsNotification() {
@@ -192,7 +195,16 @@
protected boolean involvesPeople() {
return isMessaging()
|| hasStyle(Notification.InboxStyle.class)
- || hasPerson();
+ || hasPerson()
+ || isDefaultSmsApp();
+ }
+
+ private boolean isDefaultSmsApp() {
+ ComponentName defaultSmsApp = mSmsHelper.getDefaultSmsApplication();
+ if (defaultSmsApp == null) {
+ return false;
+ }
+ return mSbn.getPackageName().equals(defaultSmsApp.getPackageName());
}
protected boolean isMessaging() {
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index 48a3974..08cc39f 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -29,28 +29,22 @@
import android.util.LruCache;
import android.view.textclassifier.ConversationAction;
import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassificationContext;
import android.view.textclassifier.TextClassificationManager;
import android.view.textclassifier.TextClassifier;
import android.view.textclassifier.TextClassifierEvent;
-import android.view.textclassifier.TextLinks;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.stream.Collectors;
public class SmartActionsHelper {
- private static final ArrayList<Notification.Action> EMPTY_ACTION_LIST = new ArrayList<>();
- private static final ArrayList<CharSequence> EMPTY_REPLY_LIST = new ArrayList<>();
-
private static final String KEY_ACTION_TYPE = "action_type";
// If a notification has any of these flags set, it's inelgibile for actions being added.
private static final int FLAG_MASK_INELGIBILE_FOR_ACTIONS =
@@ -58,19 +52,8 @@
| Notification.FLAG_FOREGROUND_SERVICE
| Notification.FLAG_GROUP_SUMMARY
| Notification.FLAG_NO_CLEAR;
- private static final int MAX_ACTION_EXTRACTION_TEXT_LENGTH = 400;
- private static final int MAX_ACTIONS_PER_LINK = 1;
- private static final int MAX_SMART_ACTIONS = 3;
- private static final int MAX_SUGGESTED_REPLIES = 3;
- // TODO: Make this configurable.
- private static final int MAX_MESSAGES_TO_EXTRACT = 5;
private static final int MAX_RESULT_ID_TO_CACHE = 20;
- private static final TextClassifier.EntityConfig TYPE_CONFIG =
- new TextClassifier.EntityConfig.Builder().setIncludedTypes(
- Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
- .includeTypesFromTextClassifier(false)
- .build();
private static final List<String> HINTS =
Collections.singletonList(ConversationActions.Request.HINT_FOR_NOTIFICATION);
@@ -92,20 +75,30 @@
mSettings = settings;
}
- @NonNull
SmartSuggestions suggest(@NonNull NotificationEntry entry) {
// Whenever suggest() is called on a notification, its previous session is ended.
mNotificationKeyToResultIdCache.remove(entry.getSbn().getKey());
- ArrayList<Notification.Action> actions = suggestActions(entry);
- ArrayList<CharSequence> replies = suggestReplies(entry);
+ boolean eligibleForReplyAdjustment =
+ mSettings.mGenerateReplies && isEligibleForReplyAdjustment(entry);
+ boolean eligibleForActionAdjustment =
+ mSettings.mGenerateActions && isEligibleForActionAdjustment(entry);
- // Not logging subsequent events of this notification if we didn't generate any suggestion
- // for it.
- if (replies.isEmpty() && actions.isEmpty()) {
- mNotificationKeyToResultIdCache.remove(entry.getSbn().getKey());
- }
+ List<ConversationAction> conversationActions =
+ suggestConversationActions(
+ entry,
+ eligibleForReplyAdjustment,
+ eligibleForActionAdjustment);
+ ArrayList<CharSequence> replies = conversationActions.stream()
+ .map(ConversationAction::getTextReply)
+ .filter(textReply -> !TextUtils.isEmpty(textReply))
+ .collect(Collectors.toCollection(ArrayList::new));
+
+ ArrayList<Notification.Action> actions = conversationActions.stream()
+ .filter(conversationAction -> conversationAction.getAction() != null)
+ .map(action -> createNotificationAction(action.getAction(), action.getType()))
+ .collect(Collectors.toCollection(ArrayList::new));
return new SmartSuggestions(replies, actions);
}
@@ -113,61 +106,48 @@
* Adds action adjustments based on the notification contents.
*/
@NonNull
- ArrayList<Notification.Action> suggestActions(@NonNull NotificationEntry entry) {
- if (!mSettings.mGenerateActions) {
- return EMPTY_ACTION_LIST;
- }
- if (!isEligibleForActionAdjustment(entry)) {
- return EMPTY_ACTION_LIST;
+ private List<ConversationAction> suggestConversationActions(
+ @NonNull NotificationEntry entry,
+ boolean includeReplies,
+ boolean includeActions) {
+ if (!includeReplies && !includeActions) {
+ return Collections.emptyList();
}
if (mTextClassifier == null) {
- return EMPTY_ACTION_LIST;
+ return Collections.emptyList();
}
List<ConversationActions.Message> messages = extractMessages(entry.getNotification());
if (messages.isEmpty()) {
- return EMPTY_ACTION_LIST;
+ return Collections.emptyList();
}
- // TODO: Move to TextClassifier.suggestConversationActions once it is ready.
- return suggestActionsFromText(
- messages.get(messages.size() - 1).getText(), MAX_SMART_ACTIONS);
- }
- @NonNull
- ArrayList<CharSequence> suggestReplies(@NonNull NotificationEntry entry) {
- if (!mSettings.mGenerateReplies) {
- return EMPTY_REPLY_LIST;
- }
- if (!isEligibleForReplyAdjustment(entry)) {
- return EMPTY_REPLY_LIST;
- }
- if (mTextClassifier == null) {
- return EMPTY_REPLY_LIST;
- }
- List<ConversationActions.Message> messages = extractMessages(entry.getNotification());
- if (messages.isEmpty()) {
- return EMPTY_REPLY_LIST;
+ TextClassifier.EntityConfig.Builder typeConfigBuilder =
+ new TextClassifier.EntityConfig.Builder();
+ if (!includeReplies) {
+ typeConfigBuilder.setExcludedTypes(
+ Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY));
+ } else if (!includeActions) {
+ typeConfigBuilder
+ .setIncludedTypes(
+ Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
+ .includeTypesFromTextClassifier(false);
}
ConversationActions.Request request =
new ConversationActions.Request.Builder(messages)
- .setMaxSuggestions(MAX_SUGGESTED_REPLIES)
+ .setMaxSuggestions(mSettings.mMaxSuggestions)
.setHints(HINTS)
- .setTypeConfig(TYPE_CONFIG)
+ .setTypeConfig(typeConfigBuilder.build())
.build();
ConversationActions conversationActionsResult =
mTextClassifier.suggestConversationActions(request);
- List<ConversationAction> conversationActions =
- conversationActionsResult.getConversationActions();
- ArrayList<CharSequence> replies = conversationActions.stream()
- .map(conversationAction -> conversationAction.getTextReply())
- .filter(textReply -> !TextUtils.isEmpty(textReply))
- .collect(Collectors.toCollection(ArrayList::new));
String resultId = conversationActionsResult.getId();
- if (resultId != null) {
+ if (!TextUtils.isEmpty(resultId)
+ && !conversationActionsResult.getConversationActions().isEmpty()) {
mNotificationKeyToResultIdCache.put(entry.getSbn().getKey(), resultId);
}
- return replies;
+ return conversationActionsResult.getConversationActions();
}
void onNotificationExpansionChanged(@NonNull NotificationEntry entry, boolean isUserAction,
@@ -248,6 +228,17 @@
mTextClassifier.onTextClassifierEvent(textClassifierEvent);
}
+ private Notification.Action createNotificationAction(
+ RemoteAction remoteAction, String actionType) {
+ return new Notification.Action.Builder(
+ remoteAction.getIcon(),
+ remoteAction.getTitle(),
+ remoteAction.getActionIntent())
+ .setContextual(true)
+ .addExtras(Bundle.forPair(KEY_ACTION_TYPE, actionType))
+ .build();
+ }
+
private TextClassifierEvent.Builder createTextClassifierEventBuilder(
int eventType, @NonNull String resultId) {
return new TextClassifierEvent.Builder(
@@ -308,7 +299,7 @@
private List<ConversationActions.Message> extractMessages(@NonNull Notification notification) {
Parcelable[] messages = notification.extras.getParcelableArray(Notification.EXTRA_MESSAGES);
if (messages == null || messages.length == 0) {
- return Arrays.asList(new ConversationActions.Message.Builder(
+ return Collections.singletonList(new ConversationActions.Message.Builder(
ConversationActions.Message.PERSON_USER_OTHERS)
.setText(notification.extras.getCharSequence(Notification.EXTRA_TEXT))
.build());
@@ -335,75 +326,13 @@
ZonedDateTime.ofInstant(Instant.ofEpochMilli(message.getTimestamp()),
ZoneOffset.systemDefault()))
.build());
- if (extractMessages.size() >= MAX_MESSAGES_TO_EXTRACT) {
+ if (extractMessages.size() >= mSettings.mMaxMessagesToExtract) {
break;
}
}
return new ArrayList<>(extractMessages);
}
- /** Returns a list of actions to act on entities in a given piece of text. */
- @NonNull
- private ArrayList<Notification.Action> suggestActionsFromText(
- @Nullable CharSequence text, int maxSmartActions) {
- if (TextUtils.isEmpty(text)) {
- return EMPTY_ACTION_LIST;
- }
- // We want to process only text visible to the user to avoid confusing suggestions, so we
- // truncate the text to a reasonable length. This is particularly important for e.g.
- // email apps that sometimes include the text for the entire thread.
- text = text.subSequence(0, Math.min(text.length(), MAX_ACTION_EXTRACTION_TEXT_LENGTH));
-
- // Extract all entities.
- TextLinks.Request textLinksRequest = new TextLinks.Request.Builder(text)
- .setEntityConfig(
- TextClassifier.EntityConfig.createWithHints(
- Collections.singletonList(
- TextClassifier.HINT_TEXT_IS_NOT_EDITABLE)))
- .build();
- TextLinks links = mTextClassifier.generateLinks(textLinksRequest);
- EntityTypeCounter entityTypeCounter = EntityTypeCounter.fromTextLinks(links);
-
- ArrayList<Notification.Action> actions = new ArrayList<>();
- for (TextLinks.TextLink link : links.getLinks()) {
- // Ignore any entity type for which we have too many entities. This is to handle the
- // case where a notification contains e.g. a list of phone numbers. In such cases, the
- // user likely wants to act on the whole list rather than an individual entity.
- if (link.getEntityCount() == 0
- || entityTypeCounter.getCount(link.getEntity(0)) != 1) {
- continue;
- }
-
- // Generate the actions, and add the most prominent ones to the action bar.
- TextClassification classification =
- mTextClassifier.classifyText(
- new TextClassification.Request.Builder(
- text, link.getStart(), link.getEnd()).build());
- if (classification.getEntityCount() == 0) {
- continue;
- }
- int numOfActions = Math.min(
- MAX_ACTIONS_PER_LINK, classification.getActions().size());
- for (int i = 0; i < numOfActions; ++i) {
- RemoteAction remoteAction = classification.getActions().get(i);
- Notification.Action action = new Notification.Action.Builder(
- remoteAction.getIcon(),
- remoteAction.getTitle(),
- remoteAction.getActionIntent())
- .setContextual(true)
- .addExtras(Bundle.forPair(KEY_ACTION_TYPE, classification.getEntity(0)))
- .build();
- actions.add(action);
-
- // We have enough smart actions.
- if (actions.size() >= maxSmartActions) {
- return actions;
- }
- }
- }
- return actions;
- }
-
static class SmartSuggestions {
public final ArrayList<CharSequence> replies;
public final ArrayList<Notification.Action> actions;
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java
new file mode 100644
index 0000000..07be0b8
--- /dev/null
+++ b/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.ext.services.notification;
+
+import static android.provider.Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL;
+
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+import com.android.internal.telephony.SmsApplication;
+
+/**
+ * A helper class for storing and retrieving the default SMS application.
+ */
+public class SmsHelper {
+ private static final String TAG = "SmsHelper";
+
+ private final Context mContext;
+ private ComponentName mDefaultSmsApplication;
+ private BroadcastReceiver mBroadcastReceiver;
+
+ SmsHelper(Context context) {
+ mContext = context.getApplicationContext();
+ }
+
+ void initialize() {
+ if (mBroadcastReceiver == null) {
+ mDefaultSmsApplication = SmsApplication.getDefaultSmsApplication(mContext, false);
+ mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL.equals(intent.getAction())) {
+ mDefaultSmsApplication =
+ SmsApplication.getDefaultSmsApplication(mContext, false);
+ } else {
+ Log.w(TAG, "Unknown broadcast received: " + intent.getAction());
+ }
+ }
+ };
+ mContext.registerReceiver(
+ mBroadcastReceiver,
+ new IntentFilter(ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL));
+ }
+ }
+
+ void destroy() {
+ if (mBroadcastReceiver != null) {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ mBroadcastReceiver = null;
+ }
+ }
+
+ @Nullable
+ public ComponentName getDefaultSmsApplication() {
+ return mDefaultSmsApplication;
+ }
+}
diff --git a/packages/ExtServices/tests/Android.bp b/packages/ExtServices/tests/Android.bp
index 5de4548..930b783 100644
--- a/packages/ExtServices/tests/Android.bp
+++ b/packages/ExtServices/tests/Android.bp
@@ -15,6 +15,7 @@
static_libs: [
"ExtServices-core",
"android-support-test",
+ "compatibility-device-util",
"mockito-target-minus-junit4",
"espresso-core",
"truth-prebuilt",
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java
index b023b36..90018e5f 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java
@@ -67,6 +67,8 @@
private IPackageManager mPackageManager;
@Mock
private AgingHelper.Callback mCallback;
+ @Mock
+ private SmsHelper mSmsHelper;
private AgingHelper mAgingHelper;
@@ -99,7 +101,7 @@
public void testNoSnoozingOnPost() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId());
- NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
+ NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
mAgingHelper.onNotificationPosted(entry);
@@ -110,7 +112,7 @@
public void testPostResetsSnooze() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId());
- NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
+ NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
mAgingHelper.onNotificationPosted(entry);
@@ -121,7 +123,7 @@
public void testSnoozingOnSeen() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId());
- NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
+ NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
entry.setSeen();
when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
@@ -134,7 +136,7 @@
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
StatusBarNotification sbn = generateSbn(channel.getId());
- NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
+ NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
mAgingHelper.onNotificationSeen(entry);
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
index 597051a..d890c1a 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
@@ -16,6 +16,10 @@
package android.ext.services.notification;
+import static android.ext.services.notification.AssistantSettings.DEFAULT_MAX_SUGGESTIONS;
+import static android.provider.DeviceConfig.NotificationAssistant;
+import static android.provider.DeviceConfig.setProperty;
+
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -26,12 +30,13 @@
import android.content.ContentResolver;
import android.os.Handler;
import android.os.Looper;
-import android.provider.DeviceConfig;
import android.provider.Settings;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
import android.testing.TestableContext;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -39,8 +44,13 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.IOException;
+
@RunWith(AndroidJUnit4.class)
public class AssistantSettingsTest {
+ private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
+ "device_config delete " + NotificationAssistant.NAMESPACE;
+
private static final int USER_ID = 5;
@Rule
@@ -69,16 +79,21 @@
handler, mResolver, USER_ID, mOnUpdateRunnable);
}
+ @After
+ public void tearDown() throws IOException {
+ clearDeviceConfig();
+ }
+
@Test
public void testGenerateRepliesDisabled() {
- DeviceConfig.setProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES,
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_REPLIES,
"false",
false /* makeDefault */);
mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES,
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_REPLIES,
"false");
assertFalse(mAssistantSettings.mGenerateReplies);
@@ -86,14 +101,14 @@
@Test
public void testGenerateRepliesEnabled() {
- DeviceConfig.setProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES,
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_REPLIES,
"true",
false /* makeDefault */);
mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES,
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_REPLIES,
"true");
assertTrue(mAssistantSettings.mGenerateReplies);
@@ -101,26 +116,26 @@
@Test
public void testGenerateRepliesEmptyFlag() {
- DeviceConfig.setProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES,
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_REPLIES,
"false",
false /* makeDefault */);
mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES,
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_REPLIES,
"false");
assertFalse(mAssistantSettings.mGenerateReplies);
- DeviceConfig.setProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES,
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_REPLIES,
"",
false /* makeDefault */);
mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_REPLIES,
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_REPLIES,
"");
// Go back to the default value.
@@ -129,14 +144,14 @@
@Test
public void testGenerateActionsDisabled() {
- DeviceConfig.setProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS,
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_ACTIONS,
"false",
false /* makeDefault */);
mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS,
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_ACTIONS,
"false");
assertFalse(mAssistantSettings.mGenerateActions);
@@ -144,14 +159,14 @@
@Test
public void testGenerateActionsEnabled() {
- DeviceConfig.setProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS,
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_ACTIONS,
"true",
false /* makeDefault */);
mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS,
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_ACTIONS,
"true");
assertTrue(mAssistantSettings.mGenerateActions);
@@ -159,26 +174,26 @@
@Test
public void testGenerateActionsEmptyFlag() {
- DeviceConfig.setProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS,
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_ACTIONS,
"false",
false /* makeDefault */);
mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS,
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_ACTIONS,
"false");
assertFalse(mAssistantSettings.mGenerateActions);
- DeviceConfig.setProperty(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS,
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_ACTIONS,
"",
false /* makeDefault */);
mAssistantSettings.onDeviceConfigPropertyChanged(
- DeviceConfig.NotificationAssistant.NAMESPACE,
- DeviceConfig.NotificationAssistant.GENERATE_ACTIONS,
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.GENERATE_ACTIONS,
"");
// Go back to the default value.
@@ -186,6 +201,46 @@
}
@Test
+ public void testMaxMessagesToExtract() {
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.MAX_MESSAGES_TO_EXTRACT,
+ "10",
+ false /* makeDefault */);
+ mAssistantSettings.onDeviceConfigPropertyChanged(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.MAX_MESSAGES_TO_EXTRACT,
+ "10");
+
+ assertEquals(10, mAssistantSettings.mMaxMessagesToExtract);
+ }
+
+ @Test
+ public void testMaxSuggestions() {
+ setProperty(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.MAX_SUGGESTIONS,
+ "5",
+ false /* makeDefault */);
+ mAssistantSettings.onDeviceConfigPropertyChanged(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.MAX_SUGGESTIONS,
+ "5");
+
+ assertEquals(5, mAssistantSettings.mMaxSuggestions);
+ }
+
+ @Test
+ public void testMaxSuggestionsEmpty() {
+ mAssistantSettings.onDeviceConfigPropertyChanged(
+ NotificationAssistant.NAMESPACE,
+ NotificationAssistant.MAX_SUGGESTIONS,
+ "");
+
+ assertEquals(DEFAULT_MAX_SUGGESTIONS, mAssistantSettings.mMaxSuggestions);
+ }
+
+ @Test
public void testStreakLimit() {
verify(mOnUpdateRunnable, never()).run();
@@ -219,4 +274,17 @@
assertEquals(newDismissToViewRatioLimit, mAssistantSettings.mDismissToViewRatioLimit, 1e-6);
verify(mOnUpdateRunnable).run();
}
+
+ private static void clearDeviceConfig() throws IOException {
+ UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ uiDevice.executeShellCommand(
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + NotificationAssistant.GENERATE_ACTIONS);
+ uiDevice.executeShellCommand(
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + NotificationAssistant.GENERATE_REPLIES);
+ uiDevice.executeShellCommand(
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + NotificationAssistant.MAX_MESSAGES_TO_EXTRACT);
+ uiDevice.executeShellCommand(
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + NotificationAssistant.MAX_SUGGESTIONS);
+ }
+
}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
index 0a95b83..f632814 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
@@ -85,6 +85,7 @@
@Mock INotificationManager mNoMan;
@Mock AtomicFile mFile;
@Mock IPackageManager mPackageManager;
+ @Mock SmsHelper mSmsHelper;
Assistant mAssistant;
Application mApplication;
@@ -467,7 +468,7 @@
public void testAssistantNeverIncreasesImportanceWhenSuggestingSilent() throws Exception {
StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C3, "min notif!", null);
Adjustment adjust = mAssistant.createEnqueuedNotificationAdjustment(new NotificationEntry(
- mPackageManager, sbn, P1C3), new ArrayList<>(), new ArrayList<>());
+ mPackageManager, sbn, P1C3, mSmsHelper), new ArrayList<>(), new ArrayList<>());
assertEquals(IMPORTANCE_MIN, adjust.getSignals().getInt(Adjustment.KEY_IMPORTANCE));
}
}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
index c59885e..05af6e7 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
@@ -18,6 +18,7 @@
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.os.Process.FIRST_APPLICATION_UID;
@@ -172,23 +173,23 @@
public void testSystemCategory() {
NotificationCategorizer nc = new NotificationCategorizer();
- when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_HIGH));
- when(mEntry.getImportance()).thenReturn(IMPORTANCE_HIGH);
+ when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
+ when(mEntry.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID - 1);
assertEquals(NotificationCategorizer.CATEGORY_SYSTEM, nc.getCategory(mEntry));
assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_SYSTEM));
when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID);
- assertEquals(NotificationCategorizer.CATEGORY_HIGH, nc.getCategory(mEntry));
+ assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
}
@Test
public void testSystemLowCategory() {
NotificationCategorizer nc = new NotificationCategorizer();
- when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
- when(mEntry.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
+ when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_LOW));
+ when(mEntry.getImportance()).thenReturn(IMPORTANCE_LOW);
when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID - 1);
assertEquals(NotificationCategorizer.CATEGORY_SYSTEM_LOW, nc.getCategory(mEntry));
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java
index 9223c3d..2d44e79 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java
@@ -31,6 +31,7 @@
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.Person;
+import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.media.AudioAttributes;
@@ -59,6 +60,10 @@
private IPackageManager mPackageManager;
@Mock
private ApplicationInfo mAppInfo;
+ @Mock
+ private SmsHelper mSmsHelper;
+
+ private static final String DEFAULT_SMS_PACKAGE_NAME = "foo";
@Rule
public final TestableContext mContext =
@@ -73,6 +78,15 @@
UserHandle.SYSTEM, null, 0);
}
+ private StatusBarNotification generateSbn(String channelId, String packageName) {
+ Notification n = new Notification.Builder(mContext, channelId)
+ .setContentTitle("foo")
+ .build();
+
+ return new StatusBarNotification(packageName, packageName, 0, "tag", mUid, mUid, n,
+ UserHandle.SYSTEM, null, 0);
+ }
+
private StatusBarNotification generateSbn(Notification n) {
return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
UserHandle.SYSTEM, null, 0);
@@ -86,6 +100,8 @@
when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
.thenReturn(mAppInfo);
mAppInfo.targetSdkVersion = Build.VERSION_CODES.P;
+ when(mSmsHelper.getDefaultSmsApplication())
+ .thenReturn(new ComponentName(DEFAULT_SMS_PACKAGE_NAME, "bar"));
}
@Test
@@ -96,7 +112,7 @@
people.add(new Person.Builder().setKey("mailto:testing@android.com").build());
sbn.getNotification().extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, people);
- NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
+ NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
assertTrue(entry.involvesPeople());
}
@@ -104,7 +120,23 @@
public void testNotPerson() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId());
- NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
+ NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
+ assertFalse(entry.involvesPeople());
+ }
+
+ @Test
+ public void testHasPerson_matchesDefaultSmsApp() {
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ StatusBarNotification sbn = generateSbn(channel.getId(), DEFAULT_SMS_PACKAGE_NAME);
+ NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
+ assertTrue(entry.involvesPeople());
+ }
+
+ @Test
+ public void testHasPerson_doesntMatchDefaultSmsApp() {
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ StatusBarNotification sbn = generateSbn(channel.getId(), "abc");
+ NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
assertFalse(entry.involvesPeople());
}
@@ -115,7 +147,8 @@
Notification n = new Notification.Builder(mContext, channel.getId())
.setStyle(new Notification.InboxStyle())
.build();
- NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
+ NotificationEntry entry =
+ new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertTrue(entry.hasStyle(Notification.InboxStyle.class));
}
@@ -126,7 +159,8 @@
Notification n = new Notification.Builder(mContext, channel.getId())
.setStyle(new Notification.MessagingStyle(""))
.build();
- NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
+ NotificationEntry entry =
+ new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertTrue(entry.hasStyle(Notification.MessagingStyle.class));
}
@@ -137,7 +171,8 @@
Notification n = new Notification.Builder(mContext, channel.getId())
.setStyle(new Notification.BigPictureStyle())
.build();
- NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
+ NotificationEntry entry =
+ new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertFalse(entry.hasStyle(Notification.InboxStyle.class));
assertFalse(entry.hasStyle(Notification.MessagingStyle.class));
}
@@ -148,7 +183,7 @@
channel.setSound(null, new AudioAttributes.Builder().setUsage(USAGE_ALARM).build());
NotificationEntry entry = new NotificationEntry(
- mPackageManager, generateSbn(channel.getId()), channel);
+ mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
assertTrue(entry.isAudioAttributesUsage(USAGE_ALARM));
}
@@ -157,7 +192,7 @@
public void testIsNotAudioAttributes() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
NotificationEntry entry = new NotificationEntry(
- mPackageManager, generateSbn(channel.getId()), channel);
+ mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
assertFalse(entry.isAudioAttributesUsage(USAGE_ALARM));
}
@@ -169,7 +204,8 @@
Notification n = new Notification.Builder(mContext, channel.getId())
.setCategory(Notification.CATEGORY_EMAIL)
.build();
- NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
+ NotificationEntry entry =
+ new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertTrue(entry.isCategory(Notification.CATEGORY_EMAIL));
assertFalse(entry.isCategory(Notification.CATEGORY_MESSAGE));
@@ -182,7 +218,8 @@
Notification n = new Notification.Builder(mContext, channel.getId())
.setFlag(FLAG_FOREGROUND_SERVICE, true)
.build();
- NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
+ NotificationEntry entry =
+ new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertTrue(entry.isOngoing());
}
@@ -194,7 +231,8 @@
Notification n = new Notification.Builder(mContext, channel.getId())
.setFlag(FLAG_CAN_COLORIZE, true)
.build();
- NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
+ NotificationEntry entry =
+ new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertFalse(entry.isOngoing());
}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
similarity index 60%
rename from packages/ExtServices/tests/src/android/ext/services/notification/SmartActionHelperTest.java
rename to packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
index 7f8127a..ebbd961 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionHelperTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
@@ -25,8 +25,15 @@
import android.annotation.NonNull;
import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.app.Person;
+import android.app.RemoteInput;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.IPackageManager;
+import android.graphics.drawable.Icon;
import android.os.Process;
import android.service.notification.NotificationAssistantService;
import android.service.notification.StatusBarNotification;
@@ -53,7 +60,6 @@
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -62,20 +68,26 @@
import javax.annotation.Nullable;
@RunWith(AndroidJUnit4.class)
-public class SmartActionHelperTest {
+public class SmartActionsHelperTest {
private static final String NOTIFICATION_KEY = "key";
private static final String RESULT_ID = "id";
-
private static final ConversationAction REPLY_ACTION =
new ConversationAction.Builder(ConversationAction.TYPE_TEXT_REPLY)
- .setTextReply("Home")
- .build();
+ .setTextReply("Home")
+ .build();
+ private static final String MESSAGE = "Where are you?";
+
+ @Mock
+ IPackageManager mIPackageManager;
+ @Mock
+ private TextClassifier mTextClassifier;
+ @Mock
+ private StatusBarNotification mStatusBarNotification;
+ @Mock
+ private SmsHelper mSmsHelper;
private SmartActionsHelper mSmartActionsHelper;
private Context mContext;
- @Mock private TextClassifier mTextClassifier;
- @Mock private NotificationEntry mNotificationEntry;
- @Mock private StatusBarNotification mStatusBarNotification;
private Notification.Builder mNotificationBuilder;
private AssistantSettings mSettings;
@@ -89,10 +101,6 @@
when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
.thenReturn(new ConversationActions(Arrays.asList(REPLY_ACTION), RESULT_ID));
- when(mNotificationEntry.getSbn()).thenReturn(mStatusBarNotification);
- // The notification is eligible to have smart suggestions.
- when(mNotificationEntry.hasInlineReply()).thenReturn(true);
- when(mNotificationEntry.isMessaging()).thenReturn(true);
when(mStatusBarNotification.getPackageName()).thenReturn("random.app");
when(mStatusBarNotification.getUser()).thenReturn(Process.myUserHandle());
when(mStatusBarNotification.getKey()).thenReturn(NOTIFICATION_KEY);
@@ -105,33 +113,96 @@
}
@Test
- public void testSuggestReplies_notMessagingApp() {
- when(mNotificationEntry.isMessaging()).thenReturn(false);
- ArrayList<CharSequence> textReplies =
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
- assertThat(textReplies).isEmpty();
+ public void testSuggest_notMessageNotification() {
+ Notification notification = mNotificationBuilder.setContentText(MESSAGE).build();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
+
+ mSmartActionsHelper.suggest(createNotificationEntry());
+
+ verify(mTextClassifier, never())
+ .suggestConversationActions(any(ConversationActions.Request.class));
}
@Test
- public void testSuggestReplies_noInlineReply() {
- when(mNotificationEntry.hasInlineReply()).thenReturn(false);
- ArrayList<CharSequence> textReplies =
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
- assertThat(textReplies).isEmpty();
+ public void testSuggest_noInlineReply() {
+ Notification notification =
+ mNotificationBuilder
+ .setContentText(MESSAGE)
+ .setCategory(Notification.CATEGORY_MESSAGE)
+ .build();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
+
+ ConversationActions.Request request = runSuggestAndCaptureRequest();
+
+ // actions are enabled, but replies are not.
+ assertThat(
+ request.getTypeConfig().resolveEntityListModifications(
+ Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
+ ConversationAction.TYPE_OPEN_URL)))
+ .containsExactly(ConversationAction.TYPE_OPEN_URL);
}
@Test
- public void testSuggestReplies_nonMessageStyle() {
- Notification notification = mNotificationBuilder.setContentText("Where are you?").build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ public void testSuggest_settingsOff() {
+ mSettings.mGenerateActions = false;
+ mSettings.mGenerateReplies = false;
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- List<ConversationActions.Message> messages = getMessagesInRequest();
+ mSmartActionsHelper.suggest(createNotificationEntry());
+
+ verify(mTextClassifier, never())
+ .suggestConversationActions(any(ConversationActions.Request.class));
+ }
+
+ @Test
+ public void testSuggest_settings_repliesOnActionsOff() {
+ mSettings.mGenerateReplies = true;
+ mSettings.mGenerateActions = false;
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
+
+ ConversationActions.Request request = runSuggestAndCaptureRequest();
+
+ // replies are enabled, but actions are not.
+ assertThat(
+ request.getTypeConfig().resolveEntityListModifications(
+ Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
+ ConversationAction.TYPE_OPEN_URL)))
+ .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
+ }
+
+ @Test
+ public void testSuggest_settings_repliesOffActionsOn() {
+ mSettings.mGenerateReplies = false;
+ mSettings.mGenerateActions = true;
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
+
+ ConversationActions.Request request = runSuggestAndCaptureRequest();
+
+ // actions are enabled, but replies are not.
+ assertThat(
+ request.getTypeConfig().resolveEntityListModifications(
+ Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
+ ConversationAction.TYPE_OPEN_URL)))
+ .containsExactly(ConversationAction.TYPE_OPEN_URL);
+ }
+
+
+ @Test
+ public void testSuggest_nonMessageStyleMessageNotification() {
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
+
+ List<ConversationActions.Message> messages =
+ runSuggestAndCaptureRequest().getConversation();
assertThat(messages).hasSize(1);
- MessageSubject.assertThat(messages.get(0)).hasText("Where are you?");
+ MessageSubject.assertThat(messages.get(0)).hasText(MESSAGE);
}
@Test
- public void testSuggestReplies_messageStyle() {
+ public void testSuggest_messageStyle() {
Person me = new Person.Builder().setName("Me").build();
Person userA = new Person.Builder().setName("A").build();
Person userB = new Person.Builder().setName("B").build();
@@ -145,10 +216,12 @@
mNotificationBuilder
.setContentText("You have three new messages")
.setStyle(style)
+ .setActions(createReplyAction())
.build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- List<ConversationActions.Message> messages = getMessagesInRequest();
+ List<ConversationActions.Message> messages =
+ runSuggestAndCaptureRequest().getConversation();
assertThat(messages).hasSize(3);
ConversationActions.Message secondMessage = messages.get(0);
@@ -172,7 +245,7 @@
}
@Test
- public void testSuggestReplies_messageStyle_noPerson() {
+ public void testSuggest_messageStyle_noPerson() {
Person me = new Person.Builder().setName("Me").build();
Notification.MessagingStyle style =
new Notification.MessagingStyle(me).addMessage("message", 1000, (Person) null);
@@ -180,10 +253,11 @@
mNotificationBuilder
.setContentText("You have one new message")
.setStyle(style)
+ .setActions(createReplyAction())
.build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
+ mSmartActionsHelper.suggest(createNotificationEntry());
verify(mTextClassifier, never())
.suggestConversationActions(any(ConversationActions.Request.class));
@@ -191,13 +265,12 @@
@Test
public void testOnSuggestedReplySent() {
- final String message = "Where are you?";
- Notification notification = mNotificationBuilder.setContentText(message).build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
+ mSmartActionsHelper.suggest(createNotificationEntry());
mSmartActionsHelper.onSuggestedReplySent(
- NOTIFICATION_KEY, message, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
+ NOTIFICATION_KEY, MESSAGE, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
ArgumentCaptor<TextClassifierEvent> argumentCaptor =
ArgumentCaptor.forClass(TextClassifierEvent.class);
@@ -208,13 +281,12 @@
@Test
public void testOnSuggestedReplySent_anotherNotification() {
- final String message = "Where are you?";
- Notification notification = mNotificationBuilder.setContentText(message).build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
+ mSmartActionsHelper.suggest(createNotificationEntry());
mSmartActionsHelper.onSuggestedReplySent(
- "something_else", message, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
+ "something_else", MESSAGE, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
verify(mTextClassifier, never())
.onTextClassifierEvent(Mockito.any(TextClassifierEvent.class));
@@ -225,13 +297,12 @@
when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
.thenReturn(new ConversationActions(Collections.emptyList(), null));
- final String message = "Where are you?";
- Notification notification = mNotificationBuilder.setContentText(message).build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
+ mSmartActionsHelper.suggest(createNotificationEntry());
mSmartActionsHelper.onSuggestedReplySent(
- "something_else", message, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
+ "something_else", MESSAGE, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
verify(mTextClassifier, never())
.onTextClassifierEvent(Mockito.any(TextClassifierEvent.class));
@@ -239,10 +310,10 @@
@Test
public void testOnNotificationDirectReply() {
- Notification notification = mNotificationBuilder.setContentText("Where are you?").build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
+ mSmartActionsHelper.suggest(createNotificationEntry());
mSmartActionsHelper.onNotificationDirectReplied(NOTIFICATION_KEY);
ArgumentCaptor<TextClassifierEvent> argumentCaptor =
@@ -254,12 +325,11 @@
@Test
public void testOnNotificationExpansionChanged() {
- final String message = "Where are you?";
- Notification notification = mNotificationBuilder.setContentText(message).build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
- mSmartActionsHelper.onNotificationExpansionChanged(mNotificationEntry, true, true);
+ mSmartActionsHelper.suggest(createNotificationEntry());
+ mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true, true);
ArgumentCaptor<TextClassifierEvent> argumentCaptor =
ArgumentCaptor.forClass(TextClassifierEvent.class);
@@ -270,12 +340,11 @@
@Test
public void testOnNotificationsSeen_notExpanded() {
- final String message = "Where are you?";
- Notification notification = mNotificationBuilder.setContentText(message).build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
- mSmartActionsHelper.onNotificationExpansionChanged(mNotificationEntry, false, false);
+ mSmartActionsHelper.suggest(createNotificationEntry());
+ mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false, false);
verify(mTextClassifier, never()).onTextClassifierEvent(
Mockito.any(TextClassifierEvent.class));
@@ -283,12 +352,11 @@
@Test
public void testOnNotifications_expanded() {
- final String message = "Where are you?";
- Notification notification = mNotificationBuilder.setContentText(message).build();
- when(mNotificationEntry.getNotification()).thenReturn(notification);
+ Notification notification = createMessageNotification();
+ when(mStatusBarNotification.getNotification()).thenReturn(notification);
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
- mSmartActionsHelper.onNotificationExpansionChanged(mNotificationEntry, false, true);
+ mSmartActionsHelper.suggest(createNotificationEntry());
+ mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false, true);
ArgumentCaptor<TextClassifierEvent> argumentCaptor =
ArgumentCaptor.forClass(TextClassifierEvent.class);
@@ -301,14 +369,41 @@
return ZonedDateTime.ofInstant(Instant.ofEpochMilli(msUtc), ZoneOffset.systemDefault());
}
- private List<ConversationActions.Message> getMessagesInRequest() {
- mSmartActionsHelper.suggestReplies(mNotificationEntry);
+ private ConversationActions.Request runSuggestAndCaptureRequest() {
+ mSmartActionsHelper.suggest(createNotificationEntry());
ArgumentCaptor<ConversationActions.Request> argumentCaptor =
ArgumentCaptor.forClass(ConversationActions.Request.class);
verify(mTextClassifier).suggestConversationActions(argumentCaptor.capture());
- ConversationActions.Request request = argumentCaptor.getValue();
- return request.getConversation();
+ return argumentCaptor.getValue();
+ }
+
+ private Notification.Action createReplyAction() {
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(mContext, 0, new Intent(mContext, this.getClass()), 0);
+ RemoteInput remoteInput = new RemoteInput.Builder("result")
+ .setAllowFreeFormInput(true)
+ .build();
+ return new Notification.Action.Builder(
+ Icon.createWithResource(mContext.getResources(),
+ android.R.drawable.stat_sys_warning),
+ "Reply", pendingIntent)
+ .addRemoteInput(remoteInput)
+ .build();
+ }
+
+ private NotificationEntry createNotificationEntry() {
+ NotificationChannel channel =
+ new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+ return new NotificationEntry(mIPackageManager, mStatusBarNotification, channel, mSmsHelper);
+ }
+
+ private Notification createMessageNotification() {
+ return mNotificationBuilder
+ .setContentText(MESSAGE)
+ .setCategory(Notification.CATEGORY_MESSAGE)
+ .setActions(createReplyAction())
+ .build();
}
private void assertTextClassifierEvent(
diff --git a/packages/NetworkStack/OWNERS b/packages/NetworkStack/OWNERS
new file mode 100644
index 0000000..a395465
--- /dev/null
+++ b/packages/NetworkStack/OWNERS
@@ -0,0 +1,5 @@
+codewiz@google.com
+jchalard@google.com
+lorenzo@google.com
+reminv@google.com
+satk@google.com
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
index 4fa7d64..923f162 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
@@ -23,6 +23,7 @@
import static android.system.OsConstants.ETH_P_IP;
import static android.system.OsConstants.ETH_P_IPV6;
import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
import static android.system.OsConstants.SOCK_RAW;
@@ -38,6 +39,7 @@
import android.content.IntentFilter;
import android.net.LinkAddress;
import android.net.LinkProperties;
+import android.net.TcpKeepalivePacketDataParcelable;
import android.net.apf.ApfGenerator.IllegalInstructionException;
import android.net.apf.ApfGenerator.Register;
import android.net.ip.IpClient.IpClientCallbacksWrapper;
@@ -55,6 +57,7 @@
import android.text.format.DateUtils;
import android.util.Log;
import android.util.Pair;
+import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -149,7 +152,9 @@
DROPPED_IPV6_NON_ICMP_MULTICAST,
DROPPED_802_3_FRAME,
DROPPED_ETHERTYPE_BLACKLISTED,
- DROPPED_ARP_REPLY_SPA_NO_HOST;
+ DROPPED_ARP_REPLY_SPA_NO_HOST,
+ DROPPED_IPV4_KEEPALIVE_ACK,
+ DROPPED_IPV6_KEEPALIVE_ACK;
// Returns the negative byte offset from the end of the APF data segment for
// a given counter.
@@ -285,6 +290,7 @@
private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
private static final int IPV4_ANY_HOST_ADDRESS = 0;
private static final int IPV4_BROADCAST_ADDRESS = -1; // 255.255.255.255
+ private static final int IPV4_HEADER_LEN = 20; // Without options
// Traffic class and Flow label are not byte aligned. Luckily we
// don't care about either value so we'll consider bytes 1-3 of the
@@ -305,6 +311,8 @@
private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 2;
private static final int UDP_HEADER_LEN = 8;
+ private static final int TCP_HEADER_SIZE_OFFSET = 12;
+
private static final int DHCP_CLIENT_PORT = 68;
// NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
@@ -788,7 +796,7 @@
boolean isExpired() {
// TODO: We may want to handle 0 lifetime RAs differently, if they are common. We'll
- // have to calculte the filter lifetime specially as a fraction of 0 is still 0.
+ // have to calculate the filter lifetime specially as a fraction of 0 is still 0.
return currentLifetime() <= 0;
}
@@ -847,11 +855,147 @@
}
}
+ // A class to hold keepalive ack information.
+ private abstract static class TcpKeepaliveAck {
+ // Note that the offset starts from IP header.
+ // These must be added ether header length when generating program.
+ static final int IP_HEADER_OFFSET = 0;
+
+ protected static class TcpKeepaliveAckData {
+ public final byte[] srcAddress;
+ public final int srcPort;
+ public final byte[] dstAddress;
+ public final int dstPort;
+ public final int seq;
+ public final int ack;
+ // Create the characteristics of the ack packet from the sent keepalive packet.
+ TcpKeepaliveAckData(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
+ srcAddress = sentKeepalivePacket.dstAddress;
+ srcPort = sentKeepalivePacket.dstPort;
+ dstAddress = sentKeepalivePacket.srcAddress;
+ dstPort = sentKeepalivePacket.srcPort;
+ seq = sentKeepalivePacket.ack;
+ ack = sentKeepalivePacket.seq + 1;
+ }
+ }
+
+ protected final TcpKeepaliveAckData mPacket;
+ protected final byte[] mSrcDstAddr;
+
+ TcpKeepaliveAck(final TcpKeepaliveAckData packet, final byte[] srcDstAddr) {
+ mPacket = packet;
+ mSrcDstAddr = srcDstAddr;
+ }
+
+ static byte[] concatArrays(final byte[]... arr) {
+ int size = 0;
+ for (byte[] a : arr) {
+ size += a.length;
+ }
+ final byte[] result = new byte[size];
+ int offset = 0;
+ for (byte[] a : arr) {
+ System.arraycopy(a, 0, result, offset, a.length);
+ offset += a.length;
+ }
+ return result;
+ }
+
+ public String toString() {
+ return String.format("%s(%d) -> %s(%d), seq=%d, ack=%d",
+ mPacket.srcAddress,
+ mPacket.srcPort,
+ mPacket.dstAddress,
+ mPacket.dstPort,
+ mPacket.seq,
+ mPacket.ack);
+ }
+
+ // Append a filter for this keepalive ack to {@code gen}.
+ // Jump to drop if it matches the keepalive ack.
+ // Jump to the next filter if packet doesn't match the keepalive ack.
+ abstract void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException;
+ }
+
+ private class TcpKeepaliveAckV4 extends TcpKeepaliveAck {
+ private static final int IPV4_SRC_ADDR_OFFSET = IP_HEADER_OFFSET + 12;
+ private static final int IPV4_TCP_SRC_PORT_OFFSET = 0;
+ private static final int IPV4_TCP_DST_PORT_OFFSET = 2;
+ private static final int IPV4_TCP_SEQ_OFFSET = 4;
+ private static final int IPV4_TCP_ACK_OFFSET = 8;
+
+ TcpKeepaliveAckV4(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
+ this(new TcpKeepaliveAckData(sentKeepalivePacket));
+ }
+ TcpKeepaliveAckV4(final TcpKeepaliveAckData packet) {
+ super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
+ }
+
+ @Override
+ void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+ final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked();
+ gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
+ gen.addJumpIfR0NotEquals(IPPROTO_TCP, nextFilterLabel);
+ gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
+ gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
+
+ // Pass the packet if it's not zero-sized :
+ // Load the IP header size into R1
+ gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
+ // Load the TCP header size into R0 (it's indexed by R1)
+ gen.addLoad8Indexed(Register.R0, ETH_HEADER_LEN + TCP_HEADER_SIZE_OFFSET);
+ // Size offset is in the top nibble, but it must be multiplied by 4, and the two
+ // top bits of the low nibble are guaranteed to be zeroes. Right-shift R0 by 2.
+ gen.addRightShift(2);
+ // R0 += R1 -> R0 contains TCP + IP headers lenght
+ gen.addAddR1();
+ // Add the Ethernet header length to R0.
+ gen.addLoadImmediate(Register.R1, ETH_HEADER_LEN);
+ gen.addAddR1();
+ // Compare total length of headers to the size of the packet.
+ gen.addLoadFromMemory(Register.R1, gen.PACKET_SIZE_MEMORY_SLOT);
+ gen.addNeg(Register.R0);
+ gen.addAddR1();
+ gen.addJumpIfR0NotEquals(0, nextFilterLabel);
+
+ // Add IPv4 header length
+ gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
+ gen.addLoad16Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_SRC_PORT_OFFSET);
+ gen.addJumpIfR0NotEquals(mPacket.srcPort, nextFilterLabel);
+ gen.addLoad16Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_DST_PORT_OFFSET);
+ gen.addJumpIfR0NotEquals(mPacket.dstPort, nextFilterLabel);
+ gen.addLoad32Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_SEQ_OFFSET);
+ gen.addJumpIfR0NotEquals(mPacket.seq, nextFilterLabel);
+ gen.addLoad32Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_ACK_OFFSET);
+ gen.addJumpIfR0NotEquals(mPacket.ack, nextFilterLabel);
+
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_KEEPALIVE_ACK);
+ gen.addJump(mCountAndDropLabel);
+ gen.defineLabel(nextFilterLabel);
+ }
+ }
+
+ private class TcpKeepaliveAckV6 extends TcpKeepaliveAck {
+ TcpKeepaliveAckV6(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
+ this(new TcpKeepaliveAckData(sentKeepalivePacket));
+ }
+ TcpKeepaliveAckV6(final TcpKeepaliveAckData packet) {
+ super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
+ }
+
+ @Override
+ void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+ throw new UnsupportedOperationException("IPv6 Keepalive is not supported yet");
+ }
+ }
+
// Maximum number of RAs to filter for.
private static final int MAX_RAS = 10;
@GuardedBy("this")
- private ArrayList<Ra> mRas = new ArrayList<Ra>();
+ private ArrayList<Ra> mRas = new ArrayList<>();
+ @GuardedBy("this")
+ private SparseArray<TcpKeepaliveAck> mKeepaliveAcks = new SparseArray<>();
// There is always some marginal benefit to updating the installed APF program when an RA is
// seen because we can extend the program's lifetime slightly, but there is some cost to
@@ -980,6 +1124,8 @@
// drop
// if it's IPv4 broadcast:
// drop
+ // if keepalive ack
+ // drop
// pass
if (mMulticastFilter) {
@@ -1023,6 +1169,9 @@
gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
}
+ // If any keepalive filters,
+ generateKeepaliveFilter(gen);
+
// If L2 broadcast packet, drop.
// TODO: can we invert this condition to fall through to the common pass case below?
maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
@@ -1030,6 +1179,8 @@
gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
gen.addJump(mCountAndDropLabel);
+ } else {
+ generateKeepaliveFilter(gen);
}
// Otherwise, pass
@@ -1037,6 +1188,13 @@
gen.addJump(mCountAndPassLabel);
}
+ private void generateKeepaliveFilter(ApfGenerator gen) throws IllegalInstructionException {
+ // Drop IPv4 Keepalive acks
+ for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
+ final TcpKeepaliveAck ack = mKeepaliveAcks.valueAt(i);
+ if (ack instanceof TcpKeepaliveAckV4) ack.generateFilterLocked(gen);
+ }
+ }
/**
* Generate filter code to process IPv6 packets. Execution of this code ends in either the
@@ -1057,6 +1215,8 @@
// drop
// if it's ICMPv6 NA to ff02::1:
// drop
+ // if keepalive ack
+ // drop
gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
@@ -1112,6 +1272,12 @@
maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
gen.addJump(mCountAndDropLabel);
gen.defineLabel(skipUnsolicitedMulticastNALabel);
+
+ // Drop IPv6 Keepalive acks
+ for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
+ final TcpKeepaliveAck ack = mKeepaliveAcks.valueAt(i);
+ if (ack instanceof TcpKeepaliveAckV6) ack.generateFilterLocked(gen);
+ }
}
/**
@@ -1489,6 +1655,36 @@
installNewProgramLocked();
}
+ /**
+ * Add keepalive ack packet filter.
+ * This will add a filter to drop acks to the keepalive packet passed as an argument.
+ *
+ * @param slot The index used to access the filter.
+ * @param sentKeepalivePacket The attributes of the sent keepalive packet.
+ */
+ public synchronized void addKeepalivePacketFilter(final int slot,
+ final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
+ log("Adding keepalive ack(" + slot + ")");
+ if (null != mKeepaliveAcks.get(slot)) {
+ throw new IllegalArgumentException("Keepalive slot " + slot + " is occupied");
+ }
+ final int ipVersion = sentKeepalivePacket.srcAddress.length == 4 ? 4 : 6;
+ mKeepaliveAcks.put(slot, (ipVersion == 4)
+ ? new TcpKeepaliveAckV4(sentKeepalivePacket)
+ : new TcpKeepaliveAckV6(sentKeepalivePacket));
+ installNewProgramLocked();
+ }
+
+ /**
+ * Remove keepalive packet filter.
+ *
+ * @param slot The index used to access the filter.
+ */
+ public synchronized void removeKeepalivePacketFilter(int slot) {
+ mKeepaliveAcks.remove(slot);
+ installNewProgramLocked();
+ }
+
static public long counterValue(byte[] data, Counter counter)
throws ArrayIndexOutOfBoundsException {
// Follow the same wrap-around addressing scheme of the interpreter.
@@ -1541,6 +1737,17 @@
}
pw.decreaseIndent();
+ pw.println("Keepalive filter:");
+ pw.increaseIndent();
+ for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
+ final TcpKeepaliveAck keepaliveAck = mKeepaliveAcks.valueAt(i);
+ pw.print("Slot ");
+ pw.print(mKeepaliveAcks.keyAt(i));
+ pw.print(" : ");
+ pw.println(keepaliveAck);
+ }
+ pw.decreaseIndent();
+
if (DBG) {
pw.println("Last program:");
pw.increaseIndent();
diff --git a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
index 87a1b5e..809327a 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
@@ -476,7 +476,7 @@
/**
* Add an instruction to the end of the program to load 16-bits from the packet into
- * {@code register}. The offset of the loaded 16-bits from the begining of the packet is
+ * {@code register}. The offset of the loaded 16-bits from the beginning of the packet is
* the sum of {@code offset} and the value in register R1.
*/
public ApfGenerator addLoad16Indexed(Register register, int offset) {
@@ -488,7 +488,7 @@
/**
* Add an instruction to the end of the program to load 32-bits from the packet into
- * {@code register}. The offset of the loaded 32-bits from the begining of the packet is
+ * {@code register}. The offset of the loaded 32-bits from the beginning of the packet is
* the sum of {@code offset} and the value in register R1.
*/
public ApfGenerator addLoad32Indexed(Register register, int offset) {
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
index 12fe8c5..9e59912 100644
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ b/packages/NetworkStack/src/android/net/ip/IpClient.java
@@ -23,6 +23,7 @@
import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
+import android.annotation.NonNull;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.DhcpResults;
@@ -34,6 +35,7 @@
import android.net.ProxyInfo;
import android.net.ProxyInfoParcelable;
import android.net.RouteInfo;
+import android.net.TcpKeepalivePacketDataParcelable;
import android.net.apf.ApfCapabilities;
import android.net.apf.ApfFilter;
import android.net.dhcp.DhcpClient;
@@ -292,6 +294,8 @@
private static final int EVENT_PROVISIONING_TIMEOUT = 10;
private static final int EVENT_DHCPACTION_TIMEOUT = 11;
private static final int EVENT_READ_PACKET_FILTER_COMPLETE = 12;
+ private static final int CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF = 13;
+ private static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF = 14;
// Internal commands to use instead of trying to call transitionTo() inside
// a given State's enter() method. Calling transitionTo() from enter/exit
@@ -522,6 +526,16 @@
checkNetworkStackCallingPermission();
IpClient.this.setMulticastFilter(enabled);
}
+ @Override
+ public void addKeepalivePacketFilter(int slot, TcpKeepalivePacketDataParcelable pkt) {
+ checkNetworkStackCallingPermission();
+ IpClient.this.addKeepalivePacketFilter(slot, pkt);
+ }
+ @Override
+ public void removeKeepalivePacketFilter(int slot) {
+ checkNetworkStackCallingPermission();
+ IpClient.this.removeKeepalivePacketFilter(slot);
+ }
}
public String getInterfaceName() {
@@ -644,6 +658,22 @@
}
/**
+ * Called by WifiStateMachine to add keepalive packet filter before setting up
+ * keepalive offload.
+ */
+ public void addKeepalivePacketFilter(int slot, @NonNull TcpKeepalivePacketDataParcelable pkt) {
+ sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, 0 /* Unused */, pkt);
+ }
+
+ /**
+ * Called by WifiStateMachine to remove keepalive packet filter after stopping keepalive
+ * offload.
+ */
+ public void removeKeepalivePacketFilter(int slot) {
+ sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF, slot, 0 /* Unused */);
+ }
+
+ /**
* Dump logs of this IpClient.
*/
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
@@ -1512,6 +1542,23 @@
break;
}
+ case CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF: {
+ final int slot = msg.arg1;
+ if (mApfFilter != null) {
+ mApfFilter.addKeepalivePacketFilter(slot,
+ (TcpKeepalivePacketDataParcelable) msg.obj);
+ }
+ break;
+ }
+
+ case CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF: {
+ final int slot = msg.arg1;
+ if (mApfFilter != null) {
+ mApfFilter.removeKeepalivePacketFilter(slot);
+ }
+ break;
+ }
+
case EVENT_DHCPACTION_TIMEOUT:
stopDhcpAction();
break;
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index dbffa6d..0d6d080 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -61,6 +61,7 @@
import android.net.util.Stopwatch;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -674,11 +675,11 @@
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_LAUNCH_CAPTIVE_PORTAL_APP:
- final Intent intent = new Intent(
- ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
+ final Bundle appExtras = new Bundle();
// OneAddressPerFamilyNetwork is not parcelable across processes.
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK, new Network(mNetwork));
- intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
+ appExtras.putParcelable(
+ ConnectivityManager.EXTRA_NETWORK, new Network(mNetwork));
+ appExtras.putParcelable(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
new CaptivePortal(new ICaptivePortal.Stub() {
@Override
public void appResponse(int response) {
@@ -700,16 +701,14 @@
}
}));
final CaptivePortalProbeResult probeRes = mLastPortalProbeResult;
- intent.putExtra(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl);
+ appExtras.putString(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl);
if (probeRes.probeSpec != null) {
final String encodedSpec = probeRes.probeSpec.getEncodedSpec();
- intent.putExtra(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC, encodedSpec);
+ appExtras.putString(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC, encodedSpec);
}
- intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
+ appExtras.putString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
mCaptivePortalUserAgent);
- intent.setFlags(
- Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ mCm.startCaptivePortalApp(appExtras);
return HANDLED;
default:
return NOT_HANDLED;
diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp
index 45fa2dc..4a09b3e 100644
--- a/packages/NetworkStack/tests/Android.bp
+++ b/packages/NetworkStack/tests/Android.bp
@@ -49,6 +49,7 @@
"libhidlbase",
"libhidltransport",
"libhwbinder",
+ "libjsoncpp",
"liblog",
"liblzma",
"libnativehelper",
diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
index f76e412..a4a1000 100644
--- a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
+++ b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
@@ -39,13 +39,14 @@
import android.content.Context;
import android.net.LinkAddress;
import android.net.LinkProperties;
+import android.net.SocketKeepalive;
+import android.net.TcpKeepalivePacketData;
+import android.net.TcpKeepalivePacketData.TcpSocketInfo;
import android.net.apf.ApfFilter.ApfConfiguration;
import android.net.apf.ApfGenerator.IllegalInstructionException;
import android.net.apf.ApfGenerator.Register;
import android.net.ip.IIpClientCallbacks;
-import android.net.ip.IpClient;
import android.net.ip.IpClient.IpClientCallbacksWrapper;
-import android.net.ip.IpClientCallbacks;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.RaEvent;
import android.net.util.InterfaceParams;
@@ -1003,15 +1004,31 @@
private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
+ private static final int IPV4_HEADER_LEN = 20;
private static final int IPV4_VERSION_IHL_OFFSET = ETH_HEADER_LEN + 0;
+ private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
+ private static final int IPV4_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 12;
private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
+ private static final int IPV4_TCP_HEADER_LEN = 20;
+ private static final int IPV4_TCP_HEADER_OFFSET = ETH_HEADER_LEN + IPV4_HEADER_LEN;
+ private static final int IPV4_TCP_SRC_PORT_OFFSET = IPV4_TCP_HEADER_OFFSET + 0;
+ private static final int IPV4_TCP_DEST_PORT_OFFSET = IPV4_TCP_HEADER_OFFSET + 2;
+ private static final int IPV4_TCP_SEQ_NUM_OFFSET = IPV4_TCP_HEADER_OFFSET + 4;
+ private static final int IPV4_TCP_ACK_NUM_OFFSET = IPV4_TCP_HEADER_OFFSET + 8;
+ private static final int IPV4_TCP_HEADER_LENGTH_OFFSET = IPV4_TCP_HEADER_OFFSET + 12;
private static final byte[] IPV4_BROADCAST_ADDRESS =
{(byte) 255, (byte) 255, (byte) 255, (byte) 255};
private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6;
private static final int IPV6_HEADER_LEN = 40;
+ private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8;
private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24;
+ private static final int IPV6_TCP_HEADER_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
+ private static final int IPV6_TCP_SRC_PORT_OFFSET = IPV6_TCP_HEADER_OFFSET + 0;
+ private static final int IPV6_TCP_DEST_PORT_OFFSET = IPV6_TCP_HEADER_OFFSET + 2;
+ private static final int IPV6_TCP_SEQ_NUM_OFFSET = IPV6_TCP_HEADER_OFFSET + 4;
+ private static final int IPV6_TCP_ACK_NUM_OFFSET = IPV6_TCP_HEADER_OFFSET + 8;
// The IPv6 all nodes address ff02::1
private static final byte[] IPV6_ALL_NODES_ADDRESS =
{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
@@ -1491,6 +1508,200 @@
return packet.array();
}
+ private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 5};
+ private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 6};
+ private static final byte[] IPV4_ANOTHER_ADDR = {10, 0 , 0, 7};
+ private static final byte[] IPV6_KEEPALIVE_SRC_ADDR =
+ {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf1};
+ private static final byte[] IPV6_KEEPALIVE_DST_ADDR =
+ {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf2};
+ private static final byte[] IPV6_ANOTHER_ADDR =
+ {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf5};
+
+ @Test
+ public void testApfFilterKeepaliveAck() throws Exception {
+ final MockIpClientCallback cb = new MockIpClientCallback();
+ final ApfConfiguration config = getDefaultConfig();
+ config.multicastFilter = DROP_MULTICAST;
+ config.ieee802_3Filter = DROP_802_3_FRAMES;
+ final TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
+ byte[] program;
+ final int srcPort = 12345;
+ final int dstPort = 54321;
+ final int seqNum = 2123456789;
+ final int ackNum = 1234567890;
+ final int anotherSrcPort = 23456;
+ final int anotherDstPort = 65432;
+ final int anotherSeqNum = 2123456780;
+ final int anotherAckNum = 1123456789;
+ final int slot1 = 1;
+ final int slot2 = 2;
+ final int window = 14480;
+ final int windowScale = 4;
+
+ // src: 10.0.0.5, port: 12345
+ // dst: 10.0.0.6, port: 54321
+ InetAddress srcAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_SRC_ADDR);
+ InetAddress dstAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_DST_ADDR);
+
+ final TcpSocketInfo v4Tsi = new TcpSocketInfo(
+ srcAddr, srcPort, dstAddr, dstPort, seqNum, ackNum, window, windowScale);
+ final TcpKeepalivePacketData ipv4TcpKeepalivePacket =
+ TcpKeepalivePacketData.tcpKeepalivePacket(v4Tsi);
+
+ apfFilter.addKeepalivePacketFilter(slot1, ipv4TcpKeepalivePacket.toStableParcelable());
+ program = cb.getApfProgram();
+
+ // Verify IPv4 keepalive ack packet is dropped
+ // src: 10.0.0.6, port: 54321
+ // dst: 10.0.0.5, port: 12345
+ assertDrop(program,
+ ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
+ // Verify IPv4 non-keepalive ack packet from the same source address is passed
+ assertPass(program,
+ ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum + 100, seqNum, 0 /* dataLength */));
+ assertPass(program,
+ ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum, seqNum + 1, 10 /* dataLength */));
+ // Verify IPv4 packet from another address is passed
+ assertPass(program,
+ ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort,
+ anotherDstPort, anotherSeqNum, anotherAckNum));
+
+ // Remove IPv4 keepalive filter
+ apfFilter.removeKeepalivePacketFilter(slot1);
+
+ try {
+ // src: 2404:0:0:0:0:0:faf1, port: 12345
+ // dst: 2404:0:0:0:0:0:faf2, port: 54321
+ srcAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_SRC_ADDR);
+ dstAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_DST_ADDR);
+ final TcpSocketInfo v6Tsi = new TcpSocketInfo(
+ srcAddr, srcPort, dstAddr, dstPort, seqNum, ackNum, window, windowScale);
+ final TcpKeepalivePacketData ipv6TcpKeepalivePacket =
+ TcpKeepalivePacketData.tcpKeepalivePacket(v6Tsi);
+ apfFilter.addKeepalivePacketFilter(slot1, ipv6TcpKeepalivePacket.toStableParcelable());
+ program = cb.getApfProgram();
+
+ // Verify IPv6 keepalive ack packet is dropped
+ // src: 2404:0:0:0:0:0:faf2, port: 54321
+ // dst: 2404:0:0:0:0:0:faf1, port: 12345
+ assertDrop(program,
+ ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum, seqNum + 1));
+ // Verify IPv6 non-keepalive ack packet from the same source address is passed
+ assertPass(program,
+ ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum + 100, seqNum));
+ // Verify IPv6 packet from another address is passed
+ assertPass(program,
+ ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, anotherSrcPort,
+ anotherDstPort, anotherSeqNum, anotherAckNum));
+
+ // Remove IPv6 keepalive filter
+ apfFilter.removeKeepalivePacketFilter(slot1);
+
+ // Verify multiple filters
+ apfFilter.addKeepalivePacketFilter(slot1, ipv4TcpKeepalivePacket.toStableParcelable());
+ apfFilter.addKeepalivePacketFilter(slot2, ipv6TcpKeepalivePacket.toStableParcelable());
+ program = cb.getApfProgram();
+
+ // Verify IPv4 keepalive ack packet is dropped
+ // src: 10.0.0.6, port: 54321
+ // dst: 10.0.0.5, port: 12345
+ assertDrop(program,
+ ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum, seqNum + 1));
+ // Verify IPv4 non-keepalive ack packet from the same source address is passed
+ assertPass(program,
+ ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum + 100, seqNum));
+ // Verify IPv4 packet from another address is passed
+ assertPass(program,
+ ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort,
+ anotherDstPort, anotherSeqNum, anotherAckNum));
+
+ // Verify IPv6 keepalive ack packet is dropped
+ // src: 2404:0:0:0:0:0:faf2, port: 54321
+ // dst: 2404:0:0:0:0:0:faf1, port: 12345
+ assertDrop(program,
+ ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum, seqNum + 1));
+ // Verify IPv6 non-keepalive ack packet from the same source address is passed
+ assertPass(program,
+ ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum + 100, seqNum));
+ // Verify IPv6 packet from another address is passed
+ assertPass(program,
+ ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, anotherSrcPort,
+ anotherDstPort, anotherSeqNum, anotherAckNum));
+
+ // Remove keepalive filters
+ apfFilter.removeKeepalivePacketFilter(slot1);
+ apfFilter.removeKeepalivePacketFilter(slot2);
+ } catch (SocketKeepalive.InvalidPacketException e) {
+ // TODO: support V6 packets
+ }
+
+ program = cb.getApfProgram();
+
+ // Verify IPv4, IPv6 packets are passed
+ assertPass(program,
+ ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum, seqNum + 1));
+ assertPass(program,
+ ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
+ dstPort, srcPort, ackNum, seqNum + 1));
+ assertPass(program,
+ ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, srcPort,
+ dstPort, anotherSeqNum, anotherAckNum));
+ assertPass(program,
+ ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, srcPort,
+ dstPort, anotherSeqNum, anotherAckNum));
+
+ apfFilter.shutdown();
+ }
+
+ private static byte[] ipv4Packet(byte[] sip, byte[] tip, int sport,
+ int dport, int seq, int ack) {
+ ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+ packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IP);
+ packet.put(IPV4_VERSION_IHL_OFFSET, (byte) 0x45);
+ put(packet, IPV4_SRC_ADDR_OFFSET, sip);
+ put(packet, IPV4_DEST_ADDR_OFFSET, tip);
+ packet.putShort(IPV4_TCP_SRC_PORT_OFFSET, (short) sport);
+ packet.putShort(IPV4_TCP_DEST_PORT_OFFSET, (short) dport);
+ packet.putInt(IPV4_TCP_SEQ_NUM_OFFSET, seq);
+ packet.putInt(IPV4_TCP_ACK_NUM_OFFSET, ack);
+ return packet.array();
+ }
+
+ private static byte[] ipv4Packet(byte[] sip, byte[] tip, int sport,
+ int dport, int seq, int ack, int dataLength) {
+ final int totalLength = dataLength + IPV4_HEADER_LEN + IPV4_TCP_HEADER_LEN;
+
+ ByteBuffer packet = ByteBuffer.wrap(ipv4Packet(sip, tip, sport, dport, seq, ack));
+ packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength);
+ // TCP header length 5, reserved 3 bits, NS=0
+ packet.put(IPV4_TCP_HEADER_LENGTH_OFFSET, (byte) 0x50);
+ return packet.array();
+ }
+
+ private static byte[] ipv6Packet(byte[] sip, byte[] tip, int sport,
+ int dport, int seq, int ack) {
+ ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+ packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IPV6);
+ put(packet, IPV6_SRC_ADDR_OFFSET, sip);
+ put(packet, IPV6_DEST_ADDR_OFFSET, tip);
+ packet.putShort(IPV6_TCP_SRC_PORT_OFFSET, (short) sport);
+ packet.putShort(IPV6_TCP_DEST_PORT_OFFSET, (short) dport);
+ packet.putInt(IPV6_TCP_SEQ_NUM_OFFSET, seq);
+ packet.putInt(IPV6_TCP_ACK_NUM_OFFSET, ack);
+ return packet.array();
+ }
+
// Verify that the last program pushed to the IpClient.Callback properly filters the
// given packet for the given lifetime.
private void verifyRaLifetime(byte[] program, ByteBuffer packet, int lifetime) {
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 5a81f8b..36ee813 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -20,7 +20,7 @@
"SettingsLibLayoutPreference",
"SettingsLibActionButtonsPreference",
"SettingsLibEntityHeaderWidgets",
- "SettingsLibBarChartPreference"
+ "SettingsLibBarChartPreference",
],
// ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
@@ -34,4 +34,18 @@
}
-// For the test package.
+// NOTE: Keep this module in sync with ./common.mk
+java_defaults {
+ name: "SettingsLibDefaults",
+ static_libs: [
+ "androidx.annotation_annotation",
+ "androidx.lifecycle_lifecycle-common",
+ "androidx.legacy_legacy-support-v4",
+ "androidx.lifecycle_lifecycle-runtime",
+ "androidx.recyclerview_recyclerview",
+ "androidx.preference_preference",
+ "androidx.appcompat_appcompat",
+ "androidx.legacy_legacy-preference-v14",
+ "SettingsLib",
+ ],
+}
diff --git a/packages/SettingsLib/HelpUtils/res/values-en-rXC/strings.xml b/packages/SettingsLib/HelpUtils/res/values-en-rXC/strings.xml
index 21084fb..e991f18 100644
--- a/packages/SettingsLib/HelpUtils/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-en-rXC/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="help_feedback_label" msgid="4550436169116444686">"Help & feedback"</string>
+ <string name="help_feedback_label" msgid="4550436169116444686">"Help & feedback"</string>
</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-en-rXC/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rXC/strings.xml
index f329a76..8b19b6e 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-en-rXC/strings.xml
@@ -17,6 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="enabled_by_admin" msgid="7797093432952898000">"Enabled by admin"</string>
- <string name="disabled_by_admin" msgid="1910810467107358241">"Disabled by admin"</string>
+ <string name="enabled_by_admin" msgid="7797093432952898000">"Enabled by admin"</string>
+ <string name="disabled_by_admin" msgid="1910810467107358241">"Disabled by admin"</string>
</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-en-rXC/strings.xml b/packages/SettingsLib/SearchWidget/res/values-en-rXC/strings.xml
index c8627c8..5dae336 100644
--- a/packages/SettingsLib/SearchWidget/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-en-rXC/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1604061903696928905">"Search settings"</string>
+ <string name="search_menu" msgid="1604061903696928905">"Search settings"</string>
</resources>
diff --git a/packages/SettingsLib/common.mk b/packages/SettingsLib/common.mk
index 834b83b..8c309ff 100644
--- a/packages/SettingsLib/common.mk
+++ b/packages/SettingsLib/common.mk
@@ -12,6 +12,11 @@
#
# include frameworks/base/packages/SettingsLib/common.mk
#
+# During the conversion to Soong bluprint files, the equivalent
+# functionality is provided by adding
+# defaults: ["SettingsLibDefaults"],
+# to the corresponding module.
+# NOTE: keep this file and ./Android.bp in sync.
LOCAL_STATIC_JAVA_LIBRARIES += \
androidx.annotation_annotation \
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index 5a96a58..0e2d0e6 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Gebruik HDCP-kontrolering net vir DRM-inhoud"</item>
<item msgid="45075631231212732">"Gebruik altyd HDCP-kontrolering"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Gedeaktiveer"</item>
+ <item msgid="1969681323976948639">"Het gefiltreer geaktiveer"</item>
+ <item msgid="8719029132154020716">"Geaktiveer"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (verstek)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 0e46f61..0988cab 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Outomaties deur %1$s gekoppel"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Outomaties deur netwerkgraderingverskaffer gekoppel"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Gekoppel via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> deur <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Gekoppel via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Beskikbaar via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tik om op te stel"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tik om aan te meld"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Gekoppel, geen internet nie"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Geen internet nie"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Aanmelding word vereis"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Toegangspunt is tydelik vol"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Gekoppel via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Beskikbaar via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Kon nie koppel nie"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Ongeldige OSU-bediener-URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU-bediener kon nie koppel nie"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU-bediener kon nie gestaaf word nie"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Ongeldige OSU-bedienersertifikaat"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Opstelling is gestaak"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Opstelling is nie beskikbaar nie"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Ongeldige OSU-bediener-URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Onvoorsiene beveltipe"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Onvoorsiene SOAP-boodskapsoort"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP-boodskappe kon nie uitgeruil word nie"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Herlei-luisteraar kon nie begin nie"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Wagperiode vir herleiding het uitgetel"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Geen OSU-aktiwiteit gekry nie"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Onvoorsiene SOAP-boodskapstatus"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Kon nie PPS-MO kry nie"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Kon nie vertroue-kernnodus vir AAA-bediener kry nie"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Kon nie vertroue-kernnodus vir regstellingbediener kry nie"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Kon nie vertroue-kernnodus vir beleidbediener kry nie"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Kon nie vertroue-kernsertifikate ophaal nie"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Kon nie vertroue-kernsertifikaat vir AAA-bediener kry nie"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Kon nie PassPoint-opstelling byvoeg nie"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Kon nie \'n OSU-verskaffer kry nie"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Koppel tans"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Gekoppel"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Koppel tans aan OSU-bediener"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-bediener is gestaaf"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Gekoppel aan OSU-bediener"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Aanvanklike SOAP-uitruiling"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Wag tans vir herlei-reaksie"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Het herlei-antwoord ontvang"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Tweede SOAP-uitruiling"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Derde SOAP-uitruiling"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Haal tans vertroue-kernsertifikate op"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Opstelling is voltooi"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Maak tans <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> oop"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Kon nie koppel nie"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Voltooi tans aanmelding …"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Kon nie aanmelding voltooi nie. Tik om weer te probeer."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Aanmelding is voltooi. Koppel tans …"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Baie stadig"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Stadig"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Bly wakker"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Skerm sal nooit slaap terwyl dit laai nie"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Aktiveer Bluetooth HCI-loerloglêer"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Vang Bluetooth-pakkette vas. (Wissel Bluetooth nadat jy hierdie instelling verander het)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-ontsluit"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Laat toe dat die selflaaiprogram ontsluit word"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Laat OEM-ontsluit toe?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Inligtingruiling"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Draadlose skermsertifisering"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktiveer Wi-Fi-woordryke aanmelding"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Gekoppelde MAC-verewekansiging"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data is altyd aktief"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardewareversnelling vir verbinding"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Wys Bluetooth-toestelle sonder name"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kon nie koppel nie"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Wys opsies vir draadlose skermsertifisering"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Verhoog Wi-Fi-aantekeningvlak, wys per SSID RSSI in Wi‑Fi-kieser"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Verewekansig MAC-adres wanneer daar aan Wi‑Fi-netwerke gekoppel word"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Beperk"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Onbeperk"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Loggerbuffer se groottes"</string>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index b1acfb7..8138a6a 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"ለDRM ይዘት ብቻ HDCP ምልከታን ተጠቀም"</item>
<item msgid="45075631231212732">"ሁልጊዜ የHDCP ምልከታ ተጠቀም"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"ተሰናክሏል"</item>
+ <item msgid="1969681323976948639">"ማጣሪያን አንቃ"</item>
+ <item msgid="8719029132154020716">"ነቅቷል"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ነባሪ)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 2304908..301d609 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"በ%1$s በኩል በራስ-ሰር ተገናኝቷል"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"በአውታረ መረብ ደረጃ ሰጪ አቅራቢ በኩል በራስ-ሰር ተገናኝቷል"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"በ%1$s በኩል መገናኘት"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> በ<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"በ <xliff:g id="NAME">%1$s</xliff:g> በኩል ተገናኝተዋል"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"በ%1$s በኩል የሚገኝ"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"ለማዋቀር መታ ያድርጉ"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"ለመመዝገብ መታ ያድርጉ"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"ተገናኝቷል፣ ምንም በይነመረብ የለም"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ምንም በይነመረብ የለም"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ወደ መለያ መግባት ያስፈልጋል"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"የመዳረሻ ነጥብ ለጊዜው ሞልቷል"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"በ%1$s በኩል ተገናኝቷል"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"በ%1$s በኩል የሚገኝ"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"ግንኙነት አልተሳካም"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"ልክ ያልኾነ OSU አገልጋይ ዩአርኤል"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU አገልጋይ ግንኙነት አልተሳካም"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU አገልጋይ ማረጋገጥ አልተሳካም"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"ልክ ያልኾነ OSU አገልጋይ ዩአርኤል"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"በባለቤትነት መያዝ ተጨናግፏል"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"በባለቤትነት መያዝ አይገኝም"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"ልክ ያልኾነ OSU አገልጋይ ዩአርኤል"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ያልተጠበቀ የትዕዛዝ ዓይነት"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ያልተጠበቀ SOAP መልዕክት ዓይነት"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP መልዕክት ልውውጥ አልተሳካም"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"አቅጣጫ ቀይር አዳማጭ መጀመር አልቻለም"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"አቅጣጫን ቀይርን መጠበቅ ጊዜው አብቅቷል"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"ምንም የOSU እንቅስቃሴ አልተገኘም"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"ያልተጠበቀ SOAP መልዕክት ሁኔታ"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO ማግኘት አልተሳካም"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"ለAAA አገልጋይ የታመነ የሥር እስር ማግኘት አልተቻለም"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ለማስተካከያ አገልጋይ የታመነ የሥር እስር ማግኘት አልተቻለም"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"ለመመሪያ አገልጋይ የታመነ የሥር እስር ማግኘት አልተቻለም"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"የሥር እውቅና ማረጋገጫን ሰርስሮ ማውጣት አልተቻለም"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"ለ AAA አገልጋይ የሥር እውቅና ማረጋገጫ ማግኘት አልተሳካም"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPointን ውቅረት ማከል አልተሳካም"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"የOSU አቅራቢን ማግኘት አልተሳካም"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"በመገናኘት ላይ"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"ተገናኝቷል"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"ወደ OSU አገልጋይ በማገናኘት ላይ"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU አገልጋይ ተረጋግጧል"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"ወደ OSU አገልጋይ ተገናኝቷል"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"የመጀመሪያ SOAP ልውውጥ"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"ለአቅጣጫ ቀይር ምላሽ በመጠባበቅ ላይ"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"የአቅጣጫ ቀይር ምላሽ ተቀብሏል"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"ሁለተኛ SOAP ልውውጥ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"ሦስተኛ SOAP ልውውጥ"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"የሥር እውቅና ማረጋገጫዎችን ሰርስሮ በማውጣት ላይ"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"በባለቤትነት መያዝ ተጠናቋል"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>ን በመክፈት ላይ"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"መገናኘት አልተቻለም"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"መመዝገብን በማጠናቀቅ ላይ…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"መመዝገብን ማጠናቀቅ አልተቻለም። እንደገና ለመሞከር መታ ያድርጉ።"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"ምዝገባ ተጠናቋል። በማገናኘት ላይ…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"በጣም ቀርፋፋ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"አዘግይ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"እሺ"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"ነቅተህ ቆይ"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ማያኃይል በመሙላት ላይበፍፁም አይተኛም"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"የብሉቱዝ HCI ስለላ ምዝግብ ማስታወሻን ያንቁ"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"የብሉቱዝ ጥቅሎችን ያዝል። (ይህን ቅንብር ከቀየሩ በኋላ ብሉቱዝን ያብሩ/ያጥፉ)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM መክፈቻ"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"የማስነሻ ተሸካሚ እንዲከፈት ፍቀድ"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"የOEM መክፈቻ ይፈቀድ?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"አውታረ መረብ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"የWi‑Fi ተጨማሪ ቃላት ምዝግብ ማስታወሻ መያዝ"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"የተገናኘ የማክ ዘፈቀደ መስሪያ"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"የተንቀሳቃሽ ስልክ ውሂብ ሁልጊዜ ገቢር ነው"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"የሃርድዌር ማቀላጠፊያን በማስተሳሰር ላይ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"የብሉቱዝ መሣሪያዎችን ያለ ስሞች አሳይ"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"መገናኘት አልተቻለም"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ አማራጮችን አሳይ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"የWi‑Fi ምዝግብ ማስታወሻ አያያዝ ደረጃ ጨምር፣ በWi‑Fi መምረጫ ውስጥ በአንድ SSID RSSI አሳይ"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ከWi-Fi አውታረ መረቦች ጋር ሲገናኙ የማክ አድራሻን በዘፈቀደ ይስሩ"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"የሚለካ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"ያልተለካ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"የምዝግብ ማስታወሻ ያዥ መጠኖች"</string>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index 49a080e..7a4dac8 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"استخدام التحقق من HDCP لمحتوى DRM فقط"</item>
<item msgid="45075631231212732">"استخدام التحقق من HDCP دومًا"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"موقوف"</item>
+ <item msgid="1969681323976948639">"تمّ تفعيل التصفية"</item>
+ <item msgid="8719029132154020716">"مفعّل"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (التلقائي)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 09cf925..91de9e3 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"تم الاتصال تلقائيًا عبر %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"تم الاتصال تلقائيًا عبر مقدم خدمة تقييم الشبكة"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"تم الاتصال عبر %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> بواسطة <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"تم الاتصال عبر <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"متوفرة عبر %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"انقر للإعداد."</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"انقر للاشتراك."</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"متصلة ولكن بلا إنترنت"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"لا يتوفر اتصال إنترنت."</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"يلزم تسجيل الدخول"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"نقطة الدخول ممتلئة مؤقتًا"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"تم الاتصال عبر %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"متوفرة عبر %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"تعذّر الاتصال"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"عنوان URL لخادم OSU غير صالح"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"تعذّر الاتصال بخادم OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"تعذّر التحقق من خادم OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"شهادة خادم OSU غير صالحة"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"تم إلغاء إدارة الحسابات"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"إدارة الحسابات غير متاحة"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"عنوان URL لخادم OSU غير صالح"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"نوع الطلب غير متوقّع"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"نوع رسالة SOAP غير متوقّع"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"تعذّر تبادل رسالة SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"تعذّر تشغيل إعادة توجيه المستمع"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"انتهت مهلة انتظار إعادة التوجيه"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"لم يتم العثور على نشاط OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"حالة رسالة SOAP غير متوقعة"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"تعذّر العثور على PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"تعذّر العثور على عقدة جذر الثقة لخادم AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"تعذّر العثور على عقدة جذر الثقة لخادم المعالجة"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"تعذّر العثور على عقدة جذر الثقة لخادم السياسة"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"تعذّر استرداد شهادات جذر الثقة"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"تعذّر العثور على شهادة جذر ثقة لخادم AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"تعذّرت إضافة ضبط PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"تعذّر العثور على مقدّم OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"جارٍ الاتصال"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"تم الاتصال"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"جارٍ الاتصال بخادم OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"تم التحقق من خادم OSU"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"تم الاتصال بخادم OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"تبادل SOAP الأوّل"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"في انتظار رد إعادة التوجيه"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"تم تلقّي رد إعادة توجيه"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"تبادل SOAP الثاني"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"تبادل SOAP الثالث"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"جارٍ استرداد شهادات جذر الثقة"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"اكتملت إدارة الحسابات"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"فتح <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"تعذّر الاتصال."</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"جارٍ إكمال الاشتراك…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"تعذّر إكمال الاشتراك. انقر للمحاولة مرة أخرى."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"اكتمل الاشتراك. جارٍ الاتصال…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"بطيئة جدًا"</string>
<string name="speed_label_slow" msgid="813109590815810235">"بطيئة"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"موافق"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"البقاء في الوضع النشط"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"لا يتم مطلقًا دخول الشاشة في وضع السكون أثناء الشحن"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"تفعيل سجلّ تطفّل بواجهة وحدة تحكّم المضيف عبر بلوتوث"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"رَقمِن محتوى حزم بيانات البلوتوث. (تبديل البلوتوث بعد تغيير هذا الإعداد)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"إلغاء قفل المصنّع الأصلي للجهاز"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"السماح بإلغاء قفل برنامج bootloader"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"هل تريد السماح بإلغاء قفل المصنّع الأصلي للجهاز؟"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"الشبكات"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"شهادة عرض شاشة لاسلكي"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"تفعيل تسجيل Wi‑Fi Verbose"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"اختيار عشوائي لعنوان MAC"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"بيانات الجوّال نشطة دائمًا"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"تسريع الأجهزة للتوصيل"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"عرض أجهزة البلوتوث بدون أسماء"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"تعذّر الاتصال"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"عرض خيارات شهادة عرض شاشة لاسلكي"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"اختيار عشوائي لعنوان MAC عند الاتصال بشبكات Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"تفرض تكلفة استخدام"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"بدون قياس"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"أحجام ذاكرة التخزين المؤقت للتسجيل"</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index e930fe3..183b310 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"কেৱল DRM সমলৰ বাবে HDCP পৰীক্ষণ ব্যৱহাৰ কৰক"</item>
<item msgid="45075631231212732">"সদায় HDCP পৰীক্ষণ ব্যৱহাৰ কৰক"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"অক্ষম আছে"</item>
+ <item msgid="1969681323976948639">"সক্ষম কৰাবিলাক ফিল্টাৰ কৰা হৈছে"</item>
+ <item msgid="8719029132154020716">"সক্ষম কৰা আছে"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP ১.৪ (ডিফ’ল্ট)"</item>
<item msgid="2809759619990248160">"AVRCP ১.৩"</item>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index b95680f..e726ae4 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -38,50 +38,27 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s মাধ্যমেদি স্বয়ংক্ৰিয়ভাৱে সংযোগ কৰা হৈছে"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"নেটৱৰ্ক ৰেটিং প্ৰদানকাৰীৰ জৰিয়তে স্বয়ং সংয়োগ কৰা হ’ল"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ৰ মাধ্যমেদি সংযোগ কৰা হৈছে"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>ৰ <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <!-- no translation found for connected_via_app (5571999941988929520) -->
+ <skip />
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"ছেট আপ কৰিবলৈ টিপক"</string>
+ <!-- no translation found for tap_to_sign_up (6449724763052579434) -->
+ <skip />
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"সংযোজিত, ইণ্টাৰনেট নাই"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ইণ্টাৰনেট সংযোগ নাই"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ছাইন ইন কৰা দৰকাৰী"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"একচেছ পইণ্ট কিছু সময়ৰ বাবে পূৰ্ণ হৈ আছে"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$sৰ যোগেৰে সংযোজিত"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"সংযোগ কৰিব পৰা নগ\'ল"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU ছাৰ্ভাৰৰ URLটো অমান্য"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU ছাৰ্ভাৰৰ সৈতে সংযোগ কৰিব পৰা নগ\'ল"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU ছাৰ্ভাৰ সত্যাপন কৰিব পৰা নগ\'ল"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU ছাৰ্ভাৰৰ প্ৰমাণপত্ৰ অমান্য"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"প্ৰৱন্ধন কৰাটো আধাতে বন্ধ কৰা হ\'ল"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"প্ৰৱন্ধন কৰিব নোৱাৰি"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU ছাৰ্ভাৰৰ URLটো অমান্য"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"অনাকাংক্ষিত কামাণ্ডৰ ধৰণ"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"অনাকাংক্ষিত SOAP বাৰ্তাৰ ধৰণ"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP বাৰ্তা অদল-বদল কৰাত বিফল হ\'ল"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"পুনৰ্নিৰ্দেশ কৰা শুনোতা আৰম্ভ কৰিব পৰা নগ\'ল"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"পুনৰ্নিৰ্দেশ হোৱালৈ ৰৈ থকা সময় সমাপ্ত হ\'ল"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"কোনো OSU কাৰ্যকলাপ বিচাৰি পোৱা নগ\'ল"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP বাৰ্তাৰ স্থিতি অনাকাংক্ষিত"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO বিচাৰি পোৱা নগ\'ল"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA ছাৰ্ভাৰৰ বাবে বিশ্বাসযোগ্য মূল ন\'ড বিচাৰি পোৱা নগ\'ল"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ৰিমেডিয়েশ্বন ছাৰ্ভাৰৰ বাবে বিশ্বাসযোগ্য মূল ন\'ড পোৱা নগ\'ল"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"পলিচি ছাৰ্ভাৰৰ বাবে বিশ্বাসযোগ্য মূল ন\'ড বিচাৰি পোৱা নগ\'ল"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"বিশ্বাসযোগ্য মূল প্ৰমাণপত্ৰ পুনৰুদ্ধাৰ কৰিব পৰা নগ\'ল"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA ছাৰ্ভাৰৰ বাবে বিশ্বাসযোগ্য মূল প্ৰমাণপত্ৰ পোৱা নগ\'ল"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"পাছপইণ্ট কনফিগাৰেশ্বন যোগ কৰিব পৰা নগ\'ল"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU প্ৰদান কৰোঁতা বিচাৰি পোৱা নগ\'ল"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"সংযোগ কৰি থকা হৈছে"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"সংযোগ কৰা হ’ল"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU ছাৰ্ভাৰৰ সৈতে সংযোগ কৰি থকা হৈছে"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU ছাৰ্ভাৰ সত্যাপন কৰা হ\'ল"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU ছাৰ্ভাৰৰ সৈতে সংযোগ কৰা হৈছে"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"প্ৰাৰম্ভিক SOAP এক্সেঞ্জ"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"পুনৰ্নিৰ্দেশৰ সঁহাৰিৰ বাবে অপেক্ষা কৰি থকা হৈছে"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"পুনৰ্নিৰ্দেশৰ সঁহাৰি পোৱা গৈছে"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"দ্বিতীয় SOAP এক্সেঞ্জ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"তৃতীয় SOAP এক্সেঞ্জ"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"বিশ্বাসযোগ্য মূল প্ৰমাণপত্ৰ পুনৰুদ্ধাৰ কৰি থকা হৈছে"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"প্রৱন্ধন কৰা সম্পূৰ্ণ হ\'ল"</string>
+ <!-- no translation found for osu_opening_provider (5488997661548640424) -->
+ <skip />
+ <!-- no translation found for osu_connect_failed (2187750899158158934) -->
+ <skip />
+ <!-- no translation found for osu_completing_sign_up (9037638564719197082) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_failed (7296159750352873260) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_complete (8207626049093289203) -->
+ <skip />
<string name="speed_label_very_slow" msgid="1867055264243608530">"অতি লেহেম"</string>
<string name="speed_label_slow" msgid="813109590815810235">"লেহেমীয়া"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ঠিক"</string>
@@ -234,8 +211,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"জাগ্ৰত কৰি ৰাখক"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"চ্চাৰ্জ হৈ থকাৰ সময়ত স্ক্ৰীণ কেতিয়াও সুপ্ত অৱস্থালৈ নাযায়"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ব্লুটুথ HCI স্নুপ ল’গ সক্ষম কৰক"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ব্লুটুথ পেকেট সংগ্ৰহ কৰক। (এই ছেটিংটো সলনি কৰাৰ পিছত ব্লুটুথ ট’গল কৰক)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"ঔইএম আনলক"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"বুটল\'ডাৰটো আনলক কৰিবলৈ অনুমতি দিয়ক"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"ঔইএম আনলক কৰাৰ অনুমতি দিবনে?"</string>
@@ -246,7 +222,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"নেটৱৰ্কিং"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"বেতাঁৰ ডিছপ্লে’ প্ৰমাণীকৰণ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"ৱাই-ফাই ভাৰ্ব\'ছ লগিং সক্ষম কৰক"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"সংযুক্ত MAC যাদৃচ্ছিকৰণ"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"ম’বাইল ডেটা সদা-সক্ৰিয়"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"নামবিহীন ব্লুটুথ ডিভাইচসমূহ দেখুৱাওক"</string>
@@ -273,7 +248,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"সংযোগ কৰিব পৰা নগ\'ল"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"বেতাঁৰ ডিছপ্লে’ প্ৰমাণপত্ৰৰ বাবে বিকল্পসমূহ দেখুৱাওক"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ৱাই-ফাই লগিঙৰ মাত্ৰা বঢ়াওক, Wi‑Fi পিকাৰত প্ৰতি SSID RSSI দেখুৱাওক"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ৱাই-ফাই নেটৱৰ্কৰ লগত সংযোগ কৰি থকাৰ সময়ত MAC ঠিকনা যাদৃচ্ছিক কৰক"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"নিৰিখ-নিৰ্দিষ্ট"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"নিৰিখ অনিৰ্দিষ্ট"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"লগাৰৰ বাফাৰৰ আকাৰ"</string>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index a662182..ddb289c 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Yalnız DRM məzmun oxumaq üçün HDCP istifadə edin"</item>
<item msgid="45075631231212732">"Həmişə HDCP yoxlama istifadə edin"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Deaktivdir"</item>
+ <item msgid="1969681323976948639">"Filtrləmə aktivdir"</item>
+ <item msgid="8719029132154020716">"Aktivdir"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Defolt)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 110c8da..4dd4817 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s üzərindən avtomatik qoşuldu"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Avtomatik olaraq şəbəkə reytinq provayderi ilə qoşuludur"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s vasitəsilə qoşuludur"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> tərəfindən <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> ilə qoşulub"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s vasitəsilə əlçatandır"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Quraşdırmaq üçün klikləyin"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Qeydiyyatdan keçmək üçün klikləyin"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Qoşuludur, internet yoxdur"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"İnternet yoxdur"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Giriş tələb olunur"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Giriş nöqtəsi müvəqqəti olaraq doludur"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ilə qoşuludur"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s vasitəsilə əlçatandır"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Bağlantı alınmadı"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Yalnış OSU server linki"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU serverinə qoşulmadı"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU serveri doğrulanmadı"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Yalnış OSU server sertifikatı"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Təchizat prosesi ləğv edildi"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Təchizat prosesi əlçatan deyil"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Yalnış OSU server linki"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Gözlənilməyən əmr növü"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Gözlənilməz SOAP mesaj növü"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP mesaj mübadiləsi alınmadı"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Yönləndirmə dinləyicisini başlatmaq alınmadı"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Yönləndirmə dinləyicisinin gözlənilməsi üçün vaxt bitdi"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU fəaliyyəti yoxdur"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Gözlənilməz SOAP mesaj statusu"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO tapılmadı"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA serveri üçün güvənli mənbə şəbəkəsi tapılmadı"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Bərpa serveri üçün güvənli mənbə şəbəkəsi tapılmadı"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Siyasət serveri üçün güvənli mənbə şəbəkəsi tapılmadı"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Güvənli mənbə sertifikatları əldə edilmədi"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA serveri üçün güvənli mənbə sertifikatı tapılmadı"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint konfiqurasiyası əlavə edilmədi"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU provayderi tapılmadı"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Qoşulur"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Qoşuldu"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU serverinə qoşulur"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU serveri doğrulandı"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU serverinə qoşuldu"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"İlk SOAP mübadiləsi"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Yönləndirmə cavabı gözlənilir"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Yönləndirilmiş cavab qəbul edildi"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"İkinci SOAP mübadiləsi"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Üçüncü SOAP mübadiləsi"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Güvənli mənbə sertifikatları əldə edilir"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Təchizat prosesi tamamlandı"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> açılır"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Qoşulmaq mümkün olmadı"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Qeydiyyat tamamlanır…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Qeydiyyat tamamlanmadı. Yenidən cəhd etmək üçün klikləyin."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Qeydiyyat tamamlandı. Qoşulur…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Çox Yavaş"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Yavaş"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Oyaq qal"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Enereji doldurularkən ekran heç vaxt yuxu rejimində olmur"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI izləmə jurnalını aktivləşdir"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth paketləri əldə edin. (Bu ayarı dəyişdikdən sonra Bluetooth\'u aktiv/deaktiv edin)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM kilidinin açılması"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Əməliyyat sistemi yükləyicisinin kilidinin açılmasına icazə ver"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM kilidinin açılmasına icazə verilsin?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Şəbəkələşmə"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz displey sertifikatlaşması"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Çoxsözlü Girişə icazə verin"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Qoşulmuş MAC Randomizasiyası"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil data həmişə aktiv"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Birləşmə üçün avadanlıq akselerasiyası"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth cihazlarını adsız göstərin"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Qoşulmaq mümkün olmadı"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi‑Fi şəbkələrinə qoşulan zaman ixtiyari MAC ünvanı seçin"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Ödənişli"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Limitsiz"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger bufer ölçüləri"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 2b7d87e..5b72fca 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Koristi HDCP proveru samo za DRM sadržaj"</item>
<item msgid="45075631231212732">"Uvek koristi HDCP proveru"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Onemogućeno"</item>
+ <item msgid="1969681323976948639">"Omogućeno filtrirano"</item>
+ <item msgid="8719029132154020716">"Omogućeno"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (podrazumevano)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 3d34593..dc54301 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano preko %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatski povezano preko dobavljača ocene mreže"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Veza je uspostavljena preko pristupne tačke %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> – <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Povezano preko: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupna je preko pristupne tačke %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Dodirnite da biste podesili"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Dodirnite da biste se registrovali"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Veza je uspostavljena, nema interneta"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nema interneta"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Treba da se prijavite"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna tačka je privremeno zauzeta"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Povezano preko %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Dostupno preko %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Povezivanje nije uspelo"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Nevažeći URL OSU servera"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Povezivanje sa OSU serverom nije uspelo"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Potvrda OSU servera nije uspela"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Nevažeći sertifikat OSU servera"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Dodela je otkazana"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Dodela nije dostupna"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Nevažeći URL OSU servera"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Neočekivani tip komande"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Neočekivani tip SOAP poruke"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Razmena SOAP poruka nije uspela"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Pokretanje obrađivača preusmeravanja nije uspelo"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Vreme čekanja preusmeravanja je isteklo"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nije pronađena nijedna OSU aktivnost"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Neočekivani status SOAP poruke"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO nije pronađen"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Pouzdani čvor osnovnog nivoa za AAA server nije pronađen"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Pouzdani čvor osnovnog nivoa za server za otklanjanje propusta nije pronađen"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Pouzdani čvor osnovnog nivoa za server za smernice nije pronađen"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Preuzimanje pouzdanih sertifikata osnovnog nivoa nije uspelo"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Pouzdani sertifikat osnovnog nivoa za server AAA nije pronađen"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Dodavanje PassPoint konfiguracije nije uspelo"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU dobavljač nije pronađen"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Povezuje se"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Povezan"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Povezujete se sa OSU serverom"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Potvrđen je OSU server"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Veza sa OSU serverom je uspostavljena"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Prva razmena SOAP-a"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Čeka se odgovor o preusmeravanju"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Primljen je odgovor o preusmeravanju"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Druga razmena SOAP-a"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Treća razmena SOAP-a"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Preuzimaju se pouzdani sertifikati osnovnog nivoa"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Dodela pristupa je završena"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Otvara se <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Povezivanje nije uspelo"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Registracija se dovršava…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Dovršavanje registracije nije uspelo. Dodirnite da biste probali ponovo."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registracija je dovršena. Povezuje se…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Veoma spora"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Spora"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Potvrdi"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Ne zaključavaj"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Ekran neće biti u režimu spavanja tokom punjenja"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Omogući snoop evidenciju za Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Snimi Bluetooth pakete. (Uključite/isključite Bluetooth kada promenite ovo podešavanje)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Otključavanje OEM-a"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Dozvoli otključavanje funkcije za pokretanje"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Želite li da dozvolite otključavanje proizvođača originalne opreme (OEM)?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikacija bežičnog ekrana"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Nasumičan izbor MAC adrese tokom povezivanja"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci su uvek aktivni"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje privezivanja"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije uspelo"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Izaberi nasumičnu MAC adresu tokom povezivanja na Wi‑Fi mreže"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Sa ograničenjem"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez ograničenja"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera podataka u programu za evidentiranje"</string>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index 9aaa5596..25f2ced 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Выкарыстанне праверкі HDCP только для змесціва, абароненага DRM"</item>
<item msgid="45075631231212732">"Заўсёды выкарыстоўваць праверку HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Выключана"</item>
+ <item msgid="1969681323976948639">"Уключана з фільтрацыяй"</item>
+ <item msgid="8719029132154020716">"Уключана"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (стандартная)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 02b0451..2fa2692 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Аўтаматычна падключана праз %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Аўтаматычна падключана праз пастаўшчыка паслугі ацэнкі сеткі"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Падлучана праз %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> (<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>)"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Падключана праз праграму \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Даступна праз %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Дакраніцеся, каб наладзіць"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Націсніце, каб зарэгістравацца"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Падключана, без доступу да інтэрнэту"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Не падключана да інтэрнэту"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Трэба выканаць уваход"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Пункт доступу часова заняты"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Падлучана праз %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Даступна праз %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Памылка падключэння"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Несапраўдны URL-адрас сервера OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Не ўдалося падключыцца да сервера OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Не ўдалося праверыць сервер OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Несапраўдны сертыфікат сервера OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Сінхранізацыя спынена"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Сінхранізацыя недаступная"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Несапраўдны URL-адрас сервера OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Нечаканы тып каманды"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Нечаканы тып паведамлення SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Не ўдалося выканаць абмен паведамленнямі SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Не ўдалося запусціць праслухоўванне перанакіравання"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Час чакання перанакіравання скончыўся"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Дзеянняў OSU не знойдзена"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Нечаканы статус паведамлення SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Не ўдалося знайсці PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Не ўдалося знайсці давераны каранёвы вузел для сервера AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Не ўдалося знайсці давераны каранёвы вузел для сервера выпраўленняў"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Не ўдалося знайсці давераны каранёвы вузел для сервера палітыкі"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Не ўдалося атрымаць давераныя каранёвыя сертыфікаты"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Не ўдалося знайсці давераны каранёвы сертыфікат для сервера AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Не ўдалося дадаць канфігурацыю PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Не ўдалося знайсці аператара OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Ідзе падключэнне"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Падключана"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Ідзе падключэнне да сервера OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Сервер OSU пацверджаны"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Падключана да сервера OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Першапачатковы абмен SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Чаканне адказу на перанакіраванне"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Атрыманы адказ на перанакіраванне"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Другі абмен SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Трэці абмен SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Ідзе атрыманне давераных каранёвых сертыфікатаў"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Сінхранізацыя завершана"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Адкрываецца <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Не ўдалося падключыцца"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Рэгістрацыя завяршаецца…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Не ўдалося выканаць рэгістрацыю. Дакраніцеся, каб паўтарыць спробу."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Рэгістрацыя завершана. Ідзе падключэнне…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Вельмі павольная"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Павольная"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ОК"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Прадухіляць ад пераходу ў рэжым сну"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Падчас зарадкі экран будзе пастаянна ўключаны"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Уключыць журнал адсочвання Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Захоўваць пакеты Bluetooth. (Пасля змены гэтай налады выключыце і ўключыце Bluetooth.)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Разблакіроўка OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Дазволіць разблакіроўку загрузчыка"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Дазволіць разблакіроўку OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Сеткі"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Сертыфікацыя бесправаднога дысплея"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Уключыць падрабязны журнал Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Стварэнне выпадковых MAC-адрасоў пры падключэнні па Wi-Fi"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Мабільная перадача даных заўсёды актыўная"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратнае паскарэнне ў рэжыме мадэма"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Паказваць прылады Bluetooth без назваў"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не атрымалася падключыцца"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Паказаць опцыі сертыфікацыі бесправаднога дысплея"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Пры выбары Wi Fi указваць у журнале RSSI для кожнага SSID"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Генерыраваць выпадковы MAC-адрас пры падключэнні да сетак Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"З улікам трафіка"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Без уліку трафіка"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Памеры буфера для сродку вядзення журнала"</string>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index 8484090..994f0ad 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Да се използва проверка с HDCP само за DRM съдържание"</item>
<item msgid="45075631231212732">"Винаги да се използва проверка с HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Деактивирано"</item>
+ <item msgid="1969681323976948639">"Филтрирането е активирано"</item>
+ <item msgid="8719029132154020716">"Активирано"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (по подразбиране)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 4efbe64..1454118 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматично е установена връзка чрез %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Автоматично е установена връзка чрез доставчик на услуги за оценяване на мрежите"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Установена е връзка през „%1$s“"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> на <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Установена е връзка през <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Мрежата е достъпна през „%1$s“"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Докоснете, за да настроите"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Докоснете, за да се регистрирате"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Установена е връзка – няма достъп до интернет"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Няма връзка с интернет"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Изисква се вход в профила"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Точката за достъп временно е пълна"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Установена е връзка през %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Мрежата е достъпна през %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Свързването не бе успешно"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Невалиден URL адрес на OSU сървъра"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Свързването с OSU сървъра не бе успешно"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Потвърждаването на OSU сървъра не бе успешно"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Невалиден сертификат на OSU сървъра"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Обезпечаването бе прекратено"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Обезпечаването не е възможно"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Невалиден URL адрес на OSU сървъра"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Неочакван тип команда"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Неочакван тип съобщение през SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Обменът на съобщения през SOAP не бе успешен"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Стартирането на приемателя за пренасочване не бе успешно"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Времето за изчакване на пренасочването изтече"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Няма намерена OSU активност"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Състояние за неочаквано съобщение през SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Намирането на PPS-MO не бе успешно"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Намирането на надежден основен възел за AAA сървъра не бе успешно"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Намирането на надежден основен възел за сървъра за отстраняване на проблеми не бе успешно"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Намирането на надежден основен възел за сървъра за правила не бе успешно"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Извличането на надеждните основни сертификати не бе успешно"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Намирането на надежден основен сертификат за AAA сървъра не бе успешно"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Добавянето на PassPoint конфигурация не бе успешно"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Намирането на OSU доставчик не бе успешно"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Установява се връзка"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Установена е връзка"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Установява се връзка с OSU сървъра"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU сървърът е потвърден"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Установена е връзка с OSU сървъра"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Първоначален обмен на данни през SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Изчаква се отговор за пренасочването"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Отговорът за пренасочването е получен"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Втори обмен на данни през SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Трети обмен на данни през SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Надеждните основни сертификати се извличат"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Обезпечаването е завършено"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> се отваря"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Не можа да се установи връзка"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Регистрацията се завършва…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Регистрацията не можа да бъде завършена. Докоснете, за да опитате отново."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Регистрацията е завършена. Установява се връзка…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Много бавна"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Бавна"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ОK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Да остане активен"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Екранът никога няма да е в спящ режим при зареждане"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Активиране на рег. файл за анализ за Bluetooth с протокола HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Запис на Bluetooth пакетите. (Превключване на Bluetooth след промяна на тази настройка)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Отключване от OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Разрешаване на първонач. зареждащата прогр. да се откл."</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Да се разреши ли отключване от OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Мрежи"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Безжичен дисплей"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"„Многословно“ регистр. на Wi‑Fi: Актив."</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Рандомизиране на свързания MAC адрес"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Винаги активни мобилни данни"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардуерно ускорение за тетъринга"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показване на устройствата с Bluetooth без имена"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не можа да се установи връзка"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показване на опциите за сертифициране на безжичния дисплей"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"По-подробно регистр. на Wi‑Fi – данни за RSSI на SSID в инстр. за избор на Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Рандомизиране на MAC адреса при свързване с Wi-Fi мрежи"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"С отчитане"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Без отчитане"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Размери на регистрац. буфери"</string>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index f055742..ce3ca16 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"শুধুমাত্র DRM সামগ্রীর জন্য HDCP চেক করা ব্যবহার করুন"</item>
<item msgid="45075631231212732">"সর্বদা HDCP পরীক্ষণ ব্যবহার করুন"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"বন্ধ করা আছে"</item>
+ <item msgid="1969681323976948639">"ফিল্টার করা চালু আছে"</item>
+ <item msgid="8719029132154020716">"চালু করা আছে"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ডিফল্ট)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 913c0c4..dbf397f 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -38,50 +38,27 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"স্বয়ংক্রিয়ভাবে %1$s এর মাধ্যমে কানেক্ট হয়েছে"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"নেটওয়ার্কের রেটিং প্রদানকারীর মাধ্যমে অটোমেটিক কানেক্ট"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s মাধ্যমে কানেক্ট হয়েছে"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> এর <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <!-- no translation found for connected_via_app (5571999941988929520) -->
+ <skip />
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s এর মাধ্যমে উপলব্ধ"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"সেট-আপ করতে ট্যাপ করুন"</string>
+ <!-- no translation found for tap_to_sign_up (6449724763052579434) -->
+ <skip />
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"কানেক্ট, ইন্টারনেট নেই"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ইন্টারনেট কানেকশন নেই"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"সাইন-ইন করা দরকার"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"এই মুহূর্তে অ্যাক্সেস পয়েন্টের কোনও কানেকশন ফাঁকা নেই"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s এর মাধ্যমে কানেক্ট হয়েছে"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s এর মাধ্যমে পাওয়া যাচ্ছে"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"কানেক্ট করা যায়নি"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"ভুল OSU সার্ভার ইউআরএল"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU সার্ভারে কানেক্ট করা যায়নি"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU সার্ভার যাচাই করা যায়নি"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"ভুল OSU সার্ভার সার্টিফিকেট"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"প্রভিশনিং বাতিল করা হয়েছে"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"প্রভিশনিং উপলভ্য নেই"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"ভুল OSU সার্ভার ইউআরএল"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"অপ্রত্যাশিত কমান্ডের ধরন"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"অপ্রত্যাশিত SOAP মেসেজের ধরন"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP মেসেজ এক্সচেঞ্জ করা যায়নি"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"রিডাইরেক্ট লিসনার শুরু হয়নি"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"রিডাইরেক্টের জন্য অপেক্ষা করার সময় শেষ হয়েছে"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"কোনও OSU অ্যাক্টিভিটি খুঁজে পাওয়া যায়নি"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"অপ্রত্যাশিত SOAP মেসেজের স্ট্যাটাস"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO খুঁজে পাওয়া যায়নি"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA সার্ভারের জন্য ট্রাস্ট রুট নোড খুঁজে পাওয়া যায়নি"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"রেমেডিয়েশন সার্ভারের জন্য ট্রাস্ট রুট নোড খুঁজে পাওয়া যায়নি"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"নীতি সার্ভারের জন্য ট্রাস্ট রুট নোড খুঁজে পাওয়া যায়নি"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"\'ট্রাস্ট রুট সার্টিফিকেট ফিরিয়ে আনা যায়নি"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA সার্ভারের জন্য ট্রাস্ট রুট সার্টিফিকেট খুঁজে পাওয়া যায়নি"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint কনফিগারেশন যোগ করা যায়নি"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU প্রদানকারী খুঁজে পাওয়া যায়নি"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"কানেক্ট হচ্ছে"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"কানেক্ট করা হয়েছে"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU সার্ভারের সাথে কানেক্ট করা হচ্ছে"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU সার্ভার যাচাই করা হয়েছে"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU সার্ভারের সাথে কানেক্ট করা আছে"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"প্রারম্ভিক SOAP এক্সচেঞ্জ"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"রিডাইরেক্টের উত্তর পাওয়ার জন্য অপেক্ষা করা হচ্ছে"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"রিডাইরেক্টের উত্তর পাওয়া গেছে"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"সেকেন্ড SOAP এক্সচেন্জ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"থার্ড SOAP এক্সচেন্জ"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"ট্রাস্ট রুট সার্টিফিকেট ফিরিয়ে আনা হচ্ছে"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"প্রভিশনিং সম্পূর্ণ হয়েছে"</string>
+ <!-- no translation found for osu_opening_provider (5488997661548640424) -->
+ <skip />
+ <!-- no translation found for osu_connect_failed (2187750899158158934) -->
+ <skip />
+ <!-- no translation found for osu_completing_sign_up (9037638564719197082) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_failed (7296159750352873260) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_complete (8207626049093289203) -->
+ <skip />
<string name="speed_label_very_slow" msgid="1867055264243608530">"খুব ধীরে"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ধীরে"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ঠিক আছে"</string>
@@ -234,8 +211,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"জাগিয়ে রাখুন"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"চার্জ হওয়ার স্ক্রিন কখনই নিদ্রা মোডে যাবে না"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ব্লুটুথ HCI স্নুপ লগ সক্ষম করুন"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ব্লুটুথ প্যাকেট ক্যাপচার করুন। (এই সেটিং পরিবর্তন করার পরে ব্লুটুথ চালু অথবা বন্ধ করুন)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM আনলক করা হচ্ছে"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"বুট-লোডার আনলক করার অনুমতি দিন"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM আনলক করার অনুমতি দিতে চান?"</string>
@@ -246,7 +222,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"নেটওয়ার্কিং"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ওয়্যারলেস ডিসপ্লে সার্টিফিকেশন"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং সক্ষম করুন"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"কানেক্ট MAC র্যান্ডমাইজেশন"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"নামহীন ব্লুটুথ ডিভাইসগুলি দেখুন"</string>
@@ -273,7 +248,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"কানেক্ট করা যায়নি"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ওয়াই-ফাই লগিং স্তর বাড়ান, ওয়াই-ফাই চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ওয়াই-ফাই নেটওয়ার্কে কানেক্ট করার সময় MAC অ্যাড্রেস র্যান্ডমাইজ করুন"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"পরিমাপ করা"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"পরিমাপ করা নয়"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"লগার বাফারের আকারগুলি"</string>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index bcb35f1..96772b6 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Koristi HDCP provjeru samo za DRM sadržaj"</item>
<item msgid="45075631231212732">"Uvijek koristi HDCP provjeru"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Onemogućeno"</item>
+ <item msgid="1969681323976948639">"Omogućeno filtrirano"</item>
+ <item msgid="8719029132154020716">"Omogućeno"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (zadano)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 1ba6904..272e797 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezano koristeći %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatski povezano putem ocjenjivača mreže"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Povezani preko %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> autora <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Povezano preko <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupan preko %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Dodirnite za postavljanje"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Dodirnite za prijavu"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Povezano, nema interneta"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nema internetske veze"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Potrebna je prijava"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna tačka je privremeno puna"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Povezano koristeći %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Dostupna koristeći %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Veza nije uspjela"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Nevažeći URL OSU servera"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Povezivanje s OSU serverom nije uspjelo"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Potvrda OSU servera nije uspjela"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Nevažeći certifikat OSU servera"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Pružanje usluga je prekinuto"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Pružanje usluga nije dostupno"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Nevažeći URL OSU servera"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Neočekivana vrsta komande"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Neočekivana vrsta poruke SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Razmjena SOAP poruka nije uspjela"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Preusmjereni slušalac nije pokrenuo sadržaj"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Vrijeme za preusmjeravanje je isteklo"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU aktivnosti nisu pronađene"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Status neočekivane SOAP poruke"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO nije pronađen"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Pouzdani temeljni čvor za AAA server nije pronađen"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Pouzdani temeljni čvor za server za uklanjanje problema nije pronađen"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Pouzdani temeljni čvor za server pravila nije pronađen"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Preuzimanje temeljnih pouzdanih certifikata nije uspjelo"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Pouzdani temeljni certifikat za AAA server nije pronađen"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Nije moguće dodati PassPoint konfiguraciju"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU pružatelj usluga nije pronađen"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Povezivanje"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Povezano"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Povezivanje na OSU server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU server je potvrđen"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Povezano na OSU server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Prva SOAP razmjena"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Čekanje odgovora za preusmjeravanje"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Primljen je odgovor o preusmjeravanju"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Druga SOAP razmjena"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Treća SOAP razmjena"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Preuzimanje pouzdanih temeljnih certifikata"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Pružanje usluge je završeno"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Otvaranje <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Povezivanje nije uspjelo"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Završavanje registracije…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Registraciju nije moguće izvršiti. Dodirnite da pokušate ponovo."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registracija je završena. Povezivanje…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Veoma sporo"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Sporo"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"UREDU"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Ostani aktivan"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Ekran neće prelaziti u stanje mirovanja tokom punjenja"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Omogući Bluetooth HCI snoop zapis"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Snimite Bluetooth pakete. (Uključite/isključite Bluetooth nakon što promijenite ovu postavku)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM otključavanje"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Dozvoli otključavanje bootloadera"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Želite li dozvoliti OEM otključavanje?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljniju evidenciju za WiFi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Nasumični odabir MAC adrese pri povezivanju"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna mreža za prijenos podataka je uvijek aktivna"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzavanje za povezivanje putem mobitela"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije uspjelo"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaži opcije za certifikaciju bežičnog prikaza"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za WiFi. Prikaz po SSID RSSI-ju u Biraču WiFi-ja"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Nasumično odaberi MAC adresu prilikom povezivanja na WiFi mreže"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"S naplatom"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Mreža bez ograničenja prometa"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera za zapisnik"</string>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index fd0df04..33385e4 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Utilitza la comprovació HDCP només per a contingut DRM"</item>
<item msgid="45075631231212732">"Utilitza sempre la comprovació HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Desactivat"</item>
+ <item msgid="1969681323976948639">"Activat amb filtres"</item>
+ <item msgid="8719029132154020716">"Activat"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (predeterminada)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 8133559b..5d2dd65 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Connectada automàticament a través de: %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connectada automàticament a través d\'un proveïdor de valoració de xarxes"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connectada mitjançant %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de: <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connectat mitjançant <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible mitjançant %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Toca per configurar"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Toca per registrar-te"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connectada, sense Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Sense connexió a Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Cal iniciar la sessió"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"El punt d\'accés està temporalment ple"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Connectat mitjançant %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponible mitjançant %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Connexió fallida"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL de servidor OSU no vàlid"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"No s\'ha pogut connectar al servidor OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"No s\'ha pogut validar el servidor OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificat de servidor OSU no vàlid"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Proveïment anul·lat"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Proveïment no disponible"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL de servidor OSU no vàlid"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tipus d\'ordre inesperada"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tipus de missatge SOAP inesperat"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"No s\'ha pogut intercanviar el missatge SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"No s\'ha pogut iniciar el processador de redirecció"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Temps d\'espera de redirecció esgotat"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"No s\'ha trobat cap activitat OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Estat de missatge SOAP inesperat"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"No s\'ha pogut trobar PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"No s\'ha pogut trobar el node arrel de confiança del servidor AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"No s\'ha pogut trobar el node arrel de confiança del servidor de solucions"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"No s\'ha pogut trobar el node arrel de confiança del servidor de polítiques"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"No s\'han pogut recuperar els certificats arrel de confiança"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"No s\'ha pogut trobar el certificat arrel de confiança del servidor AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"No s\'ha pogut afegir la configuració PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"No s\'ha pogut trobar el proveïdor OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"S\'està connectant"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connectat"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"S\'està connectant al servidor OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Servidor OSU validat"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connectat a un servidor OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Primer intercanvi SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"S\'està esperant la resposta de redirecció"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Resposta de redirecció rebuda"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Segon intercanvi SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Tercer intercanvi SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"S\'estan recuperant els certificats arrel de confiança"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Proveïment complet"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"S\'està obrint <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"No s\'ha pogut connectar"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"S\'està completant el registre…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"No s\'ha pogut completar el registre. Toca per tornar-ho a provar."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"S\'ha completat el registre. S\'està connectant…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Molt lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Correcta"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Pantalla sempre activa"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"La pantalla no entra mai en mode de repòs si el dispositiu està carregant-se"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Activa registre de Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Captura els paquets de Bluetooth. Activa el Bluetooth un cop hagis canviat aquesta opció."</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueig d\'OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Permet desbloquejar el bootloader"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Permetre el desbloqueig d\'OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Xarxes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificació de pantalla sense fil"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Activa el registre Wi‑Fi detallat"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Ordre aleatori d\'adreces MAC amb connexió"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Dades mòbils sempre actives"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Acceleració per maquinari per a compartició de xarxa"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostra els dispositius Bluetooth sense el nom"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No s\'ha pogut connectar"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra les opcions per a la certificació de pantalla sense fil"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Augmenta nivell de registre Wi‑Fi i mostra\'l per SSID RSSI al Selector de Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Ordena les adreces MAC de manera aleatòria en connectar-se a xarxes Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Amb límit de dades"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Sense límit de dades"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Mides memòria intermèdia registrador"</string>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index 29beb77..cdd7094 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Použít kontrolu HDCP pouze pro obsah DRM"</item>
<item msgid="45075631231212732">"Vždy používat kontrolu HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Vypnuto"</item>
+ <item msgid="1969681323976948639">"Povolit filtrované"</item>
+ <item msgid="8719029132154020716">"Zapnuto"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (výchozí)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 42e2ad3..19a042e 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaticky připojeno přes poskytovatele %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automaticky připojeno přes poskytovatele hodnocení sítí"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Připojeno prostřednictvím %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>: <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Připojeno přes <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupné prostřednictvím %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Nastavíte klepnutím"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Klepnutím se zaregistrujete"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Připojeno, není k dispozici internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nejste připojeni k internetu"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Je vyžadováno přihlášení"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Přístupový bod je dočasně zaplněn"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Připojeno prostřednictvím %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Dostupné prostřednictvím %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Připojení se nezdařilo"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Neplatná adresa URL serveru OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Připojení k serveru OSU se nezdařilo"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Ověření serveru OSU se nezdařilo"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Neplatný certifikát serveru OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Zajišťování bylo zrušeno"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Zajišťování není k dispozici"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Neplatná adresa URL serveru OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Neočekávaný typ příkazu"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Neočekávaný typ zprávy SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Výměna zpráva SOAP se nezdařila"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Poslech za účelem přesměrování se nepodařilo zahájit"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Vypršel časový limit čekání na přesměrování"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nebyla nalezena žádná aktivita OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Neočekávaný stav zprávy SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO se nepodařilo najít"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Kořenový uzel důvěry pro server AAA se nepodařilo najít"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Kořenový uzel důvěry pro server nápravy se nepodařilo najít"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Kořenový uzel důvěry pro server zásad se nepodařilo najít"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Kořenové certifikáty důvěry se nepodařilo načíst"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Kořenový uzel důvěry pro server AAA se nepodařilo najít"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Konfiguraci PassPoint se nepodařilo přidat"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Poskytovatele OSU se nepodařilo najít"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Připojování"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Připojeno"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Připojování k serveru OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Server OSU byl ověřen"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Připojeno k serveru OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"První výměna SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Čekání na odpověď s přesměrováním"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Byla přijata odpověď s přesměrováním"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Druhá výměna SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Třetí výměna SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Načítání kořenových certifikátů důvěry"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Zajišťování bylo dokončeno"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Spouštění aplikace <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Nelze se připojit"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Dokončování registrace…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Registraci se nepodařilo dokončit. Klepnutím opakujte akci."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registrace byla dokončena. Připojování…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Velmi pomalá"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Pomalá"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Nevypínat obrazovku"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Obrazovka se při nabíjení nepřepne do režimu spánku"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Povolit protokol Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Zaznamenávat pakety Bluetooth. (Po změně tohoto nastavení zapněte nebo vypněte Bluetooth.)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Odemknutí OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Povolit odemknutí zavaděče"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Povolit odemknutí OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Sítě"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikace bezdrát. displeje"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné protokolování Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Náhodné adresy MAC při připojení"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilní data jsou vždy aktivní"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarová akcelerace tetheringu"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Zobrazovat zařízení Bluetooth bez názvů"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nelze se připojit"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobrazit možnosti certifikace bezdrátového displeje"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi."</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Při připojení k sítím Wi-Fi používat náhodnou adresu MAC"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Měřená"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Neměřená"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávací paměť protokol. nástroje"</string>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 97e2b05..358efff 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Brug kun HDCP-kontrol ved DRM-indhold"</item>
<item msgid="45075631231212732">"Brug altid HDCP-kontrol"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Deaktiveret"</item>
+ <item msgid="1969681323976948639">"Filtreret er aktiveret"</item>
+ <item msgid="8719029132154020716">"Aktiveret"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index f504afb..bde67fd 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisk tilsluttet via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatisk forbundet via udbyder af netværksvurdering"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tilsluttet via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> fra <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Forbundet via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tilgængelig via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tryk for at konfigurere"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tryk for at registrere dig"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tilsluttet – intet internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Intet internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Login er påkrævet"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Adgangspunktet er midlertidigt fuldt"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Tilsluttet via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Tilgængelig via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Der kunne ikke oprettes forbindelse"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Ugyldig webadresse for OSU-serveren"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Der kunne ikke oprettes forbindelse til OSU-serveren"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU-servervalideringen mislykkedes"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Ugyldigt OSU-servercertifikat"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisioneringen blev annulleret"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisionering er ikke tilgængelig"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Ugyldig webadresse for OSU-serveren"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Uventet kommandotype"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Uventet SOAP-meddelelsestype"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Udvekslingen af SOAP-meddelelser mislykkedes"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Lyttefunktionen til omdirigering kunne ikke starte"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Der opstod timeout under ventetiden for omdirigering"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Der blev ikke fundet nogen OSU-aktivitet"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Uventet SOAP-meddelelsesstatus"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO kunne ikke findes"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Der blev ikke fundet nogen godkendt rodnode til AAA-serveren"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Der blev ikke fundet nogen godkendt rodnode til afhjælpningsserveren"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Der blev ikke fundet nogen godkendt rodnode til politikserveren"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Der kunne ikke hentes godkendte rodcertifikater"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Det lykkedes ikke at finde et godkendt rodcertifikat til AAA-serveren"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Der kunne ikke tilføjes PassPoint-konfiguration"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Der kunne ikke findes en OSU-udbyder"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Opretter forbindelse"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Der er oprettet forbindelse"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Opretter forbindelse til OSU-serveren"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-serveren blev godkendt"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Der er oprettet forbindelse til OSU-serveren"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Første SOAP-udveksling"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Venter på omdirigeringssvar"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Der blev modtaget et omdirigeringssvar"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Anden SOAP-udveksling"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Tredje SOAP-udveksling"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Henter godkendte rodcertifikater"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisioneringen er udført"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Åbner <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Der kunne ikke oprettes forbindelse"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Fuldfører registrering…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Registreringen kunne ikke fuldføres. Tryk for at prøve igen."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registreringen er fuldført. Opretter forbindelse…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Meget langsom"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Langsom"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Lås ikke"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Skærmen går ikke i dvale under opladning"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Aktivér Bluetooth HCI spionlog"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Gem Bluetooth-pakker. (slå Bluetooth til/fra, efter du har ændret denne indstilling)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-oplåsning"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Tillad, at startindlæseren låses op"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Vil du tillade OEM-oplåsning?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Netværk"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificering af trådløs skærm"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivér detaljeret Wi-Fi-logføring"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Forbindelse med tilfældig MAC-adresse"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er altid aktiveret"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareacceleration ved netdeling"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Vis Bluetooth-enheder uden navne"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Der kunne ikke oprettes forbindelse"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis valgmuligheder for certificering af trådløs skærm"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øg mængden af Wi‑Fi-logføring. Vis opdelt efter SSID RSSI i Wi‑Fi-vælgeren"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Brug en tilfældig MAC-adresse, når der oprettes forbindelse til Wi‑Fi-netværk"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Forbrugsafregnet"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Ikke forbrugsafregnet"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Størrelser for Logger-buffer"</string>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index 755b6bb..90e26d2 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP-Prüfung nur für DRM-Inhalte verwenden"</item>
<item msgid="45075631231212732">"HDCP-Prüfung immer verwenden"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Deaktiviert"</item>
+ <item msgid="1969681323976948639">"Filter aktiviert"</item>
+ <item msgid="8719029132154020716">"Aktiviert"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Standard)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index ad67669..543e8f8 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisch über %1$s verbunden"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatisch über Anbieter von Netzwerkbewertungen verbunden"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Über %1$s verbunden"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> von <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Verbunden über <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Verfügbar über %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Zum Einrichten tippen"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Zum Anmelden tippen"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Verbunden, kein Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Kein Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Anmeldung erforderlich"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Zugangspunkt vorübergehend voll belegt"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Über %1$s verbunden"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Verfügbar über %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Fehler beim Herstellen der Verbindung"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Ungültige OSU-Server-URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Fehler beim Verbinden mit dem OSU-Server"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Fehler bei der OSU-Servervalidierung"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Ungültiges OSU-Serverzertifikat"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Bereitstellung abgebrochen"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Bereitstellung nicht verfügbar"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Ungültige OSU-Server-URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Unerwarteter Befehlstyp"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Unerwarteter SOAP-Nachrichtentyp"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Fehler beim SOAP-Nachrichtenaustausch"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Weiterleitungs-Listener konnte nicht gestartet werden"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Zeitüberschreitung beim Warten auf die Weiterleitung"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Es wurde keine OSU-Aktivität gefunden"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Unerwarteter SOAP-Nachrichtenstatus"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO konnte nicht gefunden werden"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Es konnte kein vertrauenswürdiger Root-Knoten für den AAA-Server gefunden werden"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Es konnte kein vertrauenswürdiger Root-Knoten für den Wiederherstellungsserver gefunden werden"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Es konnte kein vertrauenswürdiger Root-Knoten für den Richtlinienserver gefunden werden"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Es konnten keine vertrauenswürdigen Root-Zertifikate abgerufen werden"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Es konnte kein vertrauenswürdiges Root-Zertifikat für den AAA-Server gefunden werden"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint-Konfiguration konnte nicht hinzugefügt werden"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Es konnte kein OSU-Anbieter gefunden werden"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Wird verbunden"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Verbunden"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Verbindung zum OSU-Server wird hergestellt"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-Server validiert"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Mit OSU-Server verbunden"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Erster SOAP-Nachrichtenaustausch"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Warten auf Weiterleitung"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Als Antwort Weiterleitung erhalten"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Zweiter SOAP-Nachrichtenaustausch"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Dritter SOAP-Nachrichtenaustausch"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Vertrauenswürdige Root-Zertifikate werden abgerufen"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Bereitstellung abgeschlossen"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> wird geöffnet"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Verbindung nicht möglich"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Anmeldung wird abgeschlossen…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Anmeldung konnte nicht abgeschlossen werden. Tippe, um es noch einmal zu versuchen."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Anmeldung abgeschlossen. Verbindung wird hergestellt…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Sehr langsam"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Langsam"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Aktiv lassen"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Display wird beim Laden nie in den Ruhezustand versetzt"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI-Snoop-Protokoll aktivieren"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth-Pakete erfassen. Nach der Änderung muss Bluetooth aus- und wieder eingeschaltet werden"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-Entsperrung"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Bootloader-Entsperrung zulassen"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM-Entsperrung zulassen?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Netzwerke"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Kabellose Übertragung"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ausführliche WLAN-Protokolle aktivieren"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Verbundene randomisierte MAC-Adresse"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile Datennutzung immer aktiviert"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarebeschleunigung für Tethering"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-Geräte ohne Namen anzeigen"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Verbindung nicht möglich"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Level für WLAN-Protokollierung erhöhen, in WiFi Picker pro SSID-RSSI anzeigen"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"MAC-Adresse randomisieren, wenn WLAN-Verbindungen hergestellt werden"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Kostenpflichtig"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Nicht kostenpflichtig"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger-Puffergrößen"</string>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 3d91c1d..96a6086 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Χρήση ελέγχου HDCP μόνο για περιεχόμενο DRM"</item>
<item msgid="45075631231212732">"Να χρησιμοποιείται πάντα έλεγχος HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Απενεργοποιήθηκε"</item>
+ <item msgid="1969681323976948639">"Ενεργοποιήθηκε το φιλτράρισμα"</item>
+ <item msgid="8719029132154020716">"Ενεργοποιήθηκε"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Προεπιλογή)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 370c9c0..f7ec12b 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Συνδέθηκε αυτόματα μέσω %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Συνδέθηκε αυτόματα μέσω παρόχου αξιολόγησης δικτύου"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Συνδέθηκε μέσω %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> από <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Συνδέθηκε μέσω <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Διαθέσιμο μέσω %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Πατήστε για ρύθμιση"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Πατήστε για εγγραφή"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Συνδέθηκε, χωρίς σύνδεση στο διαδίκτυο"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Δεν υπάρχει σύνδεση στο διαδίκτυο"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Απαιτείται σύνδεση"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Το σημείο πρόσβασης είναι προσωρινά πλήρες"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Συνδέθηκε μέσω %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Διαθέσιμο μέσω %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Η σύνδεση απέτυχε"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Μη έγκυρο URL διακομιστή OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Η σύνδεση με τον διακομιστή OSU απέτυχε"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Η επαλήθευση του διακομιστή OSU απέτυχε"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Μη έγκυρο πιστοποιητικό διακομιστή OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Η παροχή ακυρώθηκε"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Η παροχή δεν είναι διαθέσιμη"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Μη έγκυρο URL διακομιστή OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Μη αναμενόμενος τύπος εντολής"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Μη αναμενόμενος τύπος μηνύματος SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Η ανταλλαγή μηνύματος SOAP απέτυχε"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Αποτυχία εκκίνησης λειτουργίας ακρόασης ανακατεύθυνσης"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Έληξε το χρονικό όριο αναμονής για ανακατεύθυνση"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Δεν βρέθηκε δραστηριότητα OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Μη αναμενόμενη κατάσταση μηνύματος SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Η εύρεση PPS-MO απέτυχε"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Η εύρεση αξιόπιστου ριζικού κόμβου για τον διακομιστή AAA απέτυχε"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Η εύρεση αξιόπιστου ριζικού κόμβου για τον διακομιστή αποκατάστασης απέτυχε"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Η εύρεση αξιόπιστου ριζικού κόμβου για τον διακομιστή πολιτικής απέτυχε"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Η ανάκτηση αξιόπιστων πιστοποιητικών ρίζας απέτυχε"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Η εύρεση αξιόπιστου πιστοποιητικού ρίζας για τον διακομιστή AAA απέτυχε"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Η προσθήκη διαμόρφωσης PassPoint απέτυχε"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Η εύρεση παρόχου OSU απέτυχε"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Σύνδεση"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Συνδέθηκε"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Σύνδεση σε διακομιστή OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Ο διακομιστής OSU επαληθεύτηκε"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Συνδέθηκε σε διακομιστή OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Αρχική ανταλλαγή SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Αναμονή για απόκριση ανατακατεύθυνσης"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Ελήφθη απόκριση ανακατεύθυνσης"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Δεύτερη ανταλλαγή SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Τρίτη ανταλλαγή SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Ανάκτηση αξιόπιστων πιστοποιητικών ρίζας"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Η παροχή ολοκληρώθηκε"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Άνοιγμα <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Δεν ήταν δυνατή η σύνδεση"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Ολοκλήρωση εγγραφής…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Δεν ήταν δυνατή η ολοκλήρωση της εγγραφής. Πατήστε για να δοκιμάσετε ξανά."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Η εγγραφή ολοκληρώθηκε. Σύνδεση…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Πολύ αργή"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Αργή"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ΟΚ"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Παραμονή σε λειτουργία"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Η οθόνη δεν θα μεταβαίνει ποτέ σε κατάσταση αδράνειας κατά τη φόρτιση"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Ενερ/ση καταγρ. Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Λήψη πακέτων Bluetooth. (Εναλλαγή Bluetooth μετά την αλλαγή αυτής της ρύθμισης)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Ξεκλείδωμα OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Να επιτρέπεται το ξεκλείδωμα λειτουργίας εκκίνησης"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Να επιτρέπεται το ξεκλείδωμα OEM;"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Δικτύωση"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Πιστοποίηση ασύρματης οθόνης"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ενεργοποίηση λεπτομερ. καταγραφής Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Τυχαιοποίηση συνδεδεμένης διεύθυνσης MAC"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Σύνδεση επιτάχυνσης υλικού"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Εμφάνιση συσκευών Bluetooth χωρίς ονόματα"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Δεν ήταν δυνατή η σύνδεση"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Τυχαιοποίηση διεύθυνσης MAC κατά τη σύνδεση σε δίκτυα Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Μέτρηση με βάση τη χρήση"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Χωρίς μέτρηση με βάση τη χρήση"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Μέγεθος προσωρινής μνήμης για τη λειτουργία καταγραφής"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index e7d0bd4..c48f62b 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
<item msgid="45075631231212732">"Always use HDCP checking"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Disabled"</item>
+ <item msgid="1969681323976948639">"Enabled Filtered"</item>
+ <item msgid="8719029132154020716">"Enabled"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 5684369..b9d3093 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatically connected via network rating provider"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> by <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tap to set up"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"No Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign-in required"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Connection failed"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Invalid OSU server URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU server connection failed"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU server validation failed"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Invalid OSU server certificate"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisioning aborted"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisioning not available"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Invalid OSU server URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Unexpected command type"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Unexpected SOAP message type"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP message exchange failed"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Redirect listener failed to start"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Timed out waiting for redirect"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"No OSU activity found"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Unexpected SOAP message status"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Failed to find PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Failed to find trust root node for AAA server"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Failed to find trust root node for remediation server"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Failed to find trust root node for policy server"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Failed to retrieve trust root certificates"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Failed to find trust root certificate for AAA server"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Failed to add PassPoint configuration"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Failed to find an OSU provider"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Connecting"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connected"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Connecting to OSU server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU server validated"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connected to OSU server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Initial SOAP exchange"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Waiting for redirect response"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Received redirect response"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Second SOAP exchange"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Third SOAP exchange"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Retrieving trust root certificates"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisioning complete"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Couldn’t connect"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completing sign-up…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Couldn’t complete sign-up. Tap to try again"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Sign-up complete. Connecting…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Stay awake"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Screen will never sleep while charging"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Enable Bluetooth HCI snoop log"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capture Bluetooth packets. (Toggle Bluetooth after changing this setting)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM unlocking"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Allow the bootloader to be unlocked"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Allow OEM unlocking?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Connected MAC randomisation"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Randomise MAC address when connecting to Wi‑Fi networks"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/arrays.xml b/packages/SettingsLib/res/values-en-rCA/arrays.xml
index e7d0bd4..c48f62b 100644
--- a/packages/SettingsLib/res/values-en-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rCA/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
<item msgid="45075631231212732">"Always use HDCP checking"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Disabled"</item>
+ <item msgid="1969681323976948639">"Enabled Filtered"</item>
+ <item msgid="8719029132154020716">"Enabled"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 5684369..b9d3093 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatically connected via network rating provider"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> by <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tap to set up"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"No Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign-in required"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Connection failed"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Invalid OSU server URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU server connection failed"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU server validation failed"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Invalid OSU server certificate"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisioning aborted"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisioning not available"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Invalid OSU server URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Unexpected command type"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Unexpected SOAP message type"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP message exchange failed"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Redirect listener failed to start"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Timed out waiting for redirect"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"No OSU activity found"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Unexpected SOAP message status"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Failed to find PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Failed to find trust root node for AAA server"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Failed to find trust root node for remediation server"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Failed to find trust root node for policy server"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Failed to retrieve trust root certificates"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Failed to find trust root certificate for AAA server"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Failed to add PassPoint configuration"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Failed to find an OSU provider"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Connecting"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connected"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Connecting to OSU server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU server validated"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connected to OSU server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Initial SOAP exchange"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Waiting for redirect response"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Received redirect response"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Second SOAP exchange"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Third SOAP exchange"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Retrieving trust root certificates"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisioning complete"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Couldn’t connect"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completing sign-up…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Couldn’t complete sign-up. Tap to try again"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Sign-up complete. Connecting…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Stay awake"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Screen will never sleep while charging"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Enable Bluetooth HCI snoop log"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capture Bluetooth packets. (Toggle Bluetooth after changing this setting)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM unlocking"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Allow the bootloader to be unlocked"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Allow OEM unlocking?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Connected MAC randomisation"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Randomise MAC address when connecting to Wi‑Fi networks"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index e7d0bd4..c48f62b 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
<item msgid="45075631231212732">"Always use HDCP checking"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Disabled"</item>
+ <item msgid="1969681323976948639">"Enabled Filtered"</item>
+ <item msgid="8719029132154020716">"Enabled"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 5684369..b9d3093 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatically connected via network rating provider"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> by <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tap to set up"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"No Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign-in required"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Connection failed"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Invalid OSU server URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU server connection failed"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU server validation failed"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Invalid OSU server certificate"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisioning aborted"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisioning not available"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Invalid OSU server URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Unexpected command type"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Unexpected SOAP message type"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP message exchange failed"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Redirect listener failed to start"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Timed out waiting for redirect"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"No OSU activity found"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Unexpected SOAP message status"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Failed to find PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Failed to find trust root node for AAA server"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Failed to find trust root node for remediation server"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Failed to find trust root node for policy server"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Failed to retrieve trust root certificates"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Failed to find trust root certificate for AAA server"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Failed to add PassPoint configuration"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Failed to find an OSU provider"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Connecting"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connected"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Connecting to OSU server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU server validated"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connected to OSU server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Initial SOAP exchange"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Waiting for redirect response"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Received redirect response"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Second SOAP exchange"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Third SOAP exchange"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Retrieving trust root certificates"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisioning complete"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Couldn’t connect"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completing sign-up…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Couldn’t complete sign-up. Tap to try again"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Sign-up complete. Connecting…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Stay awake"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Screen will never sleep while charging"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Enable Bluetooth HCI snoop log"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capture Bluetooth packets. (Toggle Bluetooth after changing this setting)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM unlocking"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Allow the bootloader to be unlocked"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Allow OEM unlocking?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Connected MAC randomisation"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Randomise MAC address when connecting to Wi‑Fi networks"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index e7d0bd4..c48f62b 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
<item msgid="45075631231212732">"Always use HDCP checking"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Disabled"</item>
+ <item msgid="1969681323976948639">"Enabled Filtered"</item>
+ <item msgid="8719029132154020716">"Enabled"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 5684369..b9d3093 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatically connected via network rating provider"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> by <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tap to set up"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"No Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign-in required"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Connection failed"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Invalid OSU server URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU server connection failed"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU server validation failed"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Invalid OSU server certificate"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisioning aborted"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisioning not available"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Invalid OSU server URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Unexpected command type"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Unexpected SOAP message type"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP message exchange failed"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Redirect listener failed to start"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Timed out waiting for redirect"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"No OSU activity found"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Unexpected SOAP message status"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Failed to find PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Failed to find trust root node for AAA server"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Failed to find trust root node for remediation server"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Failed to find trust root node for policy server"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Failed to retrieve trust root certificates"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Failed to find trust root certificate for AAA server"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Failed to add PassPoint configuration"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Failed to find an OSU provider"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Connecting"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connected"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Connecting to OSU server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU server validated"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connected to OSU server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Initial SOAP exchange"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Waiting for redirect response"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Received redirect response"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Second SOAP exchange"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Third SOAP exchange"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Retrieving trust root certificates"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisioning complete"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Couldn’t connect"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completing sign-up…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Couldn’t complete sign-up. Tap to try again"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Sign-up complete. Connecting…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Very slow"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Stay awake"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Screen will never sleep while charging"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Enable Bluetooth HCI snoop log"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capture Bluetooth packets. (Toggle Bluetooth after changing this setting)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM unlocking"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Allow the bootloader to be unlocked"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Allow OEM unlocking?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Connected MAC randomisation"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Randomise MAC address when connecting to Wi‑Fi networks"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/arrays.xml b/packages/SettingsLib/res/values-en-rXC/arrays.xml
index 6dd2e0e..90594fd 100644
--- a/packages/SettingsLib/res/values-en-rXC/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rXC/arrays.xml
@@ -22,241 +22,243 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="wifi_status">
<item msgid="1922181315419294640"></item>
- <item msgid="8934131797783724664">"Scanning…"</item>
- <item msgid="8513729475867537913">"Connecting…"</item>
- <item msgid="515055375277271756">"Authenticating…"</item>
- <item msgid="1943354004029184381">"Obtaining IP address…"</item>
- <item msgid="4221763391123233270">"Connected"</item>
- <item msgid="624838831631122137">"Suspended"</item>
- <item msgid="7979680559596111948">"Disconnecting…"</item>
- <item msgid="1634960474403853625">"Disconnected"</item>
- <item msgid="746097431216080650">"Unsuccessful"</item>
- <item msgid="6367044185730295334">"Blocked"</item>
- <item msgid="503942654197908005">"Temporarily avoiding poor connection"</item>
+ <item msgid="8934131797783724664">"Scanning…"</item>
+ <item msgid="8513729475867537913">"Connecting…"</item>
+ <item msgid="515055375277271756">"Authenticating…"</item>
+ <item msgid="1943354004029184381">"Obtaining IP address…"</item>
+ <item msgid="4221763391123233270">"Connected"</item>
+ <item msgid="624838831631122137">"Suspended"</item>
+ <item msgid="7979680559596111948">"Disconnecting…"</item>
+ <item msgid="1634960474403853625">"Disconnected"</item>
+ <item msgid="746097431216080650">"Unsuccessful"</item>
+ <item msgid="6367044185730295334">"Blocked"</item>
+ <item msgid="503942654197908005">"Temporarily avoiding poor connection"</item>
</string-array>
<string-array name="wifi_status_with_ssid">
<item msgid="7714855332363650812"></item>
- <item msgid="8878186979715711006">"Scanning…"</item>
- <item msgid="355508996603873860">"Connecting to <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="554971459996405634">"Authenticating with <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="7928343808033020343">"Obtaining IP address from <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="8937994881315223448">"Connected to <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
- <item msgid="1330262655415760617">"Suspended"</item>
- <item msgid="7698638434317271902">"Disconnecting from <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="197508606402264311">"Disconnected"</item>
- <item msgid="8578370891960825148">"Unsuccessful"</item>
- <item msgid="5660739516542454527">"Blocked"</item>
- <item msgid="1805837518286731242">"Temporarily avoiding poor connection"</item>
+ <item msgid="8878186979715711006">"Scanning…"</item>
+ <item msgid="355508996603873860">"Connecting to <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="554971459996405634">"Authenticating with <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="7928343808033020343">"Obtaining IP address from <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="8937994881315223448">"Connected to <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
+ <item msgid="1330262655415760617">"Suspended"</item>
+ <item msgid="7698638434317271902">"Disconnecting from <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
+ <item msgid="197508606402264311">"Disconnected"</item>
+ <item msgid="8578370891960825148">"Unsuccessful"</item>
+ <item msgid="5660739516542454527">"Blocked"</item>
+ <item msgid="1805837518286731242">"Temporarily avoiding poor connection"</item>
</string-array>
<string-array name="hdcp_checking_titles">
- <item msgid="441827799230089869">"Never check"</item>
- <item msgid="6042769699089883931">"Check for DRM content only"</item>
- <item msgid="9174900380056846820">"Always check"</item>
+ <item msgid="441827799230089869">"Never check"</item>
+ <item msgid="6042769699089883931">"Check for DRM content only"</item>
+ <item msgid="9174900380056846820">"Always check"</item>
</string-array>
<string-array name="hdcp_checking_summaries">
- <item msgid="505558545611516707">"Never use HDCP checking"</item>
- <item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
- <item msgid="45075631231212732">"Always use HDCP checking"</item>
+ <item msgid="505558545611516707">"Never use HDCP checking"</item>
+ <item msgid="3878793616631049349">"Use HDCP checking for DRM content only"</item>
+ <item msgid="45075631231212732">"Always use HDCP checking"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Disabled"</item>
+ <item msgid="1969681323976948639">"Enabled Filtered"</item>
+ <item msgid="8719029132154020716">"Enabled"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
- <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
- <item msgid="2809759619990248160">"AVRCP 1.3"</item>
- <item msgid="6199178154704729352">"AVRCP 1.5"</item>
- <item msgid="5172170854953034852">"AVRCP 1.6"</item>
+ <item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
+ <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+ <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+ <item msgid="5172170854953034852">"AVRCP 1.6"</item>
</string-array>
<string-array name="bluetooth_avrcp_version_values">
- <item msgid="2838624067805073303">"avrcp14"</item>
- <item msgid="3011533352527449572">"avrcp13"</item>
- <item msgid="8837606198371920819">"avrcp15"</item>
- <item msgid="3422726142222090896">"avrcp16"</item>
+ <item msgid="2838624067805073303">"avrcp14"</item>
+ <item msgid="3011533352527449572">"avrcp13"</item>
+ <item msgid="8837606198371920819">"avrcp15"</item>
+ <item msgid="3422726142222090896">"avrcp16"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_titles">
- <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
- <item msgid="7539690996561263909">"SBC"</item>
- <item msgid="686685526567131661">"AAC"</item>
- <item msgid="5254942598247222737">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
- <item msgid="2091430979086738145">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
- <item msgid="6751080638867012696">"LDAC"</item>
- <item msgid="723675059572222462">"Enable Optional Codecs"</item>
- <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
+ <item msgid="7065842274271279580">"Use System Selection (Default)"</item>
+ <item msgid="7539690996561263909">"SBC"</item>
+ <item msgid="686685526567131661">"AAC"</item>
+ <item msgid="5254942598247222737">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
+ <item msgid="2091430979086738145">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
+ <item msgid="6751080638867012696">"LDAC"</item>
+ <item msgid="723675059572222462">"Enable Optional Codecs"</item>
+ <item msgid="3304843301758635896">"Disable Optional Codecs"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
- <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
- <item msgid="6898329690939802290">"SBC"</item>
- <item msgid="6839647709301342559">"AAC"</item>
- <item msgid="7848030269621918608">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
- <item msgid="298198075927343893">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
- <item msgid="7950781694447359344">"LDAC"</item>
- <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
- <item msgid="741805482892725657">"Disable Optional Codecs"</item>
+ <item msgid="5062108632402595000">"Use System Selection (Default)"</item>
+ <item msgid="6898329690939802290">"SBC"</item>
+ <item msgid="6839647709301342559">"AAC"</item>
+ <item msgid="7848030269621918608">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
+ <item msgid="298198075927343893">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
+ <item msgid="7950781694447359344">"LDAC"</item>
+ <item msgid="2209680154067241740">"Enable Optional Codecs"</item>
+ <item msgid="741805482892725657">"Disable Optional Codecs"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
- <item msgid="3093023430402746802">"Use System Selection (Default)"</item>
- <item msgid="8895532488906185219">"44.1 kHz"</item>
- <item msgid="2909915718994807056">"48.0 kHz"</item>
- <item msgid="3347287377354164611">"88.2 kHz"</item>
- <item msgid="1234212100239985373">"96.0 kHz"</item>
+ <item msgid="3093023430402746802">"Use System Selection (Default)"</item>
+ <item msgid="8895532488906185219">"44.1 kHz"</item>
+ <item msgid="2909915718994807056">"48.0 kHz"</item>
+ <item msgid="3347287377354164611">"88.2 kHz"</item>
+ <item msgid="1234212100239985373">"96.0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
- <item msgid="3214516120190965356">"Use System Selection (Default)"</item>
- <item msgid="4482862757811638365">"44.1 kHz"</item>
- <item msgid="354495328188724404">"48.0 kHz"</item>
- <item msgid="7329816882213695083">"88.2 kHz"</item>
- <item msgid="6967397666254430476">"96.0 kHz"</item>
+ <item msgid="3214516120190965356">"Use System Selection (Default)"</item>
+ <item msgid="4482862757811638365">"44.1 kHz"</item>
+ <item msgid="354495328188724404">"48.0 kHz"</item>
+ <item msgid="7329816882213695083">"88.2 kHz"</item>
+ <item msgid="6967397666254430476">"96.0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
- <item msgid="2684127272582591429">"Use System Selection (Default)"</item>
- <item msgid="5618929009984956469">"16 bits/sample"</item>
- <item msgid="3412640499234627248">"24 bits/sample"</item>
- <item msgid="121583001492929387">"32 bits/sample"</item>
+ <item msgid="2684127272582591429">"Use System Selection (Default)"</item>
+ <item msgid="5618929009984956469">"16 bits/sample"</item>
+ <item msgid="3412640499234627248">"24 bits/sample"</item>
+ <item msgid="121583001492929387">"32 bits/sample"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
- <item msgid="1081159789834584363">"Use System Selection (Default)"</item>
- <item msgid="4726688794884191540">"16 bits/sample"</item>
- <item msgid="305344756485516870">"24 bits/sample"</item>
- <item msgid="244568657919675099">"32 bits/sample"</item>
+ <item msgid="1081159789834584363">"Use System Selection (Default)"</item>
+ <item msgid="4726688794884191540">"16 bits/sample"</item>
+ <item msgid="305344756485516870">"24 bits/sample"</item>
+ <item msgid="244568657919675099">"32 bits/sample"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_titles">
- <item msgid="5226878858503393706">"Use System Selection (Default)"</item>
- <item msgid="4106832974775067314">"Mono"</item>
- <item msgid="5571632958424639155">"Stereo"</item>
+ <item msgid="5226878858503393706">"Use System Selection (Default)"</item>
+ <item msgid="4106832974775067314">"Mono"</item>
+ <item msgid="5571632958424639155">"Stereo"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
- <item msgid="4118561796005528173">"Use System Selection (Default)"</item>
- <item msgid="8900559293912978337">"Mono"</item>
- <item msgid="8883739882299884241">"Stereo"</item>
+ <item msgid="4118561796005528173">"Use System Selection (Default)"</item>
+ <item msgid="8900559293912978337">"Mono"</item>
+ <item msgid="8883739882299884241">"Stereo"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
- <item msgid="7158319962230727476">"Optimized for Audio Quality (990kbps/909kbps)"</item>
- <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660kbps/606kbps)"</item>
- <item msgid="8860982705384396512">"Optimized for Connection Quality (330kbps/303kbps)"</item>
- <item msgid="4414060457677684127">"Best Effort (Adaptive Bit Rate)"</item>
+ <item msgid="7158319962230727476">"Optimized for Audio Quality (990kbps/909kbps)"</item>
+ <item msgid="2921767058740704969">"Balanced Audio And Connection Quality (660kbps/606kbps)"</item>
+ <item msgid="8860982705384396512">"Optimized for Connection Quality (330kbps/303kbps)"</item>
+ <item msgid="4414060457677684127">"Best Effort (Adaptive Bit Rate)"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
- <item msgid="6398189564246596868">"Optimized for Audio Quality"</item>
- <item msgid="4327143584633311908">"Balanced Audio And Connection Quality"</item>
- <item msgid="4681409244565426925">"Optimized for Connection Quality"</item>
- <item msgid="364670732877872677">"Best Effort (Adaptive Bit Rate)"</item>
+ <item msgid="6398189564246596868">"Optimized for Audio Quality"</item>
+ <item msgid="4327143584633311908">"Balanced Audio And Connection Quality"</item>
+ <item msgid="4681409244565426925">"Optimized for Connection Quality"</item>
+ <item msgid="364670732877872677">"Best Effort (Adaptive Bit Rate)"</item>
</string-array>
<string-array name="bluetooth_audio_active_device_summaries">
<item msgid="4862957058729193940"></item>
- <item msgid="6481691720774549651">", active"</item>
- <item msgid="8962366465966010158">", active (media)"</item>
- <item msgid="4046665544396189228">", active (phone)"</item>
+ <item msgid="6481691720774549651">", active"</item>
+ <item msgid="8962366465966010158">", active (media)"</item>
+ <item msgid="4046665544396189228">", active (phone)"</item>
</string-array>
<string-array name="select_logd_size_titles">
- <item msgid="8665206199209698501">"Off"</item>
- <item msgid="1593289376502312923">"64K"</item>
- <item msgid="487545340236145324">"256K"</item>
- <item msgid="2423528675294333831">"1M"</item>
- <item msgid="180883774509476541">"4M"</item>
- <item msgid="2803199102589126938">"16M"</item>
+ <item msgid="8665206199209698501">"Off"</item>
+ <item msgid="1593289376502312923">"64K"</item>
+ <item msgid="487545340236145324">"256K"</item>
+ <item msgid="2423528675294333831">"1M"</item>
+ <item msgid="180883774509476541">"4M"</item>
+ <item msgid="2803199102589126938">"16M"</item>
</string-array>
<string-array name="select_logd_size_lowram_titles">
- <item msgid="6089470720451068364">"Off"</item>
- <item msgid="4622460333038586791">"64K"</item>
- <item msgid="2212125625169582330">"256K"</item>
- <item msgid="1704946766699242653">"1M"</item>
+ <item msgid="6089470720451068364">"Off"</item>
+ <item msgid="4622460333038586791">"64K"</item>
+ <item msgid="2212125625169582330">"256K"</item>
+ <item msgid="1704946766699242653">"1M"</item>
</string-array>
<string-array name="select_logd_size_summaries">
- <item msgid="6921048829791179331">"Off"</item>
- <item msgid="2969458029344750262">"64K per log buffer"</item>
- <item msgid="1342285115665698168">"256K per log buffer"</item>
- <item msgid="1314234299552254621">"1M per log buffer"</item>
- <item msgid="3606047780792894151">"4M per log buffer"</item>
- <item msgid="5431354956856655120">"16M per log buffer"</item>
+ <item msgid="6921048829791179331">"Off"</item>
+ <item msgid="2969458029344750262">"64K per log buffer"</item>
+ <item msgid="1342285115665698168">"256K per log buffer"</item>
+ <item msgid="1314234299552254621">"1M per log buffer"</item>
+ <item msgid="3606047780792894151">"4M per log buffer"</item>
+ <item msgid="5431354956856655120">"16M per log buffer"</item>
</string-array>
<string-array name="select_logpersist_titles">
- <item msgid="1744840221860799971">"Off"</item>
- <item msgid="3054662377365844197">"All"</item>
- <item msgid="688870735111627832">"All but radio"</item>
- <item msgid="2850427388488887328">"kernel only"</item>
+ <item msgid="1744840221860799971">"Off"</item>
+ <item msgid="3054662377365844197">"All"</item>
+ <item msgid="688870735111627832">"All but radio"</item>
+ <item msgid="2850427388488887328">"kernel only"</item>
</string-array>
<string-array name="select_logpersist_summaries">
- <item msgid="2216470072500521830">"Off"</item>
- <item msgid="172978079776521897">"All log buffers"</item>
- <item msgid="3873873912383879240">"All but radio log buffers"</item>
- <item msgid="8489661142527693381">"kernel log buffer only"</item>
+ <item msgid="2216470072500521830">"Off"</item>
+ <item msgid="172978079776521897">"All log buffers"</item>
+ <item msgid="3873873912383879240">"All but radio log buffers"</item>
+ <item msgid="8489661142527693381">"kernel log buffer only"</item>
</string-array>
<string-array name="window_animation_scale_entries">
- <item msgid="8134156599370824081">"Animation off"</item>
- <item msgid="6624864048416710414">"Animation scale .5x"</item>
- <item msgid="2219332261255416635">"Animation scale 1x"</item>
- <item msgid="3544428804137048509">"Animation scale 1.5x"</item>
- <item msgid="3110710404225974514">"Animation scale 2x"</item>
- <item msgid="4402738611528318731">"Animation scale 5x"</item>
- <item msgid="6189539267968330656">"Animation scale 10x"</item>
+ <item msgid="8134156599370824081">"Animation off"</item>
+ <item msgid="6624864048416710414">"Animation scale .5x"</item>
+ <item msgid="2219332261255416635">"Animation scale 1x"</item>
+ <item msgid="3544428804137048509">"Animation scale 1.5x"</item>
+ <item msgid="3110710404225974514">"Animation scale 2x"</item>
+ <item msgid="4402738611528318731">"Animation scale 5x"</item>
+ <item msgid="6189539267968330656">"Animation scale 10x"</item>
</string-array>
<string-array name="transition_animation_scale_entries">
- <item msgid="8464255836173039442">"Animation off"</item>
- <item msgid="3375781541913316411">"Animation scale .5x"</item>
- <item msgid="1991041427801869945">"Animation scale 1x"</item>
- <item msgid="4012689927622382874">"Animation scale 1.5x"</item>
- <item msgid="3289156759925947169">"Animation scale 2x"</item>
- <item msgid="7705857441213621835">"Animation scale 5x"</item>
- <item msgid="6660750935954853365">"Animation scale 10x"</item>
+ <item msgid="8464255836173039442">"Animation off"</item>
+ <item msgid="3375781541913316411">"Animation scale .5x"</item>
+ <item msgid="1991041427801869945">"Animation scale 1x"</item>
+ <item msgid="4012689927622382874">"Animation scale 1.5x"</item>
+ <item msgid="3289156759925947169">"Animation scale 2x"</item>
+ <item msgid="7705857441213621835">"Animation scale 5x"</item>
+ <item msgid="6660750935954853365">"Animation scale 10x"</item>
</string-array>
<string-array name="animator_duration_scale_entries">
- <item msgid="6039901060648228241">"Animation off"</item>
- <item msgid="1138649021950863198">"Animation scale .5x"</item>
- <item msgid="4394388961370833040">"Animation scale 1x"</item>
- <item msgid="8125427921655194973">"Animation scale 1.5x"</item>
- <item msgid="3334024790739189573">"Animation scale 2x"</item>
- <item msgid="3170120558236848008">"Animation scale 5x"</item>
- <item msgid="1069584980746680398">"Animation scale 10x"</item>
+ <item msgid="6039901060648228241">"Animation off"</item>
+ <item msgid="1138649021950863198">"Animation scale .5x"</item>
+ <item msgid="4394388961370833040">"Animation scale 1x"</item>
+ <item msgid="8125427921655194973">"Animation scale 1.5x"</item>
+ <item msgid="3334024790739189573">"Animation scale 2x"</item>
+ <item msgid="3170120558236848008">"Animation scale 5x"</item>
+ <item msgid="1069584980746680398">"Animation scale 10x"</item>
</string-array>
<string-array name="overlay_display_devices_entries">
- <item msgid="1606809880904982133">"None"</item>
- <item msgid="9033194758688161545">"480p"</item>
- <item msgid="1025306206556583600">"480p (secure)"</item>
- <item msgid="1853913333042744661">"720p"</item>
- <item msgid="3414540279805870511">"720p (secure)"</item>
- <item msgid="9039818062847141551">"1080p"</item>
- <item msgid="4939496949750174834">"1080p (secure)"</item>
- <item msgid="1833612718524903568">"4K"</item>
- <item msgid="238303513127879234">"4K (secure)"</item>
- <item msgid="3547211260846843098">"4K (upscaled)"</item>
- <item msgid="5411365648951414254">"4K (upscaled, secure)"</item>
- <item msgid="1311305077526792901">"720p, 1080p (dual screen)"</item>
+ <item msgid="1606809880904982133">"None"</item>
+ <item msgid="9033194758688161545">"480p"</item>
+ <item msgid="1025306206556583600">"480p (secure)"</item>
+ <item msgid="1853913333042744661">"720p"</item>
+ <item msgid="3414540279805870511">"720p (secure)"</item>
+ <item msgid="9039818062847141551">"1080p"</item>
+ <item msgid="4939496949750174834">"1080p (secure)"</item>
+ <item msgid="1833612718524903568">"4K"</item>
+ <item msgid="238303513127879234">"4K (secure)"</item>
+ <item msgid="3547211260846843098">"4K (upscaled)"</item>
+ <item msgid="5411365648951414254">"4K (upscaled, secure)"</item>
+ <item msgid="1311305077526792901">"720p, 1080p (dual screen)"</item>
</string-array>
<string-array name="enable_opengl_traces_entries">
- <item msgid="3191973083884253830">"None"</item>
- <item msgid="9089630089455370183">"Logcat"</item>
- <item msgid="5397807424362304288">"Systrace (Graphics)"</item>
- <item msgid="1340692776955662664">"Call stack on glGetError"</item>
+ <item msgid="3191973083884253830">"None"</item>
+ <item msgid="9089630089455370183">"Logcat"</item>
+ <item msgid="5397807424362304288">"Systrace (Graphics)"</item>
+ <item msgid="1340692776955662664">"Call stack on glGetError"</item>
</string-array>
<string-array name="show_non_rect_clip_entries">
- <item msgid="993742912147090253">"Off"</item>
- <item msgid="675719912558941285">"Draw non-rectangular clip region in blue"</item>
- <item msgid="1064373276095698656">"Highlight tested drawing commands in green"</item>
+ <item msgid="993742912147090253">"Off"</item>
+ <item msgid="675719912558941285">"Draw non-rectangular clip region in blue"</item>
+ <item msgid="1064373276095698656">"Highlight tested drawing commands in green"</item>
</string-array>
<string-array name="track_frame_time_entries">
- <item msgid="2193584639058893150">"Off"</item>
- <item msgid="2751513398307949636">"On screen as bars"</item>
- <item msgid="2355151170975410323">"In <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
+ <item msgid="2193584639058893150">"Off"</item>
+ <item msgid="2751513398307949636">"On screen as bars"</item>
+ <item msgid="2355151170975410323">"In <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
</string-array>
<string-array name="debug_hw_overdraw_entries">
- <item msgid="8190572633763871652">"Off"</item>
- <item msgid="7688197031296835369">"Show overdraw areas"</item>
- <item msgid="2290859360633824369">"Show areas for Deuteranomaly"</item>
+ <item msgid="8190572633763871652">"Off"</item>
+ <item msgid="7688197031296835369">"Show overdraw areas"</item>
+ <item msgid="2290859360633824369">"Show areas for Deuteranomaly"</item>
</string-array>
<string-array name="app_process_limit_entries">
- <item msgid="3401625457385943795">"Standard limit"</item>
- <item msgid="4071574792028999443">"No background processes"</item>
- <item msgid="4810006996171705398">"At most 1 process"</item>
- <item msgid="8586370216857360863">"At most 2 processes"</item>
- <item msgid="836593137872605381">"At most 3 processes"</item>
- <item msgid="7899496259191969307">"At most 4 processes"</item>
+ <item msgid="3401625457385943795">"Standard limit"</item>
+ <item msgid="4071574792028999443">"No background processes"</item>
+ <item msgid="4810006996171705398">"At most 1 process"</item>
+ <item msgid="8586370216857360863">"At most 2 processes"</item>
+ <item msgid="836593137872605381">"At most 3 processes"</item>
+ <item msgid="7899496259191969307">"At most 4 processes"</item>
</string-array>
<string-array name="usb_configuration_titles">
- <item msgid="488237561639712799">"Charging"</item>
- <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
- <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
- <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
- <item msgid="1718924214939774352">"Audio Source"</item>
- <item msgid="8126315616613006284">"MIDI"</item>
+ <item msgid="488237561639712799">"Charging"</item>
+ <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+ <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+ <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+ <item msgid="1718924214939774352">"Audio Source"</item>
+ <item msgid="8126315616613006284">"MIDI"</item>
</string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 71c14f5..2d3e830 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -20,473 +20,440 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"None"</string>
- <string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string>
- <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string>
- <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string>
- <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Not connected due to low quality network"</string>
- <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi Connection Failure"</string>
- <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Authentication problem"</string>
- <string name="wifi_cant_connect" msgid="5410016875644565884">"Can\'t connect"</string>
- <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
- <string name="wifi_check_password_try_again" msgid="516958988102584767">"Check password and try again"</string>
- <string name="wifi_not_in_range" msgid="1136191511238508967">"Not in range"</string>
- <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
- <string name="wifi_no_internet" msgid="4663834955626848401">"No internet access"</string>
- <string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
- <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatically connected via network rating provider"</string>
- <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> by <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
- <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tap to set up"</string>
- <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no internet"</string>
- <string name="wifi_status_no_internet" msgid="5784710974669608361">"No internet"</string>
- <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign in required"</string>
- <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
- <string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
- <string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Connection failed"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Invalid OSU server URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU server connection failed"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU server validation failed"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Invalid OSU server certificate"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisioning aborted"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisioning not available"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Invalid OSU server URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Unexpected command type"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Unexpected SOAP message type"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP message exchange failed"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Redirect listener failed to start"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Timed out waiting for redirect"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"No OSU activity found"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Unexpected SOAP message status"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Failed to find PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Failed to find trust root node for AAA server"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Failed to find trust root node for remediation server"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Failed to find trust root node for policy server"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Failed to retrieve trust root certificates"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Failed to find trust root certificate for AAA server"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Failed to add PassPoint configuration"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Failed to find an OSU provider"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Connecting"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connected"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Connecting to OSU server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU server validated"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connected to OSU server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Initial SOAP exchange"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Waiting for redirect response"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Received redirect response"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Second SOAP exchange"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Third SOAP exchange"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Retrieving trust root certificates"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisioning complete"</string>
- <string name="speed_label_very_slow" msgid="1867055264243608530">"Very Slow"</string>
- <string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
- <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
- <string name="speed_label_medium" msgid="3175763313268941953">"Medium"</string>
- <string name="speed_label_fast" msgid="7715732164050975057">"Fast"</string>
- <string name="speed_label_very_fast" msgid="2265363430784523409">"Very Fast"</string>
- <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
- <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
- <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
- <string name="bluetooth_connected" msgid="5427152882755735944">"Connected<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="1426882272690346242">"Pairing…"</string>
- <string name="bluetooth_connected_no_headset" msgid="616068069034994802">"Connected (no phone)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_a2dp" msgid="3736431800395923868">"Connected (no media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_map" msgid="3200033913678466453">"Connected (no message access)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2047403011284187056">"Connected (no phone or media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_connected_battery_level" msgid="5162924691231307748">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Active, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
- <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
- <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Active"</string>
- <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
- <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
- <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
- <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
- <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
- <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
- <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
- <string name="bluetooth_profile_map" msgid="1019763341565580450">"Text Messages"</string>
- <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
- <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
- <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
- <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Hearing Aid"</string>
- <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Connected to Hearing Aid"</string>
- <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
- <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
- <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file transfer server"</string>
- <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"Connected to map"</string>
- <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"Connected to SAP"</string>
- <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Not connected to file transfer server"</string>
- <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"Connected to input device"</string>
- <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"Connected to device for internet access"</string>
- <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"Sharing local internet connection with device"</string>
- <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"Use for internet access"</string>
- <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Use for map"</string>
- <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Use for SIM access"</string>
- <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Use for media audio"</string>
- <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Use for phone audio"</string>
- <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Use for file transfer"</string>
- <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Use for input"</string>
- <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Use for Hearing Aid"</string>
- <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Pair"</string>
- <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PAIR"</string>
- <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Cancel"</string>
- <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Pairing grants access to your contacts and call history when connected."</string>
- <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g> because of an incorrect PIN or passkey."</string>
- <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Can\'t communicate with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pairing rejected by <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="bluetooth_talkback_computer" msgid="4875089335641234463">"Computer"</string>
- <string name="bluetooth_talkback_headset" msgid="5140152177885220949">"Headset"</string>
- <string name="bluetooth_talkback_phone" msgid="4260255181240622896">"Phone"</string>
- <string name="bluetooth_talkback_imaging" msgid="551146170554589119">"Imaging"</string>
- <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"Headphone"</string>
- <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"Input Peripheral"</string>
- <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"Bluetooth"</string>
- <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"Pairing left hearing aid…"</string>
- <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"Pairing right hearing aid…"</string>
- <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Left - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
- <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Right - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
- <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi off."</string>
- <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi disconnected."</string>
- <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi one bar."</string>
- <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi two bars."</string>
- <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi three bars."</string>
- <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi signal full."</string>
- <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Open network"</string>
- <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Secure network"</string>
- <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
- <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Removed apps"</string>
- <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Removed apps and users"</string>
- <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB tethering"</string>
- <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Portable hotspot"</string>
- <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth tethering"</string>
- <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Tethering"</string>
- <string name="tether_settings_title_all" msgid="8356136101061143841">"Tethering & portable hotspot"</string>
- <string name="managed_user_title" msgid="8109605045406748842">"All work apps"</string>
- <string name="user_guest" msgid="8475274842845401871">"Guest"</string>
- <string name="unknown" msgid="1592123443519355854">"Unknown"</string>
- <string name="running_process_item_user_label" msgid="3129887865552025943">"User: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
- <string name="launch_defaults_some" msgid="313159469856372621">"Some defaults set"</string>
- <string name="launch_defaults_none" msgid="4241129108140034876">"No defaults set"</string>
- <string name="tts_settings" msgid="8186971894801348327">"Text-to-speech settings"</string>
- <string name="tts_settings_title" msgid="1237820681016639683">"Text-to-speech output"</string>
- <string name="tts_default_rate_title" msgid="6030550998379310088">"Speech rate"</string>
- <string name="tts_default_rate_summary" msgid="4061815292287182801">"Speed at which the text is spoken"</string>
- <string name="tts_default_pitch_title" msgid="6135942113172488671">"Pitch"</string>
- <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Affects the tone of the synthesized speech"</string>
- <string name="tts_default_lang_title" msgid="8018087612299820556">"Language"</string>
- <string name="tts_lang_use_system" msgid="2679252467416513208">"Use system language"</string>
- <string name="tts_lang_not_selected" msgid="7395787019276734765">"Language not selected"</string>
- <string name="tts_default_lang_summary" msgid="5219362163902707785">"Sets the language-specific voice for the spoken text"</string>
- <string name="tts_play_example_title" msgid="7094780383253097230">"Listen to an example"</string>
- <string name="tts_play_example_summary" msgid="8029071615047894486">"Play a short demonstration of speech synthesis"</string>
- <string name="tts_install_data_title" msgid="4264378440508149986">"Install voice data"</string>
- <string name="tts_install_data_summary" msgid="5742135732511822589">"Install the voice data required for speech synthesis"</string>
- <string name="tts_engine_security_warning" msgid="8786238102020223650">"This speech synthesis engine may be able to collect all the text that will be spoken, including personal data like passwords and credit card numbers. It comes from the <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> engine. Enable the use of this speech synthesis engine?"</string>
- <string name="tts_engine_network_required" msgid="1190837151485314743">"This language requires a working network connection for text-to-speech output."</string>
- <string name="tts_default_sample_string" msgid="4040835213373086322">"This is an example of speech synthesis"</string>
- <string name="tts_status_title" msgid="7268566550242584413">"Default language status"</string>
- <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> is fully supported"</string>
- <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requires network connection"</string>
- <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> is not supported"</string>
- <string name="tts_status_checking" msgid="5339150797940483592">"Checking…"</string>
- <string name="tts_engine_settings_title" msgid="3499112142425680334">"Settings for <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
- <string name="tts_engine_settings_button" msgid="1030512042040722285">"Launch engine settings"</string>
- <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferred engine"</string>
- <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
- <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Reset speech pitch"</string>
- <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Reset the pitch at which the text is spoken to default."</string>
+ <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string>
+ <string name="wifi_security_none" msgid="7985461072596594400">"None"</string>
+ <string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string>
+ <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string>
+ <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string>
+ <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Not connected due to low quality network"</string>
+ <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"WiFi Connection Failure"</string>
+ <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Authentication problem"</string>
+ <string name="wifi_cant_connect" msgid="5410016875644565884">"Can\'t connect"</string>
+ <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Can\'t connect to \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string>
+ <string name="wifi_check_password_try_again" msgid="516958988102584767">"Check password and try again"</string>
+ <string name="wifi_not_in_range" msgid="1136191511238508967">"Not in range"</string>
+ <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Won\'t automatically connect"</string>
+ <string name="wifi_no_internet" msgid="4663834955626848401">"No internet access"</string>
+ <string name="saved_network" msgid="4352716707126620811">"Saved by <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatically connected via %1$s"</string>
+ <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatically connected via network rating provider"</string>
+ <string name="connected_via_passpoint" msgid="2826205693803088747">"Connected via %1$s"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connected via <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="available_via_passpoint" msgid="1617440946846329613">"Available via %1$s"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap to sign up"</string>
+ <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connected, no internet"</string>
+ <string name="wifi_status_no_internet" msgid="5784710974669608361">"No internet"</string>
+ <string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sign in required"</string>
+ <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Access point temporarily full"</string>
+ <string name="connected_via_carrier" msgid="7583780074526041912">"Connected via %1$s"</string>
+ <string name="available_via_carrier" msgid="1469036129740799053">"Available via %1$s"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Opening <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Couldn’t connect"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completing sign-up…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Couldn’t complete sign-up. Tap to try again."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Sign-up complete. Connecting…"</string>
+ <string name="speed_label_very_slow" msgid="1867055264243608530">"Very Slow"</string>
+ <string name="speed_label_slow" msgid="813109590815810235">"Slow"</string>
+ <string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
+ <string name="speed_label_medium" msgid="3175763313268941953">"Medium"</string>
+ <string name="speed_label_fast" msgid="7715732164050975057">"Fast"</string>
+ <string name="speed_label_very_fast" msgid="2265363430784523409">"Very Fast"</string>
+ <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
+ <string name="bluetooth_disconnected" msgid="6557104142667339895">"Disconnected"</string>
+ <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Disconnecting…"</string>
+ <string name="bluetooth_connecting" msgid="8555009514614320497">"Connecting…"</string>
+ <string name="bluetooth_connected" msgid="5427152882755735944">"Connected<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_pairing" msgid="1426882272690346242">"Pairing…"</string>
+ <string name="bluetooth_connected_no_headset" msgid="616068069034994802">"Connected (no phone)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_a2dp" msgid="3736431800395923868">"Connected (no media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_map" msgid="3200033913678466453">"Connected (no message access)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2047403011284187056">"Connected (no phone or media)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected_battery_level" msgid="5162924691231307748">"Connected, battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"Connected (no phone), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"Connected (no media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+ <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"Connected (no phone or media), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
+ <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"Active, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+ <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+ <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Active"</string>
+ <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media audio"</string>
+ <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Phone calls"</string>
+ <string name="bluetooth_profile_opp" msgid="9168139293654233697">"File transfer"</string>
+ <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Input device"</string>
+ <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internet access"</string>
+ <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Contact sharing"</string>
+ <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Use for contact sharing"</string>
+ <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Internet connection sharing"</string>
+ <string name="bluetooth_profile_map" msgid="1019763341565580450">"Text Messages"</string>
+ <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Access"</string>
+ <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+ <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
+ <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Hearing Aid"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Connected to Hearing Aid"</string>
+ <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Connected to media audio"</string>
+ <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Connected to phone audio"</string>
+ <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Connected to file transfer server"</string>
+ <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"Connected to map"</string>
+ <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"Connected to SAP"</string>
+ <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"Not connected to file transfer server"</string>
+ <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"Connected to input device"</string>
+ <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"Connected to device for internet access"</string>
+ <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"Sharing local internet connection with device"</string>
+ <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"Use for internet access"</string>
+ <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Use for map"</string>
+ <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Use for SIM access"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Use for media audio"</string>
+ <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Use for phone audio"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Use for file transfer"</string>
+ <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Use for input"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Use for Hearing Aid"</string>
+ <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Pair"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PAIR"</string>
+ <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Cancel"</string>
+ <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Pairing grants access to your contacts and call history when connected."</string>
+ <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Couldn\'t pair with <xliff:g id="DEVICE_NAME">%1$s</xliff:g> because of an incorrect PIN or passkey."</string>
+ <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Can\'t communicate with <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"Pairing rejected by <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="bluetooth_talkback_computer" msgid="4875089335641234463">"Computer"</string>
+ <string name="bluetooth_talkback_headset" msgid="5140152177885220949">"Headset"</string>
+ <string name="bluetooth_talkback_phone" msgid="4260255181240622896">"Phone"</string>
+ <string name="bluetooth_talkback_imaging" msgid="551146170554589119">"Imaging"</string>
+ <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"Headphone"</string>
+ <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"Input Peripheral"</string>
+ <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"Bluetooth"</string>
+ <string name="bluetooth_hearingaid_left_pairing_message" msgid="7378813500862148102">"Pairing left hearing aid…"</string>
+ <string name="bluetooth_hearingaid_right_pairing_message" msgid="1550373802309160891">"Pairing right hearing aid…"</string>
+ <string name="bluetooth_hearingaid_left_battery_level" msgid="8797811465352097562">"Left - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+ <string name="bluetooth_hearingaid_right_battery_level" msgid="7309476148173459677">"Right - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+ <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi off."</string>
+ <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi disconnected."</string>
+ <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi one bar."</string>
+ <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi two bars."</string>
+ <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi three bars."</string>
+ <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi signal full."</string>
+ <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"Open network"</string>
+ <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"Secure network"</string>
+ <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
+ <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Removed apps"</string>
+ <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Removed apps and users"</string>
+ <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB tethering"</string>
+ <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Portable hotspot"</string>
+ <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth tethering"</string>
+ <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Tethering"</string>
+ <string name="tether_settings_title_all" msgid="8356136101061143841">"Tethering & portable hotspot"</string>
+ <string name="managed_user_title" msgid="8109605045406748842">"All work apps"</string>
+ <string name="user_guest" msgid="8475274842845401871">"Guest"</string>
+ <string name="unknown" msgid="1592123443519355854">"Unknown"</string>
+ <string name="running_process_item_user_label" msgid="3129887865552025943">"User: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+ <string name="launch_defaults_some" msgid="313159469856372621">"Some defaults set"</string>
+ <string name="launch_defaults_none" msgid="4241129108140034876">"No defaults set"</string>
+ <string name="tts_settings" msgid="8186971894801348327">"Text-to-speech settings"</string>
+ <string name="tts_settings_title" msgid="1237820681016639683">"Text-to-speech output"</string>
+ <string name="tts_default_rate_title" msgid="6030550998379310088">"Speech rate"</string>
+ <string name="tts_default_rate_summary" msgid="4061815292287182801">"Speed at which the text is spoken"</string>
+ <string name="tts_default_pitch_title" msgid="6135942113172488671">"Pitch"</string>
+ <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Affects the tone of the synthesized speech"</string>
+ <string name="tts_default_lang_title" msgid="8018087612299820556">"Language"</string>
+ <string name="tts_lang_use_system" msgid="2679252467416513208">"Use system language"</string>
+ <string name="tts_lang_not_selected" msgid="7395787019276734765">"Language not selected"</string>
+ <string name="tts_default_lang_summary" msgid="5219362163902707785">"Sets the language-specific voice for the spoken text"</string>
+ <string name="tts_play_example_title" msgid="7094780383253097230">"Listen to an example"</string>
+ <string name="tts_play_example_summary" msgid="8029071615047894486">"Play a short demonstration of speech synthesis"</string>
+ <string name="tts_install_data_title" msgid="4264378440508149986">"Install voice data"</string>
+ <string name="tts_install_data_summary" msgid="5742135732511822589">"Install the voice data required for speech synthesis"</string>
+ <string name="tts_engine_security_warning" msgid="8786238102020223650">"This speech synthesis engine may be able to collect all the text that will be spoken, including personal data like passwords and credit card numbers. It comes from the <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> engine. Enable the use of this speech synthesis engine?"</string>
+ <string name="tts_engine_network_required" msgid="1190837151485314743">"This language requires a working network connection for text-to-speech output."</string>
+ <string name="tts_default_sample_string" msgid="4040835213373086322">"This is an example of speech synthesis"</string>
+ <string name="tts_status_title" msgid="7268566550242584413">"Default language status"</string>
+ <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> is fully supported"</string>
+ <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> requires network connection"</string>
+ <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> is not supported"</string>
+ <string name="tts_status_checking" msgid="5339150797940483592">"Checking…"</string>
+ <string name="tts_engine_settings_title" msgid="3499112142425680334">"Settings for <xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>"</string>
+ <string name="tts_engine_settings_button" msgid="1030512042040722285">"Launch engine settings"</string>
+ <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Preferred engine"</string>
+ <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
+ <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Reset speech pitch"</string>
+ <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Reset the pitch at which the text is spoken to default."</string>
<string-array name="tts_rate_entries">
- <item msgid="6695494874362656215">"Very slow"</item>
- <item msgid="4795095314303559268">"Slow"</item>
- <item msgid="8903157781070679765">"Normal"</item>
- <item msgid="164347302621392996">"Fast"</item>
- <item msgid="5794028588101562009">"Faster"</item>
- <item msgid="7163942783888652942">"Very fast"</item>
- <item msgid="7831712693748700507">"Rapid"</item>
- <item msgid="5194774745031751806">"Very rapid"</item>
- <item msgid="9085102246155045744">"Fastest"</item>
+ <item msgid="6695494874362656215">"Very slow"</item>
+ <item msgid="4795095314303559268">"Slow"</item>
+ <item msgid="8903157781070679765">"Normal"</item>
+ <item msgid="164347302621392996">"Fast"</item>
+ <item msgid="5794028588101562009">"Faster"</item>
+ <item msgid="7163942783888652942">"Very fast"</item>
+ <item msgid="7831712693748700507">"Rapid"</item>
+ <item msgid="5194774745031751806">"Very rapid"</item>
+ <item msgid="9085102246155045744">"Fastest"</item>
</string-array>
- <string name="choose_profile" msgid="6921016979430278661">"Choose profile"</string>
- <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
- <string name="category_work" msgid="8699184680584175622">"Work"</string>
- <string name="development_settings_title" msgid="215179176067683667">"Developer options"</string>
- <string name="development_settings_enable" msgid="542530994778109538">"Enable developer options"</string>
- <string name="development_settings_summary" msgid="1815795401632854041">"Set options for app development"</string>
- <string name="development_settings_not_available" msgid="4308569041701535607">"Developer options are not available for this user"</string>
- <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN settings are not available for this user"</string>
- <string name="tethering_settings_not_available" msgid="6765770438438291012">"Tethering settings are not available for this user"</string>
- <string name="apn_settings_not_available" msgid="7873729032165324000">"Access Point Name settings are not available for this user"</string>
- <string name="enable_adb" msgid="7982306934419797485">"USB debugging"</string>
- <string name="enable_adb_summary" msgid="4881186971746056635">"Debug mode when USB is connected"</string>
- <string name="clear_adb_keys" msgid="4038889221503122743">"Revoke USB debugging authorizations"</string>
- <string name="bugreport_in_power" msgid="7923901846375587241">"Bug report shortcut"</string>
- <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Show a button in the power menu for taking a bug report"</string>
- <string name="keep_screen_on" msgid="1146389631208760344">"Stay awake"</string>
- <string name="keep_screen_on_summary" msgid="2173114350754293009">"Screen will never sleep while charging"</string>
- <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Enable Bluetooth HCI snoop log"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
- <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM unlocking"</string>
- <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Allow the bootloader to be unlocked"</string>
- <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Allow OEM unlocking?"</string>
- <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"WARNING: Device protection features will not work on this device while this setting is turned on."</string>
- <string name="mock_location_app" msgid="7966220972812881854">"Select mock location app"</string>
- <string name="mock_location_app_not_set" msgid="809543285495344223">"No mock location app set"</string>
- <string name="mock_location_app_set" msgid="8966420655295102685">"Mock location app: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
- <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
- <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi Verbose Logging"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Connected MAC Randomization"</string>
- <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
- <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
- <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
- <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
- <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
- <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string>
- <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string>
- <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="8436224899475822557">"Trigger Bluetooth Audio Codec\nSelection"</string>
- <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string>
- <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="8010380028880963535">"Trigger Bluetooth Audio Codec\nSelection: Sample Rate"</string>
- <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"Bluetooth Audio Bits Per Sample"</string>
- <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="8063859754619484760">"Trigger Bluetooth Audio Codec\nSelection: Bits Per Sample"</string>
- <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"Bluetooth Audio Channel Mode"</string>
- <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="7234956835280563341">"Trigger Bluetooth Audio Codec\nSelection: Channel Mode"</string>
- <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string>
- <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"Trigger Bluetooth Audio LDAC\nCodec Selection: Playback Quality"</string>
- <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
- <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"Private DNS"</string>
- <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Select Private DNS Mode"</string>
- <string name="private_dns_mode_off" msgid="8236575187318721684">"Off"</string>
- <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatic"</string>
- <string name="private_dns_mode_provider" msgid="8354935160639360804">"Private DNS provider hostname"</string>
- <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Enter hostname of DNS provider"</string>
- <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
- <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
- <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Randomize MAC address when connecting to Wi‑Fi networks"</string>
- <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
- <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
- <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
- <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string>
- <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"Clear logger persistent storage?"</string>
- <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"When we no longer are monitoring with the persistent logger, we are required to erase the logger data resident on your device."</string>
- <string name="select_logpersist_title" msgid="7530031344550073166">"Store logger data persistently on device"</string>
- <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"Select log buffers to store persistently on device"</string>
- <string name="select_usb_configuration_title" msgid="2649938511506971843">"Select USB Configuration"</string>
- <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Select USB Configuration"</string>
- <string name="allow_mock_location" msgid="2787962564578664888">"Allow mock locations"</string>
- <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
- <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
- <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
- <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
- <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification, and read log data."</string>
- <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you’ve previously authorized?"</string>
- <string name="dev_settings_warning_title" msgid="7244607768088540165">"Allow development settings?"</string>
- <string name="dev_settings_warning_message" msgid="2298337781139097964">"These settings are intended for development use only. They can cause your device and the applications on it to break or misbehave."</string>
- <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verify apps over USB"</string>
- <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Check apps installed via ADB/ADT for harmful behavior."</string>
- <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"Bluetooth devices without names (MAC addresses only) will be displayed"</string>
- <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
- <string name="enable_terminal_title" msgid="95572094356054120">"Local terminal"</string>
- <string name="enable_terminal_summary" msgid="67667852659359206">"Enable terminal app that offers local shell access"</string>
- <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP checking"</string>
- <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"Set HDCP checking behavior"</string>
- <string name="debug_debugging_category" msgid="6781250159513471316">"Debugging"</string>
- <string name="debug_app" msgid="8349591734751384446">"Select debug app"</string>
- <string name="debug_app_not_set" msgid="718752499586403499">"No debug application set"</string>
- <string name="debug_app_set" msgid="2063077997870280017">"Debugging application: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="select_application" msgid="5156029161289091703">"Select application"</string>
- <string name="no_application" msgid="2813387563129153880">"Nothing"</string>
- <string name="wait_for_debugger" msgid="1202370874528893091">"Wait for debugger"</string>
- <string name="wait_for_debugger_summary" msgid="1766918303462746804">"Debugged application waits for debugger to attach before executing"</string>
- <string name="debug_input_category" msgid="1811069939601180246">"Input"</string>
- <string name="debug_drawing_category" msgid="6755716469267367852">"Drawing"</string>
- <string name="debug_hw_drawing_category" msgid="6220174216912308658">"Hardware accelerated rendering"</string>
- <string name="media_category" msgid="4388305075496848353">"Media"</string>
- <string name="debug_monitoring_category" msgid="7640508148375798343">"Monitoring"</string>
- <string name="strict_mode" msgid="1938795874357830695">"Strict mode enabled"</string>
- <string name="strict_mode_summary" msgid="142834318897332338">"Flash screen when apps do long operations on main thread"</string>
- <string name="pointer_location" msgid="6084434787496938001">"Pointer location"</string>
- <string name="pointer_location_summary" msgid="840819275172753713">"Screen overlay showing current touch data"</string>
- <string name="show_touches" msgid="2642976305235070316">"Show taps"</string>
- <string name="show_touches_summary" msgid="6101183132903926324">"Show visual feedback for taps"</string>
- <string name="show_screen_updates" msgid="5470814345876056420">"Show surface updates"</string>
- <string name="show_screen_updates_summary" msgid="2569622766672785529">"Flash entire window surfaces when they update"</string>
- <string name="show_hw_screen_updates" msgid="4117270979975470789">"Show view updates"</string>
- <string name="show_hw_screen_updates_summary" msgid="6506943466625875655">"Flash views inside windows when drawn"</string>
- <string name="show_hw_layers_updates" msgid="5645728765605699821">"Show hardware layers updates"</string>
- <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"Flash hardware layers green when they update"</string>
- <string name="debug_hw_overdraw" msgid="2968692419951565417">"Debug GPU overdraw"</string>
- <string name="disable_overlays" msgid="2074488440505934665">"Disable HW overlays"</string>
- <string name="disable_overlays_summary" msgid="3578941133710758592">"Always use GPU for screen compositing"</string>
- <string name="simulate_color_space" msgid="6745847141353345872">"Simulate color space"</string>
- <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Enable OpenGL traces"</string>
- <string name="usb_audio_disable_routing" msgid="8114498436003102671">"Disable USB audio routing"</string>
- <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Disable automatic routing to USB audio peripherals"</string>
- <string name="debug_layout" msgid="5981361776594526155">"Show layout bounds"</string>
- <string name="debug_layout_summary" msgid="2001775315258637682">"Show clip bounds, margins, etc."</string>
- <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Force RTL layout direction"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"Force screen layout direction to RTL for all locales"</string>
- <string name="force_msaa" msgid="7920323238677284387">"Force 4x MSAA"</string>
- <string name="force_msaa_summary" msgid="9123553203895817537">"Enable 4x MSAA in OpenGL ES 2.0 apps"</string>
- <string name="show_non_rect_clip" msgid="505954950474595172">"Debug non-rectangular clip operations"</string>
- <string name="track_frame_time" msgid="6094365083096851167">"Profile HWUI rendering"</string>
- <string name="enable_gpu_debug_layers" msgid="3848838293793255097">"Enable GPU debug layers"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"Allow loading GPU debug layers for debug apps"</string>
- <string name="window_animation_scale_title" msgid="6162587588166114700">"Window animation scale"</string>
- <string name="transition_animation_scale_title" msgid="387527540523595875">"Transition animation scale"</string>
- <string name="animator_duration_scale_title" msgid="3406722410819934083">"Animator duration scale"</string>
- <string name="overlay_display_devices_title" msgid="5364176287998398539">"Simulate secondary displays"</string>
- <string name="debug_applications_category" msgid="4206913653849771549">"Apps"</string>
- <string name="immediately_destroy_activities" msgid="1579659389568133959">"Don’t keep activities"</string>
- <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"Destroy every activity as soon as the user leaves it"</string>
- <string name="app_process_limit_title" msgid="4280600650253107163">"Background process limit"</string>
- <string name="show_all_anrs" msgid="4924885492787069007">"Show background ANRs"</string>
- <string name="show_all_anrs_summary" msgid="6636514318275139826">"Display App Not Responding dialog for background apps"</string>
- <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Show notification channel warnings"</string>
- <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Displays on-screen warning when an app posts a notification without a valid channel"</string>
- <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string>
- <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
- <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be resizable"</string>
- <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Make all activities resizable for multi-window, regardless of manifest values."</string>
- <string name="enable_freeform_support" msgid="1461893351278940416">"Enable freeform windows"</string>
- <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Enable support for experimental freeform windows."</string>
- <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop backup password"</string>
- <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Desktop full backups aren’t currently protected"</string>
- <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap to change or remove the password for desktop full backups"</string>
- <string name="local_backup_password_toast_success" msgid="582016086228434290">"New backup password set"</string>
- <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"New password and confirmation don’t match"</string>
- <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Failure setting backup password"</string>
- <string name="loading_injected_setting_summary" msgid="4095178591461231376">"Loading…"</string>
+ <string name="choose_profile" msgid="6921016979430278661">"Choose profile"</string>
+ <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
+ <string name="category_work" msgid="8699184680584175622">"Work"</string>
+ <string name="development_settings_title" msgid="215179176067683667">"Developer options"</string>
+ <string name="development_settings_enable" msgid="542530994778109538">"Enable developer options"</string>
+ <string name="development_settings_summary" msgid="1815795401632854041">"Set options for app development"</string>
+ <string name="development_settings_not_available" msgid="4308569041701535607">"Developer options are not available for this user"</string>
+ <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN settings are not available for this user"</string>
+ <string name="tethering_settings_not_available" msgid="6765770438438291012">"Tethering settings are not available for this user"</string>
+ <string name="apn_settings_not_available" msgid="7873729032165324000">"Access Point Name settings are not available for this user"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"USB debugging"</string>
+ <string name="enable_adb_summary" msgid="4881186971746056635">"Debug mode when USB is connected"</string>
+ <string name="clear_adb_keys" msgid="4038889221503122743">"Revoke USB debugging authorizations"</string>
+ <string name="bugreport_in_power" msgid="7923901846375587241">"Bug report shortcut"</string>
+ <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Show a button in the power menu for taking a bug report"</string>
+ <string name="keep_screen_on" msgid="1146389631208760344">"Stay awake"</string>
+ <string name="keep_screen_on_summary" msgid="2173114350754293009">"Screen will never sleep while charging"</string>
+ <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Enable Bluetooth HCI snoop log"</string>
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capture Bluetooth packets. (Toggle Bluetooth after changing this setting)"</string>
+ <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM unlocking"</string>
+ <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Allow the bootloader to be unlocked"</string>
+ <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Allow OEM unlocking?"</string>
+ <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"WARNING: Device protection features will not work on this device while this setting is turned on."</string>
+ <string name="mock_location_app" msgid="7966220972812881854">"Select mock location app"</string>
+ <string name="mock_location_app_not_set" msgid="809543285495344223">"No mock location app set"</string>
+ <string name="mock_location_app_set" msgid="8966420655295102685">"Mock location app: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
+ <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
+ <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi Verbose Logging"</string>
+ <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
+ <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
+ <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
+ <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
+ <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"Select Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"Bluetooth Audio Codec"</string>
+ <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="8436224899475822557">"Trigger Bluetooth Audio Codec\nSelection"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"Bluetooth Audio Sample Rate"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="8010380028880963535">"Trigger Bluetooth Audio Codec\nSelection: Sample Rate"</string>
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"Bluetooth Audio Bits Per Sample"</string>
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="8063859754619484760">"Trigger Bluetooth Audio Codec\nSelection: Bits Per Sample"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"Bluetooth Audio Channel Mode"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="7234956835280563341">"Trigger Bluetooth Audio Codec\nSelection: Channel Mode"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"Bluetooth Audio LDAC Codec: Playback Quality"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"Trigger Bluetooth Audio LDAC\nCodec Selection: Playback Quality"</string>
+ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+ <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"Private DNS"</string>
+ <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Select Private DNS Mode"</string>
+ <string name="private_dns_mode_off" msgid="8236575187318721684">"Off"</string>
+ <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatic"</string>
+ <string name="private_dns_mode_provider" msgid="8354935160639360804">"Private DNS provider hostname"</string>
+ <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Enter hostname of DNS provider"</string>
+ <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
+ <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
+ <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+ <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
+ <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
+ <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
+ <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Select Logger sizes per log buffer"</string>
+ <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"Clear logger persistent storage?"</string>
+ <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"When we no longer are monitoring with the persistent logger, we are required to erase the logger data resident on your device."</string>
+ <string name="select_logpersist_title" msgid="7530031344550073166">"Store logger data persistently on device"</string>
+ <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"Select log buffers to store persistently on device"</string>
+ <string name="select_usb_configuration_title" msgid="2649938511506971843">"Select USB Configuration"</string>
+ <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Select USB Configuration"</string>
+ <string name="allow_mock_location" msgid="2787962564578664888">"Allow mock locations"</string>
+ <string name="allow_mock_location_summary" msgid="317615105156345626">"Allow mock locations"</string>
+ <string name="debug_view_attributes" msgid="6485448367803310384">"Enable view attribute inspection"</string>
+ <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Always keep mobile data active, even when Wi‑Fi is active (for fast network switching)."</string>
+ <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Use tethering hardware acceleration if available"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Allow USB debugging?"</string>
+ <string name="adb_warning_message" msgid="7316799925425402244">"USB debugging is intended for development purposes only. Use it to copy data between your computer and your device, install apps on your device without notification, and read log data."</string>
+ <string name="adb_keys_warning_message" msgid="5659849457135841625">"Revoke access to USB debugging from all computers you’ve previously authorized?"</string>
+ <string name="dev_settings_warning_title" msgid="7244607768088540165">"Allow development settings?"</string>
+ <string name="dev_settings_warning_message" msgid="2298337781139097964">"These settings are intended for development use only. They can cause your device and the applications on it to break or misbehave."</string>
+ <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verify apps over USB"</string>
+ <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Check apps installed via ADB/ADT for harmful behavior."</string>
+ <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"Bluetooth devices without names (MAC addresses only) will be displayed"</string>
+ <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
+ <string name="enable_terminal_title" msgid="95572094356054120">"Local terminal"</string>
+ <string name="enable_terminal_summary" msgid="67667852659359206">"Enable terminal app that offers local shell access"</string>
+ <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP checking"</string>
+ <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"Set HDCP checking behavior"</string>
+ <string name="debug_debugging_category" msgid="6781250159513471316">"Debugging"</string>
+ <string name="debug_app" msgid="8349591734751384446">"Select debug app"</string>
+ <string name="debug_app_not_set" msgid="718752499586403499">"No debug application set"</string>
+ <string name="debug_app_set" msgid="2063077997870280017">"Debugging application: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="select_application" msgid="5156029161289091703">"Select application"</string>
+ <string name="no_application" msgid="2813387563129153880">"Nothing"</string>
+ <string name="wait_for_debugger" msgid="1202370874528893091">"Wait for debugger"</string>
+ <string name="wait_for_debugger_summary" msgid="1766918303462746804">"Debugged application waits for debugger to attach before executing"</string>
+ <string name="debug_input_category" msgid="1811069939601180246">"Input"</string>
+ <string name="debug_drawing_category" msgid="6755716469267367852">"Drawing"</string>
+ <string name="debug_hw_drawing_category" msgid="6220174216912308658">"Hardware accelerated rendering"</string>
+ <string name="media_category" msgid="4388305075496848353">"Media"</string>
+ <string name="debug_monitoring_category" msgid="7640508148375798343">"Monitoring"</string>
+ <string name="strict_mode" msgid="1938795874357830695">"Strict mode enabled"</string>
+ <string name="strict_mode_summary" msgid="142834318897332338">"Flash screen when apps do long operations on main thread"</string>
+ <string name="pointer_location" msgid="6084434787496938001">"Pointer location"</string>
+ <string name="pointer_location_summary" msgid="840819275172753713">"Screen overlay showing current touch data"</string>
+ <string name="show_touches" msgid="2642976305235070316">"Show taps"</string>
+ <string name="show_touches_summary" msgid="6101183132903926324">"Show visual feedback for taps"</string>
+ <string name="show_screen_updates" msgid="5470814345876056420">"Show surface updates"</string>
+ <string name="show_screen_updates_summary" msgid="2569622766672785529">"Flash entire window surfaces when they update"</string>
+ <string name="show_hw_screen_updates" msgid="4117270979975470789">"Show view updates"</string>
+ <string name="show_hw_screen_updates_summary" msgid="6506943466625875655">"Flash views inside windows when drawn"</string>
+ <string name="show_hw_layers_updates" msgid="5645728765605699821">"Show hardware layers updates"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"Flash hardware layers green when they update"</string>
+ <string name="debug_hw_overdraw" msgid="2968692419951565417">"Debug GPU overdraw"</string>
+ <string name="disable_overlays" msgid="2074488440505934665">"Disable HW overlays"</string>
+ <string name="disable_overlays_summary" msgid="3578941133710758592">"Always use GPU for screen compositing"</string>
+ <string name="simulate_color_space" msgid="6745847141353345872">"Simulate color space"</string>
+ <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Enable OpenGL traces"</string>
+ <string name="usb_audio_disable_routing" msgid="8114498436003102671">"Disable USB audio routing"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Disable automatic routing to USB audio peripherals"</string>
+ <string name="debug_layout" msgid="5981361776594526155">"Show layout bounds"</string>
+ <string name="debug_layout_summary" msgid="2001775315258637682">"Show clip bounds, margins, etc."</string>
+ <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Force RTL layout direction"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"Force screen layout direction to RTL for all locales"</string>
+ <string name="force_msaa" msgid="7920323238677284387">"Force 4x MSAA"</string>
+ <string name="force_msaa_summary" msgid="9123553203895817537">"Enable 4x MSAA in OpenGL ES 2.0 apps"</string>
+ <string name="show_non_rect_clip" msgid="505954950474595172">"Debug non-rectangular clip operations"</string>
+ <string name="track_frame_time" msgid="6094365083096851167">"Profile HWUI rendering"</string>
+ <string name="enable_gpu_debug_layers" msgid="3848838293793255097">"Enable GPU debug layers"</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"Allow loading GPU debug layers for debug apps"</string>
+ <string name="window_animation_scale_title" msgid="6162587588166114700">"Window animation scale"</string>
+ <string name="transition_animation_scale_title" msgid="387527540523595875">"Transition animation scale"</string>
+ <string name="animator_duration_scale_title" msgid="3406722410819934083">"Animator duration scale"</string>
+ <string name="overlay_display_devices_title" msgid="5364176287998398539">"Simulate secondary displays"</string>
+ <string name="debug_applications_category" msgid="4206913653849771549">"Apps"</string>
+ <string name="immediately_destroy_activities" msgid="1579659389568133959">"Don’t keep activities"</string>
+ <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"Destroy every activity as soon as the user leaves it"</string>
+ <string name="app_process_limit_title" msgid="4280600650253107163">"Background process limit"</string>
+ <string name="show_all_anrs" msgid="4924885492787069007">"Show background ANRs"</string>
+ <string name="show_all_anrs_summary" msgid="6636514318275139826">"Display App Not Responding dialog for background apps"</string>
+ <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Show notification channel warnings"</string>
+ <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Displays on-screen warning when an app posts a notification without a valid channel"</string>
+ <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string>
+ <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
+ <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be resizable"</string>
+ <string name="force_resizable_activities_summary" msgid="6667493494706124459">"Make all activities resizable for multi-window, regardless of manifest values."</string>
+ <string name="enable_freeform_support" msgid="1461893351278940416">"Enable freeform windows"</string>
+ <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Enable support for experimental freeform windows."</string>
+ <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop backup password"</string>
+ <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Desktop full backups aren’t currently protected"</string>
+ <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap to change or remove the password for desktop full backups"</string>
+ <string name="local_backup_password_toast_success" msgid="582016086228434290">"New backup password set"</string>
+ <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"New password and confirmation don’t match"</string>
+ <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Failure setting backup password"</string>
+ <string name="loading_injected_setting_summary" msgid="4095178591461231376">"Loading…"</string>
<string-array name="color_mode_names">
- <item msgid="2425514299220523812">"Vibrant (default)"</item>
- <item msgid="8446070607501413455">"Natural"</item>
- <item msgid="6553408765810699025">"Standard"</item>
+ <item msgid="2425514299220523812">"Vibrant (default)"</item>
+ <item msgid="8446070607501413455">"Natural"</item>
+ <item msgid="6553408765810699025">"Standard"</item>
</string-array>
<string-array name="color_mode_descriptions">
- <item msgid="4979629397075120893">"Enhanced colors"</item>
- <item msgid="8280754435979370728">"Natural colors as seen by the eye"</item>
- <item msgid="5363960654009010371">"Colors optimized for digital content"</item>
+ <item msgid="4979629397075120893">"Enhanced colors"</item>
+ <item msgid="8280754435979370728">"Natural colors as seen by the eye"</item>
+ <item msgid="5363960654009010371">"Colors optimized for digital content"</item>
</string-array>
- <string name="inactive_apps_title" msgid="9042996804461901648">"Standby apps"</string>
- <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Inactive. Tap to toggle."</string>
- <string name="inactive_app_active_summary" msgid="4174921824958516106">"Active. Tap to toggle."</string>
- <string name="standby_bucket_summary" msgid="6567835350910684727">"App standby state:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <string name="runningservices_settings_title" msgid="8097287939865165213">"Running services"</string>
- <string name="runningservices_settings_summary" msgid="854608995821032748">"View and control currently running services"</string>
- <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView implementation"</string>
- <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Set WebView implementation"</string>
- <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"This choice is no longer valid. Try again."</string>
- <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convert to file encryption"</string>
- <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convert…"</string>
- <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Already file encrypted"</string>
- <string name="title_convert_fbe" msgid="1263622876196444453">"Converting to file based encryption"</string>
- <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Convert data partition to file based encryption.\n !!Warning!! This will erase all your data.\n This feature is alpha, and may not work correctly.\n Press \'Wipe and convert…\' to continue."</string>
- <string name="button_convert_fbe" msgid="5152671181309826405">"Wipe and convert…"</string>
- <string name="picture_color_mode" msgid="4560755008730283695">"Picture color mode"</string>
- <string name="picture_color_mode_desc" msgid="1141891467675548590">"Use sRGB"</string>
- <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"Disabled"</string>
- <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"Monochromacy"</string>
- <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"Deuteranomaly (red-green)"</string>
- <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomaly (red-green)"</string>
- <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomaly (blue-yellow)"</string>
- <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Color correction"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
- <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="power_remaining_settings_home_page" msgid="4845022416859002011">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
- <string name="power_remaining_duration_only" msgid="6123167166221295462">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
- <string name="power_discharging_duration" msgid="8848256785736335185">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string>
- <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_duration_only_short" msgid="3463575350656389957">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
- <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> based on your usage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> based on your usage"</string>
- <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string>
- <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_only_more_than_subtext" msgid="8931654680569617380">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="1181059207608751924">"Phone may shutdown soon"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="2606370266981054691">"Tablet may shutdown soon"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="2918084807716859985">"Device may shutdown soon"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="3090926004324573908">"Phone may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Device may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
- <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
- <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
- <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
- <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
- <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
- <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
- <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
- <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
- <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
- <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
- <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
- <string name="install_other_apps" msgid="6986686991775883017">"Install unknown apps"</string>
- <string name="home" msgid="3256884684164448244">"Settings Home"</string>
+ <string name="inactive_apps_title" msgid="9042996804461901648">"Standby apps"</string>
+ <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Inactive. Tap to toggle."</string>
+ <string name="inactive_app_active_summary" msgid="4174921824958516106">"Active. Tap to toggle."</string>
+ <string name="standby_bucket_summary" msgid="6567835350910684727">"App standby state:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
+ <string name="runningservices_settings_title" msgid="8097287939865165213">"Running services"</string>
+ <string name="runningservices_settings_summary" msgid="854608995821032748">"View and control currently running services"</string>
+ <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView implementation"</string>
+ <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Set WebView implementation"</string>
+ <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"This choice is no longer valid. Try again."</string>
+ <string name="convert_to_file_encryption" msgid="3060156730651061223">"Convert to file encryption"</string>
+ <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Convert…"</string>
+ <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Already file encrypted"</string>
+ <string name="title_convert_fbe" msgid="1263622876196444453">"Converting to file based encryption"</string>
+ <string name="convert_to_fbe_warning" msgid="6139067817148865527">"Convert data partition to file based encryption.\n !!Warning!! This will erase all your data.\n This feature is alpha, and may not work correctly.\n Press \'Wipe and convert…\' to continue."</string>
+ <string name="button_convert_fbe" msgid="5152671181309826405">"Wipe and convert…"</string>
+ <string name="picture_color_mode" msgid="4560755008730283695">"Picture color mode"</string>
+ <string name="picture_color_mode_desc" msgid="1141891467675548590">"Use sRGB"</string>
+ <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"Disabled"</string>
+ <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"Monochromacy"</string>
+ <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"Deuteranomaly (red-green)"</string>
+ <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomaly (red-green)"</string>
+ <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomaly (blue-yellow)"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Color correction"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
+ <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <string name="power_remaining_settings_home_page" msgid="4845022416859002011">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
+ <string name="power_remaining_duration_only" msgid="6123167166221295462">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
+ <string name="power_discharging_duration" msgid="8848256785736335185">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string>
+ <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_only_short" msgid="3463575350656389957">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
+ <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> based on your usage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> based on your usage"</string>
+ <string name="power_discharge_by" msgid="6453537733650125582">"Should last until about <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only" msgid="107616694963545745">"Should last until about <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Until <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining"</string>
+ <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Less than <xliff:g id="THRESHOLD">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="8931654680569617380">"More than <xliff:g id="TIME_REMAINING">%1$s</xliff:g> remaining"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="1181059207608751924">"Phone may shutdown soon"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="2606370266981054691">"Tablet may shutdown soon"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="2918084807716859985">"Device may shutdown soon"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="3090926004324573908">"Phone may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Device may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
+ <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
+ <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
+ <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
+ <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
+ <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+ <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
+ <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
+ <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
+ <string name="external_source_trusted" msgid="2707996266575928037">"Allowed"</string>
+ <string name="external_source_untrusted" msgid="2677442511837596726">"Not allowed"</string>
+ <string name="install_other_apps" msgid="6986686991775883017">"Install unknown apps"</string>
+ <string name="home" msgid="3256884684164448244">"Settings Home"</string>
<string-array name="battery_labels">
- <item msgid="8494684293649631252">"0%"</item>
- <item msgid="8934126114226089439">"50%"</item>
- <item msgid="1286113608943010849">"100%"</item>
+ <item msgid="8494684293649631252">"0%"</item>
+ <item msgid="8934126114226089439">"50%"</item>
+ <item msgid="1286113608943010849">"100%"</item>
</string-array>
- <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
- <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
- <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
- <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
- <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
- <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
- <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
- <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
- <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <string name="retail_demo_reset_message" msgid="118771671364131297">"Enter password to perform factory reset in demo mode"</string>
- <string name="retail_demo_reset_next" msgid="8356731459226304963">"Next"</string>
- <string name="retail_demo_reset_title" msgid="696589204029930100">"Password required"</string>
- <string name="active_input_method_subtypes" msgid="3596398805424733238">"Active input methods"</string>
- <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Use system languages"</string>
- <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Failed to open settings for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
- <string name="ime_security_warning" msgid="4135828934735934248">"This input method may be able to collect all the text you type, including personal data like passwords and credit card numbers. It comes from the app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Use this input method?"</string>
- <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Note: After a reboot, this app can\'t start until you unlock your phone"</string>
- <string name="ims_reg_title" msgid="7609782759207241443">"IMS registration state"</string>
- <string name="ims_reg_status_registered" msgid="933003316932739188">"Registered"</string>
- <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Not registered"</string>
- <string name="status_unavailable" msgid="7862009036663793314">"Unavailable"</string>
- <string name="wifi_status_mac_randomized" msgid="5589328382467438245">"MAC is randomized"</string>
+ <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
+ <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
+ <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
+ <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+ <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
+ <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
+ <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
+ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+ <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+ <string name="retail_demo_reset_message" msgid="118771671364131297">"Enter password to perform factory reset in demo mode"</string>
+ <string name="retail_demo_reset_next" msgid="8356731459226304963">"Next"</string>
+ <string name="retail_demo_reset_title" msgid="696589204029930100">"Password required"</string>
+ <string name="active_input_method_subtypes" msgid="3596398805424733238">"Active input methods"</string>
+ <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Use system languages"</string>
+ <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Failed to open settings for <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ime_security_warning" msgid="4135828934735934248">"This input method may be able to collect all the text you type, including personal data like passwords and credit card numbers. It comes from the app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Use this input method?"</string>
+ <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Note: After a reboot, this app can\'t start until you unlock your phone"</string>
+ <string name="ims_reg_title" msgid="7609782759207241443">"IMS registration state"</string>
+ <string name="ims_reg_status_registered" msgid="933003316932739188">"Registered"</string>
+ <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"Not registered"</string>
+ <string name="status_unavailable" msgid="7862009036663793314">"Unavailable"</string>
+ <string name="wifi_status_mac_randomized" msgid="5589328382467438245">"MAC is randomized"</string>
<plurals name="wifi_tether_connected_summary" formatted="false" msgid="3871603864314407780">
- <item quantity="other">%1$d devices connected</item>
- <item quantity="one">%1$d device connected</item>
+ <item quantity="other">%1$d devices connected</item>
+ <item quantity="one">%1$d device connected</item>
</plurals>
- <string name="accessibility_manual_zen_more_time" msgid="1636187409258564291">"More time."</string>
- <string name="accessibility_manual_zen_less_time" msgid="6590887204171164991">"Less time."</string>
- <string name="cancel" msgid="6859253417269739139">"Cancel"</string>
- <string name="okay" msgid="1997666393121016642">"OK"</string>
- <string name="zen_mode_enable_dialog_turn_on" msgid="8287824809739581837">"Turn on"</string>
- <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"Turn on Do Not Disturb"</string>
- <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"Never"</string>
- <string name="zen_interruption_level_priority" msgid="2078370238113347720">"Priority only"</string>
- <string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <string name="zen_alarm_warning_indef" msgid="3007988140196673193">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g> unless you turn this off before then"</string>
- <string name="zen_alarm_warning" msgid="6236690803924413088">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="alarm_template" msgid="4996153414057676512">"at <xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="alarm_template_far" msgid="3779172822607461675">"on <xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="zen_mode_duration_settings_title" msgid="229547412251222757">"Duration"</string>
- <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Ask every time"</string>
- <string name="zen_mode_forever" msgid="2704305038191592967">"Until you turn off"</string>
- <string name="time_unit_just_now" msgid="6363336622778342422">"Just now"</string>
- <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Phone speaker"</string>
+ <string name="accessibility_manual_zen_more_time" msgid="1636187409258564291">"More time."</string>
+ <string name="accessibility_manual_zen_less_time" msgid="6590887204171164991">"Less time."</string>
+ <string name="cancel" msgid="6859253417269739139">"Cancel"</string>
+ <string name="okay" msgid="1997666393121016642">"OK"</string>
+ <string name="zen_mode_enable_dialog_turn_on" msgid="8287824809739581837">"Turn on"</string>
+ <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"Turn on Do Not Disturb"</string>
+ <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"Never"</string>
+ <string name="zen_interruption_level_priority" msgid="2078370238113347720">"Priority only"</string>
+ <string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+ <string name="zen_alarm_warning_indef" msgid="3007988140196673193">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g> unless you turn this off before then"</string>
+ <string name="zen_alarm_warning" msgid="6236690803924413088">"You won\'t hear your next alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="alarm_template" msgid="4996153414057676512">"at <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="alarm_template_far" msgid="3779172822607461675">"on <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+ <string name="zen_mode_duration_settings_title" msgid="229547412251222757">"Duration"</string>
+ <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Ask every time"</string>
+ <string name="zen_mode_forever" msgid="2704305038191592967">"Until you turn off"</string>
+ <string name="time_unit_just_now" msgid="6363336622778342422">"Just now"</string>
+ <string name="media_transfer_phone_device_name" msgid="1003823744105758574">"Phone speaker"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index 4899346..053ef48 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Usar comprobación HDCP para contenido DRM solamente"</item>
<item msgid="45075631231212732">"Siempre utilizar comprobación HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Inhabilitado"</item>
+ <item msgid="1969681323976948639">"Filtrado habilitado"</item>
+ <item msgid="8719029132154020716">"Habilitado"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (predeterminado)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index eef0fb1..00f85e6 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Conexión automática mediante %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectado automáticamente mediante proveedor de calificación de red"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conexión a través de %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Conexión a través de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Presiona para configurar"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Presiona para registrarte"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conectado pero sin conexión a Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Sin Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Acceso obligatorio"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"El punto de acceso está completo temporalmente"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Conexión a través de %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponible a través de %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Error de conexión"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"No es válida la URL del servidor OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"No se pudo establecer conexión con el servidor OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"No se pudo validar el servidor OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"No es válido el certificado del servidor OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Se anuló el aprovisionamiento"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"No está disponible el aprovisionamiento"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"No es válida la URL del servidor OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tipo de comando inesperado"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tipo de mensaje SOAP inesperado"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"No se pudo realizar el intercambio de mensajes SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"No se pudo iniciar la recepción de redireccionamiento"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Se agotó el tiempo de espera de redireccionamiento"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"No se encontró actividad OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Estado de mensaje SOAP inesperado"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"No se encontró PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"No se encontró ningún nodo raíz de confianza para el servidor AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"No se encontró ningún nodo raíz de confianza para el servidor de soluciones"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"No se pudo recuperar el nodo raíz de confianza del servidor de políticas"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"No se pudieron recuperar los certificados raíz de confianza"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"No se encontró ningún certificado raíz de confianza para el servidor AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"No se pudo agregar la configuración de PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"No se encontró ningún proveedor OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Estableciendo conexión"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Se estableció conexión"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Estableciendo conexión con el servidor OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Se validó el servidor OSU"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Se estableció conexión con el servidor OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Intercambio SOAP inicial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Esperando respuesta de redireccionamiento"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Se recibió la respuesta de redireccionamiento"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Segundo intercambio SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Tercer intercambio SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Recuperando certificados raíz de confianza"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Se completó el aprovisionamiento"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Abriendo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"No se pudo establecer conexión"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completando registro…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"No se pudo completar el registro. Presiona para volver a intentarlo."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Se completó el registro. Conectando…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muy lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Aceptar"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Permanecer activo"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"La pantalla nunca quedará inactiva mientras el dispositivo se esté cargando."</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Registro de Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capturar paquetes de Bluetooth (activa/desactiva el Bluetooth después de cambiar esta configuración)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueo de OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Permitir que el cargador de inicio se desbloquee"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"¿Permitir desbloqueo de OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro detallado de Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Selección aleatoria de MAC conectada"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activados"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware de conexión mediante dispositivo portátil"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sin nombre"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No se pudo establecer conexión"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones de certificación de pantalla inalámbrica"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar nivel de registro Wi-Fi; mostrar por SSID RSSI en el selector de Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Seleccionar la dirección MAC de forma aleatoria cuando se establezca conexión con redes Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Con uso medido"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Sin tarifa plana"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de Logger"</string>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 52362de..c87bcae 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Utilizar comprobación de HDCP solo para contenido DRM"</item>
<item msgid="45075631231212732">"Utilizar siempre comprobación de HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Inhabilitado"</item>
+ <item msgid="1969681323976948639">"Habilitado con filtros"</item>
+ <item msgid="8719029132154020716">"Habilitado"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Predeterminada)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 64b710a..b21b7d1 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectada automáticamente a través de %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectado automáticamente a través de un proveedor de valoración de redes"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Conectado a través de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Toca para configurar"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Toca para registrarte"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conexión sin Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Sin Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Debes iniciar sesión"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punto de acceso temporalmente lleno"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Conectado a través de %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponible a través de %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"No se ha podido establecer conexión"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL del servidor OSU no válida"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"No se ha podido establecer conexión con el servidor OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"No se ha podido validar el servidor OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificado del servidor OSU no válido"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Aprovisionamiento anulado"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Aprovisionamiento no disponible"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL del servidor OSU no válida"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tipo de comando inesperado"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tipo de mensaje SOAP inesperado"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"No se ha podido completar el intercambio de mensajes SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"No se ha podido iniciar la recepción de redirección"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Se ha agotado el tiempo de espera de redirección"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"No se ha encontrado actividad de OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Estado de mensaje SOAP inesperado"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"No se ha podido encontrar PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"No se ha podido encontrar el nodo raíz de confianza del servidor AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"No se ha podido encontrar el nodo raíz de confianza del servidor de soluciones"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"No se ha podido encontrar el nodo raíz de confianza del servidor de políticas"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"No se han podido obtener certificados raíz de confianza"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"No se ha podido encontrar el certificado raíz de confianza del servidor AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"No se ha podido añadir la configuración de PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"No se ha podido encontrar ningún servidor OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Conectando"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Conectado"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Estableciendo conexión con el servidor OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Servidor OSU validado"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Se ha establecido conexión con el servidor OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Intercambio SOAP inicial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Esperando respuesta de redirección"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Respuesta de redirección recibida"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Segundo intercambio SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Tercer intercambio SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Obteniendo certificados raíz de confianza"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Aprovisionamiento completado"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Abriendo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"No se ha podido conectar"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completando registro…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"No se ha podido completar el registro. Toca para volver a intentarlo."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Se ha completado el registro. Conectando…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muy lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Aceptable"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Pantalla siempre encendida al cargar"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"La pantalla nunca entra en modo de suspensión si el dispositivo se está cargando"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Habilitar registro de Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capturar paquetes de Bluetooth (después de cambiar esta opción, desactiva y activa el Bluetooth)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueo de OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Permitir desbloquear el bootloader"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"¿Permitir desbloqueo de OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro Wi-Fi detallado"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Orden aleatorio de direcciones MAC conectadas"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activos"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración por hardware para conexión compartida"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sin nombre"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No se ha podido establecer la conexión"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar el nivel de registro de Wi-Fi, mostrar por SSID RSSI en el selector Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Ordenar las direcciones MAC de forma aleatoria al conectarse a redes Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Medida"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"No medida"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños del búfer para registrar"</string>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 76a972d..e36251b 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Kasuta HDCP-kontrolli ainult DRM-sisu korral"</item>
<item msgid="45075631231212732">"Kasuta alati HDCP-kontrollimist"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Keelatud"</item>
+ <item msgid="1969681323976948639">"Luba filtreeritud"</item>
+ <item msgid="8719029132154020716">"Lubatud"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (vaikeseade)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 9008601..fab1375 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Ühendus loodi automaatselt teenusega %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Ühendus loodi automaatselt võrgukvaliteedi hinnangute pakkuja kaudu"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Ühendatud üksuse %1$s kaudu"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> – <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Ühendatud võrgu <xliff:g id="NAME">%1$s</xliff:g> kaudu"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Saadaval üksuse %1$s kaudu"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Puudutage seadistamiseks"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Puudutage registreerumiseks"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Ühendatud, Interneti-ühendus puudub"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Interneti-ühendus puudub"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Nõutav on sisselogimine"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pääsupunkt on ajutiselt täis"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Ühendatud operaatori %1$s kaudu"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Saadaval operaatori %1$s kaudu"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Ühendamine ebaõnnestus"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU serveri kehtetu URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU serveriga ühendamine ebaõnnestus"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU serveri valideerimine ebaõnnestus"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU serveri kehtetu sertifikaat"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Ettevalmistamine katkestati"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Ettevalmistamine pole saadaval"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU serveri kehtetu URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Ootamatu käsutüüp"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Ootamatu SOAP-sõnumi tüüp"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP-sõnumi saatmine ebaõnnestus"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Kuulaja ümbersuunamist ei saanud käivitada"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Ümbersuunamine aegus"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU tegevusi ei leitud"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP-sõnumi ootamatu olek"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO-d ei leitud"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA serveri usaldusväärset juursõlme ei leitud"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Abinõude serveri usaldusväärset juursõlme ei leitud"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Eeskirjade serveri usaldusväärset juursõlme ei leitud"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Usaldusväärseid juursertifikaate ei õnnestunud tuua"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA serveri usaldusväärset juursertifikaati ei leitud"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPointi konfiguratsiooni lisamine ebaõnnestus"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU teenusepakkujat ei leitud"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Ühendamine"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Ühendatud"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Ühendamine OSU serveriga"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU server valideeriti"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Ühendatud OSU serveriga"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Esialgne SOAP-andmevahetus"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Otsevastuse ootel"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Saadi otsevastus"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Teine SOAP-andmevahetus"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Kolmas SOAP-andmevahetus"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Usaldusväärsete juursertifikaatide toomine"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Ettevalmistamine on lõpetatud"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Teenuse <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> avamine"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Ühendust ei saanud luua"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Registreerimise lõpuleviimine …"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Registreerimist ei saanud lõpule viia. Puudutage, et uuesti proovida."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registreerimine on lõpule viidud. Ühendamine …"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Väga aeglane"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Aeglane"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Hea"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Jää sisselülitatuks"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Ekraan ei lähe kunagi laadimise ajal unerežiimi"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Luba Bluetoothi HCI jälgimise logi"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Jäädvusta Bluetoothi paketid. (pärast seade muutmist muuda Bluetoothi olekut)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-i avamine"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Luba buudilaadur avada"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Kas lubada OEM-i avamine?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Võrgustik"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Juhtmeta ekraaniühenduse sertifitseerimine"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Luba WiFi sõnaline logimine"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Juhusliku MAC-aadressi määramine ühendamisel"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Hoia mobiilne andmeside alati aktiivne"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Ühenduse jagamise riistvaraline kiirendus"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Kuva ilma nimedeta Bluetoothi seadmed"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ühendamine ebaõnnestus"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Juhtmeta ekraaniühenduse sertifitseerimisvalikute kuvamine"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Suurenda WiFi logimistaset, kuva WiFi valijas SSID RSSI järgi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Määra WiFi-võrkudega ühenduse loomisel juhuslik MAC-aadress"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Mahupõhine"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Mittemahupõhine"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logija puhvri suurused"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 90df354..aa048b1 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Erabili HDCP egiaztapena DRM edukirako soilik"</item>
<item msgid="45075631231212732">"Erabili beti HDCP egiaztapena"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Desgaituta"</item>
+ <item msgid="1969681323976948639">"Gaituta baina iragazita"</item>
+ <item msgid="8719029132154020716">"Gaituta"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (lehenetsia)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index ae0fd47..7d3e1f3 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s bidez automatikoki konektatuta"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatikoki konektatuta sareen balorazioen hornitzailearen bidez"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s bidez konektatuta"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> (<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>)"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> bidez konektatuta"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s bidez erabilgarri"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Sakatu konfiguratzeko"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Sakatu erregistratzeko"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Konektatuta; ezin da atzitu Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Ez dago Interneteko konexiorik"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Saioa hasi behar da"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Sarbide-puntua beteta dago aldi baterako"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s bidez konektatuta"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s bidez erabilgarri"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Ezin izan da konektatu"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU zerbitzariaren URLak ez du balio"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Ezin izan da konektatu OSU zerbitzarira"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Ezin izan da balidatu OSU zerbitzaria"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU zerbitzariaren ziurtagiriak ez du balio"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Bertan behera utzi da hornitze-prozesua"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Ez dago horniketarik erabilgarri"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU zerbitzariaren URLak ez du balio"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Ustekabeko agindu mota"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Ustekabeko SOAP mezu mota"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Ezin izan da trukatu SOAP mezua"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Ezin izan da abiarazi birbideratze-hautemailea"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Birbideratzea jasotzeko denbora-muga gainditu da"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Ez da aurkitu OSU jarduerarik"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP mezuaren ustekabeko egoera"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Ezin izan da aurkitu PPS-MO objektua"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Ezin izan da aurkitu AAA zerbitzariaren fidagarritasunaren erroko nodoa"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Ezin izan da aurkitu konponketa-zerbitzariaren fidagarritasunaren erroko nodoa"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Ezin izan da aurkitu gidalerro-zerbitzariaren fidagarritasunaren erroko nodoa"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Ezin izan dira eskuratu fidagarritasunaren erroko ziurtagiriak"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Ezin izan da aurkitu AAA zerbitzariaren fidagarritasunaren erroko ziurtagiria"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Ezin izan da gehitu PassPoint konfigurazioa"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Ezin izan da aurkitu OSU hornitzailerik"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Konektatzen"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Konektatuta"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU zerbitzariarekin konektatzen"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Balidatu da OSU zerbitzaria"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU zerbitzarira konektatuta"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Hasierako SOAP trukaketa"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Birbideratze-erantzunaren zain"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Jaso da birbideratze-erantzun bat"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Bigarren SOAP trukaketa"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Hirugarren SOAP trukaketa"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Fidagarritasunaren erroko ziurtagiriak eskuratzen"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Osatu da hornitze-prozesua"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> irekitzen"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Ezin izan da konektatu"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Erregistroa osatzen…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Ezin izan da osatu erregistroa. Berriro saiatzeko, ukitu hau."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Erregistratu da. Konektatzen…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Oso motela"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Motela"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Ados"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Mantendu aktibo"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Pantaila ez da inoiz inaktibo ezarriko kargatu bitartean"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Gaitu Bluetooth HCI miatze-erregistroa"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Hauteman Bluetooth paketeak (aktibatu edo desaktibatu Bluetooth konexioa ezarpena aldatu ostean)."</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM desblokeoa"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Onartu abiarazlea desblokeatzea"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM desblokeoa onartu nahi duzu?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Sareak"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Hari gabeko bistaratze-egiaztapena"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Gaitu Wi-Fi sareetan saioa hasteko modu xehatua"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Konektatutako MAC helbideak ausaz aukeratzea"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Datu-konexioa beti aktibo"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Konexioa partekatzeko hardwarearen azelerazioa"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Erakutsi Bluetooth gailuak izenik gabe"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ezin izan da konektatu"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Erakutsi hari gabeko bistaratze-egiaztapenaren aukerak"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago Wi-Fi sareetan saioa hasterakoan. Erakutsi sarearen identifikatzailea eta seinalearen indarra Wi‑Fi sareen hautagailuan."</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Aukeratu ausaz MAC helbideak Wi‑Fi sareetara konektatzean"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Sare mugatua"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Sare ez-mugatua"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Erregistroen buffer-tamainak"</string>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 85720e4..2019caf 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"استفاده از بررسی HDCP فقط برای محتوای DRM"</item>
<item msgid="45075631231212732">"همیشه از بررسی HDCP استفاده شود"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"غیرفعال"</item>
+ <item msgid="1969681323976948639">"فیلترشده فعال شده است"</item>
+ <item msgid="8719029132154020716">"فعال"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP نسخه ۱.۴ (پیشفرض)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index e9c9313..293c463 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"اتصال خودکار ازطریق %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"اتصال خودکار ازطریق ارائهدهنده رتبهبندی شبکه"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"متصل از طریق %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> از <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"متصل شده ازطریق <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"در دسترس از طریق %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"برای راهاندازی ضربه بزنید"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"برای ثبتنام ضربه بزنید"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"متصل، بدون اینترنت"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"عدم دسترسی به اینترنت"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ورود به سیستم لازم است"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ظرفیت نقطه دسترسی موقتاً تکمیل شده است"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"متصل ازطریق %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"در دسترس ازطریق %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"اتصال ناموفق بود"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"نشانی وب سرور OSU نامعتبر است"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"اتصال سرور OSU ناموفق بود"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"تأییداعتبار سرور OSU ناموفق بود"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"گواهینامه سرور OSU نامعتبر است"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ارائه لغو شد"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"ارائه امکانپذیر نیست"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"نشانی وب سرور OSU نامعتبر است"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"نوع فرمان غیرمنتظره"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"نوع پیام SOAP غیرمنتظره"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"تبادل پیام SOAP ناموفق بود"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"هدایت پاسخ تماس غیرهمزمان شروع نشد"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"مهلت انتظار برای هدایت تمام شد"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"فعالیت OSU پیدا نشد"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"وضعیت پیام SOAP غیرمنتظره"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO پیدا نشد"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"گره ریشه مطمئن برای سرور AAA پیدا نشد"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"گره ریشه مطمئن برای سرور جبران خسارت پیدا نشد"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"گروه ریشه مطمئن برای سرور خطمشی پیدا نشد"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"گواهینامه ریشه مطمئن بازیابی نشد"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"گواهینامه ریشه مطمئن برای سرور AAA پیدا نشد"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"پیکربندی PassPoint اضافه نشد"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"ارائهدهنده OSU پیدا نشد"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"درحال برقراری ارتباط"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"متصل"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"اتصال به سرور OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"سرور OSU تأییداعتبار شد"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"متصل به سرور OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"تبادل SOAP اولیه"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"درانتظار پاسخ هدایت"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"پاسخ هدایت دریافتی"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"تبادل SOAP دوم"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"تبادل SOAP سوم"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"بازیابی گواهینامههای ریشه مطمئن"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ارائه کامل شد"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"درحال بازکردن <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"متصل نشد"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"درحال تکمیل ثبتنام…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"ثبتنام تکمیل نشد. برای امتحان مجدد ضربه بزنید."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"ثبتنام کامل شد. درحال اتصال…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"بسیار آهسته"</string>
<string name="speed_label_slow" msgid="813109590815810235">"آهسته"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"تأیید"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"بیدار ماندن"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"صفحه هرگز در حین شارژ شدن به حالت خواب نمیرود"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"فعال کردن گزارش تجسس Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"بستههای بلوتوث ضبط شود. (بعد از تغییر این تنظیم، بلوتوث را روشن/خاموش کنید)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"بازکردن سازنده تجهیزات اصلی"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"اجازه دهید قفل بوتلودر باز شود"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"بازکردن سازنده تجهیزات اصلی مجاز (OEM) است؟"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"شبکه"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"گواهینامه نمایش بیسیم"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"فعال کردن گزارشگیری طولانی Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"تصادفیسازی MAC متصل"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"داده تلفن همراه همیشه فعال باشد"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"شتاب سختافزاری اتصال به اینترنت با تلفن همراه"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"نمایش دستگاههای بلوتوث بدون نام"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"متصل نشد"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"نمایش گزینهها برای گواهینامه نمایش بیسیم"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"افزایش سطح گزارشگیری Wi‑Fi، نمایش به ازای SSID RSSI در انتخابکننده Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"تصادفی کردن نشانی MAC هنگام اتصال به شبکههای Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"کنتوردار"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"بدون کنتور"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"اندازههای حافظه موقت ثبتکننده"</string>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index 33b1ffc..9566a29 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Käytä HDCP-tarkistusta vain DRM-suojatulle sisällölle."</item>
<item msgid="45075631231212732">"Käytä aina HDCP-tarkistusta"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Ei käytössä"</item>
+ <item msgid="1969681323976948639">"Suodatus käytössä"</item>
+ <item msgid="8719029132154020716">"Käytössä"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (oletus)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 3f9afb0..f335eb9 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaattinen yhteys muodostettu palvelun %1$s kautta"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Yhdistetty automaattisesti verkon arviointipalvelun kautta"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Yhdistetty seuraavan kautta: %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>: <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Yhdistetty (<xliff:g id="NAME">%1$s</xliff:g>)"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Käytettävissä seuraavan kautta: %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Määritä napauttamalla"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Rekisteröidy napauttamalla"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Yhdistetty, ei internetyhteyttä"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Ei internetyhteyttä"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Sisäänkirjautuminen vaaditaan"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Yhteyspiste tilapäisesti täynnä"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Yhdistetty, verkko: %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Käytettävissä, verkko: %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Yhteys katkesi"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Virheellinen OSU-palvelimen URL-osoite"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU-palvelimen yhteys epäonnistui"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU-palvelimen vahvistus epäonnistui"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Virheellinen OSU-palvelimen varmenne"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Käyttäjien hallinta keskeytetty"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Käyttäjien hallinta ei ole käytettävissä"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Virheellinen OSU-palvelimen URL-osoite"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Odottamaton komentotyyppi"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Odottamaton SOAP-viestityyppi"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP-viestinvaihto epäonnistui"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Uudelleenohjausten seurain ei käynnistynyt"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Aikakatkaistiin odottaessa uudelleenohjausta"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU-toimintaa ei löytynyt"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Odottamaton SOAP-viestin tila"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO:ta ei löytynyt"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA-palvelimelle ei löydetty luotettavaa pääsolmua"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Hyvityskeinopalvelimelle ei löydetty luotettavaa pääsolmua"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Käytäntöpalvelimelle ei löydetty luotettavaa pääsolmua"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Luotettavien juurivarmenteiden nouto epäonnistui"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA-palvelimelle ei löydetty luotettavaa juurivarmennetta"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint-määrityksen lisääminen epäonnistui"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU-palveluntarjoajaa ei löytynyt"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Yhdistetään"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Yhdistetty"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Yhdistetään OSU-palvelimeen"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-palvelin vahvistettu"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Yhdistetty OSU-palvelimeen"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Ensimmäinen SOAP-vaihto"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Odotetaan uudelleenohjausvastausta"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Uudelleenohjausvastaus vastaanotettu"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Toinen SOAP-vaihto"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Kolmas SOAP-vaihto"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Noudetaan luotettavia juurivarmenteita"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Käyttäjien hallinta valmis"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Avataan <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Ei yhteyttä"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Viimeistellään rekisteröitymistä…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Rekisteröityminen epäonnistui. Yritä uudelleen napauttamalla."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Rekisteröityminen valmis. Yhdistetään…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Hyvin hidas"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Hidas"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Pysy käynnissä"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Näyttö ei sammu puhelimen latautuessa."</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Ota Bluetoothin HCI-tarkkailuloki käyttöön"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Tallenna Bluetoothin HCl-paketit tiedostoon (ota Bluetooth käyttöön asetuksen muuttamisen jälkeen)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM:n lukituksen avaus"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Salli käynnistysohjelman lukituksen avaaminen"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Sallitaanko OEM:n lukituksen avaus?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Yhteysominaisuudet"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Langattoman näytön sertifiointi"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Käytä Wi-Fin laajennettua lokikirjausta"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Yhdistetty MAC-satunnaistaminen"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilidata aina käytössä"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Laitteistokiihdytyksen yhteyden jakaminen"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Näytä nimettömät Bluetooth-laitteet"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ei yhteyttä"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Näytä langattoman näytön sertifiointiin liittyvät asetukset."</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Lisää Wi‑Fin lokikirjaustasoa, näytä SSID RSSI -kohtaisesti Wi‑Fi-valitsimessa."</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Käytä satunnaista MAC-osoitetta, kun yhdistät Wi-Fi-verkkoon."</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Maksullinen"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Maksuton"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Lokipuskurien koot"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 145bd98..a02406f 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Utiliser la vérification HDCP uniquement pour le contenu GDN"</item>
<item msgid="45075631231212732">"Toujours utiliser la vérification HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Désactivé"</item>
+ <item msgid="1969681323976948639">"Filtres activés"</item>
+ <item msgid="8719029132154020716">"Activé"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (par défaut)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 4fbc0ca..4959103 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiquement connecté par %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connecté automatiquement par le fournisseur d\'avis sur le réseau"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté par %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connecté sur le réseau <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Accessible par %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Touchez pour configurer"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Toucher pour vous connecter"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connecté, aucun accès à Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Aucune connexion Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Connexion requise"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Le point d\'accès est temporairement plein"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Connecté par %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Accessible par %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Échec de connexion"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL de serveur OSU non valide"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Échec de la connexion avec le serveur OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Échec de la validation du serveur OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificat de serveur OSU non valide"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"L\'approvisionnement a été abandonné"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"L\'approvisionnement n\'est pas accessible"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL de serveur OSU non valide"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Type de commande inattendu"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Type de message SOAP inattendu"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Échec de l\'échange de messages SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Impossible de démarrer l\'écoute de redirection"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Délai d\'attente pour la redirection"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Aucune activité OSU trouvée"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"État de message SOAP inattendu"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Impossible de trouver PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Impossible de trouver le nœud racine de confiance pour le serveur AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Impossible de trouver le nœud racine de confiance pour le serveur de recours"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Impossible de trouver le nœud racine de confiance pour le serveur de politiques"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Impossible de récupérer les certificats racine de confiance"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Impossible de trouver le certificat racine de confiance pour le serveur AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Impossible d\'ajouter la configuration PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Impossible de trouver un fournisseur OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Connexion en cours…"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connecté"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Connexion au serveur OSU en cours…"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Serveur OSU validé"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connecté au serveur OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Échange SOAP initial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"En attente de la réponse de redirection…"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Réponse de redirection reçue"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Deuxième échange SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Échange SOAP tiers"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Récupération des certificats racine de confiance"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Approvisionnement terminé"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Ouverture de <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> en cours…"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Impossible de se connecter"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Terminaison de l\'inscription en cours…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Impossible de terminer l\'inscription. Touchez pour réessayer."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Inscription terminée. Connexion en cours…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Très lente"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lente"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Rester activé"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"L\'écran ne se met jamais en veille lors du chargement"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Activer le journal HCI Snoop Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capturer les paquets Bluetooth. (Désactivez et réactivez le Bluetooth après le chang. de ce param.)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Déverrouillage par le fabricant"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Autoriser le déverrouillage du fichier d\'amorce"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Permettre le déverrouillage par le fabricant?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Réseautage"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certification de l\'affichage sans fil"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser enreg. données Wi-Fi détaillées"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Sélection aléatoire de l\'adresse MAC lors de la connexion"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Données cellulaires toujours actives"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afficher les appareils Bluetooth sans nom"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossible de se connecter"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification d\'affichage sans fil"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler davantage les données Wi-Fi, afficher par SSID RSSI dans sélect. Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Sélectionner l\'adresse MAC de manière aléatoire lors de la connexion aux réseaux Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Mesuré"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Non mesuré"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tailles des mémoires tampons d\'enregistreur"</string>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 34cedd8..d87388d 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Utiliser la vérification HDCP uniquement pour le contenu DRM"</item>
<item msgid="45075631231212732">"Toujours utiliser la vérification HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Désactivé"</item>
+ <item msgid="1969681323976948639">"Activé et filtré"</item>
+ <item msgid="8719029132154020716">"Activé"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (par défaut)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index c4b8b3f..1f071de 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Connecté automatiquement via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connecté automatiquement via un fournisseur d\'évaluation de l\'état du réseau"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> par <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connecté via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Appuyer pour configurer"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Appuyez ici pour vous connecter"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connecté, aucun accès à Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Aucun accès à Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Connexion requise"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Point d\'accès temporairement plein"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Connecté via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponible via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Échec de la connexion"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"L\'URL du serveur OSU n\'est pas valide"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Échec de la connexion au serveur OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Échec de la validation du serveur OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificat du serveur OSU non valide"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Préparation annulée"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Préparation non disponible"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"L\'URL du serveur OSU n\'est pas valide"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Type de commande inattendu"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Type de message SOAP inattendu"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Échec de l\'échange de messages SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Échec du démarrage de l\'écouteur de redirection"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Délai dépassé ou en attente de redirection"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Aucune activité OSU trouvée"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"État inattendu du message SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Échec de la recherche de PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Échec de la recherche de nœud racine de confiance pour le serveur AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Échec de la recherche de nœud racine de confiance pour le serveur de réparation"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Échec de la recherche de nœud racine de confiance pour le serveur de règles"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Échec de la récupération des certificats racine de confiance"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Échec de la recherche de certificat racine de confiance pour le serveur AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Échec de l\'ajout de la configuration PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Échec de la recherche de fournisseur OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Connexion…"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connecté"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Connexion au serveur OSU…"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Serveur OSU validé"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connecté au serveur OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Échange SOAP initial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"En attente de la réponse de redirection…"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Réponse de redirection reçue"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Deuxième échange SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Troisième échange SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Récupération des certificats racine de confiance…"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Préparation terminée"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Ouverture de <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>…"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Impossible de se connecter"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Finalisation de l\'inscription…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Impossible de finaliser l\'inscription. Appuyez ici pour réessayer."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Inscription terminée. Connexion…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Très lente"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lente"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Correct"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Rester activé"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"L\'écran ne se met jamais en veille lors du chargement."</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Activer journaux HCI Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capturer les paquets Bluetooth. (Activer/Désactiver le Bluetooth après avoir modifié ce paramètre)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Déverrouillage OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Autoriser le déverrouillage du chargeur d\'amorçage"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Autoriser le déverrouillage OEM ?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Mise en réseau"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certification affichage sans fil"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser enreg. infos Wi-Fi détaillées"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Sélection aléatoire de l\'adresse MAC lors de la connexion"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Données mobiles toujours actives"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afficher les appareils Bluetooth sans nom"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossible de se connecter"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options de la certification de l\'affichage sans fil"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler plus infos Wi-Fi, afficher par RSSI de SSID dans outil sélection Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Sélectionner l\'adresse MAC de manière aléatoire lors de la connexion aux réseaux Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Facturé à l\'usage"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Non facturé à l\'usage"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tailles mémoires tampons enregistr."</string>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index a0bc977..a7325c2 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Utiliza a comprobación HDCP só para contido DRM"</item>
<item msgid="45075631231212732">"Utilizar sempre a comprobación HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Opción desactivada"</item>
+ <item msgid="1969681323976948639">"Está activado o filtrado"</item>
+ <item msgid="8719029132154020716">"Opción activada"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (predeterminado)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 786e2c5..06faf00 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectouse automaticamente a través de %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectada automaticamente a través dun provedor de valoración de rede"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Wifi conectada a través de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dispoñible a través de %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Toca aquí para configuralo"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Toca para rexistrarte"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conexión sen Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Non hai conexión a Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"É obrigatorio iniciar sesión"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"O punto de acceso está temporalmente cheo"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Conectado a través de %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Dispoñible a través de %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Produciuse un erro coa conexión"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL do servidor OSU non-válido"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Produciuse un erro na conexión do servidor OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Non se puido validar o servidor OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificado do servidor OSU non-válido"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Abastecemento anulado"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Abastecemento non-dispoñible"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL do servidor OSU non-válido"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tipo de comando inesperado"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tipo de mensaxe SOAP inesperado"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Produciuse un erro no intercambio da mensaxe SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Non se puido iniciar a recepción de redirección"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Esgotouse o tempo de espera de redirección"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Non se encontrou a actividade de OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Estado da mensaxe SOAP inesperado"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"No se puido encontrar PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"No se puido encontrar o nodo raíz de confianza do servidor AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"No se puido encontrar o nodo raíz de confianza do servidor de solucións"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Non se puido encontrar o nodo raíz de confianza do servidor da política"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Produciuse un erro ao recuperar os certificados raíz de confianza"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Non se puido encontrar o certificado raíz de confianza do servidor AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Non se puido engadir a configuración de PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"No se puido encontrar ningún servidor OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Conectando"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Conectado"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Conectándose ao servidor OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Servidor OSU validado"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Conectado ao servidor OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Intercambio SOAP inicial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Agardando pola resposta de redirección"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Resposta de redirección recibida"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Segundo intercambio SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Terceiro intercambio SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Recuperando certificados raíz de confianza"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Abastecemento completado"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Abrindo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Non se puido establecer conexión"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completando o rexistro…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Non se puido completar o rexistro. Toca para tentalo de novo."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Completouse o rexistro. Conectando…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Moi lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Aceptar"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Pantalla activa"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"A pantalla nunca estará en modo de suspensión durante a carga"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Activar rexistro de busca HCI Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capturar paquetes de Bluetooth. (Activa/desactiva o Bluetooth despois de cambiar esta opción)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueo do OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Permitir que se desbloqueo o cargador de inicio"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Queres permitir o desbloqueo do OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificado de visualización sen fíos"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Activar rexistro detallado da wifi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Selección aleatoria de enderezo MAC coa conexión"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móbiles sempre activados"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware para conexión compartida"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sen nomes"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Non se puido conectar"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opcións para o certificado de visualización sen fíos"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta o nivel de rexistro da wifi, móstrao por SSID RSSI no selector de wifi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Selecciona aleatoriamente o enderezo MAC cando te conectes a redes wifi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"De pago por consumo"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Sen pago por consumo"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de rexistrador"</string>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 92f52b8e..cf1f651 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"ફક્ત DRM કન્ટેન્ટ માટે HDCP તપાસનો ઉપયોગ કરો"</item>
<item msgid="45075631231212732">"હંમેશા HDCP તપાસનો ઉપયોગ કરો"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"બંધ છે"</item>
+ <item msgid="1969681323976948639">"ફિલ્ટર કરેલ ચાલુ છે"</item>
+ <item msgid="8719029132154020716">"ચાલુ છે"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ડિફૉલ્ટ)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 492eaf0..232dea9 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s દ્વારા સ્વત: કનેક્ટ થયેલ"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"નેટવર્ક રેટિંગ પ્રદાતા દ્વારા આપમેળે કનેક્ટ થયું"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>નું <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કનેક્ટ થયેલ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s દ્વારા ઉપલબ્ધ"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"સેટઅપ કરવા માટે ટૅપ કરો"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"સાઇન અપ કરવા માટે ટૅપ કરો"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"કનેક્ટ કર્યું, કોઈ ઇન્ટરનેટ નથી"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ઇન્ટરનેટ ઍક્સેસ નથી"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"સાઇન ઇન આવશ્યક"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ઍક્સેસ પૉઇન્ટ અસ્થાયીરૂપે ભરાયેલ છે"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s દ્વારા કનેક્ટ થયેલ"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s દ્વારા ઉપલબ્ધ"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"કનેક્શન નિષ્ફળ થયું"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU સર્વરનું URL માન્ય નથી"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU સર્વર કનેક્ટ કરવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU સર્વર માન્ય કરવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU સર્વરનું પ્રમાણપત્ર માન્ય નથી"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"જોગવાઈ કરવાનું રદ કરવામાં આવ્યું"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"જોગવાઈ કરવાનું ઉપલબ્ધ નથી"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU સર્વરનું URL માન્ય નથી"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"આદેશનો અનપેક્ષિત પ્રકાર"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"SOAP સંદેશનો અનપેક્ષિત પ્રકાર"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP સંદેશ વિનિમયમાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"રીડાયરેક્ટ લિસનર શરૂ કરવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"રીડાયરેક્ટ કરવાની રાહ જોવાનો સમય સમાપ્ત થયો"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"કોઈ OSU પ્રવૃત્તિ મળી નથી"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP સંદેશનું અનપેક્ષિત સ્ટેટસ"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO શોધવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA સર્વર માટે ટ્રસ્ટ રૂટ નોડ શોધવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"રેમિડીયેશન સર્વર માટે ટ્રસ્ટ રૂટ નોડ શોધવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"પૉલિસી સર્વર માટે ટ્રસ્ટ રૂટ નોડ શોધવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"ટ્રસ્ટ રૂટ પ્રમાણપત્રો ફરી મેળવવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA સર્વર માટે ટ્રસ્ટ રૂટ પ્રમાણપત્ર શોધવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint ગોઠવણી ઉમેરવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU પ્રદાતા શોધવામાં નિષ્ફ્ળતા મળી"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"કનેક્ટ થઈ રહ્યું છે"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"કનેક્ટેડ"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU સર્વર સાથે કનેક્ટ કરી રહ્યાં છીએ"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU સર્વર માન્ય કરવામાં આવેલ"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU સર્વર સાથે કનેક્ટ કરેલ છે"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"પ્રારંભિક SOAP વિનિમય"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"રીડાયરેક્ટ કરવા માટેના પ્રતિસાદની રાહ જુએ છે"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"રીડાયરેક્ટ કરવા માટેનો પ્રતિસાદ પ્રાપ્ત થયો"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"દ્વિતીય SOAP વિનિમય"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"તૃતીય SOAP વિનિમય"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"ટ્રસ્ટ રૂટ પ્રમાણપત્રો ફરી મેળવાઈ રહ્યાં છે"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"જોગવાઈ કરવાનું પૂર્ણ થયું"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ખોલી રહ્યાં છીએ"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"કનેક્ટ કરી શકાયું નથી"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"સાઇન અપ પૂર્ણ કરી રહ્યા છીએ…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"સાઇન અપ પૂર્ણ કરી શકાયું નથી. ફરી પ્રયાસ કરવા માટે ટૅપ કરો."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"સાઇન અપ પૂર્ણ. કનેક્ટ કરી રહ્યાં છીએ…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ખૂબ જ ધીમી"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ધીમી"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ઓકે"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"સક્રિય રાખો"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ચાર્જિંગ દરમિયાન સ્ક્રીન ક્યારેય નિષ્ક્રિય થશે નહીં"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"બ્લૂટૂથ HCI સ્નૂપ લૉગ ચાલુ કરો"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"બ્લૂટૂથ પૅકેટ કૅપ્ચર કરો. (આ સેટિંગ બદલ્યા પછી બ્લૂટૂથને ટૉગલ કરો)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM અનલૉકિંગ"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"બુટલોડર અનલૉક કરવાની મંજૂરી આપો"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM ને અનલૉક કરવાની મંજૂરી આપીએ?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"નેટવર્કિંગ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"વાયરલેસ ડિસ્પ્લે પ્રમાણન"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"વાઇ-ફાઇ વર્બોઝ લૉગિંગ ચાલુ કરો"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"કનેક્ટ કરેલ MAC ઍડ્રેસને રેન્ડમાઇઝ કરવાનું ચાલુ કરો"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"મોબાઇલ ડેટા હંમેશાં સક્રિય"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"નામ વિનાના બ્લૂટૂથ ઉપકરણો બતાવો"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"કનેક્ટ કરી શકાયું નથી"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"વાઇ-ફાઇ લોગિંગ સ્તર વધારો, વાઇ-ફાઇ પીકરમાં SSID RSSI દીઠ બતાવો"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"વાઇ-ફાઇ નેટવર્ક સાથે જ્યારે કનેક્ટ કરી રહ્યાં હોય ત્યારે MAC ઍડ્રેસને રેન્ડમાઇઝ કરો"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"મીટર કરેલ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"મીટર ન કરેલ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"લોગર બફર કદ"</string>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index dd5ef6c..5ad9b01 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"एचडीसीपी जाँच का उपयोग केवल डीआरएम सामग्री के लिए करें"</item>
<item msgid="45075631231212732">"हमेशा HDCP जाँच का उपयोग करें"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"बंद है"</item>
+ <item msgid="1969681323976948639">"चालू और फ़िल्टर किया गया"</item>
+ <item msgid="8719029132154020716">"चालू है"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"एवीआरसीपी 1.4 (डिफ़ॉल्ट)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index c32a039..2f03eb1b 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s के ज़रिए ऑटोमैटिक रूप से कनेक्ट है"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदाता के ज़रिए अपने आप कनेक्ट है"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> का <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> के ज़रिए कनेक्ट किया गया"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"सेट अप करने के लिए टैप करें"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"साइन अप करने के लिए टैप करें"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"कनेक्ट हो गया है, लेकिन इंटरनेट नहीं है"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"इंटरनेट कनेक्शन नहीं है"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन करना ज़रूरी है"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"एक्सेस पॉइंट फ़िलहाल भरा हुआ है"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s के ज़रिए कनेक्ट"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s के ज़रिए उपलब्ध"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"कनेक्शन नहीं जोड़ा जा सका"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"अमान्य ओएसयू सर्वर यूआरएल"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"ओएसयू सर्वर कनेक्शन नहीं जुड़ा"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"ओएसयू सर्वर की पुष्टि नहीं हो सकी"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"अमान्य ओएसयू सर्वर सर्टिफ़िकेट"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"प्रावधान रद्द किया गया"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"प्रावधान उपलब्ध नहीं है"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"अमान्य ओएसयू सर्वर यूआरएल"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ऐसा निर्देश जिसकी उम्मीद नहीं थी"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ऐसा एसओएपी मैसेज जिसकी उम्मीद नहीं थी"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"एसओएपी मैसेज एक्सचेंज नहीं हो सका"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"रीडायरेक्ट लिसनर चालू नहीं हुआ"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"रीडायरेक्ट के लिए इंतज़ार करते हुए समय खत्म"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"कोई ओएसयू गतिविधि नहीं मिली"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"ऐसी एसओएपी मैसेज स्थिति, जिसकी उम्मीद नहीं थी"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"पीपीएस-एमओ नहीं मिला"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"एएए सर्वर के लिए भरोसेमंद रूट नोड नहीं मिला"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"रिमीडीएशन सर्वर के लिए भरोसेमंद रूट नोड नहीं मिला"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"पॉलिसी सर्वर के लिए भरोसेमंद रूट नोड नहीं मिला"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"भरोसेमंद रूट सर्टिफ़िकेट वापस नहीं लाए जा सके"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"एएए सर्वर के लिए भरोसेमंद रूट सर्टिफ़िकेट नहीं मिला"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint कॉन्फ़िगरेशन नहीं जोड़ा जा सका"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"ओएसयू प्रोवाइडर नहीं मिला"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"कनेक्ट हो रहा है"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"जुड़ गया है"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"ओएसयू सर्वर से जोड़ा जा रहा है"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"ओएसयू सर्वर की पुष्टि की गई"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"ओएसयू सर्वर से कनेक्ट किया गया है"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"शुरुआती एसओएपी एक्सचेंज"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"रीडायरेक्ट जवाब का इंतज़ार किया जा रहा है"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"रीडायरेक्ट जवाब मिला"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"दूसरा एसओएपी एक्सचेंज"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"तीसरा एसओएपी एक्सचेंज"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"भरोसेमंद रूट सर्टिफ़िकेट वापस लाए जा रहे हैं"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"प्रावधान पूरा हुआ"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> खोला जा रहा है"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"कनेक्ट नहीं किया जा सका"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"साइन-अप पूरा हो रहा है…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"साइन-अप पूरा नहीं हो सका. फिर से कोशिश करने के लिए टैप करें."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"साइन-अप पूरा हुआ. कनेक्ट हो रहा है…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"अत्यधिक धीमी"</string>
<string name="speed_label_slow" msgid="813109590815810235">"धीमी"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ठीक है"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"स्क्रीन को चालू रखें"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"चार्ज करते समय स्क्रीन कभी भी कम बैटरी मोड में नहीं जाएगी"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ब्लूटूथ एचसीआई स्नूप लॉग चालू करें"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ब्लूटूथ पैकेट कैप्चर करें. (यह सेटिंग बदलने के बाद ब्लूटूथ टॉगल करें)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"ओईएम अनलॉक करना"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"बूटलोडर को अनलाॅक किए जाने की अनुमति दें"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM अनलॉक करने की अनुमति दें?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस डिसप्ले सर्टिफ़िकेशन"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"वाई-फ़ाई वर्बोस लॉगिंग चालू करें"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"जुड़े हुए एमएसी (मैक) रैंडमाइज़ेशन (वाई-फ़ाई नेटवर्क से जुड़ते समय एमएसी पता बदले जाने की सुविधा)"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा हमेशा चालू"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"हार्डवेयर से तेज़ी लाने के लिए टेदर करें"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"बिना नाम वाले ब्लूटूथ डिवाइस दिखाएं"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"कनेक्ट नहीं हो सका"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस डिसप्ले सर्टिफ़िकेशन के विकल्प दिखाएं"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाई-फ़ाई लॉगिंग का स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"वाई-फ़ाई से जुड़ते समय अलग-अलग एमएसी पते इस्तेमाल करें"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"डेटा इस्तेमाल करने की सीमा तय की गई है"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"डेटा इस्तेमाल करने की सीमा तय नहीं की गई है"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफ़र आकार"</string>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index fcf0e09..8453c4c 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Upotrebljavaj HDCP provjeru samo za DRM sadržaj"</item>
<item msgid="45075631231212732">"Uvijek upotrebljavaj HDCP provjeru"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Onemogućeno"</item>
+ <item msgid="1969681323976948639">"Omogućeno filtrirano"</item>
+ <item msgid="8719029132154020716">"Omogućeno"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (zadano)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 8b23875..bb14b06 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatski povezan putem %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatski povezan putem ocjenjivača mreže"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Povezano putem %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>, <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Povezan putem mreže <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostupno putem %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Dodirnite za postavljanje"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Dodirnite da biste se registrirali"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Povezano, bez interneta"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nema interneta"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Obavezna prijava"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pristupna je točka privremeno puna"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Povezano putem mreže %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Dostupno putem mreže %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Povezivanje nije uspjelo"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Nevažeći URL OSU poslužitelja"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Veza s OSU poslužiteljem nije uspjela"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Ovjera OSU poslužitelja nije uspjela"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Nevažeći certifikat OSU poslužitelja"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Davanje pristupa je prekinuto"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Pružanje usluga nije dostupno"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Nevažeći URL OSU poslužitelja"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Neočekivana vrsta naredbe"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Neočekivana vrsta SOAP poruke"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Razmjena SOAP poruke nije uspjela"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Nije moguće pokrenuti osluškivač preusmjeravanja"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Isteklo je vrijeme čekanja za preusmjeravanje"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nije pronađena OSU aktivnost"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Neočekivana poruka o statusu SOAP-a"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Nije pronađen PPS MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Nije pronađen pouzdani korijenski čvor za AAA poslužitelj"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Nije pronađen pouzdani korijenski čvor za poslužitelj za popravak"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Nije pronađen pouzdani korijenski čvor za poslužitelj za pravila"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Dohvaćanje pouzdanih korijenskih certifikata nije uspjelo"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Nije pronađen pouzdani korijenski certifikat za AAA poslužitelj"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Dodavanje konfiguracije PassPointa nije uspjelo"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Nije pronađen OSU davatelj usluga"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Povezivanje"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Povezano"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Povezivanje s OSU poslužiteljem"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Potvrđen je OSU poslužitelj"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Povezano s OSU poslužiteljem"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Početna razmjena SOAP-a"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Čekanje na odgovor o preusmjeravanju"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Primljen je odgovor o preusmjeravanju"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Druga razmjena SOAP-a"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Treća razmjena SOAP-a"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Dohvaćanje pouzdanih korijenskih certifikata"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Dovršeno je davanje pristupa"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Otvaranje aplikacije <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Povezivanje nije uspjelo"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Dovršavanje registracije…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Nije moguće dovršiti registraciju. Dodirnite za ponovni pokušaj."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registracija je dovršena. Povezivanje…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Vrlo sporo"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Sporo"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"U redu"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Ne pokreći mirovanje"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Zaslon nikad neće prijeći u mirovanje tijekom punjenja"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Zapisi za Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Dohvati Bluetooth pakete. (Uključi Bluetooth nakon promjene ove postavke)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM otključavanje"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Neka kôd za pokretanje sustava bude otključan"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Želite li dopustiti OEM otključavanje?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući opširnu prijavu na Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Nasumični odabir MAC-a pri povezivanju"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci uvijek aktivni"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje za modemsko povezivanje"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije moguće"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaži opcije za certifikaciju bežičnog prikaza"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećana razina prijave na Wi‑Fi, prikaz po SSID RSSI-ju u Biraču Wi‑Fi-ja"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Nasumično odaberi MAC adresu pri povezivanju s Wi-Fi mrežama"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"S ograničenim prometom"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez ograničenja prometa"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Veličine međuspremnika zapisnika"</string>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 2e02a59..8713fc1 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Csak DRM-tartalomhoz használjon HDCP ellenőrzést"</item>
<item msgid="45075631231212732">"Mindig használjon HDCP ellenőrzést"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Letiltva"</item>
+ <item msgid="1969681323976948639">"Szűrtek engedélyezve"</item>
+ <item msgid="8719029132154020716">"Engedélyezve"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (alapértelmezett)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 589aa40..14d8c78 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatikusan csatlakozott a következőn keresztül: %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatikusan csatlakozott a hálózatértékelés szolgáltatóján keresztül"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Csatlakozva a következőn keresztül: %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>: <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Kapcsolódva a következőn keresztül: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Elérhető a következőn keresztül: %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Koppintson ide a beállításhoz"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Koppintson a regisztrációhoz"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Csatlakozva, nincs internet-hozzáférés"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nincs internetkapcsolat"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Bejelentkezést igényel"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"A hozzáférési pont átmenetileg megtelt"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Csatlakozva a következőn keresztül: %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Elérhető a következőn keresztül: %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Sikertelen kapcsolódás"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Érvénytelen az OSU-szerver URL-je"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Nem sikerült csatlakozni az OSU-szerverhez"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Nem sikerült az OSU-szerver ellenőrzése"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Érvénytelen az OSU-szerver tanúsítványa"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Hozzárendelés megszakítva"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"A hozzárendelés nem lehetséges"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Érvénytelen az OSU-szerver URL-je"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Váratlan parancstípus"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Váratlan SOAP-üzenettípus"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Sikertelen SOAP-üzenetváltás"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Nem sikerült elindítani az átirányítási eseményfigyelőt"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Időtúllépés az átirányításra várakozás közben"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nem található OSU-tevékenység"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Váratlan SOAP-üzenetállapot"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Nem található PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Nem található az AAA-szerver megbízható gyökércsomópontja"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Nem található a szerverkiszolgáló megbízható gyökércsomópontja"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Nem található a házirendszerver megbízható gyökércsomópontja"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Nem sikerült a megbízható gyökérszintű tanúsítványok lekérése"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Nem található az AAA-szerver megbízható gyökértanúsítványa"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Nem sikerült a PassPoint-konfiguráció hozzáadása"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Nem található OSU-szolgáltató"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Csatlakozás…"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Csatlakozva"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Csatlakozás az OSU-szerverhez…"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-szerver ellenőrizve"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Csatlakoztatva az OSU-szerverhez"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Első SOAP-üzenetváltás"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Várakozás az átirányítási válaszra…"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Átirányítási válasz érkezett"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Második SOAP-üzenetváltás"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Harmadik SOAP-üzenetváltás"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Megbízható gyökérszintű tanúsítványok lekérése…"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Hozzárendelés kész"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> megnyitása"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Nem sikerült csatlakozni"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Regisztráció befejezése…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Nem sikerült a regisztráció befejezése. Koppintással újrapróbálkozhat."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"A regisztráció befejeződött. Csatlakozás…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Nagyon lassú"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lassú"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Rendben"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Nem kapcsolódik ki"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"A képernyő soha nem kapcsol ki töltés során"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI snoop napló engedélyezése"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth-csomagok rögzítése. (Bluetooth be-, illetve kikapcsolása a beállítás módosítása után)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-feloldás"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"A rendszerbetöltő feloldásának engedélyezése"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Engedélyezi az OEM-feloldást?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Hálózatok"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Vezeték nélküli kijelző tanúsítványa"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Részletes Wi-Fi-naplózás engedélyezése"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Csatlakoztatott MAC-címek randomizálása"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"A mobilhálózati kapcsolat mindig aktív"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Internetmegosztás hardveres gyorsítása"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Név nélküli Bluetooth-eszközök megjelenítése"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nem sikerült kapcsolódni"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vezeték nélküli kijelző tanúsítványával kapcsolatos lehetőségek megjelenítése"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-naplózási szint növelése, RSSI/SSID megjelenítése a Wi‑Fi-választóban"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"MAC-cím véletlenszerű generálása Wi‑Fi-hálózatra való csatlakozáskor"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Forgalomkorlátos"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Nem forgalomkorlátos"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Naplózási puffer mérete"</string>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 1e1f4bf..5cffafe 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Օգտագործել HDCP-ը` միայն DRM-ի բովանդակությունը ստուգելու համար"</item>
<item msgid="45075631231212732">"Միշտ օգտագործել HDCP ստուգումը"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Անջատված է"</item>
+ <item msgid="1969681323976948639">"Միացված է զտիչներով"</item>
+ <item msgid="8719029132154020716">"Միացված է"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (կանխադրված)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index eb06172..28ebe4f 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Ավտոմատ կերպով միացել է ցանցի վարկանիշի ծառայության մատակարարի միջոցով"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Կապակցված է %1$s-ի միջոցով"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"«<xliff:g id="SSID">%1$s</xliff:g>», <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Միացված է <xliff:g id="NAME">%1$s</xliff:g>-ի միջոցով"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Հասանելի է %1$s-ի միջոցով"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Հպեք՝ կարգավորելու համար"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Հպեք՝ գրանցվելու համար"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Միացված է, սակայն ինտերնետ կապ չկա"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Ինտերնետ կապ չկա"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Անհրաժեշտ է մուտք գործել"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Հասանելիության կետը ժամանակավորապես լիքն է"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Միացված է %1$s-ի միջոցով"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Հասանելի է %1$s-ի միջոցով"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Չհաջողվեց միանալ"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU սերվերի անվավեր URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Չհաջողվեց միանալ OSU սերվերին"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Չհաջողվեց ստուգել OSU սերվերը"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU սերվերի անվավեր հավաստագիր"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Համաժամեցումն ընդհատվեց"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Համաժամեցումն անհասանելի է"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU սերվերի անվավեր URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Հրահանգի անհայտ տեսակ"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"SOAP հաղորդագրության անհայտ տեսակ"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Չհաջողվեց փոխանակել SOAP հաղորդագրությունները"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Չհաջողվեց գործարկել վերահասցեավորվող զանգերի ընդունիչը"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Սպասման ժամանակը լրացել է"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU գործողություններ չեն հայտնաբերվել"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP հաղորդագրության անհայտ կարգավիճակ"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Չհաջողվեց գտնել PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Չհաջողվեց գտնել AAA սերվերի վստահված արմատային հանգույցը"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Չհաջողվեց գտնել ուղղումների սերվերի վստահված արմատային հանգույցը"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Չհաջողվեց գտնել կանոնների սերվերի վստահված արմատային հանգույցը"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Չհաջողվեց բեռնել վստահված արմատային հավաստագրերը"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Չհաջողվեց գտնել AAA սերվերի վստահված արմատային հավաստագիրը"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Չհաջողվեց ավելացնել PassPoint-ի կարգավորումները"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Չհաջողվեց գտնել OSU-ի մատակարարին"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Միացում"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Միացած է"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Միացում OSU սերվերին"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU սերվերը ստուգված է"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Միացած է OSU սերվերին"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Առաջին փոխանակումը SOAP-ով"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Վերահասցեավորվող պատասխանի սպասում"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Պատասխանը ստացված է"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Երկրորդ փոխանակում SOAP-ով"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Երրորդ փոխանակում SOAP-ով"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Վստահված արմատային հավաստագրերը բեռնվում են"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Համաժամեցումն ավարտված է"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>, բացվում է"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Չհաջողվեց միանալ"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Գրանցումն ավարտվում է…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Չհաջողվեց ավարտել գրանցումը: Հպեք` նորից փորձելու համար:"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Գրանցումն ավարտված է: Միացում…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Շատ դանդաղ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Դանդաղ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Հաստատել"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Մնալ արթուն"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Էկրանը երբեք չի քնի լիցքավորման ընթացքում"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Միացնել Bluetooth HCI snoop log-ը"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Պահել Bluetooth փաթեթները (այս կարգավորումը փոխելուց հետո անհրաժեշտ է վերագործարկել Bluetooth-ը)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM ապակողպում"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Թույլ տալ սկզբնաբեռնման բեռնիչի ապակողպումը"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Թույլատրե՞լ OEM ապակողպումը:"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Ցանց"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Անլար էկրանների հավաստագրում"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Միացնել Wi‑Fi մանրամասն գրանցամատյանները"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"MAC հասցեների պատահական ընտրություն Wi-Fi-ին միանալիս"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Բջջային ինտերնետը միշտ ակտիվ է"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Սարքակազմի արագացման միացում"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Ցուցադրել Bluetooth սարքերն առանց անունների"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Չհաջողվեց միանալ"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ցույց տալ անլար էկրանի հավաստագրման ընտրանքները"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Բարձրացնել մակարդակը, Wi‑Fi ընտրիչում ամեն մի SSID-ի համար ցույց տալ RSSI"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Պատահականորեն ընտրել MAC հասցեն Wi-Fi ցանցերին միանալիս"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Վճարովի թրաֆիկ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Անսահմանափակ թրաֆիկ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Մատյանի բուֆերի չափերը"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 8d858a5..867f9ea 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Gunakan pemeriksaan HDCP untuk konten DRM saja"</item>
<item msgid="45075631231212732">"Selalu gunakan pemeriksaan HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Nonaktif"</item>
+ <item msgid="1969681323976948639">"Diaktifkan Difilter"</item>
+ <item msgid="8719029132154020716">"Diaktifkan"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 208508e..182e523 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Tersambung otomatis melalui %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Otomatis tersambung melalui penyedia rating jaringan"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> oleh <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Tersambung melalui <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tap untuk menyiapkan"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap untuk mendaftar"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tersambung, tidak ada internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Tidak ada internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Perlu login"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Titik akses penuh untuk sementara"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Tersambung melalui %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Tersedia melalui %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Koneksi gagal"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL server OSU tidak valid"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Koneksi server OSU gagal"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Validasi server OSU gagal"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Sertifikat server OSU tidak valid"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisioning dibatalkan"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisioning tidak tersedia"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL server OSU tidak valid"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Jenis perintah yang tidak terduga"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Jenis pesan SOAP yang tidak terduga"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Pertukaran pesan SOAP gagal"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Listener pengalihan gagal dimulai"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Waktu tunggu pengalihan habis"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Tidak ditemukan aktivitas OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Status pesan SOAP yang tidak terduga"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Gagal menemukan PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Gagal menemukan node root tepercaya untuk server AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Gagal menemukan node root tepercaya untuk server perbaikan"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Gagal menemukan node root tepercaya untuk server kebijakan"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Gagal mengambil root certificate tepercaya"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Gagal menemukan root certificate tepercaya untuk server AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Gagal menambahkan konfigurasi PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Gagal menemukan penyedia OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Menghubungkan"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Tersambung"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Menyambungkan ke server OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Server OSU divalidasi"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Tersambung ke server OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Pertukaran SOAP awal"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Menunggu respons pengalihan"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Respons pengalihan diterima"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Pertukaran SOAP kedua"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Pertukaran SOAP ketiga"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Mengambil root certificate tepercaya"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisioning selesai"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Membuka <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Tidak dapat tersambung"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Menyelesaikan pendaftaran…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Tidak dapat menyelesaikan pendaftaran. Tap untuk mencoba lagi."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Pendaftaran selesai. Menyambungkan…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Lambat"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lambat"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Oke"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Tetap terjaga"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Layar tidak akan redup selama mengisi daya"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Aktifkan log pengintaian HCI Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Ambil paket Bluetooth. (Aktifkan/nonaktifkan Bluetooth setelah mengubah setelan ini)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Buka kunci OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Izinkan bootloader dibuka kuncinya"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Izinkan buka kunci OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Jaringan"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikasi layar nirkabel"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktifkan Pencatatan Log Panjang Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Pengacakan MAC yang Terhubung"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Data seluler selalu aktif"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Akselerasi hardware tethering"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Tampilkan perangkat Bluetooth tanpa nama"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tidak dapat terhubung"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Acak alamat MAC saat menghubungkan ke jaringan Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Berbayar"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Tidak berbayar"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Ukuran buffer pencatat log"</string>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 16d5b8a4..d467a68 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Nota HDCP-athugun aðeins fyrir höfundarréttarvarið efni"</item>
<item msgid="45075631231212732">"Nota alltaf HDCP-eftirlit"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Slökkt"</item>
+ <item msgid="1969681323976948639">"Kveikt á síuðu"</item>
+ <item msgid="8719029132154020716">"Kveikt"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (sjálfgefið)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index ffa3ddc..577b7ae 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Sjálfkrafa tengt um %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Sjálfkrafa tengt um netgæðaveitu"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tengt í gegnum %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> með <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Tenging í gegnum <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Í boði í gegnum %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Ýttu til að setja upp"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Ýttu til að skrá þig"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tengt, enginn netaðgangur"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Engin nettenging"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Innskráningar krafist"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Aðgangsstaður tímabundið fullur"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Tengt í gegnum %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Í boði í gegnum %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Tenging mistókst"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Ógild vefslóð OSU-þjóns"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Tenging OSU-þjóns mistókst"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Staðfesting OSU-þjóns mistókst"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Ógilt vottorð OSU-þjóns"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Hætt við úthlutun"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Úthlutun ekki tiltæk"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Ógild vefslóð OSU-þjóns"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Óvænt tegund skipunar"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Óvænt gerð SOAP- skilaboða"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Skipti SOAP-skilaboða mistókust"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Ekki tókst að ræsa framsenda hlustunarþjónustu"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Tímamörk runnu út við að bíða eftir framsendingu"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Engin OSU-virkni fannst"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Óvænt staða SOAP-skilaboða"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Ekki tókst að finna PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Ekki tókst að finna traustan rótarhnút fyrir AAA-þjón"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Ekki tókst að finna traustan rótarhnút fyrir úrbótaþjón"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Ekki tókst að finna traustan rótarhnút fyrir regluþjón"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Ekki tókst að sækja traust rótarvottorð"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Ekki tókst að finna traust rótarvottorð fyrir AAA-þjón"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Ekki tókst að bæta við PassPoint-stillingu"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Ekki tókst að finna OSU-veitu"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Tengist"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Tengt"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Tengist við OSU-þjón"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-þjónn staðfestur"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Tengt við OSU-þjón"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Fyrstu SOAP-skipti"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Bíður eftir framsendu svari"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Framsent svar móttekið"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Önnur SOAP-skipti"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Þriðju SOAP-skipti"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Sækir traust rótarvottorð"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Úthlutun lokið"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Opnar <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Ekki tókst að tengjast"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Gengur frá nýskráningu…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Ekki tókst að ljúka við nýskráningu. Ýttu til að reyna aftur."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Nýskráningu lokið. Tengist…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Mjög hægt"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Hægt"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Í lagi"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Vaka"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Skjárinn fer aldrei í hvíld við hleðslu"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Gera HCI-snuðraraskrá Bluetooth virka"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Fanga Bluetooth-pakka. (Velja skal Bluetooth eftir að þessari stillingu er breytt)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Opnun framleiðanda"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Leyfa opnun ræsiforritsins"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Leyfa opnun framleiðanda?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Netkerfi"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Vottun þráðlausra skjáa"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Kveikja á ítarlegri skráningu Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Slembival MAC-vistfanga við tengingu"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Alltaf kveikt á farsímagögnum"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Vélbúnaðarhröðun fyrir tjóðrun"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Sýna Bluetooth-tæki án heita"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tenging mistókst"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Sýna valkosti fyrir vottun þráðlausra skjáa"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Auka skráningarstig Wi-Fi, sýna RSSI fyrir hvert SSID í Wi-Fi vali"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Velja MAC-vistfang af handahófi þegar tengst er við Wi‑Fi net"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Mæld notkun"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Notkun ekki mæld"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Annálsritastærðir biðminna"</string>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index 555cd1c..7d316ab8 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Usa la verifica HDCP solo per contenuti DRM"</item>
<item msgid="45075631231212732">"Usa sempre la verifica HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Non attiva"</item>
+ <item msgid="1969681323976948639">"Filtro attivo"</item>
+ <item msgid="8719029132154020716">"Attiva"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (predefinita)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index a370ad1..9fc32949 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Collegato automaticamente tramite %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Collegato automaticamente tramite fornitore di servizi di valutazione rete"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Collegato tramite %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> di <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Connesso tramite <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponibile tramite %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tocca per configurare"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tocca per registrarti"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Connesso, senza Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nessuna connessione a Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Accesso richiesto"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punto di accesso momentaneamente al completo"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Connesso tramite %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponibile tramite %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Connessione non riuscita"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL del server OSU non valido"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Connessione al server OSU non riuscita"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Convalida del server OSU non riuscita"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificato server OSU non valido"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisioning interrotto"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisioning non disponibile"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL del server OSU non valido"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tipo di comando imprevisto"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tipo di messaggio SOAP imprevisto"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Scambio messaggi SOAP non riuscito"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Avvio del listener di reindirizzamento non riuscito"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Timeout durante l\'attesa del reindirizzamento"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nessuna attività OSU rilevata"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Stato imprevisto del messaggio SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Individuazione di PPS-MO non riuscita"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Individuazione del nodo radice di attendibilità per il server AAA non riuscita"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Individuazione del nodo radice di attendibilità per il server di correzione non riuscita"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Individuazione del nodo radice di attendibilità per il server delle norme non riuscita"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Recupero dei certificati radice di attendibilità non riuscito"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Individuazione del certificato radice di attendibilità per il server AAA non riuscita"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Aggiunta della configurazione PassPoint non riuscita."</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Individuazione di un provider OSU non riuscita"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Connessione"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Connesso"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Connessione al server OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Server OSU convalidato"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Connessione con server OSU stabilita"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Scambio SOAP iniziale"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"In attesa della risposta di reindirizzamento"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"È stata ricevuta una risposta di reindirizzamento"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Secondo scambio SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Terzo scambio SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Recupero dei certificati radice di attendibilità"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisioning completato"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Apertura di <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>…"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Impossibile collegarsi"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Completamento della registrazione…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Impossibile completare la registrazione. Tocca per riprovare."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registrazione completata. Connessione…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Molto lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Rimani attivo"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Lo schermo non va mai in stand-by se sotto carica"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Attiva log di esame HCI Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Acquisisci pacchetti Bluetooth. Attiva/disattiva Bluetooth dopo aver modificato questa impostazione."</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Sblocco OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Consenti lo sblocco del bootloader"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Consentire lo sblocco OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Reti"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificazione display wireless"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Attiva registrazione dettagliata Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Selezione casuale dell\'indirizzo MAC con connessione"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Dati mobili sempre attivi"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering accelerazione hardware"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostra dispositivi Bluetooth senza nome"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossibile collegarsi"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opzioni per la certificazione display wireless"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta il livello di registrazione Wi-Fi, mostrando il SSID RSSI nel selettore Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Seleziona indirizzo MAC casuale con reti Wi-Fi collegate"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"A consumo"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Non a consumo"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Dimensioni buffer Logger"</string>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index 4ad9b34..9feaa2a 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"השתמש בבדיקת HDCP עבור תוכן DRM בלבד"</item>
<item msgid="45075631231212732">"תמיד השתמש בבדיקת HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"מושבת"</item>
+ <item msgid="1969681323976948639">"המסננים המופעלים"</item>
+ <item msgid="8719029132154020716">"מופעל"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ברירת המחדל)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 04fd750..8ee11e4 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"מחובר אוטומטית דרך %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"מחובר אוטומטית דרך ספק של דירוג רשת"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"מחובר דרך %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> של <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"מחוברת באמצעות <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"זמינה דרך %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"יש להקיש כדי להגדיר"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"יש להקיש כדי להירשם"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"מחובר. אין אינטרנט"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"אין אינטרנט"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"נדרשת כניסה"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"נקודת הגישה מלאה באופן זמני"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"מחובר לרשת של %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"זמינה דרך %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"החיבור נכשל"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"כתובת URL לא חוקית של שרת OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"נכשל חיבור לשרת OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"נכשל אימות של שרת OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"אישור לא חוקי של שרת OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ניהול תצורה בוטל"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"ניהול תצורה לא זמין"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"כתובת URL לא חוקית של שרת OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"סוג פקודה לא צפוי"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"סוג הודעה לא צפוי של SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"נכשלו חילופין של הודעת SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"נכשלה התחלה של הפניה אוטומטית של מאזין"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"תם פרק הזמן הקצוב לתפוגה בהמתנה להפניה אוטומטית"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"לא נמצאה פעילות OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"סטטוס לא צפוי של הודעת SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"נכשלה מציאה של PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"נכשלה מציאה של צומת בסיס למהימנות עבור שרת AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"נכשלה מציאה של צומת בסיס למהימנות עבור שרת תיקון"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"נכשלה מציאה של צומת בסיס למהימנות עבור שרת מדיניות"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"נכשל אחזור של אישורי בסיס למהימנות"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"נכשלה מציאה של אישור בסיס למהימנות עבור שרת AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"נכשלה הוספה של הגדרת PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"נכשלה מציאה של ספק OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"מתבצעת התחברות"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"מחובר"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"מתבצע חיבור לשרת OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"שרת OSU אומת"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"יש חיבור לשרת OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"חילופי SOAP ראשוניים"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"בהמתנה לתגובה להפניה אוטומטית"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"התקבלה תגובה להפניה אוטומטית"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"חילופי SOAP בפעם השנייה"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"חילופי SOAP בפעם השלישית"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"מתבצע אחזור של אישורי בסיס למהימנות"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ניהול תצורה הושלם"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"מתבצעת פתיחה של <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"לא ניתן היה להתחבר"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"מתבצעת השלמה של ההרשמה…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"לא ניתן היה להשלים את ההרשמה. יש להקיש כדי לנסות שוב."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"תהליך ההרשמה הסתיים. בתהליך התחברות…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"איטית מאוד"</string>
<string name="speed_label_slow" msgid="813109590815810235">"איטית"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"אישור"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"השאר פועל"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"המסך לעולם לא יהיה במצב שינה במהלך טעינה"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"הפעלת Snoop Log של Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"איחוד חבילות Bluetooth. (יש להחליף מצב Bluetooth לאחר שינוי הגדרה זו)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"ביטול נעילה של OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"אפשר ביטול של נעילת מנהל האתחול"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"האם לאפשר ביטול נעילה של OEM (יצרן ציוד מקורי)?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"תקשורת רשתות"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"אישור של תצוגת WiFi"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"הפעל רישום מפורט של Wi‑Fi ביומן"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"חיבור כתובת MAC אקראית"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"חבילת הגלישה פעילה תמיד"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"שיפור מהירות באמצעות חומרה לצורך שיתוף אינטרנט בין ניידים"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"הצגת מכשירי Bluetooth ללא שמות"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"לא ניתן היה להתחבר"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"הצג אפשרויות עבור אישור של תצוגת WiFi"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"יצירת כתובת MAC אקראית בהתחברות לרשתות Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"נמדדת"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"לא נמדדת"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"גדלי מאגר של יומן רישום"</string>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 978f6da..2de8c86 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRMコンテンツにのみHDCPチェックを使用する"</item>
<item msgid="45075631231212732">"HDCPチェックを常に使用する"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"無効"</item>
+ <item msgid="1969681323976948639">"有効(フィルタ済み)"</item>
+ <item msgid="8719029132154020716">"有効"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4(デフォルト)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 9699e86..4efd61b 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s 経由で自動的に接続しています"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ネットワーク評価プロバイダ経由で自動的に接続しています"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s経由で接続"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>(<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>)"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> で接続しました"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s経由で使用可能"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"設定するにはタップします"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"タップして登録してください"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"接続済み、インターネット接続なし"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"インターネット未接続"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ログインが必要"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"アクセス ポイントが一時的にいっぱいです"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s 経由で接続済み"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s 経由で使用可能"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"接続できませんでした"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU サーバーの URL が無効です"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU サーバーに接続できませんでした"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU サーバーの検証に失敗しました"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU サーバー証明書が無効です"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"プロビジョニングが中断されました"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"プロビジョニングは利用できません"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU サーバーの URL が無効です"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"予期しないコマンドタイプです"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"予期しない SOAP メッセージ タイプです"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP メッセージの交換に失敗しました"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"リダイレクト リスナーを起動できませんでした"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"リダイレクトの待機中にタイムアウトになりました"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU アクティビティが見つかりませんでした"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"予期しない SOAP メッセージ ステータスです"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO が見つかりませんでした"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA サーバー用の信頼できるルートノードが見つかりませんでした"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"修復サーバー用の信頼できるルートノードが見つかりませんでした"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"ポリシー サーバー用の信頼できるルートノードが見つかりませんでした"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"信頼できるルート証明書を取得できませんでした"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA サーバー用の信頼できるルート証明書が見つかりませんでした"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint 設定を追加できませんでした"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU プロバイダが見つかりませんでした"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"接続しています"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"接続しました"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU サーバーに接続しています"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU サーバーの検証が完了しました"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU サーバーに接続しました"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"1 回目の SOAP 交換です"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"リダイレクト レスポンスを待機しています"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"リダイレクト レスポンスを受信しました"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"2 回目の SOAP 交換です"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"3 回目の SOAP 交換です"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"信頼できるルート証明書を取得しています"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"プロビジョニングが完了しました"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"「<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>」を開いています"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"接続できませんでした"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"登録を完了しています…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"登録を完了できませんでした。タップしてもう一度お試しください。"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"登録が完了しました。接続しています…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"とても遅い"</string>
<string name="speed_label_slow" msgid="813109590815810235">"遅い"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"スリープモードにしない"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"充電中に画面をスリープにしない"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCIスヌープログをON"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth パケットをキャプチャします(この設定を変更した場合は Bluetooth を切り替えてください)。"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEMロック解除"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"ブートローダーによるロック解除を許可する"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEMロック解除の許可"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ネットワーク"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ワイヤレスディスプレイ認証"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi詳細ログの有効化"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"接続先 MAC のランダム化"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"モバイルデータを常に ON にする"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"テザリング時のハードウェア アクセラレーション"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth デバイスを名前なしで表示"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"接続できませんでした"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ワイヤレスディスプレイ認証のオプションを表示"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fiログレベルを上げて、Wi-Fi選択ツールでSSID RSSIごとに表示します"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi-Fi ネットワーク接続時の MAC アドレスのランダム化"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"従量制"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"定額制"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ログバッファのサイズ"</string>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index 73dbdfa..d315bfe 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP შემოწმების გამოყენება მხოლოდ DRM კონტენტის შემთხვევაში"</item>
<item msgid="45075631231212732">"ყოველთვის გამოიყენე HDCP შემოწმება"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"გათიშულია"</item>
+ <item msgid="1969681323976948639">"გაფილტრულის ჩართვა"</item>
+ <item msgid="8719029132154020716">"ჩართულია"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ნაგულისხმევი)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 64d78bb..c613a06b 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"ავტომატურად დაკავშირდა %1$s-ის მეშვეობით"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ავტომატურად დაკავშირდა ქსელის ხარისხის შეფასების პროვაიდერის მეშვეობით"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ით დაკავშირებული"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>, უზრუნველყოფს <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"დაკავშირებულია <xliff:g id="NAME">%1$s</xliff:g>-ით"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"ხელმისაწვდომია %1$s-ით"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"შეეხეთ დასაყენებლად"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"შეეხეთ რეგისტრაციისთვის"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"დაკავშირებულია, ინტერნეტის გარეშე"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ინტერნეტ-კავშირი არ არის"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"აუცილებელია სისტემაში შესვლა"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"წვდომის წერტილი დროებით გადატვირთულია"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s-ით დაკავშირებული"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"ხელმისაწვდომია %1$s-ით"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"დაკავშირება ვერ მოხერხდა"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU სერვერის URL არასწორია"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU სერვერთან დაკავშირება ვერ მოხერხდა"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU სერვერის დადასტურება ვერ მოხერხდა"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU სერვერის სერტიფიკატი არასწორია"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"უზრუნველყოფა შეწყვეტილია"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"უზრუნველყოფა მიუწვდომელია"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU სერვერის URL არასწორია"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ბრძანების ტიპი მოულოდნელია"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"SOAP-შეტყობინების ტიპი მოულოდნელია"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP-შეტყობინებების მიმოცვლა ვერ მოხერხდა"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"გადამისამართებების მიმღების გაშვება ვერ მოხერხდა"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"გადამისამართების მოლოდინის დრო ამოიწურა"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU აქტივობა ვერ მოიძებნა"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP-შეტყობინების სტატუსი მოულოდნელია"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO ვერ მოიძებნა"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA სერვერისთვის ნდობით აღჭურვილი ძირეული კვანძი ვერ მოიძებნა"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"გამართვების სერვერისთვის ნდობით აღჭურვილი ძირეული კვანძი ვერ მოიძებნა"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"წესების სერვერისთვის ნდობით აღჭურვილი ძირეული კვანძი ვერ მოიძებნა"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"ნდობით აღჭურვილი ძირეული სერტიფიკატების მოძიება ვერ მოხერხდა"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA სერვერისთვის ნდობით აღჭურვილი ძირეული სერტიფიკატი ვერ მოიძებნა"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint კონფიგურაციის დამატება ვერ მოხერხდა"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU პროვაიდერი ვერ მოიძებნა"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"მიმდინარეობს დაკავშირება"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"დაკავშირებულია"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"მიმდინარეობს დაკავშირება OSU სერვერთან"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU სერვერი დადასტურებულია"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"დაკავშირებულია OSU სერვერთან"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"SOAP-შეტყობინებების საწყისი მიმოცვლა"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"გადამისამართების პასუხის მოლოდინში"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"მიღებულია გადამისამართების პასუხი"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"SOAP-შეტყობინებების მეორე მიმოცვლა"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"SOAP-შეტყობინებების მესამე მიმოცვლა"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"მინდინარეობს ნდობით აღჭურვილი ძირეული სერტიფიკატების მოძიება"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"უზრუნველყოფა დასრულებულია"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"მიმდინარეობს <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>-ის გახსნა"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"დაკავშირება ვერ მოხერხდა"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"მიმდინარეობს რეგისტრაციის დასრულება…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"რეგისტრაციის დასრულება ვერ მოხერხდა. შეეხეთ ხელახლა საცდელად."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"რეგისტრაცია დასრულდა. მიმდინარეობს დაკავშირება…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ძალიან ნელი"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ნელი"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"კარგი"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"არ დაიძინო"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"დატენვისას ეკრანი არ დაიძინებს"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI snoop ჟურნალის ჩართვა"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth პაკეტების წატაცება. (ამ პარამეტრის შეცვლის შემდეგ ჩართეთ და გამორთეთ Bluetooth)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM განბლოკვა"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"ნება დართოს განბლოკოს ჩამტვირთველმა"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"მისცეს ნება OEM განბლოკვას?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ქსელი"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"უსადენო ეკრანის სერტიფიცირება"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi-ს დაწვრილებითი აღრიცხვის ჩართვა"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"დაკავშირებული MAC მისამართის შემთხვევითობა"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"მობილური ინტერნეტის ყოველთვის გააქტიურება"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ტეტერინგის აპარატურული აჩქარება"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-მოწყობილობების ჩვენება სახელების გარეშე"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"დაკავშირება ვერ მოხერხდა"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"უსადენო ეკრანის სერტიფიცირების ვარიანტების ჩვენება"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-ს აღრიცხვის დონის გაზრდა, Wi‑Fi ამომრჩეველში ყოველ SSID RSSI-ზე ჩვენება"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"MAC მისამართის შემთხვევითობა ჩაირთოს, როცა Wi‑Fi-ქსელებთან დაკავშირება ხდება"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"ლიმიტირებული"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"არალიმიტირებული"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ჟურნალიზაციის ბუფერის ზომები"</string>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 0f06e39..af578a9 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP тексерісін DRM мазмұны үшін ғана қолдану"</item>
<item msgid="45075631231212732">"Әрқашан HDCP (жоғары кең жолақты сандық мазмұн қорғаушы) тексерулерін қолданыңыз"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Өшірулі"</item>
+ <item msgid="1969681323976948639">"Сүзгіленгендері қосулы"</item>
+ <item msgid="8719029132154020716">"Қосулы"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (әдепкі)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 58f10ac..8d6d76e 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s арқылы автоматты қосылды"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Желі рейтингі провайдері арқылы автоматты түрде қосылған"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s арқылы қосылған"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> ұсынған <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> арқылы жалғанған"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s арқылы қолжетімді"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Реттеу үшін түртіңіз"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Тіркелу үшін түртіңіз."</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Қосылған, интернет жоқ"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Интернетпен байланыс жоқ"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Есептік жазбаға кіру керек"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Кіру нүктесі уақытша бос емес"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s арқылы қосылды"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s арқылы қолжетімді"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Байланыс орнатылмады"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU серверінің URL мекенжайы жарамсыз"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU серверімен байланыс қатесі шықты"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU сервері тексеруден өтпеді"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU серверінің сертификаты жарамсыз"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Дайындық процесі үзілді"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Дайындықты жүзеге асыру мүмкін емес"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU серверінің URL мекенжайы жарамсыз"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Күтпеген пәрмен түрі"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"SOAP хабарының белгісіз түрі"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP хабарын алмасу мүмкін болмады"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Тыңдаушының бағытын ауыстыру мүмкін болмады"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Бағыттың ауыстырылуын күту уақыты бітті"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Ешқандай OSU әрекеті табылмады"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP хабарының белгісіз күйі"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO табылмады"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA сервері үшін сенімді түбір табылмады"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Жөндеулер сервері үшін сенімді түбір табылмады"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Саясат сервері үшін сенімді түбір табылмады"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Сенімді түбірлік сертификаттар алынбады"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA сервері үшін сенімді түбірлік сертификатты табу мүмкін болмады"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint конфигурациясы енгізілмеді"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU провайдері табылмады"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Жалғануда"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Жалғанды"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU серверіне жалғануда"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU сервері тексерілді"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU серверіне жалғанды"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Бастапқы SOAP алмасуы"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Бағытты ауыстыру туралы жауап күтілуде"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Бағытты ауыстыру туралы жауап алынды"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Екінші SOAP алмасуы"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Үшінші SOAP алмасуы"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Сенімді түбірлік сертификаттар алынуда"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Дайындық аяқталды"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ашылуда"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Жалғанбады"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Тіркелу процесі аяқталуда…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Тіркелу процесі аяқталмады. Әрекетті қайталау үшін түртіңіз."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Тіркелу процесі аяқталды. Жалғануда…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Өте баяу"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Баяу"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Жарайды"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Ояу тұру"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Зарядтау кезінде экран ұйықтамайды"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI snoop тіркелімін қосу"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth пакеттерін алу (осы параметрді өзгерткен соң, Bluetooth-ды қосыңыз немесе өшіріңіз)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM бекітпесін ашу"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Жүктеуші бекітпесін ашуға рұқсат ету"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM бекітпесін ашуға рұқсат ету керек пе?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Желі орнату"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Сымсыз дисплей сертификаты"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi егжей-тегжейлі журналы"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Қосылу кезінде MAC мекенжайларын еркін таңдау"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік деректер әрқашан қосулы"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Тетерингтің аппараттық жеделдетуі"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth құрылғыларын атаусыз көрсету"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Қосылмады"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Сымсыз дисплей сертификаты опцияларын көрсету"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi тіркеу деңгейін арттыру, Wi‑Fi таңдағанда әр SSID RSSI бойынша көрсету"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi‑Fi желісіне қосылу кезінде MAC мекенжайларын еркін таңдау"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Шектелген"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Шектелмеген"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Журналға тіркеуші буферінің өлшемдері"</string>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 4867c8f..88583ad 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"ប្រើការពិនិត្យ HDCP សម្រាប់តែមាតិកា DRM ប៉ុណ្ណោះ"</item>
<item msgid="45075631231212732">"ប្រើការពិនិត្យ HDCP ជានិច្ច"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"បានបិទ"</item>
+ <item msgid="1969681323976948639">"បានបើកការត្រង"</item>
+ <item msgid="8719029132154020716">"បានបើក"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (លំនាំដើម)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 45723ed..9903201 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"បានភ្ជាប់ដោយស្វ័យប្រវត្តិតាមរយៈ %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"បានភ្ជាប់ដោយស្វ័យប្រវត្តិតាមរយៈក្រុមហ៊ុនផ្តល់ការវាយតម្លៃលើបណ្តាញ"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"បានភ្ជាប់តាមរយៈ %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> ដោយ <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"ភ្ជាប់តាម <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"មានតាមរយៈ %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"ចុចដើម្បីរៀបចំ"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"ចុចដើម្បីចុះឈ្មោះ"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"បានភ្ជាប់ ប៉ុន្តែគ្មានអ៊ីនធឺណិតទេ"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"គ្មានអ៊ីនធឺណិតទេ"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"តម្រូវឱ្យចូលគណនី"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ចំណុចចូលប្រើពេញជាបណ្តោះអាសន្ន"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"បានភ្ជាប់តាមរយៈ %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"មានតាមរយៈ %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"ការតភ្ជាប់មិនបានសម្រេច"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL ម៉ាស៊ីនមេ OSU មិនត្រឹមត្រូវទេ"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"មិនអាចផ្ទៀងផ្ទាត់ការតភ្ជាប់ម៉ាស៊ីនមេ OSU បានទេ"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"មិនអាចផ្ទៀងផ្ទាត់ម៉ាស៊ីនមេ OSU បានទេ"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"វិញ្ញាបនបត្រម៉ាស៊ីនមេ OSU មិនត្រឹមត្រូវទេ"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"បានបោះបង់ការផ្ដល់ជូន"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"គ្មានការផ្ដល់ជូនទេ"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL ម៉ាស៊ីនមេ OSU មិនត្រឹមត្រូវទេ"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ប្រភេទការបញ្ជាដែលមិនបានរំពឹងទុក"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ប្រភេទសារ SOAP ដែលមិនបានរំពឺងទុក"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"មិនអាចផ្លាស់ប្ដូរសារ SOAP បានទេ"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"មិនអាចចាប់ផ្ដើមការបញ្ជូនអ្នកស្ដាប់បន្តបានទេ"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"ការរង់ចាំដើម្បីបញ្ជូនបន្តអស់ម៉ោងហើយ"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"រកមិនឃើញសកម្មភាព OSU ទេ"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"ស្ថានភាពសារ SOAP ដែលមិនបានរំពឺងទុក"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"រកមិនឃើញ PPS-MO ទេ"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"រកមិនឃើញថ្នាំងឫសដែលទុកចិត្តសម្រាប់ម៉ាស៊ីនមេ AAA ទេ"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"រកមិនឃើញថ្នាំងឫសដែលទុកចិត្តសម្រាប់ម៉ាស៊ីនមេកែបញ្ហាទេ"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"រកមិនឃើញថ្នាំងឫសដែលទុកចិត្តសម្រាប់ម៉ាស៊ីនមេដែលផ្អែកតាមគោលការណ៍ទេ"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"មិនអាចទាញយកវិញ្ញាបនបត្រគោលដែលទុកចិត្តបានទេ"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"រកមិនឃើញវិញ្ញាបនបត្រគោលដែលទុកចិត្តសម្រាប់ម៉ាស៊ីនមេ AAA ទេ"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"មិនអាចបញ្ចូលការកំណត់រចនាសម្ព័ន្ធ PassPoint បានទេ"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"រកមិនឃើញបណ្ដាញផ្ដល់ OSU ទេ"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"កំពុងភ្ជាប់"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"បានភ្ជាប់"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"កំពុងភ្ជាប់ទៅម៉ាស៊ីនមេ OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"បានផ្ទៀងផ្ទាត់ម៉ាស៊ីនមេ OSU ហើយ"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"បានភ្ជាប់ទៅម៉ាស៊ីនមេ OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"ការផ្លាស់ប្ដូរ SOAP ដំបូង"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"កំពុងរង់ចាំការឆ្លើយតបបន្ត"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"បានទទួលការឆ្លើយតបបន្ត"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"ការផ្លាស់ប្ដូរ SOAP ទីពីរ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"ការផ្លាស់ប្ដូរ SOAP ទីបី"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"កំពុងទាញយកវិញ្ញាបនបត្រគោលដែលទុកចិត្ត"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ការផ្ដល់ជូនបានបញ្ចប់"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"កំពុងបើក <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"មិនអាចភ្ជាប់បានទេ"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"កំពុងបញ្ចប់ការចុះឈ្មោះ…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"មិនអាចបញ្ចប់ការចុះឈ្មោះបានទេ។ សូមចុច ដើម្បីព្យាយាមម្ដងទៀត។"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"ការចុះឈ្មោះបានបញ្ចប់។ កំពុងភ្ជាប់…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"យឺតណាស់"</string>
<string name="speed_label_slow" msgid="813109590815810235">"យឺត"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"យល់ព្រម"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"ទុកឲ្យបើកចោល"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"អេក្រង់នឹងមិនដេកពេលបញ្ចូលថ្ម"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"បើកកំណត់ហេតុ HCI snoop ប៊្លូធូស"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ចាប់យកកញ្ចប់ប៊្លូធូស។ (បិទ/បើកប៊្លូធូស បន្ទាប់ពីប្ដូរការកំណត់នេះ)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"ការដោះសោ OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"អនុញ្ញាតឲ្យដោះសោកម្មវិធីចាប់ផ្តើមប្រព័ន្ធ"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"អនុញ្ញាតការដោះសោ OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ការភ្ជាប់បណ្ដាញ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"សេចក្តីបញ្ជាក់ការបង្ហាញឥតខ្សែ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"បើកកំណត់ហេតុរៀបរាប់ Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"ការជ្រើសរើស MAC ដោយចៃដន្យ នៅពេលបានភ្ជាប់"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"ទិន្នន័យទូរសព្ទចល័តដំណើរការជានិច្ច"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ការបង្កើនល្បឿនផ្នែករឹងសម្រាប់ការភ្ជាប់"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"បង្ហាញឧបករណ៍ប្ល៊ូធូសគ្មានឈ្មោះ"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"មិនអាចភ្ជាប់បានទេ"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"បង្ហាញជម្រើសសម្រាប់សេចក្តីបញ្ជាក់ការបង្ហាញឥតខ្សែ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"បង្កើនកម្រិតកំណត់ហេតុវ៉ាយហ្វាយបង្ហាញក្នុង SSID RSSI ក្នុងកម្មវិធីជ្រើសវ៉ាយហ្វាយ"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ជ្រើសរើសអាសយដ្ឋាន MAC ដោយចៃដន្យ នៅពេលភ្ជាប់បណ្តាញ Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"មានការកំណត់"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"មិនមានការកំណត់"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ទំហំ buffer របស់ Logger"</string>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index 4ac8d56..96e5fc3 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRM ವಿಷಯಗಳಿಗೆ ಮಾತ್ರ HDCP ಪರೀಕ್ಷಿಸುವಿಕೆಯನ್ನು ಬಳಸು"</item>
<item msgid="45075631231212732">"HDCP ಪರಿಶೀಲನೆಯನ್ನು ಯಾವಾಗಲೂ ಬಳಸು"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</item>
+ <item msgid="1969681323976948639">"ಫಿಲ್ಟರ್ ಮಾಡುವುದನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</item>
+ <item msgid="8719029132154020716">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ಡಿಫಾಲ್ಟ್)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index bb889e9..888b93f 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -38,50 +38,27 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ನೆಟ್ವರ್ಕ್ ರೇಟಿಂಗ್ ಒದಗಿಸುವವರ ಮೂಲಕ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> ಮೂಲಕ <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <!-- no translation found for connected_via_app (5571999941988929520) -->
+ <skip />
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"ಸೆಟಪ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <!-- no translation found for tap_to_sign_up (6449724763052579434) -->
+ <skip />
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ, ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ಸೈನ್ ಇನ್ ಮಾಡುವ ಅಗತ್ಯವಿದೆ"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ಪ್ರವೇಶ ಕೇಂದ್ರ ತಾತ್ಕಾಲಿಕವಾಗಿ ಭರ್ತಿಯಾಗಿದೆ"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ಮೂಲಕ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s ಮೂಲಕ ಲಭ್ಯವಿದೆ"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"ಸಂಪರ್ಕ ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"ಅಮಾನ್ಯ OSU ಸರ್ವರ್ URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU ಸರ್ವರ್ ಸಂಪರ್ಕ ವಿಫಲಗೊಂಡಿದೆ"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU ಸರ್ವರ್ ಮೌಲ್ಯಮಾಪನ ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"ಅಮಾನ್ಯ OSU ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರ"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ಪೂರೈಕೆಯನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"ಪೂರೈಕೆ ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"ಅಮಾನ್ಯ OSU ಸರ್ವರ್ URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ಅನಿರೀಕ್ಷಿತ ಕಮಾಂಡ್ ಪ್ರಕಾರ"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ಅನಿರೀಕ್ಷಿತ SOAP ಸಂದೇಶ ಪ್ರಕಾರ"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP ಸಂದೇಶ ವಿನಿಮಿಯ ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"ಮರುನಿರ್ದೇಶನ ಆಲಿಸುವವರು ಪ್ರಾರಂಭಿಸುವಲ್ಲ ವಿಫಲರಾಗಿದ್ದಾರೆ"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"ಮರುನಿರ್ದೇಶನಕ್ಕಾಗಿ ನಿರೀಕ್ಷಿಸುತ್ತಿರುವ ಅವಧಿ ಮೀರಿದೆ"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU ಚಟುವಟಿಕೆ ಕಂಡುಬಂದಿಲ್ಲ"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"ಅನಿರೀಕ್ಷಿತ SOAP ಸಂದೇಶ ಸ್ಥಿತಿ"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO ಹುಡುಕಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA ಸರ್ವರ್ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ ರೂಟ್ ನೋಡ್ ಹುಡುಕಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ಪರಿಹಾರ ಸರ್ವರ್ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ ರೂಟ್ ನೋಡ್ ಅನ್ನು ಹುಡುಕಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"ಕಾರ್ಯನೀತಿ ಸರ್ವರ್ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ ರೂಟ್ ನೋಡ್ ಅನ್ನು ಹುಡುಕಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"ವಿಶ್ವಾಸಾರ್ಹ ರೂಟ್ ಪ್ರಮಾಣಪತ್ರಗಳನ್ನು ಹಿಂಪಡೆಯಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA ಸರ್ವರ್ಗಾಗಿ ವಿಶ್ವಾಸಾರ್ಹ ರೂಟ್ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಹುಡುಕಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಸೇರಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU ಒದಗಿಸುವವರನ್ನು ಹುಡುಕಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU ಸರ್ವರ್ಗೆ ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU ಸರ್ವರ್ ಮೌಲ್ಯಮಾಪನ ಮಾಡಲಾಗಿದೆ"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU ಸರ್ವರ್ಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"ಆರಂಭಿಕ SOAP ವಿನಿಮಯ"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"ಮರುನಿರ್ದೇಶನ ಪ್ರತಿಕ್ರಿಯೆಗಾಗಿ ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"ಮರುನಿರ್ದೇಶನ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಸ್ವೀಕರಿಸಲಾಗಿದೆ"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"ಎರಡನೇ SOAP ವಿನಿಮಯ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"ಮೂರನೇ SOAP ವಿನಿಮಯ"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"ವಿಶ್ವಾಸಾರ್ಹ ರೂಟ್ ಪ್ರಮಾಣಪತ್ರಗಳನ್ನು ಮರುಪಡೆಯಲಾಗುತ್ತಿದೆ"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ಪೂರೈಸುವಿಕೆ ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
+ <!-- no translation found for osu_opening_provider (5488997661548640424) -->
+ <skip />
+ <!-- no translation found for osu_connect_failed (2187750899158158934) -->
+ <skip />
+ <!-- no translation found for osu_completing_sign_up (9037638564719197082) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_failed (7296159750352873260) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_complete (8207626049093289203) -->
+ <skip />
<string name="speed_label_very_slow" msgid="1867055264243608530">"ತುಂಬಾ ನಿಧಾನವಾಗಿದೆ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ನಿಧಾನ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ಸರಿ"</string>
@@ -234,8 +211,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"ಎಚ್ಚರವಾಗಿರು"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ಚಾರ್ಜ್ ಮಾಡುವಾಗ ಪರದೆಯು ಎಂದಿಗೂ ನಿದ್ರಾವಸ್ಥೆಗೆ ಹೋಗುವುದಿಲ್ಲ"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ಬ್ಲೂಟೂತ್ HCI ಸ್ನೂಪ್ ಲಾಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ಬ್ಲೂಟೂತ್ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ. (ಈ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಬದಲಾಯಿಸಿದ ನಂತರ ಬ್ಲೂಟೂತ್ ಟಾಗಲ್ ಮಾಡಿ)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"ಬೂಟ್ಲೋಡರ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ಅನುಮತಿಸಿ"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM ಅನ್ಲಾಕ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
@@ -246,7 +222,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ನೆಟ್ವರ್ಕಿಂಗ್"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ವೈರ್ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ವೆರ್ಬೋಸ್ ಲಾಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"MAC ಯಾದೃಚ್ಛಿಕರಣವನ್ನು ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"ಮೊಬೈಲ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ಹಾರ್ಡ್ವೇರ್ನ ವೇಗವರ್ಧನೆಯನ್ನು ಟೆಥರಿಂಗ್ ಮಾಡಿ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ಹೆಸರುಗಳಿಲ್ಲದ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ತೋರಿಸಿ"</string>
@@ -273,7 +248,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ವೈರ್ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ತೋರಿಸು"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ಲಾಗಿಂಗ್ ಮಟ್ಟನ್ನು ಹೆಚ್ಚಿಸಿ, Wi‑Fi ಆಯ್ಕೆಯಲ್ಲಿ ಪ್ರತಿಯೊಂದು SSID RSSI ತೋರಿಸಿ"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಸಂಪರ್ಕಿಸುವಾಗ MAC ವಿಳಾಸವನ್ನು ಯಾದೃಚ್ಛಿಕಗೊಳಿಸಿ"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"ಮೀಟರ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"ಮೀಟರ್ ಮಾಡಲಾಗಿಲ್ಲ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ಲಾಗರ್ ಬಫರ್ ಗಾತ್ರಗಳು"</string>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 7330843..e2d8e02 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRM 콘텐츠에 대해서만 HDCP 확인 사용"</item>
<item msgid="45075631231212732">"항상 HDCP 확인 사용"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"사용 중지됨"</item>
+ <item msgid="1969681323976948639">"필터링 사용 설정됨"</item>
+ <item msgid="8719029132154020716">"사용 설정됨"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4(기본)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f6409d9..d7e9488 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s을(를) 통해 자동으로 연결됨"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"네트워크 평가 제공업체를 통해 자동으로 연결됨"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s을(를) 통해 연결됨"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>의 <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g>을(를) 통해 연결됨"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s을(를) 통해 사용 가능"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"설정하려면 탭하세요."</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"탭하여 가입"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"연결됨, 인터넷 사용 불가"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"인터넷 연결 없음"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"로그인 필요"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"액세스 포인트가 일시적으로 가득 참"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s을(를) 통해 연결됨"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s을(를) 통해 사용 가능"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"연결에 실패했습니다."</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"잘못된 OSU 서버 URL입니다."</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU 서버 연결에 실패했습니다."</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU 서버 인증에 실패했습니다."</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"잘못된 OSU 서버 인증서입니다."</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"프로비저닝이 취소되었습니다."</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"프로비저닝을 사용할 수 없습니다."</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"잘못된 OSU 서버 URL입니다."</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"예상치 못한 명령어 유형입니다."</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"예상치 못한 SOAP 메시지 유형입니다."</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP 메시지 교환에 실패했습니다."</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"리스너 리디렉션을 시작하지 못했습니다."</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"리디렉션을 기다리는 중에 타임아웃되었습니다."</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU 활동이 없습니다."</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"예상치 못한 SOAP 메시지 상태입니다."</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO를 찾지 못했습니다."</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA 서버의 공인 루트 노드를 찾지 못했습니다."</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"복구 서버의 공인 루트 노드를 찾지 못했습니다."</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"정책 서버의 공인 루트 노드를 찾지 못했습니다."</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"공인 루트 인증서를 가져오지 못했습니다."</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA 서버의 공인 루트 인증서를 찾지 못했습니다."</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint 설정을 추가하지 못했습니다."</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU 제공업체를 찾지 못했습니다."</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"연결 중입니다."</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"연결되었습니다."</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU 서버에 연결하는 중입니다."</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU 서버가 인증되었습니다."</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU 서버에 연결되었습니다."</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"첫 SOAP 교환"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"리디렉션 응답을 기다리는 중입니다."</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"리디렉션 응답이 수신되었습니다."</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"2번째 SOAP 교환"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"3번째 SOAP 교환"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"공인 루트 인증서를 가져오는 중입니다."</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"프로비저닝이 완료되었습니다."</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> 여는 중"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"연결할 수 없음"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"가입 완료 중…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"가입을 완료할 수 없습니다. 다시 시도하려면 탭하세요."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"가입이 완료되었습니다. 연결 중…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"매우 느림"</string>
<string name="speed_label_slow" msgid="813109590815810235">"느림"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"보통"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"화면 켜짐 상태 유지"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"충전하는 동안 화면이 꺼지지 않음"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"블루투스 HCI 스누프 로그 사용"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"블루투스 패킷을 캡처합니다. (설정 변경 후 블루투스 전환)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM 잠금 해제"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"부트로더 잠금 해제 허용"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM 잠금 해제를 허용하시겠습니까?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"네트워크"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"무선 디스플레이 인증서"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi 상세 로깅 사용"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"연결된 MAC 임의 선택"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"항상 모바일 데이터 활성화"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"테더링 하드웨어 가속"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"이름이 없는 블루투스 기기 표시"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"연결할 수 없음"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"무선 디스플레이 인증서 옵션 표시"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi 로깅 수준을 높이고, Wi‑Fi 선택도구에서 SSID RSSI당 값을 표시"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi‑Fi 네트워크에 연결할 때 MAC 주소 임의 선택"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"종량제"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"무제한"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"로거 버퍼 크기"</string>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index da0248d..14eb110 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP текшерүү DRM мазмунуна гана колдонулат"</item>
<item msgid="45075631231212732">"Ар дайым HDCP текшерүү колдонулсун"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Өчүк"</item>
+ <item msgid="1969681323976948639">"Чыпкалар иштетилди"</item>
+ <item msgid="8719029132154020716">"Иштетилди"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Демейки)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index c30f96c..6898c61 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s аркылуу автоматтык түрдө туташты"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Тармактар рейтингинин автору аркылуу автоматтык түрдө туташты"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s аркылуу жеткиликтүү"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>, <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> аркылуу туташтырылган"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> аркылуу туташты"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Жөндөө үчүн таптаңыз"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Катталуу үчүн таптап коюңуз"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Туташып турат, Интернет жок"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Интернет жок"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Аккаунтка кирүү талап кылынат"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Байланыш түйүнүнө өтө көп түзмөк туташып турат"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s аркылуу туташты"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s аркылуу иштейт"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Туташпай койду"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU серверинин URL\'и жараксыз"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU серверине туташкан жок"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU сервери текшерилген жок"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU серверинин тастыктамасы жараксыз"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Камсыздоо жоюлду"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Камсыздоо жеткиликтүү эмес"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU серверинин URL\'и жараксыз"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Күтүлбөгөн буйрук түрү"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Күтүлбөгөн SOAP билдирүү түрү"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP билдирүүсү алмаштырылган жок"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Багыттоо тыңшагычы башталган жок"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Багыттоону күтүү мөөнөтү аяктады"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU аракети табылган жок"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Күтүлбөгөн SOAP билдирүү абалы"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO табылган жок"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA сервери үчүн ишеним негизги түйүнү табылган жок"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Оңдоо сервери үчүн ишеним негизги түйүнү табылган жок"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Саясат сервери үчүн ишеним негизги түйүнү табылган жок"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Ишеним негизги тастыктамалары алынган жок"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA сервери үчүн ишеним негизги тастыктамасы табылган жок"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint конфигурациясы кошулган жок"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU камсыздоочусу табылган жок"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Туташууда"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Туташты"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU серверине туташууда"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU сервери текшерилди"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU серверине туташты"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Баштапкы SOAP алмаштыруу"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Багыттоо жообу күтүлүүдө"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Багыттоо жообу кабыл алынды"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Экинчи SOAP алмаштыруу"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Үчүнчү SOAP алмаштыруу"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Ишеним негизги тастыктамалары алынууда"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Камсыздоо аягына чыкты"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ачылууда"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Туташпай койду"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Катталуу аяктоодо…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Катталуу аягына чыккан жок. Кайра аракет кылуу үчүн таптап коюңуз."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Катталуу аягына чыкты. Туташууда…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Өтө жай"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Жай"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Жарайт"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Ойгоо туруу"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Түзмөк кубатталып жатканда экран өчпөйт"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI журналын иштетүү"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth таңгактарын алуу. (Бул жөндөөнү өзгөрткөндөн кийин Bluetooth\'ду өчүрүп / күйгүзүңүз)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM бөгөттөн чыгаруу"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Кайра жүктөгүчтү бөгөттөн чыгарууга уруксат берүү"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM бөгөттөн чыгарууга уруксатпы?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Тармактар"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Зымсыз мониторлорду тастыктамалоо"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi дайын-даректүү журналы"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Wi-Fi аркылуу туташканда башаламан MAC даректерди түзүү"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилдик Интернет иштей берет"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Модем режиминде аппараттын иштешин тездетүү"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Аталышсыз Bluetooth түзмөктөрү көрсөтүлсүн"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Туташпай койду"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Зымсыз мониторлорду тастыктамалоо параметрлери көрүнүп турат"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi тандалганда ар бир SSID үчүн RSSI көрүнүп турат"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi‑Fi тармактарын туташканда MAC даректери башаламан түзүлүп турат"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Трафик ченелет"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Чектелбеген тармак"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Журнал буферинин өлчөмү"</string>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 7f56494..d41aa6d 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"ໃຊ້ການກວດສອບ HDCP ສຳລັບເນື້ອຫາ DRM ເທົ່ານັ້ນ"</item>
<item msgid="45075631231212732">"ໃຊ້ການກວດສອບ HDCP ສະເໝີ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"ປິດການນຳໃຊ້ແລ້ວ"</item>
+ <item msgid="1969681323976948639">"ເປີດການກັ່ນຕອງແລ້ວ"</item>
+ <item msgid="8719029132154020716">"ເປີດໃຊ້ແລ້ວ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index edb6b12..acbaf70 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"ເຊື່ອມຕໍ່ຜ່ານທາງ %1$s ໂດຍອັດຕະໂນມັດ"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ເຊື່ອມຕໍ່ກັບອັດຕະໂນມັດແລ້ວຜ່ານຜູ້ໃຫ້ບໍລິການຄະແນນເຄືອຂ່າຍ"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"ເຊື່ອມຕໍ່ຜ່ານ %1$s ແລ້ວ"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> ໂດຍ <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"ເຊື່ອມຕໍ່ຜ່ານ <xliff:g id="NAME">%1$s</xliff:g> ແລ້ວ"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"ມີໃຫ້ຜ່ານ %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"ແຕະເພື່ອຕັ້ງຄ່າ"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"ແຕະເພື່ອສະໝັກ"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"ເຊື່ອມຕໍ່ແລ້ວ, ບໍ່ມີອິນເຕີເນັດ"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ບໍ່ມີອິນເຕີເນັດ"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ຈຳເປັນຕ້ອງເຂົ້າສູ່ລະບົບ"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ຈຸດການເຂົ້າເຖິງເຕັມຊົ່ວຄາວ"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"ເຊື່ອມຕໍ່ຜ່ານ %1$s ແລ້ວ"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"ໃຊ້ໄດ້ຜ່ານ %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"ການເຊື່ອມຕໍ່ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL ເຊີບເວີ OSU ບໍ່ຖືກຕ້ອງ"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"ການເຊື່ອມຕໍ່ເຊີບເວີ OSU ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"ການກວດສອບເຊີບເວີ OSU ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"ໃບຮັບຮອງເຊີບເວີ OSU ບໍ່ຖືກຕ້ອງ"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ຍົກເລີກການຈັດຫາແລ້ວ"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"ບໍ່ສາມາດໃຊ້ການຈັດຫາໄດ້"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL ເຊີບເວີ OSU ບໍ່ຖືກຕ້ອງ"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ປະເພດຄຳສັ່ງທີ່ບໍ່ຄາດຄິດ"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ປະເພດຂໍ້ຄວາມ SOAP ທີ່ບໍ່ຄາດຄິດ"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"ການແລກປ່ຽນຂໍ້ຄວາມ SOAP ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"ເລີ່ມການປ່ຽນເສັ້ນທາງຕົວຟັງບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"ໝົດເວລາລໍຖ້າການປ່ຽນເສັ້ນທາງແລ້ວ"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"ບໍ່ພົບການເຄື່ອນໄຫວ OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"ສະຖານະຂໍ້ຄວາມ SOAP ທີ່ບໍ່ຄາດຄິດ"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"ຊອກຫາ PPS-MO ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"ຊອກຫາ root node ທີ່ເຊື່ອຖືໄດ້ສຳລັບເຊີບເວີ AAA ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ຊອກຫາ root node ທີ່ເຊື່ອຖືໄດ້ສຳລັບເຊີບເວີການແກ້ໄຂບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"ຊອກຫາ root node ທີ່ເຊື່ອຖືໄດ້ສຳລັບເຊີບເວີນະໂຍບາຍບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"ໂຫຼດໃບຮັບຮອງ root ທີ່ເຊື່ອຖືໄດ້ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"ຊອກຫາໃບຮັບຮອງ root ທີ່ເຊື່ອຖືໄດ້ສຳລັບເຊີບເວີ AAA ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"ເພີ່ມການຕັ້ງຄ່າ PassPoint ບໍ່ສຳເລັດ"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"ຊອກຫາຜູ້ໃຫ້ບໍລິການ OSU ບໍ່ສຳເລັດ"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"ກຳລັງເຊື່ອມຕໍ່"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"ເຊື່ອມຕໍ່ແລ້ວ"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"ກຳລັງເຊື່ອມຕໍ່ຫາເຊີບເວີ OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"ກວດສອບເຊີບເວີ OSU ແລ້ວ"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"ເຊື່ອມຕໍ່ຫາເຊີບເວີ OSU ແລ້ວ"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"ການແລກປ່ຽນ SOAP ເບື້ອງຕົ້ນ"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"ກຳລັງລໍຖ້າການຕອບກັບປ່ຽນເສັ້ນທາງ"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"ໄດັຮັບການຕອບກັບປ່ຽນເສັ້ນທາງແລ້ວ"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"ການແລກປ່ຽນ SOAP ທີສອງ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"ການແລກປ່ຽນ SOAP ທີສາມ"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"ກຳລັງໂຫຼດໃບຮັບຮອງ root ທີ່ເຊື່ອຖືໄດ້"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ການຈັດຫາສຳເລັດແລ້ວ"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"ກຳລັງເປີດ <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"ກຳລັງສຳເລັດການສະໝັກ…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"ບໍ່ສາມາດສຳເລັດການສະໝັກໄດ້. ແຕະເພື່ອລອງໃໝ່."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"ສະໝັກສຳເລັດແລ້ວ. ກຳລັງເຊື່ອມຕໍ່…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ຊ້າຫຼາຍ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ຊ້າ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ຕົກລົງ"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"ເປີດໜ້າຈໍຕະຫຼອດ"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ໜ້າຈໍຈະບໍ່ປິດໃນຂະນະທີ່ສາກໄຟຢູ່"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ບັນທຶກການເຮັດວຽກຂອງ Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ບັນທຶກແພັກເກັດ Bluetooth. (ເປີດ/ປິດ Bluetooth ຫຼັງຈາກປ່ຽນການຕັ້ງຄ່ານີ້)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"ການປົດລັອກ OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"ອະນຸຍາດໃຫ້ປົດລັອກບູດໂຫຼດເດີ"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"ອະນຸຍາດການປົກລັອກ OEM ບໍ?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ການສ້າງເຄືອຂ່າຍ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ສະແດງການຮັບຮອງຂອງລະບົບໄຮ້ສາຍ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"ເປີດນຳໃຊ້ການເກັບປະຫວັດ Verbose Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"ເຊື່ອມຕໍ່ການສຸ່ມ MAC ແລ້ວ"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"ເປີດໃຊ້ອິນເຕີເນັດມືຖືຕະຫຼອດເວລາ"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ເປີດໃຊ້ການເລັ່ງຄວາມໄວດ້ວຍຮາດແວ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ສະແດງອຸປະກອນ Bluetooth ທີ່ບໍ່ມີຊື່"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ສະແດງໂຕເລືອກສຳລັບການສະແດງການຮັບຮອງລະບົບໄຮ້ສາຍ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ເພີ່ມລະດັບການເກັບປະຫວັດ Wi‑Fi, ສະແດງຕໍ່ SSID RSSI ໃນ Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ສຸ່ມທີ່ຢູ່ MAC ເມື່ອເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"ມີການວັດແທກ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"ບໍ່ໄດ້ວັດແທກ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ຂະໜາດບັບເຟີຕົວບັນທຶກ"</string>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index b78988a..af9df3e 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Taikyti HDCP tikrinimą tik DRM turiniui"</item>
<item msgid="45075631231212732">"Visada naudoti HDCP tikrinimą"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Išjungta"</item>
+ <item msgid="1969681323976948639">"Įgalinta filtruota"</item>
+ <item msgid="8719029132154020716">"Įgalinta"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (numatytoji)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 0938463..8933451 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiškai prisijungta naudojant „%1$s“"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatiškai prisijungta naudojant tinklo įvertinimo paslaugos teikėjo paslaugomis"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Prisijungta naudojant „%1$s“"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>, <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Prisijungta naudojant programą „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Pasiekiama naudojant „%1$s“"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Palieskite, kad nustatytumėte"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Palieskite, kad prisiregistruotumėte"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Prisijungta, nėra interneto"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nėra interneto ryšio"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Reikia prisijungti"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Prieigos taškas laikinai visiškai užimtas"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Prisijungta naudojant „%1$s“"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Pasiekiama naudojant „%1$s“"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Nepavyko užmegzti ryšio"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Netinkamas OSU serverio URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Nepavyko užmegzti OSU serverio ryšio"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Nepavyko patvirtinti OSU serverio"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Netinkamas OSU serverio sertifikatas"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Aprūpinimas nutrauktas"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Negalima aprūpinti"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Netinkamas OSU serverio URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Nenumatytas komandos tipas"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Nenumatytas SOAP pranešimo tipas"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Nepavyko atlikti SOAP pranešimo mainų operacijos"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Nepavyko paleisti peradresavimo apdorojimo priemonės"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Laukiant peradresavimo baigėsi skirtasis laikas"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nerasta OSU veiklos duomenų"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Nenumatyta SOAP pranešimo būsena"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Nepavyko rasti PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Nepavyko rasti patikimo AAA serverio šakninio mazgo"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Nepavyko rasti patikimo problemų sprendimo serverio šakninio mazgo"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Nepavyko rasti patikimo politikos serverio šakninio mazgo"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Nepavyko gauti patikimų šakninių sertifikatų"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Nepavyko rasti patikimo AAA serverio šakninio sertifikato"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Nepavyko pridėti „PassPoint“ konfigūracijos"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Nepavyko rasti OSU teikėjo"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Sujungiama"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Sujungta"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Prisijungiama prie OSU serverio"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU serveris patvirtintas"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Prisijungta prie OSU serverio"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Pradinė SOAP mainų operacija"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Laukiama tiesioginio atsakymo"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Gautas tiesioginis atsakymas"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Antroji SOAP mainų operacija"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Trečioji SOAP mainų operacija"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Gaunami patikimi šakniniai sertifikatai"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Aprūpinta"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Atidaroma: „<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>“"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Nepavyko prisijungti"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Baigiamas prisiregistravimas…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Nepavyko užbaigti prisiregistravimo. Jei norite bandyti dar kartą, palieskite."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Prisiregistravimas baigtas. Prijungiama…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Labai lėtas"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lėtas"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Gerai"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Veikti"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Kraunant ekranas niekada neveiks miego režimu"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Įgalinti „Bluetooth“ HCI šnipinėjimo žurnalą"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Fiksuoti „Bluetooth“ paketus. (Perjungti „Bluetooth“ pakeitus šį nustatymą)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OĮG atrakinimas"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Leisti atrakinti oper. sistemos paleidimo progr."</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Leisti OĮG atrakinimą?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Tinklai"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Belaidžio rodymo sertifikavimas"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Įgal. „Wi‑Fi“ daugiaž. įraš. į žurnalą"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Atsitiktinis MAC adreso parinkimas prisijungiant"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiliojo ryšio duomenys visada suaktyvinti"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Įrenginio kaip modemo naudojimo aparatinės įrangos spartinimas"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Rodyti „Bluetooth“ įrenginius be pavadinimų"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Prisijungti nepavyko"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rodyti belaidžio rodymo sertifikavimo parinktis"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Padidinti „Wi‑Fi“ įrašymo į žurnalą lygį, rodyti SSID RSSI „Wi-Fi“ rinkiklyje"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Atsitiktinai parinkti MAC adresą prisijungiant prie „Wi‑Fi“ tinklų"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Matuojamas"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Neišmatuotas"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Registruotuvo buferio dydžiai"</string>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 3812c20..cadb764 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Izmantot HDCP pārbaudi tikai DRM saturam"</item>
<item msgid="45075631231212732">"Vienmēr izmantot HDCP pārbaudi"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Atspējots"</item>
+ <item msgid="1969681323976948639">"Iespējot filtrētos"</item>
+ <item msgid="8719029132154020716">"Iespējots"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (noklusējuma)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 84d42c2..ac41ae0 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automātiski savienots, izmantojot %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automātiski izveidots savienojums, izmantojot tīkla vērtējuma sniedzēju"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Savienots, izmantojot %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> — <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Savienojums ar <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Pieejams, izmantojot %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Pieskarieties, lai iestatītu"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Pieskarieties, lai reģistrētos"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Savienojums izveidots, nav piekļuves internetam"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nav piekļuves internetam"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Nepieciešama pierakstīšanās"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Piekļuves punkts īslaicīgi ir pilns"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Savienojums izveidots, izmantojot %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Pieejams, izmantojot %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Neizdevās izveidot savienojumu"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Nederīgs OSU servera URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Neizdevās izveidot savienojumu ar OSU serveri"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Neizdevās apstiprināt OSU serveri"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Nederīgs OSU servera sertifikāts"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Nodrošinājums priekšlaikus pārtraukts"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Nodrošinājums nav pieejams"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Nederīgs OSU servera URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Neparedzēts komandas veids"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Neparedzēts SOAP ziņojuma veids"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP ziņojumu apmaiņa neizdevās"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Neizdevās palaist novirzīšanas uztvērēju"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Gaidot novirzīšanu, iestājās noildze"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Netika konstatēta OSU aktivitāte"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Neparedzēts SOAP ziņojuma statuss"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Neizdevās atrast PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Neizdevās atrast uzticamu saknes mezglu AAA serverim"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Neizdevās atrast uzticamu saknes mezglu koriģēšanas serverim"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Neizdevās atrast uzticamu saknes mezglu noteikumu serverim"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Neizdevās izgūt uzticamus saknes sertifikātus"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Neizdevās atrast uzticamu saknes sertifikātu AAA serverim"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Neizdevās pievienot PassPoint konfigurāciju"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Neizdevās atrast OSU nodrošinātāju"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Notiek savienojuma izveide"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Savienojums izveidots"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Notiek savienojuma izveide ar OSU serveri"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU serveris apstiprināts"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Izveidots savienojums ar OSU serveri"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Sākotnējā SOAP apmaiņa"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Tiek gaidīta novirzīšanas atbilde"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Saņemta novirzīšanas atbilde"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Otrā SOAP apmaiņa"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Trešā SOAP apmaiņa"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Notiek uzticamu saknes sertifikātu izgūšana"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Nodrošinājums pabeigts"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Notiek lietotnes <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> atvēršana."</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Nevarēja izveidot savienojumu"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Notiek reģistrācijas pabeigšana…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Nevarēja pabeigt reģistrāciju. Pieskarieties, lai mēģinātu vēlreiz."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Reģistrācija ir pabeigta. Notiek savienojuma izveide…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Ļoti lēns"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lēns"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Labi"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Atstāt nomodā"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Uzlādes laikā ekrāns nekad nepārslēgsies miega režīmā"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Iespējot Bluetooth HCI analizētāja žurnālu"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Tvert Bluetooth paketes. (Pārslēgt Bluetooth pēc šī iestatījuma mainīšanas.)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM atbloķēšana"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Atļaut palaišanas ielādētāja atbloķēšanu"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Vai atļaut OEM atbloķēšanu?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Tīklošana"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Bezvadu attēlošanas sertifikācija"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Iespējot Wi‑Fi detalizēto reģistrēšanu"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Nejaušu MAC adrešu izveide savienojuma laikā"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Vienmēr aktīvs mobilo datu savienojums"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Paātrināta aparatūras darbība piesaistei"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Rādīt Bluetooth ierīces bez nosaukumiem"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nevarēja izveidot savienojumu."</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rādīt bezvadu attēlošanas sertifikācijas iespējas"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Palieliniet Wi‑Fi reģistrēšanas līmeni; rādīt katram SSID RSSI Wi‑Fi atlasītājā."</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Izveidot nejaušas MAC adreses, izveidojot savienojumu ar Wi‑Fi tīkliem"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Maksas"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Bezmaksas"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Reģistrētāja buferu lielumi"</string>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 797e017..22ff506 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Користи HDCP проверка само за DRM содржина"</item>
<item msgid="45075631231212732">"Секогаш користи HDCP проверка"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Оневозможено"</item>
+ <item msgid="1969681323976948639">"Овозможено е филтрирано"</item>
+ <item msgid="8719029132154020716">"Овозможено"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Стандардно)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 9fca9c1c..5b45977 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматски поврзано преку %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Автоматски поврзано преку оператор за оценување мрежа"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Поврзано преку %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> од <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Поврзано преку <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Достапно преку %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Допрете за поставување"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Допрете за да се регистрирате"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Поврзана, нема интернет"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Нема интернет"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Потребно е најавување"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Пристапната точка привремено е преоптоварена"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Поврзано преку %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Достапно преку %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Поврзувањето беше неуспешно"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Неважечка URL-адреса на OSU-серверот"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Неуспешно поврзување со OSU-серверот"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Неуспешна проверка на OSU-серверот"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Неважечки сертификат на OSU-серверот"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Доделувањето е прекинато"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Доделувањето не е достапно"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Неважечка URL-адреса на OSU-серверот"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Неочекуван тип наредба"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Неочекуван тип SOAP-порака"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Неуспешна размена на SOAP-пораката"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Пренасочувањето на слушателот не успеа да се стартува"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Истечено чекање за пренасочување"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Не е најдена OSU-активност"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Неочекуван статус на SOAP-пораката"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Не успеа да се најде PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Не успеа да се најде доверлив јазол со администраторски права за серверот за AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Не успеа да се најде доверлив јазол со администраторски права за серверот за санација"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Не успеа да се најде доверлив јазол со администраторски права за серверот на правилото"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Не успеаја да се преземат доверливи сертификати за администраторски права"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Не успеа да се најде доверлив сертификат со администраторски права за серверот за AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Не успеа да се додаде конфигурација за PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Не успеа да се најде давател на OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Се поврзува"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Поврзано"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Се поврзува со OSU-серверот"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-серверот е потврден"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Поврзано со OSU-сервер"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Првична размена на SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Се чека одговор за пренасочување"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Примен е одговор за пренасочување"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Втора размена на SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Трета размена на SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Се преземаат доверливи сертификати за администраторски права"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Доделувањето е завршено"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Се отвора <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Не можеше да се поврзе"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Се завршува регистрацијата…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Не можеше да се заврши регистрацијата. Допрете за да се обидете повторно."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Регистрацијата е завршена. Се поврзува…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Многу бавна"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Бавна"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Во ред"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Остани во активен режим"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Екранот никогаш нема да биде во режим на штедење додека се полни"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Овозможи Bluetooth HCI за евиденција на пресретнување пакети"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Снимај Bluetooth-пакети. (Вклучи Bluetooth по промената на поставкава)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Отклучување со OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Дозволи да се отклучи подигнувачот"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Дозволете отклучување со OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Вмрежување"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Приказ на сертификација на безжична мрежа"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Овозможи преопширно пријавување Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Поврзана MAC-рандомизација"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилниот интернет е секогаш активен"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско забрзување за врзување"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Прикажувај уреди со Bluetooth без имиња"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не може да се поврзе"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Покажи ги опциите за безжичен приказ на сертификат"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Зголеми Wi‑Fi ниво на пријавување, прикажи по SSID RSSI во Wi‑Fi бирач"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Користи MAC-адреса по случаен избор при поврзување на Wi‑Fi мрежи"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Со ограничен интернет"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Без ограничен интернет"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Величини на меѓумеморија за дневникот"</string>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index f977ad2..6444b30 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRM ഉള്ളടക്കത്തിനുമാത്രമായി HDCP പരിശോധന ഉപയോഗിക്കുക"</item>
<item msgid="45075631231212732">"എല്ലായ്പ്പോഴും HDCP പരിശോധന ഉപയോഗിക്കുക"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"പ്രവർത്തനരഹിതമാക്കി"</item>
+ <item msgid="1969681323976948639">"ഫിൽട്ടറിംഗ് പ്രവർത്തനക്ഷമമാക്കി"</item>
+ <item msgid="8719029132154020716">"പ്രവർത്തനക്ഷമമാക്കി"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ഡിഫോൾട്ട്)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index cda04cc..efe6cd6 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s വഴി സ്വയമേവ ബന്ധിപ്പിച്ചു"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"നെറ്റ്വർക്ക് റേറ്റിംഗ് ദാതാവുമായി സ്വയം കണക്റ്റുചെയ്തു"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> നല്കുന്ന <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> മുഖേന കണക്റ്റ് ചെയ്തു"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s വഴി ലഭ്യം"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"സജ്ജീകരിക്കാന് ടാപ്പ് ചെയ്യുക"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"സൈൻ അപ്പ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"കണക്റ്റ് ചെയ്തു, ഇന്റർനെറ്റ് ഇല്ല"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ഇന്റർനെറ്റ് ഇല്ല"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"സൈൻ ഇൻ ചെയ്യേണ്ടത് ആവശ്യമാണ്"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ആക്സസ് പോയിന്റ് താൽക്കാലികമായി നിറഞ്ഞിരിക്കുന്നു"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s വഴി ബന്ധിപ്പിച്ചു"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s വഴി ലഭ്യം"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"കണക്ഷന് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"അസാധുവായ OSU സെര്വര് URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU സെര്വര് കണക്ഷന് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU സെര്വര് മൂല്യനിര്ണ്ണയം പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"അസാധുവായ OSU സെര്വര് സര്ട്ടിഫിക്കറ്റ്"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"പ്രൊവിഷനിംഗ് റദ്ദാക്കി"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"പ്രൊവിഷനിംഗ് ലഭ്യമല്ല"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"അസാധുവായ OSU സെര്വര് URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"അപ്രതീക്ഷിത കമാന്ഡ് തരം"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"അപ്രതീക്ഷിത SOAP സന്ദേശ തരം"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP സന്ദേശ എക്സ്ചേഞ്ച് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"റീഡയറക്റ്റ് ചെയ്ത ശ്രോതാവ് ആരംഭിക്കുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"കാലഹരണപ്പെടല്, റീഡയറക്റ്റിനായി കാത്തിരിക്കുന്നു"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU ആക്റ്റിവിറ്റിയൊന്നും കണ്ടെത്തിയില്ല"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"അപ്രതീക്ഷിത SOAP സന്ദേശ നില"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO കണ്ടെത്തുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA സെര്വറിനായുള്ള വിശ്വസനീയ റൂട്ട് നോഡ് കണ്ടെത്തുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"പരിഹാര സെര്വറിനുള്ള വിശ്വസനീയ റൂട്ട് നോഡ് കണ്ടെത്തുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"നയ സെര്വറുകള്ക്കായുള്ള വിശ്വസനീയ റൂട്ട് നോഡ് കണ്ടെത്തുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"വിശ്വസനീയ റൂട്ട് സര്ട്ടിഫിക്കറ്റുകള് വീണ്ടെടുക്കുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA സെര്വറിനുള്ള വിശ്വസനീയ റൂട്ട് സര്ട്ടിഫിക്കറ്റ് കണ്ടെത്തുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint കോണ്ഫിഗറേഷന് ചേര്ക്കുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU പ്രൊവൈഡര് കണ്ടെത്തുന്നതില് പരാജയപ്പെട്ടു"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"കണക്റ്റ് ചെയ്യുന്നു"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"കണക്റ്റ് ചെയ്തു"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU സെര്വറിലേക്ക് കണക്റ്റ് ചെയ്യുന്നു"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU സെര്വര് സാധൂകരിച്ചു"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU സെര്വറിലേക്ക് കണക്റ്റ് ചെയ്തു"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"പ്രാരംഭ SOAP എക്സ്ചേഞ്ച്"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"റീഡയറക്റ്റ് ചെയ്യുന്ന പ്രതികരണത്തിനായി കാത്തിരിക്കുന്നു"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"റീഡയറക്റ്റ് ചെയ്ത പ്രതികരണം ലഭിച്ചു"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"രണ്ടാമത്തെ SOAP എക്സ്ചേഞ്ച്"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"മൂന്നാമത്തെ SOAP എക്സ്ചേഞ്ച്"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"വിശ്വസനീയ റൂട്ട് സര്ട്ടിഫിക്കറ്റുകള് വീണ്ടെടുക്കുന്നു"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"പ്രൊവിഷനിംഗ് പൂര്ത്തിയായി"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> തുറക്കുന്നു"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"കണക്റ്റ് ചെയ്യാനായില്ല"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"സൈൻ അപ്പ് പൂർത്തിയാക്കുന്നു…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"സൈൻ അപ്പ് പൂർത്തിയാക്കാനായില്ല. വീണ്ടും ശ്രമിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"സൈൻ അപ്പ് പൂർത്തിയായി. കണക്റ്റ് ചെയ്യുന്നു…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"വളരെ കുറഞ്ഞ വേഗത്തിൽ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"കുറഞ്ഞ വേഗത്തിൽ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ശരി"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"സജീവമായി തുടരുക"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ചാർജ്ജ് ചെയ്യുമ്പോൾ സ്ക്രീൻ ഒരിക്കലും ഉറങ്ങില്ല"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ബ്ലൂടൂത്ത് HCI സ്നൂപ്പ് ലോഗ് സജീവമാക്കൂ"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth പായ്ക്കറ്റുകൾ ക്യാപ്ചർ ചെയ്യുക. (ഈ ക്രമീകരണം മാറ്റിയ ശേഷം Bluetooth മാറ്റുക)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM അൺലോക്കുചെയ്യൽ"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"അൺലോക്കാകാൻ ബൂട്ട്ലോഡറിനെ അനുവദിക്കുക"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM അൺലോക്കുചെയ്യൽ അനുവദിക്കണോ?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"നെറ്റ്വര്ക്കിംഗ്"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"വയർലെസ് ഡിസ്പ്ലേ സർട്ടിഫിക്കേഷൻ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"വൈഫൈ വെർബോസ് ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"കണക്റ്റ് ചെയ്ത MAC ക്രമരഹിതമാക്കൽ"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"മൊബൈൽ ഡാറ്റ എല്ലായ്പ്പോഴും സജീവം"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ടെതറിംഗ് ഹാർഡ്വെയർ ത്വരിതപ്പെടുത്തൽ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"പേരില്ലാത്ത Bluetooth ഉപകരണങ്ങൾ കാണിക്കുക"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"കണക്റ്റ് ചെയ്യാനായില്ല"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"വയർലെസ് ഡിസ്പ്ലേ സർട്ടിഫിക്കേഷനായി ഓപ്ഷനുകൾ ദൃശ്യമാക്കുക"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"വൈഫൈ പിക്കറിൽ ഓരോ SSID RSSI പ്രകാരം കാണിക്കാൻ വൈഫൈ ലോഗിംഗ് നില വർദ്ധിപ്പിക്കുക"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"വൈഫൈ നെറ്റ്വർക്കുകളിലേക്ക് കണക്റ്റ് ചെയ്യുമ്പോൾ MAC വിലാസം ക്രമരഹിതമാക്കുക"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"മീറ്റർചെയ്ത"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"മീറ്റർമാപകമല്ലാത്തത്"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ലോഗർ ബഫർ വലുപ്പം"</string>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index 4ed99c6..35a54d2d 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP шалгахыг зөвхөн DRM контентэд ашиглах"</item>
<item msgid="45075631231212732">"Байнга HDCP шалгахыг ашиглах"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Идэвхгүй болгосон"</item>
+ <item msgid="1969681323976948639">"Идэвхжүүлсэн Шүүсэн"</item>
+ <item msgid="8719029132154020716">"Идэвхжүүлсэн"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Өгөгдмөл)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 46415e2..9c3db2e 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s-р автоматаар холбогдсон"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Сүлжээний үнэлгээ үзүүлэгчээр автоматаар холбогдох"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-р холбогдсон"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>-н <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g>-р холбогдсон"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s-р боломжтой"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Тохируулахын тулд товшино уу"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Бүртгүүлэхийн тулд товшино уу"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Холбогдсон хэдий ч интернет алга"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Интернэт алга"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Нэвтрэх шаардлагатай"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Хандах цэг түр хугацаанд дүүрсэн байна"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s-р холбогдсон"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s-р боломжтой"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Холбогдож чадсангүй"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU серверийн URL хүчингүй байна"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU серверт холбогдож чадсангүй"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU серверийг бататгаж чадсангүй"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU серверийн гэрчилгээ хүчингүй байна"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Хангамжийг тасаллаа"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Хангамж боломжгүй байна"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU серверийн URL хүчингүй байна"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Тушаалын тооцоолоогүй төрөл байна"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"SOAP мессежийн тооцоолоогүй төрөл байна"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP мессежийг солилцож чадсангүй"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Дахин чиглүүлэх сонсогчийг эхлүүлж чадсангүй"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Завсарлагыг дахин чиглүүлэхээр хүлээж байна"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU үйл ажиллагаа олдсонгүй"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP мессежийн тооцоолоогүй төлөв байна"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO-г олж чадсангүй"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA серверийн итгэмжлэлийн үндсэн зангилаа цэгийг олж чадсангүй"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Сайжруулалтын серверийн итгэмжлэлийн үндсэн зангилаа цэгийг олж чадсангүй"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Удирдамжийн серверийн итгэмжлэлийн үндсэн зангилааны цэгийг олж чадсангүй"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Итгэмжлэлийн үндсэн гэрчилгээг сэргээж чадсангүй"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA серверийн итгэмжлэлийн үндсэн гэрчилгээг олж чадсангүй"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint-н тохируулгыг нэмж чадсангүй"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU нийлүүлэгчийг олж чадсангүй"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Холбогдож байна"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Холбогдсон"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU серверт холбогдож байна"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU серверийг баталлаа"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU серверт холбогдлоо"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"SOAP-г анх удаа солилцож байна"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Дахин чиглүүлэх хариу үйлдлийг хүлээж байна"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Дахин чиглүүлэх хариу үйлдлийг хүлээн авлаа"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"SOAP-г хоёр дахь удаагаа солилцож байна"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"SOAP-г гурав дахь удаагаа солилцож байна"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Итгэмжлэлийн үндсэн гэрчилгээг сэргээж байна"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Хангаж дууслаа"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>-г нээж байна"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Холбогдож чадсангүй"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Бүртгүүлэлтийг дуусгаж байна…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Бүртгүүлэлтийг дуусгаж чадсангүй. Дахин оролдохын тулд товшино уу."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Бүртгүүлж дууслаа. Холбогдож байна…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Маш удаан"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Удаан"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ЗА"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Идэвхтэй байлгах"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Цэнэглэж байх үед дэлгэц хэзээ ч амрахгүй"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI снүүп логыг идэвхжүүлэх"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth-н багцыг авна уу. (Энэ тохиргоог өөрчилсний дараа Bluetooth-г унтрааж/асаана уу)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM түгжээ тайлагч"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Bootloader-н түгжээг тайлахыг зөвшөөрөх"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM түгжээ тайлагчийг зөвшөөрөх үү?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Сүлжээ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Утасгүй дэлгэцийн сертификат"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi дэлгэрэнгүй лог-г идэвхжүүлэх"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Холбогдсон дурын MAC хаяг үүсгэлт (Randomization)"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Мобайл дата байнга идэвхтэй"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Модем болгох хардвер хурдасгуур"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Нэргүй Bluetooth төхөөрөмжийг харуулах"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Холбогдож чадсангүй"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Утасгүй дэлгэцийн сертификатын сонголтыг харуулах"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi лог-н түвшинг нэмэгдүүлэх, Wi‑Fi Сонгогч дээрх SSID-д ногдох RSSI-г харуулах"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi‑Fi сүлжээнд холбогдох үедээ шинэ дурын (random) MAC хаяг үүсгэх"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Хязгаартай"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Хязгааргүй"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Логгерын буферын хэмжээ"</string>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 9fc6970..d8652bf 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"केवळ DRM सामग्रीसाठी HDCP तपासणी वापरा"</item>
<item msgid="45075631231212732">"नेहमी HDCP तपासणी वापरा"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"बंद आहे"</item>
+ <item msgid="1969681323976948639">"फिल्टर केलेले सुरू केले"</item>
+ <item msgid="8719029132154020716">"सुरू केले"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (डीफॉल्ट)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 47757e4..a792c4f 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s द्वारे स्वयंचलितपणे कनेक्ट केले"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदात्याद्वारे स्वयंचलितपणे कनेक्ट केले"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s द्वारे कनेक्ट केले"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> चे <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे कनेक्ट केले"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s द्वारे उपलब्ध"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"सेट करण्यासाठी टॅप करा"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"साइन अप करण्यासाठी टॅप करा"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"कनेक्ट केले, इंटरनेट नाही"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"इंटरनेट नाही"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन करणे आवश्यक आहे"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"अॅक्सेस पॉइंट तात्पुरते भरलेले"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ने कनेक्ट केले"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s ने उपलब्ध"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"कनेक्शन झाले नाही"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"चुकीचे OSU सर्व्हर URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU सर्व्हर कनेक्शन करता आले नाही"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU सर्व्हर पडताळणी करता आली नाही"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"चुकीचे OSU सर्व्हर सर्टिफिकेट"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"तरतूद निरस्त केली"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"तरतूद उपलब्ध नाही"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"चुकीचे OSU सर्व्हर URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"अनपेक्षित कमांड प्रकार"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"अनपेक्षित SOAP संदेश प्रकार"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP मेसेज एक्सचेंज करता आले नाही"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"रीडिरेक्ट श्रोता सुरू करता आले नाही"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"रीडिरेक्टसाठी पाहाण्याची वेळ संपली"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"कोणतीही OSU अॅक्टिव्हिटी आढळली नाही"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"अनपेक्षित SOAP मेसेज स्थिती"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO शोधता आले नाही"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA सर्व्हरसाठी विश्वासू रूट नोड शोधता आले नाही"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"उपाय सर्व्हरसाठी विश्वासू रूट नोड शोधता आले नाही"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"धोरण सर्व्हरसाठी विश्वासू रूट नोड शोधता आले नाही"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"विश्वासू रूट सर्टिफिकेट परत मिळवता आली नाहीत"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA सर्व्हरसाठी विश्वासू रूट सर्टिफिकेट शोधता आले नाही"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint कॉन्फिगरेशन जोडता आले नाही"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU पुरवठादार शोधता आला नाही"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"कनेक्ट करत आहे"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"कनेक्ट केले"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU शी कनेक्ट करत आहे"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU सर्व्हर पडताळण्यात आले"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU सर्व्हरशी कनेक्ट केले"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"सुरुवातीचे SOAP एक्सचेंज"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"रीडिरेक्ट प्रतिसादासाठी वाट पाहत आहे"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"रीडिरेक्ट प्रतिसाद मिळाला"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"द्वितीय SOAP एक्सचेंज"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"तृतीय SOAP एक्सचेंज"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"विश्वासू रूट सर्टिफिकेट परत मिळवत आहे"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"तरतूद पूर्ण झाली"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> उघडत आहे"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"कनेक्ट करता आले नाही"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"साइन अप पूर्ण होत आहे…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"साइन अप पूर्ण करता आले नाही. पुन्हा प्रयत्न करण्यासाठी टॅप करा."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"साइन अप पूर्ण झाले. कनेक्ट करत आहे…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"खूप हळू"</string>
<string name="speed_label_slow" msgid="813109590815810235">"हळू"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ठीक आहे"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"सक्रिय रहा"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"चार्ज होत असताना स्क्रीन कधीही निष्क्रिय होणार नाही"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ब्लूटूथ HCI स्नूप लॉग सुरू करा"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ब्लूटूथ पॅकेट कॅप्चर करा (हे सेटिंग बदलल्यानंतर ब्ल्यूटूथ टॉगल करा)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM अनलॉक करणे"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"बूटलोडर अनलॉक करण्यासाठी अनुमती द्या"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM अनलॉक करण्यास अनुमती द्यायची?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस डिस्प्ले प्रमाणीकरण"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"वाय-फाय व्हर्बोझ लॉगिंग सुरू करा"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"कनेक्ट केलेले MAC Randomization"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा नेहमी सक्रिय"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिंग हार्डवेअर प्रवेग"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"नावांशिवाय ब्लूटूथ डिव्हाइस दाखवा"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"कनेक्ट करू शकलो नाही"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस डिस्प्ले प्रमाणिकरणाचे पर्याय दाखवा"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्तर वाढवा, वाय-फाय सिलेक्टरमध्ये प्रति SSID RSSI दर्शवा"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"वाय-फाय नेटवर्कशी कनेक्ट करताना MAC अॅड्रेस रँडमाइझ करा"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"मीटरने मोजलेले"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"मीटरने न मोजलेले"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफर आकार"</string>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index 3ecd792..14729df 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Gunakan penyemakan HDCP untuk kandungan DRM sahaja"</item>
<item msgid="45075631231212732">"Sentiasa gunakan penyemakan HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Dilumpuhkan"</item>
+ <item msgid="1969681323976948639">"Didayakan Ditapis"</item>
+ <item msgid="8719029132154020716">"Didayakan"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Lalai)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 12e463c..419c6ec 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Disambungkan secara automatik melalui %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Disambungkan secara automatik melalui pembekal penilaian rangkaian"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Disambungkan melalui %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> oleh <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Disambungkan melalui <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Ketik untuk menyediakan"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Ketik untuk daftar"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Disambungkan, tiada Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Tiada Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Log masuk diperlukan"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Titik akses penuh buat sementara waktu"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Disambungkan melalui %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Tersedia melalui %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Sambungan gagal"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL pelayan OSU tidak sah"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Sambungan pelayan OSU gagal"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Pengesahan pelayan OSU gagal"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Sijil pelayan OSU tidak sah"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Peruntukan dihenti paksa"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Peruntukan tidak tersedia"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL pelayan OSU tidak sah"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Jenis perintah tidak dijangka"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Jenis mesej SOAP tidak dijangka"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Pertukaran mesej SOAP gagal"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Ubah hala pendengar gagal dimulakan"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Tamat masa menunggu ubah hala"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Tiada aktiviti OSU yang ditemukan"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Status mesej SOAP tidak dijangka"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Gagal menemukan PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Gagal menemukan nod akar amanah untuk pelayan AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Gagal menemukan nod akar amanah untuk pelayan pemulihan"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Gagal menemukan nod akar amanah untuk pelayan dasar"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Gagal mengambil sijil akar amanah"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Gagal menemukan sijil akar amanah untuk pelayan AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Gagal menambah konfigurasi PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Gagal menemukan pembekal OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Menyambung"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Disambungkan"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Menyambung ke pelayan OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Pelayan OSU disahkan"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Disambungkan ke pelayan OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Pertukaran SOAP permulaan"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Menunggu respons ubah hala"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Menerima respons ubah hala"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Pertukaran SOAP kedua"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Pertukaran SOAP ketiga"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Mengambil sijil akar amanah"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Peruntukan selesai"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Membuka <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Tidak dapat menyambung"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Menyelesaikan pendaftaran…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Tidak dapat menyelesaikan pendaftaran. Ketik untuk mencuba lagi."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Pendaftaran selesai. Menyambung…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Perlahan"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Perlahan"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Tetap berjaga"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Skrin tidak sekali-kali akan tidur semasa pengecasan"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Dayakan log intip HCI Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Tangkap paket Bluetooth. (Togol Bluetooth selepas menukar tetapan ini)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Pembukaan kunci OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Benarkan pemuat but untuk dibuka kunci"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Benarkan pembukaan kunci OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Perangkaian"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Pensijilan paparan wayarles"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Dayakan Pengelogan Berjela-jela Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Perawakan MAC Tersambung"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Data mudah alih sentiasa aktif"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Pecutan perkakasan penambatan"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Tunjukkan peranti Bluetooth tanpa nama"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tidak dapat menyambung"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Rawakkan alamat MAC apabila menyambung ke rangkaian Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Bermeter"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Tidak bermeter"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Saiz penimbal pengelog"</string>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 75ee0cb..ba9c904 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRM အကြောင်းအရာအတွက်သာ HDCP စစ်ဆေးမည်"</item>
<item msgid="45075631231212732">"HDCP checkingအားအမြဲသုံးပါ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"ပိတ်ထားသည်"</item>
+ <item msgid="1969681323976948639">"စစ်ထုတ်ထားသည်များကို ဖွင့်ထားသည်"</item>
+ <item msgid="8719029132154020716">"ဖွင့်ထားသည်"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (မူလ)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index c9896f0..3e9e181 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s မှတစ်ဆင့် အလိုအလျောက် ချိတ်ဆက်ထားပါသည်"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ကွန်ရက်အဆင့်သတ်မှတ်ပေးသူ မှတစ်ဆင့် အလိုအလျောက် ချိတ်ဆက်ထားပါသည်"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> ၏ <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s မှတစ်ဆင့်ရနိုင်သည်"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"စနစ်ထည့်သွင်းရန် တို့ပါ"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"အကောင့်ဖွင့်ရန် တို့ပါ"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"ချိတ်ဆက်ထားသည်၊ အင်တာနက်မရှိ"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"အင်တာနက် မရှိပါ"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"လက်မှတ်ထိုးဝင်ရန် လိုအပ်သည်"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ကွန်ရက်ချိတ်ဆက်မှု ယာယီပြည့်နေသည်"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s မှတစ်ဆင့် ရနိုင်သည်"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"ချိတ်ဆက်၍ မရပါ"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"မမှန်ကန်သည့် OSU ဆာဗာ URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU ဆာဗာသို့ ချိတ်ဆက်၍ မရပါ"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU ဆာဗာကို အတည်ပြု၍မရပါ"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"မမှန်ကန်သည့် OSU ဆာဗာအသိအမှတ်ပြုလက်မှတ်"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ပံ့ပိုးခြင်းကို ဖျက်သိမ်းလိုက်ပါပြီ"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"ပံ့ပိုးမှု မရနိုင်ပါ"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"မမှန်ကန်သည့် OSU ဆာဗာ URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"မျှော်လင့်မထားသော ကွန်မန်းအမျိုးအစား"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"မမျှော်လင့်ထားသည့် SOAP မက်ဆေ့ဂျ်အမျိုးအစား"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP မက်ဆေ့ဂျ်ကို ဖလှယ်၍ မရပါ"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"တစ်ဆင့်ပြန်ညွှန်ချက်ကို စောင့်ကြည့်သည့်စနစ်ကို စတင်၍မရပါ"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"တစ်ဆင့်ပြန်ညွှန်ချက်ကို စောင့်ရာတွင် အချိန်ကုန်သွားပါပြီ"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"မည်သည့် OSU လုပ်ဆောင်ချက်ကိုမျှ မတွေ့ပါ"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"မျှော်လင့်မထားသော SOAP မက်ဆေ့ဂျ်အခြေအနေ"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO ကို ရှာမတွေ့ပါ"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA ဆာဗာအတွက် ယုံကြည်ချက်ဆိုင်ရာ အရင်းအမြစ်စက် နုတ်ကို ရှာမတွေ့ပါ"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ပြောင်းရွှေ့ခြင်းဆာဗာအတွက် ယုံကြည်ချက်ဆိုင်ရာ အရင်းအမြစ် နုတ်ကို ရှာမတွေ့ပါ"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"မူဝါဒဆာဗာအတွက် ယုံကြည်ချက်ဆိုင်ရာ အရင်းအမြစ် နုတ်ကို ရှာမတွေ့ပါ"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"ယုံကြည်ချက်ဆိုင်ရာ အရင်းအမြစ်အသိအမှတ်ပြုလက်မှတ်များကို ယူ၍မရပါ"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA ဆာဗာအတွက် ယုံကြည်ချက်ဆိုင်ရာ အရင်းအမြစ် အသိအမှတ်ပြုလက်မှတ်ကို ရှာမတွေ့ပါ"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint စီစဉ်သတ်မှတ်ချက်ကို ထည့်၍မရပါ"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU ဝန်ဆောင်မှုထောက်ပံ့သူကို ရှာမတွေ့ပါ"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"ချိတ်ဆက်နေသည်"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"ချိတ်ဆက်ထားသည်"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU ဆာဗာသို့ ချိတ်ဆက်နေသည်"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU ဆာဗာကို အတည်ပြုထားသည်"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU ဆာဗာသို့ ချိတ်ဆက်ထားသည်"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"ကနဦး SOAP ဖလှယ်မှု"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"တစ်ဆင့်ပြန်ညွှန်သည့် တုံ့ပြန်ချက်ကို စောင့်နေသည်"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"တစ်ဆင့်ပြန်ညွှန်ထားသည့် တုံ့ပြန်မှုကို ရရှိထားသည်"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"ဒုတိယ SOAP ဖလှယ်မှု"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"တတိယ SOAP ဖလှယ်မှု"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"ယုံကြည်မှုဆိုင်ရာ အရင်းအမြစ်အသိအမှတ်ပြုလက်မှတ်များ ရယူနေသည်"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ပံ့ပိုးပြီးပါပြီ"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ကို ဖွင့်နေသည်"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"ချိတ်ဆက်၍ မရပါ"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"အကောင့်ဖွင့်ခြင်း အပြီးသတ်နေသည်…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"အကောင့်ဖွင့်ခြင်း အပြီးသတ်၍ မရပါ။ ပြန်စမ်းကြည့်ရန် တို့ပါ။"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"အကောင့်ဖွင့်ခြင်း ပြီးပါပြီ။ ချိတ်ဆက်နေသည်…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"အလွန်နှေး"</string>
<string name="speed_label_slow" msgid="813109590815810235">"နှေး"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"ဖွင့်လျက်သား"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"အားသွင်းနေစဉ် ဖန်သားပြင်မှာဘယ်သောအခါမှ ပိတ်မည်မဟုတ်ပါ။"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ဘလူးတုသ် HCI snoop မှတ်တမ်းကို ဖွင့်ခြင်း"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ဘလူးတုသ် အတွဲများ သိမ်းယူပါ။ (ဤဆက်တင်ကို ပြောင်းပြီးသည့်အခါ ဘလူးတုသ် ဖွင့်/ပိတ် လုပ်ပါ)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM သော့ဖွင့်ခြင်း"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"အစပြုခြင်းကိရိယာအား သော့ဖွင့်ရန် ခွင့်ပြုမည်"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM သော့ဖွင့်ခြင်း ခွင့်ပြုမလား?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ချိတ်ဆက်ဆောင်ရွက်ခြင်း"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ကြိုးမဲ့ပြသမှု အသိအမှတ်ပြုလက်မှတ်"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Verbose မှတ်တမ်းတင်ခြင်းအား ဖွင့်မည်"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"MAC ကျပန်းပြုလုပ်မှုကို ချိတ်ဆက်ထားခြင်း"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"မိုဘိုင်းဒေတာကို အမြဲဖွင့်ထားရန်"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ဖုန်းကို မိုဒမ်အဖြစ်အသုံးပြုမှု စက်ပစ္စည်းဖြင့် အရှိန်မြှင့်တင်ခြင်း"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"အမည်မရှိသော ဘလူးတုသ်စက်ပစ္စည်းများကို ပြသရန်"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ချိတ်ဆက်၍ မရပါ"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ကြိုးမဲ့ အခင်းအကျင်း အသိအမှတ်ပြုလက်မှတ်အတွက် ရွေးချယ်စရာများပြရန်"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi မှတ်တမ်းတင်ခြင်း နှုန်းအားမြင့်ကာ၊ Wi‑Fi ရွေးရာတွင် SSID RSSI ဖြင့်ပြပါ"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi‑Fi ကွန်ရက်များသို့ ချိတ်ဆက်သည့်အခါ MAC လိပ်စာ ကျပန်းပြုလုပ်ခြင်း"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"အခမဲ့ မဟုတ်ပါ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"အခမဲ့"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"မှတ်တမ်းကြားခံနယ် အရွယ်အစားများ"</string>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 214e2d5..0c3b0c7 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Bruk HDCP-kontroll kun for DRM-innhold"</item>
<item msgid="45075631231212732">"Bruk alltid HDCP-kontroll"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Slått av"</item>
+ <item msgid="1969681323976948639">"Filtrering er slått på"</item>
+ <item msgid="8719029132154020716">"Slått på"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 86f5347..65085e8 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisk tilkoblet via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatisk tilkoblet via leverandør av nettverksvurdering"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Tilkoblet via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> fra <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Tilkoblet via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tilgjengelig via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Trykk for å konfigurere"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Trykk for å registrere deg"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tilkoblet – ingen Internett-tilgang"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Ingen internettilkobling"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Pålogging kreves"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Tilgangspunktet er midlertidig fullt"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Tilkoblet via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Tilgjengelig via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Kunne ikke koble til"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Ugyldig nettadresse for OSU-tjener"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Tilkoblingen til OSU-tjeneren mislyktes"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Godkjenning av OSU-tjeneren mislyktes"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Ugyldig sertifikat for OSU-tjener"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Identitetshåndtering ble avbrutt"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Identitetshåndtering er ikke tilgjengelig"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Ugyldig nettadresse for OSU-tjener"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Uventet kommandotype"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Uventet SOAP-meldingstype"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Utveksling av SOAP-melding mislyktes"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Lytteren for viderekoblinger kunne ikke starte"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Tidsavbrudd ved venting for viderekobling"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Fant ingen OSU-aktivitet"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Uventet status for SOAP-melding"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Kunne ikke finne PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Kunne ikke finne rotnode for klarering for AAA-tjeneren"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Kunne ikke finne rotnode for klarering for tjeneren for utbedringer"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Kunne ikke finne rotnode for klarering for tjeneren for retningslinjer"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Kunne ikke hente rotsertifikatene for klarering"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Kunne ikke finne rotsertifikat for klarering for AAA-tjeneren"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Kunne ikke legge til PassPoint-konfigurering"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Kunne ikke finne en OSU-leverandør"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Kobler til"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Tilkoblet"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Kobler til OSU-tjeneren"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-tjeneren er godkjent"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Koblet til OSU-tjener"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Første SOAP-utveksling"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Venter på viderekoblingssvar"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Har mottatt viderekoblingssvar"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Andre SOAP-utveksling"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Tredje SOAP-utveksling"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Henter rotsertifikater for klarering"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Identitetshåndtering er fullført"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Åpner <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Kunne ikke koble til"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Fullfører registreringen …"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Kunne ikke fullføre registreringen. Trykk for å prøve på nytt."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registreringen er fullført. Kobler til …"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Veldig treg"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Treg"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Forbli våken"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Skjermen blir aldri svart under lading"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Slå på Bluetooth HCI snoop-logg"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Samle Bluetooth-pakker. (Slå Bluetooth av/på etter at du har endret denne innstillingen)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-opplåsing"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Tillat at oppstartsinnlasteren låses opp"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Vil du tillate OEM-opplåsing?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Nettverk"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Trådløs skjermsertifisering"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktiver detaljert Wi-Fi-loggføring"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Tilfeldig MAC-adresse ved tilkobling"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er alltid aktiv"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvareakselerasjon for internettdeling"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Vis Bluetooth-enheter uten navn"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kunne ikke koble til"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis alternativer for sertifisering av trådløs skjerm"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øk Wi-Fi-loggenivå – vis per SSID RSSI i Wi-Fi-velgeren"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Angi tilfeldig MAC-adresse når du kobler til Wi-Fi-nettverk"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Med datamåling"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Uten datamåling"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Bufferstørrelser for logg"</string>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index a246d606..0213e9d 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRM सामग्रीको लागि मात्र HDCP जाँचको प्रयोग गर्नुहोस्"</item>
<item msgid="45075631231212732">"सधैँ HDCP जाँच प्रयोग गर्नुहोस्"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"असक्षम पारिएको छ"</item>
+ <item msgid="1969681323976948639">"फिल्टर सक्षम पारियो"</item>
+ <item msgid="8719029132154020716">"सक्षम पारिएको छ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP १.४ (पूर्वनिर्धारित)"</item>
<item msgid="2809759619990248160">"AVRCP १.३"</item>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index eb6d9d3..16b3b07 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -38,50 +38,27 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s मार्फत् स्वतः जडान गरिएको"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्कको दर्जा प्रदायक मार्फत स्वत: जडान गरिएको"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s मार्फत जडित"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> को <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <!-- no translation found for connected_via_app (5571999941988929520) -->
+ <skip />
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s मार्फत उपलब्ध"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"सेटअप गर्न ट्याप गर्नुहोस्"</string>
+ <!-- no translation found for tap_to_sign_up (6449724763052579434) -->
+ <skip />
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"जडान गरियो तर इन्टरनेट छैन"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"इन्टरनेटमाथिको पहुँच छैन"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन गर्न आवश्यक छ"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"पहुँचसम्बन्धी स्थान अस्थायी रूपमा भरिएको छ"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s मार्फत जडान गरियो"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s मार्फत उपलब्ध"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"जडान गर्न सकिएन"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU सर्भरको अमान्य URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU सर्भरमा जडान गर्न सकिएन"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU सर्भर प्रमाणीकरण गर्न सकिएन"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"अमान्य OSU सर्भरको प्रमाणपत्र"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"प्रावधानीकरण रद्द गरियो"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"प्रावधानीकरण गर्ने कार्य उपलब्ध छैन"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU सर्भरको अमान्य URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"अनपेक्षित आदेशको प्रकार"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"अनपेक्षित प्रकारको SOAP सन्देश"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP सन्देशको विनिमय असफल भयो"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"रिडिरेक्ट श्रोता सुरु गर्न सकिएन"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"रिडिरेक्ट गर्नका लागि प्रतीक्षा गर्ने समय सकियो"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"कुनै पनि OSU क्रियाकलाप फेला परेन"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"अनपेक्षित SOAP सन्देशको स्थिति"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO फेला पार्न सकिएन"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA सर्भरको विश्वसनीय मूल नोड फेला पार्न सकिएन"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"समाधान गर्ने काम हुने सर्भरका लागि विश्वसनीय मूल नोड फेला पार्न सकिएन"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"नीतिको सर्भरका लागि विश्वसनीय मूल नोड फेला पार्न सकिएन"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"विश्वसनीय मूल प्रमाणपत्रहरू फेला पार्न सकिएन"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA सर्भरका लागि विश्वसनीय मूल प्रमाणपत्र फेला पार्न सकिएन"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint कन्फिगुरेसन थप्न सकिएन"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"कुनै OSU प्रदायक फेला पार्न सकिएन"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"जडान गर्दै"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"जडान गरिएको छ"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU सर्भरमा जडान गर्दै"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU सर्भर प्रमाणीकरण गरियो"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU सर्भरमा जडान गरियो"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"प्रारम्भिक SOAP विनिमय"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"रिडिरेक्ट प्रतिक्रियाको प्रतिक्षा गर्दै"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"रिडिरेक्ट प्रतिक्रिया प्राप्त गरियो"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"दोस्रो SOAP विनिमय"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"तेस्रो SOAP विनिमय"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"विश्वसनीय मूल प्रमाणपत्रहरू प्राप्त गर्दै"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"प्रावधानीकरण गर्ने प्रक्रिया सम्पन्न भयो"</string>
+ <!-- no translation found for osu_opening_provider (5488997661548640424) -->
+ <skip />
+ <!-- no translation found for osu_connect_failed (2187750899158158934) -->
+ <skip />
+ <!-- no translation found for osu_completing_sign_up (9037638564719197082) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_failed (7296159750352873260) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_complete (8207626049093289203) -->
+ <skip />
<string name="speed_label_very_slow" msgid="1867055264243608530">"धेरै ढिलो"</string>
<string name="speed_label_slow" msgid="813109590815810235">"बिस्तारै"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ठिक छ"</string>
@@ -234,8 +211,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"जागा रहनुहोस्"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"चार्ज गर्ने बेलामा स्क्रिन कहिल्यै सुत्दैन।"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ब्लुटुथ HCI snoop लग सक्षम पार्नुहोस्"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ब्लुटुथका प्याकेटहरू समावेश गर्नुहोस्। (यो सेटिङ परिवर्तन गरेपछि ब्लुटुथ टगल गर्नुहोस्)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM अनलक गर्दै"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"अनलक हुन बूटलोडरलाई अनुमति दिनुहोस्"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM अनलक गर्न अनुमति दिने?"</string>
@@ -246,7 +222,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किङ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ताररहित प्रदर्शन प्रमाणीकरण"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi वर्बोज लग सक्षम पार्नुहोस्"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"जडान गरिएको MAC को अनियमितता"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिङको लागि हार्डवेयरको प्रवेग"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू देखाउनुहोस्"</string>
@@ -273,7 +248,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"जडान गर्न सकिएन"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi लग स्तर बढाउनुहोस्, Wi-Fi चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi‑Fi नेटवर्कहरूमा जडान गर्ने बेला MAC को ठेगाना अनियमित गर्नुहोस्"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"मिटर गरिएको जडान भनी चिन्ह लगाइएको"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"मिटर नगरिएको"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"लगर बफर आकारहरू"</string>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 4aa4eae..f3eeac6 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP-controle alleen voor DRM-content gebruiken"</item>
<item msgid="45075631231212732">"HDCP-controle altijd gebruiken"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Uitgeschakeld"</item>
+ <item msgid="1969681323976948639">"Gefilterd ingeschakeld"</item>
+ <item msgid="8719029132154020716">"Ingeschakeld"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (standaard)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 019f225..2f8c2c2 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatisch verbonden via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatisch verbonden via provider van netwerkbeoordelingen"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Verbonden via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> via <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Verbonden via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Beschikbaar via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tik om in te stellen"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tik om aan te melden"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Verbonden, geen internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Geen internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Inloggen vereist"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Toegangspunt tijdelijk vol"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Verbonden via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Beschikbaar via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Verbinding mislukt"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Ongeldige URL voor OSU-server"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Verbinding met OSU-server mislukt"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Validatie van OSU-server mislukt"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Ongeldig OSU-servercertificaat"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Registratie afgebroken"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Registratie niet beschikbaar"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Ongeldige URL voor OSU-server"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Onverwacht opdrachttype"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Onverwacht SOAP-berichttype"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP-berichtuitwisseling mislukt"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Kan listener voor omleiding niet starten"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Time-out bij wachten op omleiding"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Geen OSU-activiteit gevonden"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Onverwachte SOAP-berichtstatus"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Kan PPS-MO niet vinden"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Kan geen vertrouwde root-node vinden voor AAA-server"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Kan geen vertrouwde root-node vinden voor herstelserver"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Kan geen vertrouwde root-node vinden voor beleidsserver"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Kan vertrouwde rootcertificaten niet ophalen"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Kan geen vertrouwd rootcertificaat vinden voor AAA-server"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Kan PassPoint-configuratie niet toevoegen"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Kan geen OSU-provider vinden"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Verbinden"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Verbonden"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Verbinden met OSU-server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-server gevalideerd"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Verbonden met OSU-server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Eerste SOAP-uitwisseling"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Wachten op omleidingsreactie"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Omleidingsreactie ontvangen"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Tweede SOAP-uitwisseling"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Derde SOAP-uitwisseling"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Vertrouwde rootcertificaten ophalen"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Registratie voltooid"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> wordt geopend"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Kan geen verbinding maken"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Aanmelding voltooien…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Kan aanmelding niet voltooien. Tik om het opnieuw te proberen."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Aanmelding voltooid. Verbinden…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Zeer langzaam"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Langzaam"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Redelijk"</string>
@@ -191,7 +161,7 @@
<string name="tts_play_example_summary" msgid="8029071615047894486">"Een korte demonstratie van spraaksynthese afspelen"</string>
<string name="tts_install_data_title" msgid="4264378440508149986">"Spraakgegevens installeren"</string>
<string name="tts_install_data_summary" msgid="5742135732511822589">"De spraakgegevens voor spraaksynthese installeren"</string>
- <string name="tts_engine_security_warning" msgid="8786238102020223650">"Deze engine voor spraaksynthese kan mogelijk alle tekst verzamelen die wordt gesproken, waaronder persoonlijke gegevens zoals wachtwoorden en creditcardnummers. Deze engine is afkomstig van de <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>-engine. Het gebruik van deze engine voor spraaksynthese inschakelen?"</string>
+ <string name="tts_engine_security_warning" msgid="8786238102020223650">"Deze engine voor spraaksynthese kan mogelijk alle tekst verzamelen die wordt gesproken, waaronder persoonsgegevens zoals wachtwoorden en creditcardnummers. Deze engine is afkomstig van de <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>-engine. Het gebruik van deze engine voor spraaksynthese inschakelen?"</string>
<string name="tts_engine_network_required" msgid="1190837151485314743">"Deze taal heeft een werkende netwerkverbinding nodig voor tekst-naar-spraak-uitvoer."</string>
<string name="tts_default_sample_string" msgid="4040835213373086322">"Dit is een voorbeeld van spraaksynthese"</string>
<string name="tts_status_title" msgid="7268566550242584413">"Status van standaardtaal"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Stand-by"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Scherm gaat nooit uit tijdens het opladen"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Snoop-logbestand voor Bluetooth-HCI inschakelen"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth-pakketten opslaan. (Schakel Bluetooth in nadat je deze instelling hebt gewijzigd)."</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-ontgrendeling"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Toestaan dat de bootloader wordt ontgrendeld"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM-ontgrendeling toestaan?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Netwerken"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificering van draadloze weergave"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Uitgebreide wifi-logregistratie insch."</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Willekeurig MAC-adres bij verbinding"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data altijd actief"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareversnelling voor tethering"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-apparaten zonder namen weergeven"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kan geen verbinding maken"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Een willekeurig MAC-adres bij het maken van verbinding met wifi-netwerken"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Met datalimiet"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Gratis"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Logger-buffergrootten"</string>
@@ -460,7 +427,7 @@
<string name="active_input_method_subtypes" msgid="3596398805424733238">"Actieve invoermethoden"</string>
<string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"Systeemtalen gebruiken"</string>
<string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"Instellingen openen voor <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> mislukt"</string>
- <string name="ime_security_warning" msgid="4135828934735934248">"Deze invoermethode verzamelt mogelijk alle tekst die je typt, inclusief persoonlijke gegevens zoals wachtwoorden en creditcardnummers. De methode is afkomstig uit de app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Deze invoermethode inschakelen?"</string>
+ <string name="ime_security_warning" msgid="4135828934735934248">"Deze invoermethode verzamelt mogelijk alle tekst die je typt, inclusief persoonsgegevens zoals wachtwoorden en creditcardnummers. De methode is afkomstig uit de app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Deze invoermethode inschakelen?"</string>
<string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"Opmerking: Wanneer je telefoon opnieuw is opgestart, kan deze app pas worden gestart nadat je je telefoon hebt ontgrendeld"</string>
<string name="ims_reg_title" msgid="7609782759207241443">"IMS-registratiestatus"</string>
<string name="ims_reg_status_registered" msgid="933003316932739188">"Geregistreerd"</string>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index 15c3ee5..274136a 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"କେବଳ DRM କଣ୍ଟେଣ୍ଟ ପାଇଁ HDCP ଯାଞ୍ଚ ବ୍ୟବହାର କରନ୍ତୁ"</item>
<item msgid="45075631231212732">"ସର୍ବଦା HDCP ଯାଞ୍ଚ ବ୍ୟବହାର କରନ୍ତୁ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"ଅକ୍ଷମ କରାଯାଇଛି"</item>
+ <item msgid="1969681323976948639">"ଫିଲ୍ଟର୍କୁ ସକ୍ଷମ କରାଯାଇଛି"</item>
+ <item msgid="8719029132154020716">"ସକ୍ଷମ କରାଯାଇଛି"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ଡିଫଲ୍ଟ)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index b1d1179..95ab7bb 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -38,50 +38,27 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲୀ ସଂଯୁକ୍ତ"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ନେଟୱର୍କ ମୂଲ୍ୟାୟନ ପ୍ରଦାତାଙ୍କ ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲ୍ୟ ସଂଯୁକ୍ତ"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> ଦ୍ଵାରା <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <!-- no translation found for connected_via_app (5571999941988929520) -->
+ <skip />
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"ସେଟ୍ଅପ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for tap_to_sign_up (6449724763052579434) -->
+ <skip />
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"ସଂଯୁକ୍ତ, ଇଣ୍ଟର୍ନେଟ୍ ନାହିଁ"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"କୌଣସି ଇଣ୍ଟରନେଟ୍ ନାହିଁ"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ସାଇନ୍-ଇନ୍ ଆବଶ୍ୟକ"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ଆକ୍ସେସ୍ ପଏଣ୍ଟ ସାମୟିକ ଭାବେ ପୂର୍ଣ୍ଣ"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"ସଂଯୋଗ ହେଇପାରିଲା ନାହିଁ"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"ଅବୈଧ OSU ସର୍ଭର୍ URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU ସର୍ଭର୍ ସଂଯୋଗ ପ୍ରକ୍ରିୟା ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU ସର୍ଭର୍ ବୈଧକରଣ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"ଅବୈଧ OSU ସର୍ଭର୍ ସାର୍ଟିଫିକେଟ୍"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ପ୍ରାବଧାନ ବାତିଲ୍ କରାଯାଇଛି"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"ପ୍ରାବଧନ ଉପଲବ୍ଧ ନାହିଁ"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"ଅବୈଧ OSU ସର୍ଭର୍ URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ଅପ୍ରତ୍ୟାଶିତ ନିର୍ଦ୍ଦେଶ ପ୍ରକାର"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ଅପ୍ରତ୍ୟାଶିତ SOAP ମେସେଜ୍ ପ୍ରକାର"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP ମେସେଜ୍ ଏକ୍ସଚେଞ୍ଜ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"ପୁନଃନିର୍ଦ୍ଦେଶ ଶ୍ରୋତା ଆରମ୍ଭ କରିବାରେ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"ସମୟ ଶେଷ ହୋଇଛି, ପୁନଃନିର୍ଦ୍ଦେଶ ପାଇଁ ଅପେକ୍ଷାରତ"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"କୌଣସି OSU ଗତିବିଧି ମିଳିଲା ନାହିଁ"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"ଅପ୍ରତ୍ୟାଶିତ SOAP ମେସେଜ୍ ସ୍ଥିତି"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO ଖୋଜିବାରେ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA ସର୍ଭର୍ ପାଇଁ ଟ୍ରଷ୍ଟ ରୁଟ୍ ନୋଡ୍ ଖୋଜିବାରେ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ରିମେଡିଟେସନ୍ ସର୍ଭର୍ ପାଇଁ ଟ୍ରଷ୍ଟ ରୁଟ୍ ନୋଡ୍ ଖୋଜିବାରେ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"ପଲିସି ସର୍ଭର୍ ପାଇଁ ଟ୍ରଷ୍ଟ ରୁଟ୍ ନୋଡ୍ ଖୋଜିବାରେ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"ଟ୍ରଷ୍ଟ ରୁଟ୍ ସାର୍ଟିଫିକେଟ୍କୁ ପୁନରୁଦ୍ଧାର କରିହେଲା ନାହିଁ"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA ସର୍ଭର୍ ପାଇଁ ଟ୍ରଷ୍ଟ ରୁଟ୍ ସାର୍ଟିଫିକେଟ୍ ଖୋଜିବାରେ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint କନ୍ଫିଗ୍ରେସନ୍ ଯୋଗ କରିବାରେ ବିଫଳ ହେଲା"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"ଏକ OSU ପ୍ରଦାତା ଖୋଜିବାରେ ବିଫଳ ହେଲା"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"ସଂଯୋଗ କରୁଛି"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"ସଂଯୋଗ ହୋଇଛି"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU ସର୍ଭର୍ରେ ସଂଯୋଗ କରାଯାଉଛି"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU ସର୍ଭର୍ ବୈଧକରଣ କରାଗଲା"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU ସର୍ଭର ସହ ସଂଯୋଗ କରାଯାଇଛି"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"ପ୍ରାରମ୍ଭିକ SOAP ଏକ୍ସଚେଞ୍ଜ"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"ପୁନଃନିର୍ଦ୍ଦେଶ ପ୍ରତିକ୍ରିୟା ପାଇଁ ଅପେକ୍ଷାରତ"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"ପୁନଃନିର୍ଦ୍ଦେଶିତ ପ୍ରତିକ୍ରିୟା ପ୍ରାପ୍ତ ହୋଇଛି"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"ଦ୍ଵିତୀୟ SOAP ଏକ୍ସଚେଞ୍ଜ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"ତୃତୀୟ SOAP ଏକ୍ସଚେଞ୍ଜ"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"ଟ୍ରଷ୍ଟ ରୁଟ୍ ସାର୍ଟିଫିକେଟ୍କୁ ପୁନରୁଦ୍ଧାର କରାଯାଉଛି"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ପ୍ରାବଧାନ ସମ୍ପୂର୍ଣ୍ଣ ହୋଇଛି"</string>
+ <!-- no translation found for osu_opening_provider (5488997661548640424) -->
+ <skip />
+ <!-- no translation found for osu_connect_failed (2187750899158158934) -->
+ <skip />
+ <!-- no translation found for osu_completing_sign_up (9037638564719197082) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_failed (7296159750352873260) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_complete (8207626049093289203) -->
+ <skip />
<string name="speed_label_very_slow" msgid="1867055264243608530">"ବହୁତ ମନ୍ଥର"</string>
<string name="speed_label_slow" msgid="813109590815810235">"କମ୍ ବେଗ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ଠିକ୍ ଅଛି"</string>
@@ -234,8 +211,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"ଜାଗ୍ରତ ରଖନ୍ତୁ"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ଚାର୍ଜ ହେବାବେଳେ ସ୍କ୍ରୀନ୍ ଆଦୌ ବନ୍ଦ ହେବନାହିଁ"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ବ୍ଲୁ-ଟୂଥ୍ HCI ସ୍ନୁପ୍ ଲଗ୍ ସକ୍ଷମ କରନ୍ତୁ"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ବ୍ଲୁଟୁଥ୍ ପ୍ୟାକେଟ୍ କ୍ୟାପଚର୍ କରନ୍ତୁ (ଏହି ସେଟିଂ ବଦଳାଇବା ପରେ ବ୍ଲୁଟୁଥ୍କୁ ଟୋଗଲ୍ କରନ୍ତୁ)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM ଅନଲକ୍ କରିବା"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"bootloaderକୁ ଅନ୍ଲକ୍ ହେବାର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM ଅନଲକ୍ କରିବା ଅନୁମତି ଦେବେ?"</string>
@@ -246,7 +222,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ନେଟ୍ୱର୍କିଙ୍ଗ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ୱାୟରଲେସ୍ ଡିସ୍ପ୍ଲେ ସର୍ଟିଫିକେଶନ୍"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"ୱାଇ-ଫାଇ ଭର୍ବୋସ୍ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"କନେକ୍ଟ ହୋଇଥିବା MACର ରେଣ୍ଡୋମାଇଜେଶନ୍"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"ମୋବାଇଲ୍ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ବେଗ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ବ୍ଲୁ-ଟୂଥ୍ ଡିଭାଇସ୍ଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖନ୍ତୁ"</string>
@@ -273,7 +248,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ୱେୟାରଲେସ୍ ଡିସ୍ପ୍ଲେ ସର୍ଟିଫିକେଶନ୍ ପାଇଁ ବିକଳ୍ପ ଦେଖାନ୍ତୁ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କଗୁଡ଼ିକ ସହିତ କନେକ୍ଟ କରିବାବେଳେ MAC ଠିକଣାକୁ ରେଣ୍ଡୋମାଇଜ୍ କରନ୍ତୁ"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"ମପାଯାଉଥିବା"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"ମପାଯାଉନଥିବା"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ଲଗର୍ ବଫର୍ ସାଇଜ୍"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 45d96b7..0bc2ce6 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"ਸਿਰਫ਼ DRM ਸਮੱਗਰੀ ਲਈ HDCP ਜਾਂਚ ਦੀ ਵਰਤੋਂ ਕਰੋ"</item>
<item msgid="45075631231212732">"ਹਮੇਸਾਂ HDCP ਜਾਂਚ ਵਰਤੋ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"ਬੰਦ"</item>
+ <item msgid="1969681323976948639">"ਫਿਲਟਰ ਕੀਤਿਆਂ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</item>
+ <item msgid="8719029132154020716">"ਚਾਲੂ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 6ba9de7..1ddd862 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -38,50 +38,27 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ਰਾਹੀਂ ਆਪਣੇ-ਆਪ ਕਨੈਕਟ ਹੋਇਆ"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ਨੈੱਟਵਰਕ ਰੇਟਿੰਗ ਪ੍ਰਦਾਨਕ ਰਾਹੀਂ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਹੋਇਆ"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> ਵੱਲੋਂ <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <!-- no translation found for connected_via_app (5571999941988929520) -->
+ <skip />
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <!-- no translation found for tap_to_sign_up (6449724763052579434) -->
+ <skip />
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"ਕਨੈਕਟ ਕੀਤਾ, ਕੋਈ ਇੰਟਰਨੈੱਟ ਨਹੀਂ"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ਇੰਟਰਨੈੱਟ ਨਹੀਂ"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ਸਾਈਨ-ਇਨ ਲੋੜੀਂਦਾ ਹੈ"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ਐਕਸੈੱਸ ਪੁਆਇੰਟ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਸੰਪੂਰਨ ਰੁਝੇਂਵੇਂ ਵਿੱਚ ਹੈ"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ਰਾਹੀਂ ਕਨੈਕਟ ਕੀਤਾ"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s ਰਾਹੀਂ ਉਪਲਬਧ"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"ਕਨੈਕਸ਼ਨ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"ਅਵੈਧ OSU ਸਰਵਰ URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU ਸਰਵਰ ਕਨੈਕਸ਼ਨ ਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU ਸਰਵਰ ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ ਰਹੀ"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"ਅਵੈਧ OSU ਸਰਵਰ ਸਰਟੀਫੀਕੇਟ"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ਵਿਵਸਥਾਕਰਨ ਰੱਦ ਕੀਤਾ ਗਿਆ"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"ਵਿਵਸਥਾਕਰਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"ਅਵੈਧ OSU ਸਰਵਰ URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ਅਚਾਨਕ ਆਦੇਸ਼ ਦੀ ਕਿਸਮ"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ਅਚਾਨਕ SOAP ਦੀ ਸੁਨੇਹਾ ਕਿਸਮ"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP ਸੁਨੇਹੇ ਦਾ ਵਟਾਂਦਰਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"ਰੀਡਾਇਰੈਕਟ ਲਿਸਨਰ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"ਰੀਡਾਇਰੈਕਟ ਦੀ ਉਡੀਕ ਕਰਨ ਦਾ ਸਮਾਂ ਸਮਾਪਤ ਹੋਇਆ"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"ਕੋਈ OSU ਸਰਗਰਮੀ ਨਹੀਂ ਮਿਲੀ"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"ਅਚਾਨਕ SOAP ਦੀ ਸੁਨੇਹੇ ਦੀ ਸਥਿਤੀ"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO ਨੂੰ ਲੱਭਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA ਸਰਵਰ ਲਈ ਭਰੋਸੇਯੋਗ ਰੂਟ ਨੋਡ ਲੱਭਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ਰੇਮੇਡੀਅਸ਼ਨ ਸਰਵਰ ਲਈ ਭਰੋਸੇਯੋਗ ਰੂਟ ਨੋਡ ਲੱਭਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"ਨੀਤੀ ਸਰਵਰ ਲਈ ਭਰੋਸੇਯੋਗ ਰੂਟ ਨੋਡ ਲੱਭਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"ਭਰੋਸੇਯੋਗ ਰੂਟ ਸਰਟੀਫਿਕੇਟਾਂ ਨੂੰ ਮੁੜ-ਪ੍ਰਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA ਸਰਵਰ ਲਈ ਭਰੋਸੇਯੋਗ ਰੂਟ ਸਰਟੀਫਿਕੇਟ ਲੱਭਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint ਸੰਰੂਪਣ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU ਪ੍ਰਦਾਨਕ ਲੱਭਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"ਕਨੈਕਟ ਹੈ"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU ਸਰਵਰ ਪ੍ਰਮਾਣਿਤ ਕੀਤਾ ਗਿਆ"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"ਸ਼ੁਰੂਆਤੀ SOAP ਦਾ ਵਟਾਂਦਰਾ"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"ਰੀਡਾਇਰੈਕਟ ਜਵਾਬ ਲਈ ਉਡੀਕ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"ਰੀਡਾਇਰੈਕਟ ਜਵਾਬ ਪ੍ਰਾਪਤ ਹੋਇਆ"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"ਦੂਜੇ SOAP ਦਾ ਵਟਾਂਦਰਾ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"ਤੀਜੇ SOAP ਦਾ ਵਟਾਂਦਰਾ"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"ਭਰੋਸੇਯੋਗ ਰੂਟ ਸਰਟੀਫਿਕੇਟਾਂ ਨੂੰ ਮੁੜ-ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ਵਿਵਸਥਾਕਰਨ ਪੂਰਾ ਹੋਇਆ"</string>
+ <!-- no translation found for osu_opening_provider (5488997661548640424) -->
+ <skip />
+ <!-- no translation found for osu_connect_failed (2187750899158158934) -->
+ <skip />
+ <!-- no translation found for osu_completing_sign_up (9037638564719197082) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_failed (7296159750352873260) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_complete (8207626049093289203) -->
+ <skip />
<string name="speed_label_very_slow" msgid="1867055264243608530">"ਬਹੁਤ ਹੌਲੀ"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ਹੌਲੀ"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ਠੀਕ ਹੈ"</string>
@@ -234,8 +211,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"ਸੁਚੇਤ ਰਹੋ"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ਸਕ੍ਰੀਨ ਚਾਰਜਿੰਗ ਦੇ ਸਮੇਂ ਕਦੇ ਵੀ ਸਲੀਪ ਨਹੀਂ ਹੋਵੇਗੀ"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"ਬਲੂਟੁੱਥ HCI ਸਨੂਪ ਲੌਗ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"ਬਲੂਟੁੱਥ ਪੈਕੇਟ ਕੈਪਚਰ ਕਰੋ। (ਇਹ ਸੈਟਿੰਗ ਬਦਲਣ ਤੋਂ ਬਾਅਦ ਬਲੂਟੁੱਥ ਨੂੰ ਟੌਗਲ ਕਰੋ)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM ਅਣਲਾਕ ਕਰਨਾ"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"ਬੂਟਲੋਡਰ ਨੂੰ ਅਣਲਾਕ ਕੀਤੇ ਜਾਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"ਕੀ OEM ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
@@ -246,7 +222,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ਨੈੱਟਵਰਕਿੰਗ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"ਵਾਈ-ਫਾਈ ਵਰਬੋਸ ਲੌਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"ਬੇਤਰਤੀਬਵਾਰ ਕਨੈਕਟ ਕੀਤਾ ਹੋਇਆ MAC ਪਤਾ"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"ਮੋਬਾਈਲ ਡਾਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੈੱਲਰੇਸ਼ਨ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ਅਨਾਮ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਦਿਖਾਓ"</string>
@@ -273,7 +248,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ਵਾਈ‑ਫਾਈ ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, ਵਾਈ‑ਫਾਈ Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ ਨਾਲ ਕਨੈਕਟ ਹੋਣ \'ਤੇ MAC ਪਤਾ ਬੇਤਰਤੀਬਵਾਰ ਚੁਣੋ"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"ਗੈਰ-ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ਲੌਗਰ ਬਫ਼ਰ ਆਕਾਰ"</string>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 6221793..4364b38 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Użyj sprawdzania HDCP tylko w przypadku treści chronionych DRM"</item>
<item msgid="45075631231212732">"Zawsze używaj sprawdzania HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Wyłączono"</item>
+ <item msgid="1969681323976948639">"Filtrowanie włączone"</item>
+ <item msgid="8719029132154020716">"Włączono"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (domyślna)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 609ed2a..e2109c8 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatycznie połączono przez: %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatycznie połączono przez dostawcę ocen jakości sieci"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Połączono przez %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> – <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Połączenie przez: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Dostępne przez %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Kliknij, by skonfigurować"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Kliknij, by się zarejestrować"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Połączono, brak internetu"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Brak internetu"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Musisz się zalogować"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punkt dostępu jest tymczasowo zajęty"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Połączono przez: %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Dostępna przez: %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Nie udało się nawiązać połączenia"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Nieprawidłowy adres URL serwera OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Nie udało się połączyć z serwerem OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Niepowodzenie weryfikacji przez serwer OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Nieprawidłowy certyfikat serwera OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Udostępnianie zostało przerwane"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Udostępnianie niedostępne"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Nieprawidłowy adres URL serwera OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Nieoczekiwany typ polecenia"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Nieoczekiwany typ komunikatu SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Nie udało się wymienić komunikatów SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Nie udało się uruchomić procesu nasłuchującego przekierowań"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Przekroczony limit czasu oczekiwania na przekierowanie"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Brak aktywności OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Nieoczekiwany stan komunikatu SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Nie można znaleźć PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Nie można znaleźć głównego węzła zaufania dla serwera AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Nie udało się znaleźć głównego węzła zaufania dla serwera naprawczego"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Nie udało się znaleźć głównego węzła zaufania dla serwera zasad"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Nie udało się pobrać głównych certyfikatów zaufania"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Nie udało się znaleźć głównego certyfikatu zaufania dla serwera AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Nie można dodać konfiguracji PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Nie udało się znaleźć dostawcy OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Łączę"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Połączono"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Nawiązuję połączenie z serwerem OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Pomyślna weryfikacja przez serwer OSU"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Połączono z serwerem OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Początkowa wymiana SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Czekam na odpowiedź przekierowującą"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Odebrano odpowiedź przekierowującą"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Druga wymiana SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Trzecia wymiana SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Pobieram główne certyfikaty zaufania"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Zakończono udostępnianie"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Otwieram: <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Nie udało się połączyć"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Kończę rejestrować…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Nie udało się dokończyć rejestracji. Kliknij, by spróbować ponownie."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Rejestracja zakończona. Łączę…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Bardzo wolna"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Wolna"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Pozostaw włączony ekran"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Ekran nie będzie gaszony podczas ładowania telefonu"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Włącz dziennik snoop Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Przechwyć wszystkie pakiety Bluetooth (przełącz Bluetooth po zmianie tego ustawienia)."</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Zdjęcie blokady OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Zezwalaj na odblokowanie programu rozruchowego"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Zezwolić na zdjęcie blokady OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Sieci"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Wyświetlacz bezprzewodowy"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Szczegółowy dziennik Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Losowe generowanie adresu MAC przy łączeniu"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna transmisja danych zawsze aktywna"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Akceleracja sprzętowa tetheringu"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Pokaż urządzenia Bluetooth bez nazw"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nie udało się połączyć"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wygeneruj losowo adres MAC podczas łączenia z siecią Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Użycie danych jest mierzone"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Użycie danych nie jest mierzone"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Rozmiary bufora Rejestratora"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index b8bb563..9e7d040 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Usar a verificação HDCP somente para conteúdo DRM"</item>
<item msgid="45075631231212732">"Sempre usar a verificação HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Desativada"</item>
+ <item msgid="1969681323976948639">"Filtro ativado"</item>
+ <item msgid="8719029132154020716">"Ativada"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (padrão)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index ef9e61d..19e22e420 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectado automaticamente via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectado automaticamente via provedor de avaliação de rede"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Conectado via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Toque para configurar"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Toque para se inscrever"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conectada, sem Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Sem Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"É necessário fazer login"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Conectado via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponível via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Falha na conexão"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL do servidor OSU inválido"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Falha na conexão do servidor OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Falha ao validar o servidor OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificado do servidor OSU inválido"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisionamento cancelado"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisionamento indisponível"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL do servidor OSU inválido"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tipo de comando inesperado"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tipo de mensagem SOAP inesperado"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Falha na troca de mensagens SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Falha ao iniciar o listener de redirecionamento"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Tempo limite esgotado ao aguardar redirecionamento"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nenhuma atividade OSU encontrada"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Status de mensagem SOAP inesperado"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Não foi possível encontrar o PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Não foi possível encontrar um nó raiz confiável para o servidor AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Não foi possível encontrar um nó raiz confiável para o servidor de atualizações"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Não foi possível encontrar um nó raiz confiável para o servidor da política"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Falha ao recuperar certificados raiz confiáveis"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Não foi possível encontrar um certificado raiz confiável para o servidor AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Falha ao adicionar a configuração do PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Falha ao localizar um provedor OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Conectando"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Conectado"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Conectando-se ao servidor OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Servidor OSU validado"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Conectado ao servidor OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Troca de SOAP inicial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Aguardando resposta de redirecionamento"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Resposta de redirecionamento recebida"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Segunda troca de SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Terceira troca de SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Recuperando certificados raiz confiáveis"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisionamento concluído"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Abrindo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Não foi possível conectar"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Concluindo inscrição…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Inscrição concluída. Conectando…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Permanecer ativo"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"A tela nunca entrará em suspensão enquanto estiver carregando."</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Ativar registro de rastreamento Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capturar pacotes de Bluetooth. Ative o Bluetooth depois de alterar essa configuração."</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueio de OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Permitir que o bootloader seja desbloqueado"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Permitir desbloqueio de OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro extenso de Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Escolha aleatória de MAC conectado"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível conectar"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Escolher o endereço MAC de forma aleatória quando estiver conectado a redes Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Limitada"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Ilimitada"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index b580317..ac170ca 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Utilizar a verificação HDCP para conteúdo DRM apenas"</item>
<item msgid="45075631231212732">"Utilizar sempre a verificação HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Desativado"</item>
+ <item msgid="1969681323976948639">"Filtrado ativado"</item>
+ <item msgid="8719029132154020716">"Ativado"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (predefinição)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index bb1dcc4..1f1072c 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Ligado automaticamente através de %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Ligado automaticamente através do fornecedor de classificação de rede"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Ligado através de %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Ligado via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível através de %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Toque para configurar"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Toque para se inscrever"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Ligado, sem Internet."</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Sem Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"É necessário iniciar sessão"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Ligado através de %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponível através de %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Falha na ligação"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL do servidor OSU inválido"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Falha ao ligar ao servidor OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Falha ao validar o servidor OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificado do servidor OSU inválido"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Aprovisionamento interrompido"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Aprovisionamento não disponível"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL do servidor OSU inválido"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tipo de comando inesperado"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tipo de mensagem SOAP inesperado"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Falha ao trocar mensagens SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Falha ao iniciar o redirecionamento do listener"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"O tempo limite foi excedido ao aguardar o redirecionamento"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nenhuma atividade do OSU encontrada"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Estado da mensagem SOAP inesperado"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Falha ao localizar o PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Falha ao localizar um nó raiz fidedigno para o servidor AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Falha ao localizar um nó raiz fidedigno para o servidor de soluções"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Falha ao localizar um nó raiz fidedigno para o servidor de políticas"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Falha ao obter certificados de raiz fidedignos"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Falha ao localizar um certificado de raiz fidedigno para o servidor AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Falha ao adicionar a configuração PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Falha ao localizar um fornecedor de OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"A ligar…"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Ligado"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"A ligar ao servidor OSU…"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Servidor OSU validado"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Ligado ao servidor OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Troca SOAP inicial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"A aguardar a resposta de redirecionamento…"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Resposta de redirecionamento recebida"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Segunda troca SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Terceira troca SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"A obter certificados de raiz fidedignos…"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Aprovisionamento concluído"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"A abrir <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Não foi possível estabelecer ligação"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"A concluir a inscrição…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Inscrição concluída. A ligar…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Manter ativo"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"O ecrã nunca entrará em suspensão durante o carregamento"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Ativar registo de monit. Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capturar os pacotes Bluetooth (ative/desative o Bluetooth após alterar esta definição)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueio de OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Permitir o desbloqueio do carregador de arranque"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Pretende permitir o desbloqueio de OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de display sem fios"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar o registo verboso de Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Seleção aleatória do MAC ligado"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware para ligação (à Internet) via telemóvel"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível estabelecer ligação"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções da certificação de display sem fios"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Selecionar aleatoriamente o endereço MAC quando estabelecer ligação a redes Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Acesso limitado"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Acesso ilimitado"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos da memória intermédia do registo"</string>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index b8bb563..9e7d040 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Usar a verificação HDCP somente para conteúdo DRM"</item>
<item msgid="45075631231212732">"Sempre usar a verificação HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Desativada"</item>
+ <item msgid="1969681323976948639">"Filtro ativado"</item>
+ <item msgid="8719029132154020716">"Ativada"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (padrão)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index ef9e61d..19e22e420 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectado automaticamente via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectado automaticamente via provedor de avaliação de rede"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Conectado via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponível via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Toque para configurar"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Toque para se inscrever"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conectada, sem Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Sem Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"É necessário fazer login"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Ponto de acesso temporariamente cheio"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Conectado via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponível via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Falha na conexão"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL do servidor OSU inválido"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Falha na conexão do servidor OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Falha ao validar o servidor OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificado do servidor OSU inválido"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Provisionamento cancelado"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Provisionamento indisponível"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL do servidor OSU inválido"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tipo de comando inesperado"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tipo de mensagem SOAP inesperado"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Falha na troca de mensagens SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Falha ao iniciar o listener de redirecionamento"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Tempo limite esgotado ao aguardar redirecionamento"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nenhuma atividade OSU encontrada"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Status de mensagem SOAP inesperado"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Não foi possível encontrar o PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Não foi possível encontrar um nó raiz confiável para o servidor AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Não foi possível encontrar um nó raiz confiável para o servidor de atualizações"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Não foi possível encontrar um nó raiz confiável para o servidor da política"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Falha ao recuperar certificados raiz confiáveis"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Não foi possível encontrar um certificado raiz confiável para o servidor AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Falha ao adicionar a configuração do PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Falha ao localizar um provedor OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Conectando"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Conectado"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Conectando-se ao servidor OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Servidor OSU validado"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Conectado ao servidor OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Troca de SOAP inicial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Aguardando resposta de redirecionamento"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Resposta de redirecionamento recebida"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Segunda troca de SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Terceira troca de SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Recuperando certificados raiz confiáveis"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Provisionamento concluído"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Abrindo <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Não foi possível conectar"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Concluindo inscrição…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Não foi possível concluir a inscrição. Toque para tentar novamente."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Inscrição concluída. Conectando…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Muito lenta"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lenta"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Ok"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Permanecer ativo"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"A tela nunca entrará em suspensão enquanto estiver carregando."</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Ativar registro de rastreamento Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Capturar pacotes de Bluetooth. Ative o Bluetooth depois de alterar essa configuração."</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueio de OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Permitir que o bootloader seja desbloqueado"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Permitir desbloqueio de OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro extenso de Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Escolha aleatória de MAC conectado"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível conectar"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Escolher o endereço MAC de forma aleatória quando estiver conectado a redes Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Limitada"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Ilimitada"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index c7d0e2f..28ae161 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Utilizează verificarea HDCP numai pentru conținut DRM"</item>
<item msgid="45075631231212732">"Utilizează întotdeauna verificarea HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Dezactivat"</item>
+ <item msgid="1969681323976948639">"Este activat Filtrat"</item>
+ <item msgid="8719029132154020716">"Activat"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (prestabilit)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index a1298c9..7fa75a8 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectată automat prin %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectată automat prin furnizor de evaluări ale rețelei"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Conectată prin %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> de la <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Conectat prin <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponibilă prin %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Atingeți pentru a configura"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Atingeți pentru a vă înscrie"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Conectată, fără internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Fără conexiune la internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Trebuie să vă conectați"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Punctul de acces este temporar plin"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Conectată prin %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Disponibilă prin %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Conectare eșuată"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL invalid pentru serverul OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Conectarea la serverul OSU a eșuat"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Validarea serverului OSU a eșuat"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certificat nevalid pentru serverul OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Asigurarea accesului a fost întreruptă"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Asigurarea accesului nu este disponibilă"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL invalid pentru serverul OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Tip de comandă neprevăzut"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Tip de mesaj SOAP neprevăzut"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Schimbul de mesaje SOAP a eșuat"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"„Listenerul” redirecționării nu a pornit"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"A expirat așteptând redirecționarea"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nu s-a găsit nicio activitate OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Status mesaj SOAP neprevăzut"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Nu a fost găsit PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Certificatul rădăcină de certificare pentru serverul AAA nu a fost găsit"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Nodul rădăcină de certificare pentru serverul de remediere nu a fost găsit"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Nodul rădăcină de certificare pentru serverul de politici nu a fost găsit"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Certificatele rădăcină de certificare nu s-au putut prelua"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Certificatul rădăcină de certificare pentru serverul AAA nu a fost găsit"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Configurarea PassPoint nu a fost adăugată"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Nu a fost găsit niciun furnizor OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Se conectează"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Conectat"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Se conectează la serverul OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Server OSU validat"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Conectat la serverul OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Schimb SOAP inițial"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Se așteaptă răspunsul redirecționării"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Răspunsul redirecționat a fost primit"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Al doilea schimb SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Al treilea schimb SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Se preiau certificatele rădăcină de certificare"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Asigurarea accesului finalizată"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Se deschide <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Nu s-a putut conecta"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Se finalizează înscrierea…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Nu s-a putut finaliza înscrierea. Atingeți pentru a încerca din nou."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Înscrierea a fost finalizată. Se conectează…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Foarte lentă"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Lentă"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Bine"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Activ permanent"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Ecranul nu va fi inactiv pe durata încărcării"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Activați jurnalul de examinare HCI Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Înregistrați pachetele Bluetooth. (Comutați Bluetooth după modificarea setării)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Deblocarea OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Permiteți deblocarea bootloaderului"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Permiteți deblocarea OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Conectare la rețele"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certificare Ecran wireless"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Înregistrare prin Wi-Fi de volume mari de date"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Afișare aleatorie a dispozitivului MAC conectat"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Date mobile permanent active"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Accelerare hardware pentru tethering"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afișați dispozitivele Bluetooth fără nume"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nu s-a putut conecta"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afișați opțiunile pentru certificarea Ecran wireless"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Afișează aleatoriu adresa MAC când te conectezi la rețele Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Contorizată"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Necontorizată"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Dimensiunile tamponului jurnalului"</string>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index bf27fc9..cca30fb 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Использовать проверку HDCP только для DRM-контента"</item>
<item msgid="45075631231212732">"Всегда использовать проверку HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Отключено"</item>
+ <item msgid="1969681323976948639">"Включены фильтры"</item>
+ <item msgid="8719029132154020716">"Включено"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (по умолчанию)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index c71d29b..6cdfd3c 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматически подключено к %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Автоматически подключено через автора рейтинга сетей"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Подключено к %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>, <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Подключено через приложение \"<xliff:g id="NAME">%1$s</xliff:g>\"."</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступно через %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Нажмите, чтобы настроить"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Нажмите, чтобы зарегистрироваться"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Подключено, без доступа к Интернету"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Нет подключения к Интернету"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Требуется выполнить вход."</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"К точке доступа подключено слишком много устройств"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Подключено к %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Доступно через %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Ошибка подключения"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Недействительный URL сервера OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Не удалось подключиться к серверу OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Не удалось выполнить проверку сервера OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Недействительный сертификат сервера OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Синхронизация прервана"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Синхронизация недоступна"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Недействительный URL сервера OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Неизвестный тип команды"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Неизвестный тип сообщения SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Не удалось провести обмен сообщениями SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Не удалось запустить приемник обратных вызовов"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Превышено время ожидания"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Действий OSU не обнаружено"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Неизвестный статус сообщения SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Не удалось найти PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Не удалось найти доверенный корневой узел сервера AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Не удалось найти доверенный корневой узел сервера исправлений"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Не удалось найти доверенный корневой узел сервера правил"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Не удалось получить доверенные корневые сертификаты"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Не удалось найти доверенный корневой сертификат для сервера AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Не удалось добавить настройки Passpoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Не удалось найти поставщика OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Подключение…"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Подключено"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Подключение к серверу OSU…"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Сервер OSU проверен"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Соединение с сервером OSU установлено"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Первый обмен по SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Ожидание ответа для перенаправления…"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Ответ получен"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Второй обмен по SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Третий обмен по SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Получение доверенных корневых сертификатов…"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Синхронизация завершена"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Открытие <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>…"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Не удалось подключиться."</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Завершение регистрации…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Не удалось завершить регистрацию. Нажмите, чтобы повторить попытку."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Регистрация завершена. Подключение…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Очень медленная"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Медленная"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ОК"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Не выключать экран"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Во время зарядки экран будет всегда включен"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Включить журнал HCI Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Сохранять все пакеты Bluetooth (перезапустите Bluetooth после изменения этой настройки)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Заводская разблокировка"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Разрешить разблокировку загрузчика ОС"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Разрешить заводскую разблокировку?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Сети"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Серт. беспроводн. мониторов"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Подробный журнал Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Создание случайных MAC-адресов при подключении по Wi-Fi"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Не отключать мобильный Интернет"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Аппаратное ускорение в режиме модема"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показывать Bluetooth-устройства без названий"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ошибка подключения"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показывать параметры сертификации беспроводных мониторов"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"При выборе Wi‑Fi указывать в журнале RSSI для каждого SSID"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Генерировать случайные MAC-адреса при подключении к сетям Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Сеть с тарификацией трафика"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Сеть без тарификации трафика"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Размер буфера журнала"</string>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 6d8e15b..4cd0b60 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRM අන්තර්ගත සඳහා පමණක් HDCP පරික්ෂාව භාවිතා කරන්න"</item>
<item msgid="45075631231212732">"සැමවිටම HDCP පිරික්සුම භාවිතා කරන්න"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"අබලයි"</item>
+ <item msgid="1969681323976948639">"සබල පෙරහන් කළ"</item>
+ <item msgid="8719029132154020716">"සබලයි"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (පෙරනිමි)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 1daffd9..f85289c6 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s හරහා ස්වයංක්රියව සම්බන්ධ විය"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ජාල ශ්රේණිගත සපයන්නා හරහා ස්වයංක්රියව සම්බන්ධ විය"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s හරහා සම්බන්ධ විය"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> මඟින් <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> හරහා සම්බන්ධයි"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"පිහිටුවීමට තට්ටු කරන්න"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"ලියාපදිංචි වීමට තට්ටු කරන්න"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"සම්බන්ධයි, අන්තර්ජාලය නැත"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"අන්තර්ජාලය නැත"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"පිරීම අවශ්යයි"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ප්රවේශ ලක්ෂ්ය තාවකාලිකව පිරී ඇත"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s හරහා සම්බන්ධ විය"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s හරහා ලබා ගැනීමට හැකිය"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"සබැඳුම අසමත් විය"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"අවලංගු OSU සේවාදායක URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU සේවාදායක සබැඳුම අසමත් විය"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU සේවාදායකය වලංගුකරණය අසමත් විය"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"අවලංගු OSU සේවාදායක සහතිකය"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ප්රතිපාදනය රෝධනය කෙරිණි"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"ප්රතිපාදනය නොමැත"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"අවලංගු OSU සේවාදායක URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"අනපේක්ෂිත විධාන වර්ගය"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"අනපේක්ෂිත SOAP පණිවිඩ වර්ගය"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP පණිවිඩ හුවමාරුව අසමත් විය"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"ප්රතියොමු සවන් දෙන්නා ඇරඹීමට අසමත් විය"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"ප්රතියොමුව සඳහා රැඳීම් කාලය ඉක්මවා ඇත"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU ක්රියාකාරකමක් හමු නොවිණි"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"අනපේක්ෂිත SOAP පණිවිඩ තත්ත්වය"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO සොයා ගැනීමට අසමත් විය"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA සේවාදායකය සඳහා විශ්වාසී මූල නෝඩුව සොයා ගැනීමට අසමත් විය"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ප්රතිව්යවධාන සේවාදායකය සඳහා විශ්වාසී මූල නෝඩුව සොයා ගැනීමට අසමත් විය"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"ප්රතිපත්ති සේවාදායකය සඳහා විශ්වාසී මූල නෝඩුව සොයා ගැනීමට අසමත් විය"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"විශ්වාසී මූල සහතික ලබා ගැනීමට අසමත් විය"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA සේවාදායකය සඳහා විශ්වාසී මූල සහතිකය සොයා ගැනීමට අසමත් විය"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint වින්යාසය එක් කිරීමට අසමත් විය"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU සපයන්නෙකු සොයා ගැනීමට අසමත් විය"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"සබැඳෙමින්"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"සම්බන්ධයි"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU සේවාදායකයට සබැඳෙමින්"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU සේවාදායකය වලංගු කෙරිණි"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU සේවාදායකයට සම්බන්ධිතයි"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"ආරම්භක SOAP හුවමාරුව"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"ප්රතියොමු ප්රතිචාරය සඳහා රැඳෙමින්"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"ප්රතියොමු ප්රතිචාරය ලැබුණි"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"දෙවන SOAP හුවමාරුව"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"තුන්වන SOAP හුවමාරුව"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"විශ්වාසී මූල සහතික ලබා ගනිමින්"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"ප්රතිපාදනය සම්පූර්ණයි"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> විවෘත කරමින්"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"සබැඳීමට නොහැකි විය"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"ලියාපදිංචිය සම්පූර්ණ කරමින්…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"ලියාපදිංචිය සම්පූර්ණ කළ නොහැකි විය. නැවත උත්සාහ කිරීමට තට්ටු කරන්න."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"ලියාපදිංචිය සම්පූර්ණයි. සබැඳෙමින්…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ඉතා මන්දගාමී"</string>
<string name="speed_label_slow" msgid="813109590815810235">"මන්දගාමී"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"හරි"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"අවදියෙන් සිටින්න"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ආරෝපණය වන අතර තුර තීරය නිද්රාවට නොයනු ඇත"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"බ්ලූටූත් HCI ස්නුප් ලොගය සබල කරන්න"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"බ්ලූටූත් පැකට් ග්රහණ කරන්න. (මෙම සැකසීම වෙනස් කළ පසු බ්ලූටූත් ටොගල් කරන්න)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM අඟුල ඇරීම"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"බුට්ලොඩරයට අගුළු ඇර තිබීමට ඉඩ දෙන්න"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM අඟුල ඇරීමට ඉඩ දෙන්න?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"ජාලකරණය"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"නොරැහැන් සංදර්ශක සහතිකය"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"විස්තරාත්මක Wi‑Fi ලොග් කිරීම සබල කරන්න"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"සම්බන්ධිත MAC සසම්භාවීකරණය"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"ජංගම දත්ත සැමවිට ක්රියාකාරීය"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ටෙදරින් දෘඪාංග ත්වරණය"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"නම් නොමැති බ්ලූටූත් උපාංග පෙන්වන්න"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"සම්බන්ධ වීමට නොහැකි විය"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"නොරැහැන් සංදර්ශක සහතිකය සඳහා විකල්ප පෙන්වන්න"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ලොග් මට්ටම වැඩි කරන්න, Wi‑Fi තෝරනයෙහි SSID RSSI අනුව පෙන්වන්න"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi-Fi ජාලවලට සම්බන්ධ වීමේදී MAC ලිපිනය සසම්භාවීකරණය"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"මනිනු ලැබේ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"මනින්නේ නැත"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ලෝගයේ අන්තරාවක ප්රමාණය"</string>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index dfa6994..8a81a943 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Použiť kontrolu HDCP len pre obsah DRM"</item>
<item msgid="45075631231212732">"Vždy používať kontrolu HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Deaktivované"</item>
+ <item msgid="1969681323976948639">"Aktivované filtrované"</item>
+ <item msgid="8719029132154020716">"Aktivované"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (predvolené)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index e6047bb..eae5be7 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaticky pripojené prostredníctvom %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automaticky pripojené prostredníctvom poskytovateľa hodnotenia siete"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Pripojené prostredníctvom %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> – <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Pripojené prostredníctvom siete <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"K dispozícii prostredníctvom %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Klepnutím nastavíte"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Prihláste sa klepnutím"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Pripojené, žiadny internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Žiadny internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Vyžaduje sa prihlásenie"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Prístupový bod je dočasne plný"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Pripojené prostredníctvom operátora %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"K dispozícii prostredníctvom operátora %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Nepodarilo sa pripojiť"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Neplatná webová adresa servera OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Pripojenie servera OSU zlyhalo"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Server OSU sa nepodarilo overiť"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Neplatný certifikát servera OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Údržba bolo prerušená"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Údržba nie je k dispozícii"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Neplatná webová adresa servera OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Neočakávaný typ príkazu"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Neočakávaný typ správy SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Výmena správ SOAP sa nepodarila"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Prijímač presmerovania sa nespustil"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Časový limit čakania na presmerovanie vypršal"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nenašla sa žiadna aktivita OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Neočakávaný stav správy SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Objekt PPS-MO sa nenašiel"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Nepodarilo sa nájsť dôveryhodný koreňový uzol pre server AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Nepodarilo sa nájsť dôveryhodný koreňový uzol pre server opráv"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Nepodarilo sa nájsť dôveryhodný koreňový uzol pre server pravidiel"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Nepodarilo sa načítať dôveryhodné koreňové certifikáty"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Nepodarilo sa nájsť dôveryhodný koreňový certifikát pre server AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Konfiguráciu PassPoint sa nepodarilo pridať"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Poskytovateľ OSU sa nenašiel"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Pripája sa"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Pripojené"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Pripája sa k serveru OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Server OSU bol overený"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Pripojené k serveru OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Počiatočná výmena SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Čaká sa na odpoveď presmerovania"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Bola prijatá odpoveď presmerovania"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Druhá výmena SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Tretia výmena SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Načítavajú sa dôveryhodné koreňové certifikáty"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Poskytovanie bolo dokončené"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Otvára sa <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Nepodarilo sa pripojiť"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Dokončuje sa registrácia…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Registráciu sa nepodarilo dokončiť. Klepnutím to skúste znova."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registrácia je dokončená. Pripája sa…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Veľmi nízka"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Nízka"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Nevypínať obrazovku"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Obrazovka sa pri nabíjaní neprepne do režimu spánku"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Povoliť denník Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Zachytávať pakety rozhrania Bluetooth (Prepnúť Bluetooth po zmene tohto nastavenia.)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Odblokovať OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Povoliť odblokovanie ponuky bootloader"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Povoliť odblokovanie OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Siete"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikácia bezdrôtového zobrazenia"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné denníky Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Randomizácia pripojených adries MAC"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilné dáta ponechať vždy aktívne"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardvérová akcelerácia tetheringu"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Zobrazovať zariadenia Bluetooth bez názvov"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nepodarilo sa pripojiť"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi‑Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Randomizovať adresu MAC pri pripájaní k sieťam Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"S meraním dát"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez merania dát"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávacia pamäť nástroja denníkov"</string>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index fdadbff..62a4ff4 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Preverjanje HDCP uporabi samo za vsebino DRM"</item>
<item msgid="45075631231212732">"Vedno uporabi preverjanje HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Onemogočeno"</item>
+ <item msgid="1969681323976948639">"Omogočeno filtrirano"</item>
+ <item msgid="8719029132154020716">"Omogočeno"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (privzeto)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 3099f12..bef9a3e 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Samodejno vzpostavljena povezava prek: %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Samodejno vzpostavljena povezava prek ponudnika ocenjevanja omrežij"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Vzpostavljena povezava prek: %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> zagotavlja <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Povezava vzpostavljena prek omrežja <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Na voljo prek: %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Dotaknite se za nastavitev"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Dotaknite se, če se želite registrirati"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Vzpostavljena povezava, brez interneta"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Brez internetne povezave"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Zahtevana je prijava"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Dostopna točka je trenutno zasedena"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Vzpostavljena povezava prek: %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Na voljo prek: %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Vzpostavitev povezave ni uspela"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Neveljaven URL strežnika OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Vzpostavitev povezave s strežnikom OSU ni uspela"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Preverjanje veljavnosti strežnika OSU ni uspelo"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Neveljavno potrdilo strežnika OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Omogočanje uporabe je preklicano"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Omogočanje uporabe ni na voljo"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Neveljaven URL strežnika OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Nepričakovana vrsta ukaza"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Nepričakovana vrsta sporočila SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Izmenjava sporočila SOAP ni uspela"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Zagon prisluškovalca preusmeritev ni uspel"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Časovna omejitev čakanja na preusmeritev je potekla"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Najdena ni bila nobena aktivnost OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Nepričakovano stanje sporočila SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO ni bilo mogoče najti"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Zaupanja vrednega korenskega vozlišča za strežnik AAA ni bilo mogoče najti"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Zaupanja vrednega korenskega vozlišča za strežnik za odpravljanje težav ni bilo mogoče najti"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Zaupanja vrednega korenskega vozlišča za strežnik pravilnikov ni bilo mogoče najti"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Zaupanja vrednih korenskih potrdil ni bilo mogoče pridobiti"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Zaupanja vrednega korenskega potrdila za strežnik AAA ni bilo mogoče najti"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Konfiguracije PassPoint ni bilo mogoče dodati"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Ponudnika OSU ni bilo mogoče najti"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Vzpostavljanje povezave"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Povezava je vzpostavljena"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Vzpostavljanje povezave s strežnikom OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Strežnik OSU je preverjen"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Povezava s strežnikom OSU je vzpostavljena"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Začetna izmenjava SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Čakanje na odgovor za preusmeritev"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Prejet je odgovor za preusmeritev"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Druga izmenjava SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Tretja izmenjava SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Pridobivanje zaupanja vrednih korenskih potrdil"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Omogočanje uporabe je končano"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Odpiranje ponudnika <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Povezave ni bilo mogoče vzpostaviti"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Dokončevanje registracije …"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Registracije ni bilo mogoče dokončati. Če želite poskusiti znova, se dotaknite."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registracija je končana. Povezovanje …"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Zelo počasna"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Počasna"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"V redu"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Brez zaklepanja"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Med polnjenjem se zaslon ne bo nikoli zaklenil"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Omogoči zajem dnevnika Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Zajemanje paketov Bluetooth. (po spremembi te nastavitve preklopite Bluetooth)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Odklepanje OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Dovoli odklepanje zagonskega nalagalnika"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Želite omogočiti odklepanje OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Omrežja"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Potrdilo brezžičnega zaslona"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogoči podrob. zapis. dnevnika za Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Dodelitev naključnega naslova MAC ob vzpostavitvi povezave"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Prenos podatkov v mobilnem omrežju je vedno aktiven"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Strojno pospeševanje za internetno povezavo prek mobilnega telefona"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži naprave Bluetooth brez imen"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezave ni bilo mogoče vzpostaviti"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži možnosti za potrdilo brezžičnega zaslona"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapis. dnev. za Wi-Fi; v izbir. Wi‑Fi-ja pokaži glede na SSID RSSI"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Dodelitev naključnega naslova MAC pri povezovanju z omrežji Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Z omejenim prenosom podatkov"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Z neomejenim prenosom podatkov"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Velikosti medpomn. zapisov. dnevnika"</string>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 3128eb7..4dab74c 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Përdor kontrollin e HDCP-së vetëm për përmbajtjet DRM"</item>
<item msgid="45075631231212732">"Përdor gjithmonë kontrollin e HDCP-së"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Joaktiv"</item>
+ <item msgid="1969681323976948639">"Të aktivizuara të filtruara"</item>
+ <item msgid="8719029132154020716">"Aktiv"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (I parazgjedhur)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 6716cfc..8bb67f9 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Lidhur automatikisht përmes %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Lidhur automatikisht nëpërmjet ofruesit të vlerësimit të rrjetit"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"E lidhur përmes %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> nga <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Lidhur përmes <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"E mundshme përmes %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Trokit për ta konfiguruar"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Trokit për t\'u regjistruar"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"U lidh, por nuk ka internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Nuk ka internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Kërkohet identifikimi"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pika e qasjes është përkohësisht plot"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"E lidhur përmes %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"E disponueshme përmes %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Lidhja dështoi"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL e pavlefshme e serverit të OSU-së"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Lidhja e serverit të OSU-së dështoi"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Verifikimi i serverit të OSU-së dështoi"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Certifikatë e pavlefshme e serverit të OSU-së"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Përgatitja u ndërpre"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Përgatitja nuk ofrohet"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL e pavlefshme e serverit të OSU-së"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Lloj i papritur komande"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Lloji i papritur i mesazhit SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Mesazhi i shkëmbimit të SOAP-it dështoi"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Dështoi nisja e dëgjuesit të ridrejtimit"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Pritja për ridrejtim skadoi"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Nuk u gjet aktivitet i OSU-së"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Status i papritur i mesazhit të SOAP-it"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Dështoi gjetja e PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Dështoi gjetja e nyjës rrënjë të besuar për serverin e AAA-së"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Dështoi gjetja e nyjës rrënjë të besuar për serverin e zgjidhjes"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Dështoi gjetja e nyjës rrënjë të besuar për serverin e politikës"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Dështoi marrja e certifikatave rrënjë të besuara"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Dështoi gjetja e certifikatës rrënjë të besuar për serverin e AAA-së"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Dështoi shtimi i konfigurimit të PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Dështoi gjetja e një ofruesi të OSU-së"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Po lidhet"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Lidhur"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Po lidhe me serverin e OSU-së"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Serveri i OSU-së u verifikua"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Lidhur me serverin e OSU-së"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Shkëmbimi fillestar i SOAP-it"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Në pritje të përgjigjes së ridrejtimit"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"U mor përgjigje ridrejtimi"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Shkëmbimi i dytë i SOAP-it"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Shkëmbimi i tretë i SOAP-it"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Po merr certifikatat rrënjë të besuara"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Përgatitja përfundoi"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Po hapet <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Nuk mund të lidhej"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Po përfundon regjistrimin…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Regjistrimi nuk mund të përfundonte. Trokit për të provuar përsëri."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Regjistrimi përfundoi. Po lidhet…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Shumë e ulët"</string>
<string name="speed_label_slow" msgid="813109590815810235">"E ngadaltë"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Në rregull"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Qëndro zgjuar"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Ekrani nuk do të kalojë asnjëherë në gjendje gjumi gjatë ngarkimit"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Aktivizo regjistrin testues të paketave HCI të Bluetooth-it"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Regjistro paketat e Bluetooth-it. (Ndrysho Bluetooth-in pas ndryshimit të këtij cilësimi)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Shkyçja e OEM-së"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Lejo shkyçjen e ngarkimit të sistemit"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Të lejohet shkyçja e OEM-së?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Rrjetet"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifikimi i ekranit valor"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivizo hyrjen Wi-Fi Verbose"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Zgjedhja e rastësishme e adresave MAC të lidhura"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Të dhënat celulare gjithmonë aktive"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Përshpejtimi i harduerit për ndarjen e lidhjes (internet)"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Shfaq pajisjet me Bluetooth pa emra"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nuk mund të lidhej"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Shfaq opsionet për certifikimin e ekranit valor"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Zgjidh rastësisht adresën MAC kur lidhesh me rrjete Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Me matje"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Pa matje"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Madhësitë e regjistruesit"</string>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index b735b47..3ed9cd9 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Користи HDCP проверу само за DRM садржај"</item>
<item msgid="45075631231212732">"Увек користи HDCP проверу"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Онемогућено"</item>
+ <item msgid="1969681323976948639">"Омогућено филтрирано"</item>
+ <item msgid="8719029132154020716">"Омогућено"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (подразумевано)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 0285605..4378a46 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Аутоматски повезано преко %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Аутоматски повезано преко добављача оцене мреже"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Веза је успостављена преко приступне тачке %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> – <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Повезано преко: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступна је преко приступне тачке %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Додирните да бисте подесили"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Додирните да бисте се регистровали"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Веза је успостављена, нема интернета"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Нема интернета"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Треба да се пријавите"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Приступна тачка је привремено заузета"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Повезано преко %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Доступно преко %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Повезивање није успело"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Неважећи URL OSU сервера"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Повезивање са OSU сервером није успело"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Потврда OSU сервера није успела"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Неважећи сертификат OSU сервера"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Додела је отказана"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Додела није доступна"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Неважећи URL OSU сервера"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Неочекивани тип команде"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Неочекивани тип SOAP поруке"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Размена SOAP порука није успела"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Покретање обрађивача преусмеравања није успело"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Време чекања преусмеравања је истекло"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Није пронађена ниједна OSU активност"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Неочекивани статус SOAP поруке"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO није пронађен"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Поуздани чвор основног нивоа за AAA сервер није пронађен"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Поуздани чвор основног нивоа за сервер за отклањање пропуста није пронађен"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Поуздани чвор основног нивоа за сервер за смернице није пронађен"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Преузимање поузданих сертификата основног нивоа није успело"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Поуздани сертификат основног нивоа за сервер AAA није пронађен"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Додавање PassPoint конфигурације није успело"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU добављач није пронађен"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Повезује се"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Повезан"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Повезујете се са OSU сервером"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Потврђен је OSU сервер"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Веза са OSU сервером је успостављена"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Прва размена SOAP-а"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Чека се одговор о преусмеравању"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Примљен је одговор о преусмеравању"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Друга размена SOAP-а"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Трећа размена SOAP-а"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Преузимају се поуздани сертификати основног нивоа"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Додела приступа је завршена"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Отвара се <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Повезивање није успело"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Регистрација се довршава…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Довршавање регистрације није успело. Додирните да бисте пробали поново."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Регистрација је довршена. Повезује се…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Веома спора"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Спора"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Потврди"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Не закључавај"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Екран неће бити у режиму спавања током пуњења"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Омогући snoop евиденцију за Bluetooth HCI"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Сними Bluetooth пакете. (Укључите/искључите Bluetooth када промените ово подешавање)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Откључавање OEM-a"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Дозволи откључавање функције за покретање"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Желите ли да дозволите откључавање произвођача оригиналне опреме (OEM)?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Умрежавање"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Сертификација бежичног екрана"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Омогући детаљнију евиденцију за Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Насумичан избор MAC адресе током повезивања"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилни подаци су увек активни"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско убрзање привезивања"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Прикажи Bluetooth уређаје без назива"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Повезивање није успело"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Приказ опција за сертификацију бежичног екрана"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Изабери насумичну MAC адресу током повезивања на Wi‑Fi мреже"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Са ограничењем"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Без ограничења"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Величине бафера података у програму за евидентирање"</string>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index fc4d17f..1a4ee00 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Använd bara HDCP-kontroll för DRM-innehåll"</item>
<item msgid="45075631231212732">"Använd alltid HDCP-kontroll"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Inaktiverat"</item>
+ <item msgid="1969681323976948639">"Filtrering har aktiverats"</item>
+ <item msgid="8719029132154020716">"Aktiverad"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (standard)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index fd7bb0b..3fcb6dc 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automatiskt ansluten via %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automatiskt ansluten via leverantör av nätverksbetyg"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Anslutet via %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> av <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Anslutet via <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Tillgängligt via %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Tryck för att konfigurera"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Tryck för att logga in"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Ansluten, inget internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Inget internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Inloggning krävs"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Åtkomstpunkten har inga platser över för tillfället"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Anslutet via %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Tillgängligt via %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Anslutningen misslyckades"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Ogiltig webbadress för OSU-server"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Det gick inte att ansluta till OSU-servern"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU-servervalideringen misslyckades"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Ogiltigt certifikat för OSU-server"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Utfärdandet avbröts"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Utfärdande ej tillgängligt"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Ogiltig webbadress för OSU-server"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Oväntad kommandotyp"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Oväntad meddelandetyp för SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Utväxlingen av SOAP-meddelanden misslyckades"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Det gick inte att starta omdirigeringslyssnaren"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Väntetiden för omdirigering överskreds"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Ingen OSU-aktivitet hittades"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Oväntad status för SOAP-meddelande"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Inget PPS-MO hittades"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Det gick inte att hitta någon betrodd rotnod för AAA-servern"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Det gick inte att hitta någon betrodd rotnod för åtgärdsservern"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Det gick inte att hitta någon betrodd rotnod för policyservern"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Det gick inte att hämta betrodda rotcertifikat"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Det gick inte att hitta någon betrodd rotnod för AAA-servern"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Det gick inte att lägga till PassPoint-konfigurationen"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Ingen OSU-leverantör hittades"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Ansluter"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Ansluten"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Ansluter till OSU-server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU-servern har validerats"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Ansluten till OSU-server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Första SOAP-utväxlingen"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Väntar på omdirigeringssvar"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Omdirigeringssvar mottaget"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Andra SOAP-utväxlingen"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Tredje SOAP-utväxlingen"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Hämtar betrodda rotcertifikat"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Utfärdandet har slutförts"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Öppnar <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Det gick inte att ansluta"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Registreringen slutförs …"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Det gick inte att slutföra registreringen. Tryck för att försöka igen."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registrering slutförd. Ansluter …"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Mycket långsam"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Långsam"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Okej"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Håll aktiverad"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Skärmen vilar aldrig när laddning pågår"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Aktivera HCI snoop-logg för Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Registrera paket för Bluetooth. (Aktivera och inaktivera Bluetooth när inställningen har ändrats)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-upplåsning"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Tillåt att bootloadern låses upp"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Vill du tillåta OEM-upplåsning?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Nätverk"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certifiering för Wi-Fi-skärmdelning"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivera utförlig loggning för Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Ansluten MAC-slumpgenerering"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata alltid aktiverad"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvaruacceleration för internetdelning"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Visa namnlösa Bluetooth-enheter"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kan inte ansluta"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Visa certifieringsalternativ för Wi-Fi-skärmdelning"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Öka loggningsnivån för Wi-Fi, visa per SSID RSSI i Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Generera en slumpmässig MAC-adress när du ansluter till Wi‑Fi-nätverk"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Med datapriser"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Utan datapriser"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Buffertstorlekar för logg"</string>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index e7f6dd6..a05797e 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Tumia ukaguaji wa HDCP kwa maudhui ya DRM pekee"</item>
<item msgid="45075631231212732">"Kila wakati tumia ukakuaji wa HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Imezimwa"</item>
+ <item msgid="1969681323976948639">"Vichujio Vilivyowekwa"</item>
+ <item msgid="8719029132154020716">"Imewashwa"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Chaguomsingi)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 6d6b571..47c7bb2 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Imeunganishwa kiotomatiki kupitia %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Imeunganishwa kiotomatiki kupitia mtoa huduma wa ukadiriaji wa mtandao"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Imeunganishwa kupitia %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> kutoka <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Imeunganishwa kupitia <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Inapatikana kupitia %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Gusa ili uweke mipangilio"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Gusa ili ujisajili"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Imeunganishwa, hakuna intaneti"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Hakuna intaneti"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Unahitaji kuingia katika akaunti"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Lango la mtandao lina shughuli nyingi kwa sasa"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Imeunganishwa kupitia %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Inapatikana kupitia %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Imeshindwa kuunganisha"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL ya seva ya OSU si sahihi"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Imeshindwa kuunganisha seva ya OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Imeshindwa kuthibitisha seva ya OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Cheti cha seva ya OSU si sahihi"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Imeghairi mchakato wa kupanga"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Kipengele cha kupanga hakipatikani"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL ya seva ya OSU si sahihi"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Aina ya amri isiyotarajiwa"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Aina ya ujumbe wa SOAP usiotarajiwa"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Imeshindwa kubadilisha ujumbe wa SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Imeshindwa kuanzisha kisikilizaji cha kuelekeza kwingine"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Muda umeisha ikisubiri kuelekeza kwingine"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Hakuna shughuli ya OSU iliyopatikana"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Hali isiyotarajiwa ya ujumbe wa SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Imeshindwa kupata PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Imeshindwa kupata cheti msingi cha seva ya AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Imeshindwa kupata njia ya chanzo kinachoaminika cha seva ya utatuzi"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Imeshindwa kupata njia ya chanzo kinachoaminika cha seva ya sera"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Imeshindwa kuleta vyeti vya msingi vinavyoaminika"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Imeshindwa kupata cheti cha msingi kinachoaminika cha seva ya AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Imeshindwa kuongeza mipangilio ya PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Imeshindwa kupata mtoa huduma wa OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Inaunganisha"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Imeunganisha"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Inaunganisha kwenye seva ya OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Imethibitisha seva ya OSU"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Imeunganishwa kwenye seva ya OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Mabadiliko ya kwanza ya SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Inasubiri jibu la kuelekeza kwingine"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Imepokea jibu la kuelekeza kwingine"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Kubadilisha SOAP mara ya pili"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Kubadilisha SOAP mara ya tatu"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Inaleta vyeti vya msingi vinavyoaminika"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Imekamilisha kupanga"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Inafungua <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Imeshindwa kuunganisha"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Inakamilisha usajili…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Imeshindwa kukamilisha usajili. Gusa ili ujaribu tena."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Imekamilisha kusajili. Inaunganisha…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Polepole Sana"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Polepole"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Sawa"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Weka skrini ikiwa imewashwa"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Skrini haitawahi kuzima wakati unachaji"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Washa kumbukumbu ya Bluetooth HCI Snoop"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Aina za paketi za Bluetooth. (Washa Bluetooth baada ya kubadilisha mipangilio hii)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Ufunguaji wa OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Ruhusu bootloader ifunguliwe"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Je, ungependa kuruhusu ufunguaji wa OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Mtandao"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Chaguo za cheti cha kuonyesha pasiwaya"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Washa Uwekaji kumbukumbu za WiFi kutumia Sauti"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Anwani za MAC Zinazowekwa kwa Nasibu"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Iendelee kutumia data ya simu"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Kuongeza kasi kwa kutumia maunzi ili kusambaza mtandao"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Onyesha vifaa vya Bluetooth visivyo na majina"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Imeshindwa kuunganisha"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Onyesha chaguo za cheti cha kuonyesha pasiwaya"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Ongeza hatua ya uwekaji kumbukumbu ya Wi-Fi, onyesha kwa kila SSID RSSI kwenye Kichukuzi cha Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Weka anwani ya MAC kwa nasibu wakati unaunganisha kwenye mitandao ya Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Mtandao unapima data"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Mtandao usiopima data"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Ukubwa wa kiweka bafa ya kumbukumbu"</string>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 02c1623..a7839f6 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRM உள்ளடக்கத்திற்கு மட்டும் HDCP சோதனையைப் பயன்படுத்து"</item>
<item msgid="45075631231212732">"HDCP சரிபார்ப்பை எப்போதும் பயன்படுத்து"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"முடக்கப்பட்டது"</item>
+ <item msgid="1969681323976948639">"இயக்கப்பட்டு வடிகட்டப்பட்டது"</item>
+ <item msgid="8719029132154020716">"இயக்கப்பட்டது"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (இயல்பு)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index f83b1a7..63c6cd9 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -38,50 +38,27 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s மூலம் தானாக இணைக்கப்பட்டது"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"நெட்வொர்க் மதிப்பீடு வழங்குநரால் தானாக இணைக்கப்பட்டது"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s வழியாக இணைக்கப்பட்டது"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> இன் <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <!-- no translation found for connected_via_app (5571999941988929520) -->
+ <skip />
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s வழியாகக் கிடைக்கிறது"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"அமைப்பதற்குத் தட்ட வேண்டும்"</string>
+ <!-- no translation found for tap_to_sign_up (6449724763052579434) -->
+ <skip />
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"இணைக்கப்பட்டுள்ளது, ஆனால் இண்டர்நெட் இல்லை"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"இணைய இணைப்பு இல்லை"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"உள்நுழைய வேண்டும்"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"தற்காலிகமாக அணுகல் புள்ளி நிரம்பியுள்ளது"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s வழியாக இணைக்கப்பட்டது"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s வழியாகக் கிடைக்கிறது"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"இணைக்க இயலவில்லை"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU சேவையகத்தின் URL தவறானது"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU சேவையகத்துடன் இணைக்க இயலவில்லை"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU சேவையகத்தைச் சரிபார்க்க இயலவில்லை"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU சேவையகத்தின் சான்றிதழ் தவறானது"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"புரொவிஷனிங் ரத்துசெய்யப்பட்டது"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"புரொவிஷனிங் இல்லை"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU சேவையகத்தின் URL தவறானது"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"எதிர்பாராத கட்டளை வகை"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"எதிர்பாராத SOAP மெசேஜ் வகை"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP மெசேஜ் பரிமாற்றம் தோல்வியடைந்தது"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"திசைதிருப்புதலைக் கேட்கும் அம்சம் தொடங்கவில்லை"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"திசைதிருப்புதலுக்கான காத்திருப்பு நேரம் முடிந்துவிட்டது"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU செயல்பாடு காணப்படவில்லை"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"எதிர்பாராத SOAP மெசேஜ் நிலை"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MOவைக் கண்டறிய இயலவில்லை"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA சேவையகத்தின் நம்பகமான முதன்மை நோடைக் கண்டறிய இயலவில்லை"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"சிக்கல் தீர்க்கும் சேவையகத்தின் நம்பகமான முதன்மை நோடைக் கண்டறிய இயலவில்லை"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"கொள்கைச் சேவையகத்தின் நம்பகமான முதன்மை நோடைக் கண்டறிய இயலவில்லை"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"நம்பகமான முதன்மைச் சான்றிதழ்களை மீட்டெடுக்க இயலவில்லை"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA சேவையகத்தின் நம்பகமான முதன்மைச் சான்றிதழைக் கண்டறிய இயலவில்லை"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint உள்ளமைவைச் சேர்க்க இயலவில்லை"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU வழங்குநரைக் கண்டறிய இயலவில்லை"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"இணைக்கிறது"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"இணைக்கப்பட்டது"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU சேவையகத்துடன் இணைக்கிறது"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU சேவையகம் சரிபார்க்கப்பட்டது"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU சேவையகத்துடன் இணைக்கப்பட்டது"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"முதல் SOAP பரிமாற்றம்"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"திசைதிருப்புதலுக்கான பதிலுக்குக் காத்திருக்கிறது"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"திசைதிருப்புதலுக்கான பதில் பெறப்பட்டது"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"இரண்டாம் SOAP பரிமாற்றம்"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"மூன்றாம் SOAP பரிமாற்றம்"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"நம்பகமான முதன்மைச் சான்றிதழ்களை மீட்டெடுக்கிறது"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"புரொவிஷனிங் நிறைவடைந்தது"</string>
+ <!-- no translation found for osu_opening_provider (5488997661548640424) -->
+ <skip />
+ <!-- no translation found for osu_connect_failed (2187750899158158934) -->
+ <skip />
+ <!-- no translation found for osu_completing_sign_up (9037638564719197082) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_failed (7296159750352873260) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_complete (8207626049093289203) -->
+ <skip />
<string name="speed_label_very_slow" msgid="1867055264243608530">"மிகவும் வேகம் குறைவானது"</string>
<string name="speed_label_slow" msgid="813109590815810235">"வேகம் குறைவு"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"சரி"</string>
@@ -234,8 +211,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"செயலில் வைத்திரு"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"சார்ஜ் ஏறும்போது திரை எப்போதும் உறக்கநிலைக்குச் செல்லாது"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"புளூடூத் HCI ஸ்னுப் பதிவை இயக்கு"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"புளூடூத் பேக்கெட்டுகளைக் கண்டறி. (இந்த அமைப்பை மாற்றிய பின்பு, புளூடூத்தை மாற்று)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM திறத்தல்"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"பூட்லோடரைத் திறக்க அனுமதி"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM திறத்தலை அனுமதிக்கவா?"</string>
@@ -246,7 +222,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"நெட்வொர்க்கிங்"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"வயர்லெஸ் காட்சிக்கான சான்றிதழ்"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"வைஃபை அதிவிவர நுழைவை இயக்கு"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"இணைக்கப்பட்ட MAC ரேண்டம் ஆக்குதல்"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"மொபைல் டேட்டாவை எப்போதும் இயக்கத்திலேயே வை"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"பெயர்கள் இல்லாத புளூடூத் சாதனங்களைக் காட்டு"</string>
@@ -273,7 +248,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"இணைக்க முடியவில்லை"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டு"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"வைஃபை நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"வைஃபை நெட்வொர்க்குகளில் இணைக்கும்போது MAC முகவரிகளை ரேண்டம் ஆக்கு"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"கட்டண நெட்வொர்க்"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"கட்டணமில்லா நெட்வொர்க்"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"லாகர் பஃபர் அளவுகள்"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index 6d5a16b..22d57ef 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"DRM కంటెంట్కు మాత్రమే HDCP తనిఖీని ఉపయోగించండి"</item>
<item msgid="45075631231212732">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించు"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"నిలిపివేయబడింది"</item>
+ <item msgid="1969681323976948639">"ప్రారంభించబడింది ఫిల్టర్ చేయబడింది"</item>
+ <item msgid="8719029132154020716">"ప్రారంభించబడింది"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (డిఫాల్ట్)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index e4e0e41..d8ec167 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ద్వారా స్వయంచాలకంగా కనెక్ట్ చేయబడింది"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"నెట్వర్క్ రేటింగ్ ప్రదాత ద్వారా స్వయంచాలకంగా కనెక్ట్ చేయబడింది"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> ద్వారా <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> ద్వారా కనెక్ట్ చేయబడింది"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"సెటప్ చేయడానికి నొక్కండి"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"సైన్ అప్ చేయడానికి నొక్కండి"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"కనెక్ట్ చేయబడింది, ఇంటర్నెట్ లేదు"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ఇంటర్నెట్ లేదు"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"సైన్ ఇన్ చేయాలి"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"యాక్సెస్ పాయింట్ తాత్కాలికంగా నిండుకుంది"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ద్వారా కనెక్ట్ చేయబడింది"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s ద్వారా అందుబాటులో ఉంది"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"కనెక్షన్ విఫలమైంది"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"చెల్లని OSU సర్వర్ URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU సర్వర్ కనెక్షన్ విఫలమైంది"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU సర్వర్ ప్రామాణీకరణ విఫలమైంది"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"చెల్లని OSU సర్వర్ సర్టిఫికెట్"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"కేటాయింపు రద్దు చేయబడింది"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"కేటాయింపు అందుబాటులో లేదు"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"చెల్లని OSU సర్వర్ URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ఊహించని ఆదేశ రకం"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ఊహించని SOAP సందేశ రకం"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP సందేశ మార్పిడి విఫలమైంది"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"మళ్లింపు పరిశీలన ప్రారంభమవడం విఫలమైంది"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"మళ్లింపు కోసం వేచి ఉండటంలో సమయం ముగిసింది"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"ఏ OSU కార్యకలాపం కనుగొనబడలేదు"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"ఊహించని SOAP సందేశ స్థితి"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO కనుగొనడం విఫలమైంది."</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA సర్వర్ కోసం మూల విశ్వసనీయత కనుగొనడంలో విఫలమైంది."</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"నివారణోపాయం సర్వర్ విశ్వసనీయత మూల నోడ్ను కనుగొనడం విఫలమైంది"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"విధాన సర్వర్ కోసం మూల విశ్వసనీయత కనుగొనడంలో విఫలమైంది."</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"విశ్వసనీయ రూట్ సర్టిఫికెట్లు తిరిగి పొందడం విఫలమైంది."</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA సర్వర్ కోసం రూట్ సర్టిఫికెట్ విశ్వసనీయత కనుగొనడం విఫలమైంది."</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"కాన్ఫిగరేషన్ పాయింట్ జోడించడం విఫలమైంది."</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"ఒక OSU ప్రొవైడర్ని కనుగొనడం విఫలమైంది"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"కనెక్ట్ చేయబడుతోంది"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"కనెక్ట్ చేయబడింది"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU సర్వర్కి కనెక్ట్ చేయబడుతోంది…"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU సర్వర్ ప్రామాణీకరించబడింది"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU సర్వర్కి కనెక్ట్ చేయబడింది"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"ప్రారంభ SOAP మార్పిడి"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"మళ్లింపు ప్రతిస్పందన కోసం వేచి ఉంది"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"మళ్లింపు ప్రతిస్పందన స్వీకరించబడింది"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"రెండవ SOAP మార్పిడి"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"మూడో SOAP మార్పిడి"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"విశ్వసనీయ రూట్ సర్టిఫికెట్లను తిరిగి పొందుతోంది"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"కేటాయింపు పూర్తయింది"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> తెరవబడుతోంది"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"సైన్ అప్ పూర్తివుతోంది…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"సైన్ అప్ను పూర్తి చేయడం సాధ్య పడలేదు. మళ్లీ ప్రయత్నించడానికి నొక్కండి."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"సైన్ అప్ పూర్తయింది. కనెక్ట్ చేయబడుతోంది…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"చాలా నెమ్మది"</string>
<string name="speed_label_slow" msgid="813109590815810235">"నెమ్మది"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"సరే"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"యాక్టివ్గా ఉంచు"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"ఛార్జ్ చేస్తున్నప్పుడు స్క్రీన్ ఎప్పటికీ నిద్రావస్థలోకి వెళ్లదు"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"బ్లూటూత్ HCI రహస్య లాగ్ను ప్రారంభించు"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"బ్లూటూత్ ప్యాకెట్లను క్యాప్చర్ చేయి. (ఈ సెట్టింగ్ని మార్చిన తర్వాత బ్లూటూత్ని టోగుల్ చేయండి)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM అన్లాకింగ్"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"బూట్లోడర్ అన్లాక్ కావడానికి అనుమతించు"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM అన్లాకింగ్ను అనుమతించాలా?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"నెట్వర్కింగ్"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"వైర్లెస్ ప్రదర్శన ప్రమాణీకరణ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi విశదీకృత లాగింగ్ను ప్రారంభించండి"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"కనెక్ట్ చేయబడిన MAC చిరునామాలను యాదృచ్ఛికం చేయడం"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"మొబైల్ డేటాని ఎల్లప్పుడూ యాక్టివ్గా ఉంచు"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"టెథెరింగ్ హార్డ్వేర్ వేగవృద్ధి"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"పేర్లు లేని బ్లూటూత్ పరికరాలు చూపించు"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"వైర్లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi-Fi నెట్వర్క్కు కనెక్ట్ చేస్తున్నప్పుడు MAC చిరునామాను యాదృచ్ఛికం చేయండి"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"గణించబడుతోంది"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"గణించబడటం లేదు"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"లాగర్ బఫర్ పరిమాణాలు"</string>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 2b65080..62cd9875 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"ใช้การตรวจสอบ HDCP สำหรับเนื้อหา DRM เท่านั้น"</item>
<item msgid="45075631231212732">"ใช้การตรวจสอบ HDCP เสมอ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"ปิดใช้"</item>
+ <item msgid="1969681323976948639">"เปิดใช้รายการที่กรอง"</item>
+ <item msgid="8719029132154020716">"เปิดใช้"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ค่าเริ่มต้น)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index b7a7019..1f4c727 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"เชื่อมต่ออัตโนมัติผ่าน %1$s แล้ว"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"เชื่อมต่ออัตโนมัติผ่านผู้ให้บริการการจัดอันดับเครือข่าย"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> โดย <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"เชื่อมต่อแล้วผ่าน <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"พร้อมใช้งานผ่านทาง %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"แตะเพื่อตั้งค่า"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"แตะเพื่อลงชื่อสมัครใช้"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"เชื่อมต่อแล้ว ไม่พบอินเทอร์เน็ต"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"ไม่มีอินเทอร์เน็ต"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"ต้องลงชื่อเข้าใช้"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"จุดเข้าใช้งานเต็มชั่วคราว"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"เชื่อมต่อผ่าน %1$s แล้ว"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"พร้อมใช้งานผ่านทาง %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"การเชื่อมต่อล้มเหลว"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL ของเซิร์ฟเวอร์ OSU ไม่ถูกต้อง"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"การเชื่อมต่อเซิร์ฟเวอร์ OSU ล้มเหลว"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"การตรวจสอบเซิร์ฟเวอร์ OSU ล้มเหลว"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"ใบรับรองเซิร์ฟเวอร์ OSU ไม่ถูกต้อง"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"ล้มเลิกการจัดสรรแล้ว"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"การจัดสรรไม่พร้อมใช้งาน"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL ของเซิร์ฟเวอร์ OSU ไม่ถูกต้อง"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"ประเภทคำสั่งที่ไม่คาดคิด"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"ประเภทข้อความ SOAP ที่ไม่คาดคิด"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"การแลกเปลี่ยนข้อความ SOAP ล้มเหลว"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"เริ่มการเปลี่ยนเส้นทางผู้ฟังไม่สำเร็จ"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"หมดเวลาการอการเปลี่ยนเส้นทางแล้ว"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"ไม่พบกิจกรรม OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"สถานะข้อความ SOAP ที่ไม่คาดคิด"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"ค้นหา PPS-MO ไม่สำเร็จ"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"ค้นหาโหนดรากที่เชื่อถือได้สำหรับเซิร์ฟเวอร์ AAA ไม่สำเร็จ"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"ค้นหาโหนดระดับรากที่เชื่อถือได้สำหรับเซิร์ฟเวอร์การแก้ไขไม่สำเร็จ"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"ค้นหาโหนดระดับรากที่เชื่อถือได้สำหรับเซิร์ฟเวอร์นโยบายไม่สำเร็จ"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"เรียกดูใบรับรองรูทที่เชื่อถือได้ไม่สำเร็จ"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"ค้นหาใบรับรองรูทที่เชื่อถือได้สำหรับเซิร์ฟเวอร์ AAA ไม่สำเร็จ"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"เพิ่มการกำหนดค่า PassPoint ไม่สำเร็จ"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"ค้นหาผู้ให้บริการ OSU ไม่สำเร็จ"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"กำลังเชื่อมต่อ"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"เชื่อมต่อแล้ว"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"กำลังเชื่อมต่อกับเซิร์ฟเวอร์ OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"ตรวจสอบเซิร์ฟเวอร์ OSU แล้ว"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"เชื่อมต่อกับเซิร์ฟเวอร์ OSU แล้ว"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"การแลกเปลี่ยน SOAP เริ่มต้น"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"กำลังรอการตอบสนองการเปลี่ยนเส้นทาง"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"ได้รับการตอบสนองการเปลี่ยนเส้นทางแล้ว"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"การแลกเปลี่ยน SOAP ที่สอง"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"การแลกเปลี่ยน SOAP ที่สาม"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"กำลังเรียกดูใบรับรองรูทที่เชื่อถือได้"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"การจัดสรรเสร็จสมบูรณ์"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"กำลังเปิด <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"เชื่อมต่อไม่ได้"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"กำลังลงชื่อสมัครใช้ให้เสร็จสิ้น…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"ลงชื่อสมัครใช้ให้เสร็จสิ้นไม่ได้ แตะเพื่อลองอีกครั้ง"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"การลงชื่อสมัครใช้เสร็จสมบูรณ์ กำลังเชื่อมต่อ…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"ช้ามาก"</string>
<string name="speed_label_slow" msgid="813109590815810235">"ช้า"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ตกลง"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"เปิดหน้าจอค้าง"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"หน้าจอจะไม่เข้าสู่โหมดสลีปขณะชาร์จ"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"เปิดใช้งานบันทึก HCI Snoop ของบลูทูธ"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"บันทึกแพ็กเก็ตบลูทูธ (ปิด-เปิดบลูทูธหลังจากเปลี่ยนการตั้งค่านี้)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"การปลดล็อก OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"อนุญาตให้ปลดล็อกตัวโหลดการเปิดเครื่อง"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"อนุญาตการปลดล็อก OEM ไหม"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"เครือข่าย"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"การรับรองการแสดงผลแบบไร้สาย"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"เปิดใช้การบันทึกรายละเอียด Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"การสุ่ม MAC ที่เชื่อมต่อ"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"เปิดใช้เน็ตมือถือเสมอ"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"การเร่งฮาร์ดแวร์การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"แสดงอุปกรณ์บลูทูธที่ไม่มีชื่อ"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"เชื่อมต่อไม่ได้"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"แสดงตัวเลือกสำหรับการรับรองการแสดงผล แบบไร้สาย"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"สุ่มที่อยู่ MAC เมื่อเชื่อมต่อกับเครือข่าย Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"มีการวัดปริมาณอินเทอร์เน็ต"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"ไม่มีการวัดปริมาณอินเทอร์เน็ต"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"ขนาดบัฟเฟอร์ของตัวบันทึก"</string>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 8e3aaf7..cfab9c1 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Gamitin lang ang pagsusuring HDCP para sa nilalamang DRM"</item>
<item msgid="45075631231212732">"Palaging gumamit ng pagsusuring HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Naka-disable"</item>
+ <item msgid="1969681323976948639">"Na-enable Na-filter"</item>
+ <item msgid="8719029132154020716">"Naka-enable"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Default)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 4f92302..7a31cc9e 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Awtomatikong nakakonekta sa pamamagitan ng %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Awtomatikong nakakonekta sa pamamagitan ng provider ng rating ng network"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Nakakonekta sa pamamagitan ng %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> ni <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Nakakonekta sa pamamagitan ng <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Available sa pamamagitan ng %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Mag-tap para i-set up"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"I-tap para mag-sign up"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Nakakonekta, walang internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Walang internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Kinakailangang mag-sign in"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Pansamantalang puno ang access point"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Nakakonekta sa pamamagitan ng %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Available sa pamamagitan ng %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Hindi nakakonekta"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Invalid na URL ng OSU server"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Hindi nakakonekta sa OSU server"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Hindi na-validate ang OSU server"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Invalid na certificate ng OSU server"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Na-abort ang provisioning"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Hindi available ang provisioning"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Invalid na URL ng OSU server"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Hindi inaasahang uri ng command"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Hindi inaasahang uri ng mensahe ng SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Hindi nakapagpalitan ng mensahe ng SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Hindi nakapagsimula ang listener ng pag-redirect"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Nag-time out sa paghihintay ng pag-redirect"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Walang nakitang aktibidad ng OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Hindi inaasahang status ng mensahe ng SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Hindi nakakita ng PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Hindi nakakita ng trust root node para sa AAA server"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Hindi nakita ang trust root node para sa server ng pagremedyo"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Hindi nakita ang trust root node para sa server ng patakaran"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Hindi nakuha ang mga trust root certificate"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Hindi nakita ang trust root certificate para sa AAA server"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Hindi naidagdag ang configuration ng PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Hindi nakakita ng OSU provider"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Kumokonekta"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Nakakonekta"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Kumokonekta sa OSU server"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Na-validate na ang OSU server"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Nakakonekta sa OSU server"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Paunang pakikipagpalitan ng SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Naghihintay ng tugon sa pag-redirect"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Nakatanggap ng tugon sa pag-redirect"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Pangalawang pakikipagpalitan ng SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Pangatlong pakikipagpalitan ng SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Kinukuha ang mga trust root certificate"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Tapos na ang provisioning"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Binubuksan ang <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Hindi makakonekta"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Kinukumpleto ang pag-sign up…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Hindi makumpleto ang pag-sign up. I-tap para subukang muli."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Kumpleto na ang pag-sign up. Kumokonekta…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Napakabagal"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Mabagal"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Manatiling gumagana"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Hindi kailanman hihinto ang screen kapag kinakargahan"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"I-enable ang Bluetooth HCI snoop log"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"I-capture ang mga Bluetooth packet. (I-toggle ang Bluetooth pagkatapos baguhin ang setting na ito)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Pag-a-unlock ng OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Payagan na ma-unlock ang bootloader"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Payagan ang pag-a-unlock ng OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Certification ng wireless display"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"I-enable ang Pagla-log sa Wi‑Fi Verbose"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Nakakonektang MAC Randomization"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Palaging aktibo ang mobile data"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardware acceleration para sa pag-tether"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Ipakita ang mga Bluetooth device na walang pangalan"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Hindi makakonekta"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ipakita ang mga opsyon para sa certification ng wireless display"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Pataasin ang antas ng Wi‑Fi logging, ipakita sa bawat SSID RSSI sa Wi‑Fi Picker"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"I-randomize ang MAC address kapag kumokonekta sa mga Wi‑Fi network"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Nakametro"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Hindi Nakametro"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Mga laki ng buffer ng Logger"</string>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index 1a0ab57..b9bbda3 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP denetimini yalnızca DRM içeriği için kullan"</item>
<item msgid="45075631231212732">"HDCP denetimini her zaman kullan"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Devre dışı"</item>
+ <item msgid="1969681323976948639">"Etkin Filtrelenmiş"</item>
+ <item msgid="8719029132154020716">"Etkin"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Varsayılan)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 67aee02..28fc38f 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s üzerinden otomatik olarak bağlı"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Ağ derecelendirme sağlayıcı aracılığıyla otomatik olarak bağlandı"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s üzerinden bağlı"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>, <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> ile bağlandı"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s üzerinden kullanılabilir"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Ayarlamak için dokunun"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Kaydolmak için dokunun"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Bağlı, internet yok"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"İnternet yok"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Oturum açılması gerekiyor"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Erişim noktası geçici olarak dolu"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s üzerinden bağlı"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s üzerinden kullanılabilir"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Bağlantı başarısız oldu"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU sunucu URL\'si geçersiz"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU sunucusu ile bağlantı kurulamadı"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU sunucusu doğrulanamadı"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU sunucu sertifikası geçersiz"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Temel hazırlık iptal edildi"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Temel hazırlık kullanılamıyor"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU sunucu URL\'si geçersiz"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Beklenmeyen komut türü"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Beklenmeyen SOAP mesaj türü"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP mesajlaşması başarısız"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Yönlendirme işleyici başlatılamadı"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Yönlendirme beklenirken süre doldu"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU etkinliği bulunamadı"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Beklenmeyen SOAP mesaj durumu"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO bulunamadı"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA sunucusu için güvenilir kök düğüm bulunamadı"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Düzeltme sunucusu için güvenilir kök düğüm bulunamadı"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Politika sunucusu için güvenilir kök düğüm bulunamadı"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Güvenilir kök sertifikalar alınamadı"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA sunucusu için güvenilir kök sertifika bulunamadı"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint yapılandırması eklenemedi"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU sağlayıcı bulunamadı"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Bağlanıyor"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Bağlandı"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU sunucusu ile bağlantı kuruluyor"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU sunucusu doğrulandı"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU sunucusuna bağlandı"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"İlk SOAP değişimi"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Yönlendirme yanıtı bekleniyor"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Yönlendirme yanıtı alındı"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"İkinci SOAP değişimi"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Üçüncü SOAP değişimi"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Güvenilir kök sertifikalar alınıyor"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Temel hazırlık tamamlandı"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> açılıyor"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Bağlanılamadı"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Kayıt işlemi tamamlanıyor…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Kayıt işlemi tamamlanamadı. Tekrar denemek için dokunun."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Kayıt tamamlandı. Bağlanıyor…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Çok Yavaş"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Yavaş"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Tamam"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Uyanık kal"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Şarj edilirken ekran hiçbir zaman uykuya geçmez"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI araştırmayı etkinleştir"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Bluetooth paketlerini yakalayın. (Bu ayarı değiştirdikten sonra Bluetooth seçimini değiştirin)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM kilit açma"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Önyükleyicinin kilidinin açılmasına izin ver"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM kilit açmaya izin verilsin mi?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Ağ işlemleri"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Kablosuz ekran sertifikası"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Kablosuz Ayrıntılı Günlük Kaydını etkinleştir"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Bağlı MAC Rastgele Seçimi"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil veri her zaman etkin"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering donanım hızlandırıcısı"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Adsız Bluetooth cihazlarını göster"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Bağlanılamadı"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Kablosuz ekran sertifikası seçeneklerini göster"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Kablosuz günlük kaydı seviyesini artır. Kablosuz Seçici\'de her bir SSID RSSI için göster."</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Kablosuz ağlara bağlanırken MAC adresini rastgele seç"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Sayaçlı"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Sayaçsız"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Günlük Kaydedici arabellek boyutları"</string>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index 5e14286..63538e1 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Використовувати перевірку HDCP лише для вмісту, захищеного DRM"</item>
<item msgid="45075631231212732">"Завжди використовувати перевірку HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Вимкнено"</item>
+ <item msgid="1969681323976948639">"Увімкнено з фільтром"</item>
+ <item msgid="8719029132154020716">"Увімкнено"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (за умовчанням)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 1cfa0eb..c63f7e0 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Автоматично під’єднано через %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Автоматично під’єднано через постачальника оцінки якості мережі"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Під’єднано через %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> надає <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Підключено через додаток <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Доступ через %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Торкніться, щоб налаштувати"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Торкніться, щоб увійти"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Під’єднано, але немає доступу до Інтернету"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Немає Інтернету"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Потрібно ввійти в обліковий запис"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Точка доступу тимчасово переповнена"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Під’єднано через мережу %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Доступ через мережу %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Помилка підключення"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Недійсна URL-адреса сервера OSU"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Не вдалося підключитися до сервера OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Не вдалося перевірити сервер OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Недійсний сертифікат сервера OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Надання скасовано"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Надання недоступне"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Недійсна URL-адреса сервера OSU"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Неочікуваний тип команди"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Неочікуваний тип повідомлення SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Не вдалося провести обмін повідомленнями SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Не вдалося запустити обробник переспрямування"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Час очікування переспрямування минув"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Не виявлено активності OSU"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Неочікуваний статус повідомлення SOAP"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Не вдалося знайти PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Не вдалося знайти надійний кореневий вузол для AAA-сервера"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Не вдалося знайти надійний кореневий вузол для сервера виправлень"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Не вдалося знайти надійний кореневий вузол для сервера політики"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Не вдалось отримати надійні кореневі сертифікати"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Не вдалося знайти надійний кореневий сертифікат для AAA-сервера"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Не вдалося додати налаштування PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Не вдалося знайти постачальника OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Підключення"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Підключено"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Підключення до сервера OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Сервер OSU перевірено"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Підключено до сервера OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Початковий обмін SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Очікування відповіді переспрямування"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Відповідь переспрямування отримано"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Другий обмін SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Третій обмін SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Отримання надійних кореневих сертифікатів"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Надання завершено"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> відкривається"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Не вдалося підключитись"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Завершення реєстрації…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Не вдалося завершити реєстрацію. Торкніться, щоб повторити спробу."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Реєстрацію завершено. Підключення…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Дуже повільна"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Повільна"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ОК"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Залишати активним"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Екран не засинатиме під час заряджання"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Увімкнути журнал відстеження інтерфейсу Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Отримання пакетів Bluetooth. (Змінивши це налаштування, увімкніть Bluetooth.)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Розблокування виробником"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Дозволити розблокування завантажувача"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Дозволити виробникові розблоковувати пристрій?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Мережі"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Сертифікація бездрот. екрана"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Докладний запис у журнал Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Довільний вибір MAC-адрес під час з’єднання"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Не вимикати мобільне передавання даних"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратне прискорення під час використання телефона в режимі модема"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показувати пристрої Bluetooth без назв"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не вдалося під’єднатися"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показати параметри сертифікації бездротового екрана"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Показувати в журналі RSSI для кожного SSID під час вибору Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Довільно вибирати MAC-адресу під час з’єднання з мережами Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"З тарифікацією трафіку"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Без тарифікації трафіку"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Розміри буфера журналу"</string>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index 27b26b7..bb1765fa 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP چیکنگ صرف DRM مواد کیلئے استعمال کریں"</item>
<item msgid="45075631231212732">"ہمیشہ HDCP چیکنگ استعمال کریں"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"غیر فعال"</item>
+ <item msgid="1969681323976948639">"فعال کردہ فلٹر کردہ"</item>
+ <item msgid="8719029132154020716">"فعال"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (ڈیفالٹ)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 5e8ab54..27aa730 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -38,50 +38,27 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s کے ذریعے از خود منسلک کردہ"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"نیٹ ورک درجہ بندی کے فراہم کنندہ کے ذریعے از خود منسلک"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"منسلک بذریعہ %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g> بذریعہ <xliff:g id="SSID">%1$s</xliff:g>"</string>
+ <!-- no translation found for connected_via_app (5571999941988929520) -->
+ <skip />
<string name="available_via_passpoint" msgid="1617440946846329613">"دستیاب بذریعہ %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"سیٹ اپ کرنے کے لیے تھپتھپائیں"</string>
+ <!-- no translation found for tap_to_sign_up (6449724763052579434) -->
+ <skip />
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"منسلک، انٹرنیٹ نہیں ہے"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"انٹرنیٹ نہیں ہے"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"سائن ان درکار ہے"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"رسائی پوائنٹ عارضی طور پر فُل ہے"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"منسلک بذریعہ %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"دستیاب بذریعہ %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"کنکشن ناکام ہو گیا"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"غلط OSU سرور کا URL"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU سرور کنکشن ناکام ہو گيا"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU سرور کی توثیق ناکام ہو گئی"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"غلط OSU سرور کا سرٹیفیکیٹ"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"فراہمی کو منسوخ کر دیا گیا"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"فراہمی دستیاب نہیں ہے"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"غلط OSU سرور کا URL"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"غیر متوقع کمانڈ کی قسم"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"غیر متوقع SOAP پیغام کی قسم"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP پیغام کا تبادلہ ناکام ہو گیا"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"ری ڈائریکٹ سامع شروع ہونے میں ناکام ہو گیا"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"ری ڈائریکٹ کے انتظار میں ٹائم آؤٹ ہو گیا"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"OSU کی کوئی سرگرمی نہیں ملی"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"غیرمتوقع SOAP پیغام کی صورتحال"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO تلاش کرنے میں ناکام"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA سرور کے لیے معتبر روٹ نوڈ تلاش کرنے میں ناکام"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"تلافی سرور کے لیے معتبر روٹ نوڈ تلاش کرنے میں ناکام"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"پالیسی سرور کے لیے معتبر روٹ نوڈ تلاش کرنے میں ناکام"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"معتبر روٹ سرٹیفکیٹس کو دوبارہ حاصل کرنے میں ناکام"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA سرور کے لیے معتبر روٹ سرٹیفکیٹ تلاش کرنے میں ناکام"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint کی کنفیگریشن شامل کرنے میں ناکام"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU فراہم کنندہ کو تلاش کرنے میں ناکام"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"منسلک ہو رہا ہے"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"منسلک ہے"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU سرور سے منسلک ہو رہا ہے"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU سرور کی توثیق ہو گئی"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU سرور سے منسلک ہے"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"SOAP کا ابتدائی تبادلہ"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"ری ڈائریکٹ کے جواب کا منتظر"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"ری ڈائریکٹ کا جواب موصول ہو گیا"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"دوسرے SOAP کا تبادلہ"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"تیسرے SOAP کا تبادلہ"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"معتبر روٹ سرٹیفکیٹس کو دوبارہ حاصل کیا جا رہا ہے"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"فراہمی مکمل ہو گئی"</string>
+ <!-- no translation found for osu_opening_provider (5488997661548640424) -->
+ <skip />
+ <!-- no translation found for osu_connect_failed (2187750899158158934) -->
+ <skip />
+ <!-- no translation found for osu_completing_sign_up (9037638564719197082) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_failed (7296159750352873260) -->
+ <skip />
+ <!-- no translation found for osu_sign_up_complete (8207626049093289203) -->
+ <skip />
<string name="speed_label_very_slow" msgid="1867055264243608530">"بہت سست"</string>
<string name="speed_label_slow" msgid="813109590815810235">"سست"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"ٹھیک ہے"</string>
@@ -234,8 +211,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"بیدار رکھیں"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"چارج ہوتے وقت اسکرین کبھی بھی سلیپ وضع میں نہيں جائے گی"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"بلوٹوتھ HCI کا جاسوسی لاگ فعال کریں"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"بلوٹوتھ پیکیٹس کیپچر کریں۔ (اس ترتیب کو تبدیل کرنے کے بعد بلوٹوتھ ٹوگل کریں)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM اَن لاکنگ"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"بوٹ لوڈر کو غیر مقفل ہونے کی اجازت دیں"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM اَن لاکنگ کی اجازت دیں؟"</string>
@@ -246,7 +222,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"نیٹ ورکنگ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"وائرلیس ڈسپلے سرٹیفیکیشن"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi وربوس لاگنگ فعال کریں"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"منسلک کردہ MAC رینڈمائزیشن"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"ٹیدرنگ ہارڈویئر سرعت کاری"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"بغیر نام والے بلوٹوتھ آلات دکھائیں"</string>
@@ -273,7 +248,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"منسلک نہیں ہو سکا"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"وائرلیس ڈسپلے سرٹیفیکیشن کیلئے اختیارات دکھائیں"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi لاگنگ لیول میں اضافہ کریں، Wi‑Fi منتخب کنندہ میں فی SSID RSSI دکھائیں"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi-Fi نیٹ ورکس سے منسلک کرتے وقت MAC پتے کو غیر مرتب کریں"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"میٹرڈ"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"غیر میٹر شدہ"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"لاگر بفر کے سائز"</string>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index d127689..e64ccfa 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"HDCP tekshiruvi faqat DRM kontent uchun ishlatilsin"</item>
<item msgid="45075631231212732">"Har doim HDCP tekshiruvidan foydalanilsin"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Oʻchiq"</item>
+ <item msgid="1969681323976948639">"Filtrlar yoniq"</item>
+ <item msgid="8719029132154020716">"Yoniq"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (asosiy)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 133e25e..bcb4d27 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s orqali avtomatik ulandi"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Tarmoqlar reytingi muallifi orqali avtomatik ulandi"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s orqali ulangan"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>, <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> orqali ulandi"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s orqali ishlaydi"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Sozlash uchun bosing"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Yozilish uchun bosing"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Ulangan, lekin internet aloqasi yo‘q"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Internet yo‘q"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Hisob bilan kirish zarur"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Internet kirish nuqtasi vaqtinchalik to‘lgan"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"%1$s orqali ulangan"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"%1$s orqali ishlaydi"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Ulanishda xatolik yuz berdi"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"Yaroqsiz OSU serveri URL manzili"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"OSU serveriga ulanmadi"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU serveri tasdiqlanmadi"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Yaroqsiz OSU serveri sertifikati"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Sinxronizatsiya uzildi"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Sinxronizatsiya mavjud emas"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"Yaroqsiz OSU serveri URL manzili"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Notanish buyruq turi"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Notanish SOAP xabari turi"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"SOAP xabarlari almashinuvi amalga oshmadi"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Teskari chaqiruv qabul qilgichi ishga tushmadi"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Kutish vaqtidan oshib ketdi"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Hech qanday OSU harakatlari topilmadi"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"SOAP xabari holati noaniq"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"PPS-MO topilmadi"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"AAA serveri uchun ishonchli root tuguni topilmadi"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Tuzatish serveri uchun ishonchli root tuguni topilmadi"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Qoidalar serveri uchun ishonchli root tuguni topilmadi"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Ishonchli root sertifikatlari olinmadi"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"AAA serveri uchun ishonchli root sertifikati topilmadi"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"PassPoint sozlamalari kiritilmadi"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"OSU taʼminotchisi topilmadi"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Ulanmoqda"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Ulandi"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"OSU serveriga ulanmoqda"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU serveri tasdiqlandi"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"OSU serveriga ulangan"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Birinchi SOAP almashinuvi"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Uzatish uchun javob kutilmoqda"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Javob olindi"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Ikkinchi SOAP almashinuvi"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Uchinchi SOAP almashinuvi"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Ishonchli root sertifikatlari olinmoqda"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Sinxronizatsiya yakunlandi"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> ochilmoqda"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Ulanmadi"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Registratsiya tamomlanmoqda…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Registratsiya tamomlanmadi. Qayta urinish uchun tegining."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Registratsiya qilindi. Ulanmoqda…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Juda sekin"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Sekin"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"OK"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Ekranning yoniq turishi"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Qurilma quvvat olayotganda ekran doim yoniq turadi"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI amallari translatsiyasi jurnali"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Barcha Bluetooth paketlarini saqlash. (Sozlashdan keyin Bluetooth qurilmasini qayta ishga tushiring)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Zavod qulfini yechish"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Operatsion tizimni yuklash dasturining qulfini yechishga ruxsat berish"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Zavod qulfini yechishga ruxsat berilsinmi?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Tarmoqlar"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz monitor sertifikatlari"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Batafsil Wi-Fi jurnali"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Wi-Fi orqali ulanganda tasodifiy MAC manzillar yaratish"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil internet doim yoniq tursin"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Modem rejimida apparatli tezlashtirish"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth qurilmalarini nomlarisiz ko‘rsatish"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ulanmadi"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz monitorlarni sertifikatlash parametrini ko‘rsatish"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi ulanishini tanlashda har bir SSID uchun jurnalda ko‘rsatilsin"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Wi-Fi tarmoqlarga ulanishda MAC manzilini tasodifiy tanlash"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Trafik hisoblanadigan tarmoq"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Trafik hisobi yuritilmaydigan tarmoq"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Jurnal buferi hajmi"</string>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index bfc4d75..433df8e 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Chỉ sử dụng kiểm tra HDCP cho nội dung DRM"</item>
<item msgid="45075631231212732">"Luôn sử dụng kiểm tra HDCP"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Đã tắt"</item>
+ <item msgid="1969681323976948639">"Đã bật và lọc"</item>
+ <item msgid="8719029132154020716">"Đã bật"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (Mặc định)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 1cd1b29..d03b2f1 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Tự động được kết nối qua %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Tự động được kết nối qua nhà cung cấp dịch vụ xếp hạng mạng"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Được kết nối qua %1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> của <xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Đã kết nối qua <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Có sẵn qua %1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Nhấn để thiết lập"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Nhấn để đăng ký"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Đã kết nối, không có Internet"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Không có Internet"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Yêu cầu đăng nhập"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Điểm truy cập tạm thời đã đạt đến giới hạn số lượng thiết bị truy cập."</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Được kết nối qua %1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Có sẵn qua %1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Không kết nối được"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"URL máy chủ OSU không hợp lệ"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Không kết nối được với máy chủ OSU"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Không xác thực được máy chủ OSU"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Chứng chỉ máy chủ OSU không hợp lệ"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Đã hủy cấp phép"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Hiện không cấp phép được"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"URL máy chủ OSU không hợp lệ"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Loại lệnh không mong muốn"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Loại thông báo SOAP không mong muốn"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Không trao đổi được thông báo SOAP"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Không thể bắt đầu chuyển hướng người nghe"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Đã hết thời gian chờ chuyển hướng"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Không tìm thấy hoạt động OSU nào"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Trạng thái thông báo SOAP không mong muốn"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Không tìm thấy PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Không tìm thấy nút gốc tin cậy cho máy chủ AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Không tìm thấy nút gốc tin cậy cho máy chủ khắc phục"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Không tìm thấy nút gốc tin cậy cho máy chủ chính sách"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Không truy xuất được chứng chỉ gốc tin cậy"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Không tìm thấy chứng chỉ gốc tin cậy cho máy chủ AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Không thêm được cấu hình PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Không tìm thấy nhà cung cấp OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Đang kết nối"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Đã kết nối"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Đang kết nối với máy chủ OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Đã xác thực máy chủ OSU"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Đã kết nối với máy chủ OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Lần trao đổi SOAP ban đầu"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Đang đợi thông tin phản hồi chuyển hướng"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Đã nhận được thông tin phản hồi chuyển hướng"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Lần trao đổi SOAP thứ hai"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Lần trao đổi SOAP thứ ba"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Đang truy xuất chứng chỉ gốc tin cậy"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Quá trình cấp phép đã hoàn tất"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Đang mở <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Không thể kết nối"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Đang hoàn tất đăng ký…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Không thể hoàn tất đăng ký. Nhấn để thử lại."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Đã hoàn tất đăng ký. Đang kết nối…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Rất chậm"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Chậm"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"Khá tốt"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Không khóa màn hình"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Màn hình sẽ không bao giờ chuyển sang chế độ nghỉ khi sạc"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bật nhật ký theo dõi HCI Bluetooth"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Chụp các gói Bluetooth. (Chuyển đổi Bluetooth sau khi thay đổi tùy chọn cài đặt này)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Mở khóa OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Cho phép mở khóa trình khởi động"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Cho phép mở khóa OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Mạng"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Chứng nhận hiển thị không dây"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Bật ghi nhật ký chi tiết Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Lựa chọn ngẫu nhiên địa chỉ MAC khi kết nối"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Dữ liệu di động luôn hoạt động"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"Tăng tốc phần cứng cho chia sẻ kết nối"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Hiển thị các thiết bị Bluetooth không có tên"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Không thể kết nối"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Hiển thị tùy chọn chứng nhận hiển thị không dây"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tăng mức ghi nhật ký Wi‑Fi, hiển thị mỗi SSID RSSI trong bộ chọn Wi‑Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Lựa chọn ngẫu nhiên địa chỉ MAC khi kết nối với mạng Wi‑Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Đo lượng dữ liệu"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Không đo lượng dữ liệu"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Kích thước bộ đệm của trình ghi nhật ký"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 82d8fae..2706823 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"仅使用 HDCP 检查 DRM 内容"</item>
<item msgid="45075631231212732">"始终使用 HDCP 检查"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"已停用"</item>
+ <item msgid="1969681323976948639">"已启用“已过滤”"</item>
+ <item msgid="8719029132154020716">"已启用"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4(默认)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index f656e1e..6967447 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"已通过%1$s自动连接"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"已自动连接(通过网络评分服务提供方)"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"已通过%1$s连接"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g>(通过<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>连接)"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"已通过<xliff:g id="NAME">%1$s</xliff:g>连接到网络"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可通过%1$s连接"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"点按即可进行设置"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"点按即可注册"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"已连接,但无法访问互联网"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"无法访问互联网"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"必须登录"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"接入点暂时满载"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"已通过%1$s连接"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"可通过%1$s连接"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"连接失败"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"OSU 服务器网址无效"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"无法连接到 OSU 服务器"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"OSU 服务器验证失败"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"OSU 服务器证书无效"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"已取消配置"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"配置不可用"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"OSU 服务器网址无效"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"非预期的命令类型"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"非预期的 SOAP 消息类型"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"无法交换 SOAP 消息"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"无法启动重定向侦听器"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"等待重定向时出现超时问题"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"未找到任何 OSU 活动"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"非预期的 SOAP 消息状态"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"找不到 PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"找不到 AAA 服务器的信任根节点"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"找不到修复服务器的信任根节点"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"找不到政策服务器的信任根节点"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"未能检索到信任的根证书"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"找不到 AAA 服务器的信任根证书"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"无法添加 PassPoint 配置"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"找不到 OSU 提供程序"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"正在连接"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"已连接"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"正在连接到 OSU 服务器"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU 服务器已经过验证"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"已连接到 OSU 服务器"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"初始 SOAP 交换"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"正在等待重定向响应"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"已收到重定向响应"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"第二次 SOAP 交换"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"第三次 SOAP 交换"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"正在检索信任的根证书"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"配置完成"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"正在打开<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"无法连接"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"正在完成注册…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"无法完成注册。点按即可重试。"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"注册完毕。正在连接…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"很慢"</string>
<string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"良好"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"不锁定屏幕"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"充电时屏幕不会休眠"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"启用蓝牙 HCI 信息收集日志"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"捕获蓝牙数据包(更改此设置之后请切换蓝牙开关)。"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM 解锁"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"允许解锁引导加载程序"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"要允许 OEM 解锁吗?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"网络"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"无线显示认证"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"启用 WLAN 详细日志记录功能"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"连接时随机选择 MAC 网址"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"始终开启移动数据网络"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"网络共享硬件加速"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"显示没有名称的蓝牙设备"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"无法连接"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"显示无线显示认证选项"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"提升 WLAN 日志记录级别(在 WLAN 选择器中显示每个 SSID 的 RSSI)"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"连接到 WLAN 网络时随机选择 MAC 地址"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"按流量计费"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"不按流量计费"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"日志记录器缓冲区大小"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index 0a956fc..8872cc96 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"僅使用 HDCP 檢查 DRM 內容"</item>
<item msgid="45075631231212732">"永遠使用 HDCP 檢查"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"已停用"</item>
+ <item msgid="1969681323976948639">"已啟用篩選"</item>
+ <item msgid="8719029132154020716">"已啟用"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (預設)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 325a56a..5394afc 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"已透過 %1$s 自動連線"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"已透過網絡評分供應商自動連線"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>的「<xliff:g id="SSID">%1$s</xliff:g>」"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"透過「<xliff:g id="NAME">%1$s</xliff:g>」連線"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 連線"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"輕按即可設定"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"輕觸即可註冊"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"已連線,但沒有互聯網"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"沒有互聯網連線"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"必須登入"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"存取點暫時已滿"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"已透過 %1$s 連線"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"可透過 %1$s 連線"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"連接失敗"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"無效的 OSU 伺服器網址"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"無法連接 OSU 伺服器"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"無法驗證 OSU 伺服器"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"無效的 OSU 伺服器憑證"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"已取消佈建"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"無法佈建"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"無效的 OSU 伺服器網址"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"非預期的指令類型"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"非預期的 SOAP 訊息類型"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"無法交換 SOAP 訊息"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"無法啟用重新導向非同步回呼"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"等待重新導向逾時"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"找不到 OSU 活動"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"非預期的 SOAP 訊息狀態"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"找不到 PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"找不到可信賴的 AAA 伺服器根節點"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"找不到可信賴的修復伺服器根節點"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"找不到可信賴的政策伺服器根節點"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"無法擷取可信賴的根憑證"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"找不到可信賴的 AAA 伺服器根憑證"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"無法新增 PassPoint 設定"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"找不到 OSU 供應商"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"正在連接"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"已連接"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"正在連接至 OSU 伺服器"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"已驗證 OSU 伺服器"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"已連接至 OSU 伺服器"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"初始 SOAP 交換"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"正在等待重新導向回應"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"已收到重新導向回應"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"第二次 SOAP 交換"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"第三次 SOAP 交換"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"正在擷取可信賴的根憑證"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"佈建已完成"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"正在開啟 <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"無法連線"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"正在完成註冊程序…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"無法完成註冊程序。輕觸即可重試。"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"註冊完成。連線中…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"非常慢"</string>
<string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"良好"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"保持啟用"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"充電時螢幕永不休眠"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"啟用藍牙 HCI 窺探記錄"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"擷取藍牙套裝。(變更此設定後必須切換藍牙)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"原始設備製造商 (OEM) 解鎖"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"允許 Bootloader 被解鎖"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"允許原始設備製造商 (OEM) 解鎖嗎?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"網絡"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細記錄"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"已連線的 MAC 隨機化處理"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"一律保持啟用流動數據"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"網絡共享硬件加速"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"顯示沒有名稱的藍牙裝置"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"無法連線"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"連線至 Wi‑Fi 網絡時隨機產生 MAC 位址"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"按用量收費"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"不限數據用量收費"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 20d0242..207be3f 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"僅使用 HDCP 檢查 DRM 內容"</item>
<item msgid="45075631231212732">"一律使用 HDCP 檢查"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"已停用"</item>
+ <item msgid="1969681323976948639">"已啟用篩選結果"</item>
+ <item msgid="8719029132154020716">"已啟用"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"AVRCP 1.4 (預設)"</item>
<item msgid="2809759619990248160">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index dff2fab..107eb6d 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"已透過 %1$s 自動連線"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"已透過網路評分供應商自動連線"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> (透過「<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>」連線)"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"透過「<xliff:g id="NAME">%1$s</xliff:g>」連線"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"可透過 %1$s 使用"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"輕觸即可進行設定"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"輕觸即可註冊"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"已連線,沒有網際網路"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"沒有網際網路連線"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"必須登入"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"存取點暫時滿載"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"已透過 %1$s 連線"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"可透過 %1$s 使用"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"連線失敗"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"無效的 OSU 伺服器網址"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"無法連線至 OSU 伺服器"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"無法驗證 OSU 伺服器"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"無效的 OSU 伺服器憑證"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"已取消佈建作業"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"無法進行佈建"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"無效的 OSU 伺服器網址"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"非預期的指令類型"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"非預期的 SOAP 訊息類型"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"無法交換 SOAP 訊息"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"無法啟動重新導向接聽器"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"等待重新導向的過程中發生逾時情形"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"找不到 OSU 活動"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"非預期的 SOAP 訊息狀態"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"找不到 PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"找不到 AAA 伺服器的可信任根節點"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"找不到修正伺服器的可信任根節點"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"找不到政策伺服器的可信任根節點"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"無法擷取信任的根憑證"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"找不到 AAA 伺服器的可信任根憑證"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"無法新增 PassPoint 設定"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"找不到 OSU 提供者"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"連線中"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"已連線"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"正在連線至 OSU 伺服器"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"OSU 伺服器已通過驗證"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"已連線至 OSU 伺服器"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"初始 SOAP 交換"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"正在等待重新導向回覆"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"已接收重新導向回覆"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"第二次 SOAP 交換"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"第三次 SOAP 交換"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"正在擷取信任的根憑證"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"已完成佈建作業"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"正在開啟 <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"無法連線"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"正在完成註冊程序…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"無法完成註冊程序。輕觸即可重試。"</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"註冊完成。連線中…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"非常慢"</string>
<string name="speed_label_slow" msgid="813109590815810235">"慢"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"確定"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"螢幕不休眠"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"充電時螢幕不會進入休眠"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"啟用藍牙 HCI 窺探記錄"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"擷取藍牙數據包 (變更這項設定後請切換藍牙)。"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM 解鎖"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"允許解除鎖定開機載入器"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"要允許 OEM 解鎖嗎?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"網路連線"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細記錄設定"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"已連線的 MAC 隨機化處理"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"行動數據連線一律保持啟用狀態"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"數據連線硬體加速"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"顯示沒有名稱的藍牙裝置"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"無法連線"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細記錄"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"連線至 Wi‑Fi 網路時隨機化 MAC 位址"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"計量付費"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"非計量付費"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index caa7da3..20983e3 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -58,9 +58,11 @@
<item msgid="3878793616631049349">"Sebenzisa ukuhlola kwe-HDCP kokuqukethwe i-DRM kuphela"</item>
<item msgid="45075631231212732">"Sebenzisa njalo ukuhlola kwe-HDPC"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_entries:0 (3966341281672645384) -->
- <!-- no translation found for bt_hci_snoop_log_entries:1 (1969681323976948639) -->
- <!-- no translation found for bt_hci_snoop_log_entries:2 (8719029132154020716) -->
+ <string-array name="bt_hci_snoop_log_entries">
+ <item msgid="3966341281672645384">"Kukhutshaziwe"</item>
+ <item msgid="1969681323976948639">"Okuhlungiwe okunikwe amandla"</item>
+ <item msgid="8719029132154020716">"Kunikwe amandla"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="5347678900838034763">"I-AVRCP 1.4 (Okuzenzakalelayo)"</item>
<item msgid="2809759619990248160">"I-AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index b8c1637..920df4b 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -38,50 +38,20 @@
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Ixhumeke ngokuzenzakalela nge-%1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Kuxhunywe ngokuzenzakalelayo ngomhlinzeki wesilinganiso wenethiwekhi"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Kuxhumeke nge-%1$s"</string>
- <string name="ssid_by_passpoint_provider" msgid="7898171424140673315">"<xliff:g id="SSID">%1$s</xliff:g> ngo-<xliff:g id="PASSPOINTPROVIDER">%2$s</xliff:g>"</string>
+ <string name="connected_via_app" msgid="5571999941988929520">"Ixhumeke nge-<xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Iyatholakala nge-%1$s"</string>
- <string name="tap_to_set_up" msgid="2468970825530423314">"Thepha ukuze usethe"</string>
+ <string name="tap_to_sign_up" msgid="6449724763052579434">"Thepha ukuze ubhalisele"</string>
<string name="wifi_connected_no_internet" msgid="8202906332837777829">"Kuxhunyiwe, ayikho i-inthanethi"</string>
<string name="wifi_status_no_internet" msgid="5784710974669608361">"Ayikho i-inthanethi"</string>
<string name="wifi_status_sign_in_required" msgid="123517180404752756">"Ukungena ngemvume kuyadingeka"</string>
<string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"Iphoyinti lokufinyelela ligcwele okwesikhashana"</string>
<string name="connected_via_carrier" msgid="7583780074526041912">"Kuxhumeke nge-%1$s"</string>
<string name="available_via_carrier" msgid="1469036129740799053">"Iyatholakala nge-%1$s"</string>
- <string name="osu_failure_ap_connection" msgid="598977488344424542">"Ukuxhumeka kuhlulekile"</string>
- <string name="osu_failure_server_url_invalid" msgid="2237477219243136714">"I-URL yeseva ye-OSU engavumelekile"</string>
- <string name="osu_failure_server_connection" msgid="8192988165059982174">"Ukuxhumeka kweseva ye-OSU kuhlulekile"</string>
- <string name="osu_failure_server_validation" msgid="4631649978129606823">"Ukuqinisekiswa kweseva ye-OSU kuhlulekile"</string>
- <string name="osu_failure_service_provider_verification" msgid="4854091521439785597">"Isitifiketi esingavumelekile seseva ye-OSU"</string>
- <string name="osu_failure_provisioning_aborted" msgid="424627208135320329">"Ukunikezelwa kuyekeliwe"</string>
- <string name="osu_failure_provisioning_not_available" msgid="3021783729256985432">"Ukunikezelwa akutholakali"</string>
- <string name="osu_failure_invalid_server_url" msgid="8548886196179435758">"I-URL yeseva ye-OSU engavumelekile"</string>
- <string name="osu_failure_unexpected_command_type" msgid="8245921319866603904">"Uhlobo lomyalo ongalindelwe"</string>
- <string name="osu_failure_unexpected_soap_message_type" msgid="2255897608510053065">"Uhlobo lomlayezo ongalindelwe we-SOAP"</string>
- <string name="osu_failure_soap_message_exchange" msgid="4357358438685987192">"Ukushintshaniswa komlayezo we-SOAP kuhlulekile"</string>
- <string name="osu_failure_start_redirect_listener" msgid="4292769407279548482">"Ukuqondisa kabusha umlaleli kuhlulekile ukuqala"</string>
- <string name="osu_failure_timed_out_redirect_listener" msgid="3168657820278807508">"Iphelelwe isikhathi ilindele ukuqondiswa kabusha"</string>
- <string name="osu_failure_no_osu_activity_found" msgid="4593038891437878675">"Awukho umsebenzi we-OSU otholiwe"</string>
- <string name="osu_failure_unexpected_soap_message_status" msgid="6568467710235256675">"Isimo somlayezo we-SOAP ongalindelwe"</string>
- <string name="osu_failure_no_pps_mo" msgid="850567403039076835">"Yehlulekile ukuthola i-PPS-MO"</string>
- <string name="osu_failure_no_aaa_server_trust_root_node" msgid="8961455873459838456">"Yehlulekile ukuthola inodi yempande yokuthemba yeseva ye-AAA"</string>
- <string name="osu_failure_no_remediation_server_trust_root_node" msgid="5041179688081545244">"Yehlulekile ukuthola inodi yempande yokuthemba yeseva yokuxazulula"</string>
- <string name="osu_failure_no_policy_server_trust_root_node" msgid="6617290380940513539">"Yehlulekile ukuthola inodi yempande yokuthemba yeseva yenqubomgomo"</string>
- <string name="osu_failure_retrieve_trust_root_certificates" msgid="1499136256195528265">"Yehlulekile ukuthola izitofiketi zempande yokuthenga"</string>
- <string name="osu_failure_no_aaa_trust_root_certificate" msgid="1904322497042226984">"Yehlulekile ukuthola isitifiketi sempande yokuthemba yamaseva e-AAA"</string>
- <string name="osu_failure_add_passpoint_configuration" msgid="2173557755811446047">"Yehlulekile ukungeza ukulungiselelwa kwe-PassPoint"</string>
- <string name="osu_failure_osu_provider_not_found" msgid="6616172862116673082">"Yehlulekile ukuthola umhlinzeki we-OSU"</string>
- <string name="osu_status_ap_connecting" msgid="5296821043003441437">"Iyaxhuma"</string>
- <string name="osu_status_ap_connected" msgid="3777289375683170728">"Ixhunyiwe"</string>
- <string name="osu_status_server_connecting" msgid="8499785407540355867">"Ixhumeka kuseva ye-OSU"</string>
- <string name="osu_status_server_validated" msgid="3158727184762596355">"Iseva ye-OSU iqinisekisiwe"</string>
- <string name="osu_status_server_connected" msgid="8382024481520158168">"Ixhumeke kuseva ye-OSU"</string>
- <string name="osu_status_init_soap_exchange" msgid="8628063888912101981">"Ukushintshisana kwasekuqaleni kwe-SOAP"</string>
- <string name="osu_status_waiting_for_redirect_response" msgid="2343016207837053197">"Ilindele impendulo yokuqondisa kabusha"</string>
- <string name="osu_status_redirect_response_received" msgid="5323368411922609405">"Ithole impendulo eqondiswe kabusha"</string>
- <string name="osu_status_second_soap_exchange" msgid="7115332266758483909">"Ukushintshisana kwesibili kwe-SOAP"</string>
- <string name="osu_status_third_soap_exchange" msgid="8460901783597440766">"Ukushintshaniswa kwesithathu kwe-SOAP"</string>
- <string name="osu_status_retrieving_trust_root_certs" msgid="1563445892926269689">"Ithola izitifiketi zempande yokuthemba"</string>
- <string name="osu_provisioning_complete" msgid="5120178802493970149">"Ukunikezelwa kuqediwe"</string>
+ <string name="osu_opening_provider" msgid="5488997661548640424">"Ivula i-<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
+ <string name="osu_connect_failed" msgid="2187750899158158934">"Ayikwazanga ukuxhumeka"</string>
+ <string name="osu_completing_sign_up" msgid="9037638564719197082">"Iqedela ukubhalisa…"</string>
+ <string name="osu_sign_up_failed" msgid="7296159750352873260">"Ayikwazanga ukuqedelela ukubhalisa. Thepha ukuze uzame futhi."</string>
+ <string name="osu_sign_up_complete" msgid="8207626049093289203">"Ukubhalisa kuqediwe. Iyaxhuma…"</string>
<string name="speed_label_very_slow" msgid="1867055264243608530">"Phansi kakhulu"</string>
<string name="speed_label_slow" msgid="813109590815810235">"Phansi"</string>
<string name="speed_label_okay" msgid="2331665440671174858">"KULUNGILE"</string>
@@ -234,8 +204,7 @@
<string name="keep_screen_on" msgid="1146389631208760344">"Hlala uphapheme"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Isikrini asisoze salala ngenkathi sishaja"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Nika amandla i-Bluetooth HCI yelogu lokuhlola"</string>
- <!-- no translation found for bt_hci_snoop_log_summary (8857606786588106495) -->
- <skip />
+ <string name="bt_hci_snoop_log_summary" msgid="8857606786588106495">"Thwebula amaphakethi e-Bluetooth. (Guqula i-Bluetooth ngemuva kokushintsha lesi silungiselelo)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Ukuvula i-OEM"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Vumela ukuthi i-bootloader ivulwe"</string>
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"Vumela ukuvula i-OEM?"</string>
@@ -246,7 +215,6 @@
<string name="debug_networking_category" msgid="7044075693643009662">"Ukunethiwekha"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Ukunikezwa isitifiketi sokubukeka okungenantambo"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Nika amandlaukungena kwe-Wi-Fi Verbose"</string>
- <string name="wifi_connected_mac_randomization" msgid="3168165236877957767">"Okungahleliwe kwe-MAC exhunyiwe"</string>
<string name="mobile_data_always_on" msgid="8774857027458200434">"Idatha yeselula ihlala isebenza"</string>
<string name="tethering_hardware_offload" msgid="7470077827090325814">"I-Tethering hardware acceleration"</string>
<string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bonisa amadivayisi e-Bluetooth ngaphandle kwamagama"</string>
@@ -273,7 +241,6 @@
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ayikwazanga ukuxhuma"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Bonisa izinketho zokunikeza isitifiketi ukubukeka okungenantambo"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"khuphula izinga lokungena le-Wi-Fi, bonisa nge-SSID RSSI engayodwana kusikhethi se-Wi-Fi"</string>
- <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Ungahleli ikheli le-MAC uma kuxhumeke kumanethiwekhi e-Wi-Fi"</string>
<string name="wifi_metered_label" msgid="4514924227256839725">"Kulinganisiwe"</string>
<string name="wifi_unmetered_label" msgid="6124098729457992931">"Akulinganiselwa"</string>
<string name="select_logd_size_title" msgid="7433137108348553508">"Amasayizi weloga ngebhafa"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 3e904a3..d644833 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -218,9 +218,9 @@
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec">HD audio</string>
<!-- Bluetooth settings. The user-visible string that is used whenever referring to the Hearing Aid profile. -->
- <string name="bluetooth_profile_hearing_aid">Hearing Aid</string>
+ <string name="bluetooth_profile_hearing_aid">Hearing Aids</string>
<!-- Bluetooth settings. Connection options screen. The summary for the Hearing Aid checkbox preference when Hearing Aid is connected. -->
- <string name="bluetooth_hearing_aid_profile_summary_connected">Connected to Hearing Aid</string>
+ <string name="bluetooth_hearing_aid_profile_summary_connected">Connected to Hearing Aids</string>
<!-- Bluetooth settings. Connection options screen. The summary for the A2DP checkbox preference when A2DP is connected. -->
<string name="bluetooth_a2dp_profile_summary_connected">Connected to media audio</string>
@@ -260,7 +260,7 @@
will set the HID profile as preferred. -->
<string name="bluetooth_hid_profile_summary_use_for">Use for input</string>
<!-- Bluetooth settings. Connection options screen. The summary for the Hearing Aid checkbox preference that describes how checking it will set the Hearing Aid profile as preferred. -->
- <string name="bluetooth_hearing_aid_profile_summary_use_for">Use for Hearing Aid</string>
+ <string name="bluetooth_hearing_aid_profile_summary_use_for">Use for Hearing Aids</string>
<!-- Button text for accepting an incoming pairing request. [CHAR LIMIT=20] -->
<string name="bluetooth_pairing_accept">Pair</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
index cc970b9..bd9a636 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
@@ -26,21 +26,23 @@
import java.util.ArrayList;
import java.util.List;
+import androidx.annotation.VisibleForTesting;
+
/**
- * Loader for network data usage history. It returns a list of usage data per billing cycle for a
- * specific Uid.
+ * Loader for network data usage history. It returns a list of usage data per billing cycle for the
+ * specific Uid(s).
*/
public class NetworkCycleDataForUidLoader extends
NetworkCycleDataLoader<List<NetworkCycleDataForUid>> {
private static final String TAG = "NetworkDataForUidLoader";
private final List<NetworkCycleDataForUid> mData;
- private final int mUid;
+ private final List<Integer> mUids;
private final boolean mRetrieveDetail;
private NetworkCycleDataForUidLoader(Builder builder) {
super(builder);
- mUid = builder.mUid;
+ mUids = builder.mUids;
mRetrieveDetail = builder.mRetrieveDetail;
mData = new ArrayList<NetworkCycleDataForUid>();
}
@@ -48,18 +50,27 @@
@Override
void recordUsage(long start, long end) {
try {
- final NetworkStats stats = mNetworkStatsManager.queryDetailsForUid(
- mNetworkType, mSubId, start, end, mUid);
- final long total = getTotalUsage(stats);
- if (total > 0L) {
+ long totalUsage = 0L;
+ long totalForeground = 0L;
+ for (int uid : mUids) {
+ final NetworkStats stats = mNetworkStatsManager.queryDetailsForUid(
+ mNetworkType, mSubId, start, end, uid);
+ final long usage = getTotalUsage(stats);
+ if (usage > 0L) {
+ totalUsage += usage;
+ if (mRetrieveDetail) {
+ totalForeground += getForegroundUsage(start, end, uid);
+ }
+ }
+ }
+ if (totalUsage > 0L) {
final NetworkCycleDataForUid.Builder builder = new NetworkCycleDataForUid.Builder();
builder.setStartTime(start)
.setEndTime(end)
- .setTotalUsage(total);
+ .setTotalUsage(totalUsage);
if (mRetrieveDetail) {
- final long foreground = getForegroundUsage(start, end);
- builder.setBackgroundUsage(total - foreground)
- .setForegroundUsage(foreground);
+ builder.setBackgroundUsage(totalUsage - totalForeground)
+ .setForegroundUsage(totalForeground);
}
mData.add(builder.build());
}
@@ -82,24 +93,29 @@
};
}
- private long getForegroundUsage(long start, long end) {
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ public List<Integer> getUids() {
+ return mUids;
+ }
+
+ private long getForegroundUsage(long start, long end, int uid) {
final NetworkStats stats = mNetworkStatsManager.queryDetailsForUidTagState(
- mNetworkType, mSubId, start, end, mUid, TAG_NONE, STATE_FOREGROUND);
+ mNetworkType, mSubId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
return getTotalUsage(stats);
}
public static abstract class Builder<T extends NetworkCycleDataForUidLoader>
extends NetworkCycleDataLoader.Builder<T> {
- private int mUid;
+ private final List<Integer> mUids = new ArrayList<>();
private boolean mRetrieveDetail = true;
public Builder(Context context) {
super(context);
}
- public Builder<T> setUid(int uid) {
- mUid = uid;
+ public Builder<T> addUid(int uid) {
+ mUids.add(uid);
return this;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
index 9451b36..ec8bb80 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
@@ -420,7 +420,7 @@
List<InputMethodInfo> getInputMethodList() {
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
- return imm.getInputMethodList();
+ return imm.getInputMethodListAsUser(mUser.getIdentifier());
}
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
index d915963..aafb46a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
@@ -70,7 +70,7 @@
final String subId = "TestSubscriber";
final int uid = 1;
mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
- .setUid(uid).setSubscriberId(subId).build());
+ .addUid(uid).setSubscriberId(subId).build());
doReturn(1024L).when(mLoader).getTotalUsage(any());
mLoader.recordUsage(start, end);
@@ -88,11 +88,32 @@
final String subId = "TestSubscriber";
final int uid = 1;
mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
- .setRetrieveDetail(false).setUid(uid).setSubscriberId(subId).build());
+ .setRetrieveDetail(false).addUid(uid).setSubscriberId(subId).build());
doReturn(1024L).when(mLoader).getTotalUsage(any());
mLoader.recordUsage(start, end);
verify(mNetworkStatsManager, never()).queryDetailsForUidTagState(
networkType, subId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
}
+
+ @Test
+ public void recordUsage_multipleUids_shouldQueryNetworkDetailsForEachUid() {
+ final long end = System.currentTimeMillis();
+ final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
+ final int networkType = ConnectivityManager.TYPE_MOBILE;
+ final String subId = "TestSubscriber";
+ mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
+ .addUid(1)
+ .addUid(2)
+ .addUid(3)
+ .setSubscriberId(subId).build());
+ doReturn(1024L).when(mLoader).getTotalUsage(any());
+
+ mLoader.recordUsage(start, end);
+
+ verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, 1);
+ verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, 2);
+ verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, 3);
+ }
+
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 479c964..fad93cb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2079,6 +2079,9 @@
Settings.Secure.NOTIFICATION_BADGING,
SecureSettingsProto.Notification.BADGING);
dumpSetting(s, p,
+ Settings.Secure.NOTIFICATION_BUBBLES,
+ SecureSettingsProto.Notification.BUBBLES);
+ dumpSetting(s, p,
Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING,
SecureSettingsProto.Notification.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING);
dumpSetting(s, p,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index c032683..e8c728d 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -166,6 +166,7 @@
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
<uses-permission android:name="android.permission.SUSPEND_APPS" />
+ <uses-permission android:name="android.permission.OBSERVE_APP_USAGE" />
<uses-permission android:name="android.permission.READ_CLIPBOARD_IN_BACKGROUND" />
<!-- Permission needed to wipe the device for Test Harness Mode -->
<uses-permission android:name="android.permission.ENABLE_TEST_HARNESS_MODE" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 815ae9a..3778a9c 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -22,11 +22,6 @@
android:sharedUserId="android.uid.systemui"
coreApp="true">
- <!-- Using OpenGL ES 2.0 -->
- <uses-feature
- android:glEsVersion="0x00020000"
- android:required="true" />
-
<!-- SysUI must be the one to define this permission; its name is
referenced by the core OS. -->
<permission android:name="android.permission.systemui.IDENTITY"
@@ -631,6 +626,14 @@
android:exported="true">
</provider>
+ <!-- Provides list and realistic previews of clock faces for the picker app. -->
+ <provider
+ android:name="com.android.keyguard.clock.ClockOptionsProvider"
+ android:authorities="com.android.keyguard.clock"
+ android:exported="true"
+ android:grantUriPermissions="true">
+ </provider>
+
<receiver
android:name=".statusbar.KeyboardShortcutsReceiver">
<intent-filter>
diff --git a/packages/SystemUI/docs/physics-animation-layout.md b/packages/SystemUI/docs/physics-animation-layout.md
index a67b5e8..300f63a 100644
--- a/packages/SystemUI/docs/physics-animation-layout.md
+++ b/packages/SystemUI/docs/physics-animation-layout.md
@@ -26,7 +26,7 @@
### Animation Control Methods
![Diagram of how calls to animateValueForChildAtIndex dispatch to DynamicAnimations.](physics-animation-layout-control-methods.png)
-Once the layout has used the controller’s configuration properties to build the animations, the controller can use them to actually run animations. This is done for two reasons - reacting to a view being added or removed, or responding to another class (such as a touch handler or broadcast receiver) requesting an animation. ```onChildAdded``` and ```onChildRemoved``` are called automatically by the layout, giving the controller the opportunity to animate the child in/out. Custom methods are called by anyone with access to the controller instance to do things like expand, collapse, or move the child views.
+Once the layout has used the controller’s configuration properties to build the animations, the controller can use them to actually run animations. This is done for two reasons - reacting to a view being added or removed, or responding to another class (such as a touch handler or broadcast receiver) requesting an animation. ```onChildAdded```, ```onChildRemoved```, and ```setChildVisibility``` are called automatically by the layout, giving the controller the opportunity to animate the child in/out/visible/gone. Custom methods are called by anyone with access to the controller instance to do things like expand, collapse, or move the child views.
In either case, the controller has access to the layout’s protected ```animateValueForChildAtIndex(ViewProperty property, int index, float value)``` method. This method is used to actually run an animation.
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_preview.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_preview.png
new file mode 100644
index 0000000..67f072f
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_preview.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_thumbnail.png
new file mode 100644
index 0000000..8d0e6ed
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_preview.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_preview.png
new file mode 100644
index 0000000..035a4df
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_preview.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_thumbnail.png
new file mode 100644
index 0000000..1ac0113
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_preview.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_preview.png
new file mode 100644
index 0000000..63927bc
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_preview.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_thumbnail.png
new file mode 100644
index 0000000..83d714b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_preview.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_preview.png
new file mode 100644
index 0000000..a538149
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_preview.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png
new file mode 100644
index 0000000..2bfd655
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/layout/type_clock.xml b/packages/SystemUI/res-keyguard/layout/type_clock.xml
index 21c64e9..f4a7376 100644
--- a/packages/SystemUI/res-keyguard/layout/type_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/type_clock.xml
@@ -24,32 +24,8 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- >
- <TextView
- android:id="@+id/header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="50dp"
- style="@style/widget_big"
- android:textColor="@color/typeClockAccentColor"
- android:text="@string/type_clock_header"
- android:textSize="40dp"
- />
- <TextView
- android:id="@+id/hour"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="50dp"
- style="@style/widget_big"
- android:textSize="40dp"
- />
- <TextView
- android:id="@+id/minute"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="50dp"
- style="@style/widget_big"
- android:textSize="40dp"
- />
- </com.android.keyguard.clock.TypographicClock>
+ android:paddingLeft="50dp"
+ style="@style/widget_big"
+ android:textSize="40dp"
+ />
</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 41acf82..94481e7 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -402,8 +402,25 @@
number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item>
</plurals>
- <!-- Header for typographic clock face. [CHAR LIMIT=8] -->
- <string name="type_clock_header">It\u2019s</string>
+ <!-- Time displayed on typographic clock face, which displays the time in words.
+ Example:
+
+ It's
+ Four
+ Twenty
+ Nine
+
+ This string requires two arguments: the first in the hours of the time and
+ the second is the minutes of the time. The hours string is obtained from
+ string-array type_clock_hours below and the minutes string is obtained
+ from string-array type_clock_minutes below.
+
+ [CHAR LIMIT=8] -->
+ <plurals name="type_clock_header">
+ <item quantity="one"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item>
+ <item quantity="few"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item>
+ <item quantity="other"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item>
+ </plurals>
<!-- Hour displayed in words on the typographic clock face. [CHAR LIMIT=12] -->
<string-array name="type_clock_hours">
@@ -485,4 +502,17 @@
<item>Fifty\nNine</item>
</string-array>
+ <!-- Title for default clock face that will appear in the picker app next to a preview image of
+ the clock face. [CHAR LIMIT=8] -->
+ <string name="clock_title_default" translatable="false">Default</string>
+ <!-- Title for Bubble clock face that will appear in the picker app next to a preview image of
+ the clock face. [CHAR LIMIT=8] -->
+ <string name="clock_title_bubble" translatable="false">Bubble</string>
+ <!-- Title for Stretch clock face that will appear in the picker app next to a preview image of
+ the clock face. [CHAR LIMIT=8] -->
+ <string name="clock_title_stretch" translatable="false">Stretch</string>
+ <!-- Title for Typographic clock face that will appear in the picker app next to a preview image of
+ the clock face. [CHAR LIMIT=8] -->
+ <string name="clock_title_type" translatable="false">Type</string>
+
</resources>
diff --git a/packages/SystemUI/res/drawable/bubble_expanded_header_bg.xml b/packages/SystemUI/res/drawable/bubble_expanded_header_bg.xml
index 26bf981..a76b7b1 100644
--- a/packages/SystemUI/res/drawable/bubble_expanded_header_bg.xml
+++ b/packages/SystemUI/res/drawable/bubble_expanded_header_bg.xml
@@ -23,10 +23,4 @@
android:topRightRadius="@dimen/corner_size"/>
</shape>
</item>
- <item android:gravity="bottom">
- <shape>
- <size android:height="1dp"/>
- <solid android:color="?android:attr/textColorSecondary" />
- </shape>
- </item>
</layer-list>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bubble_expanded_view.xml b/packages/SystemUI/res/layout/bubble_expanded_view.xml
index f0d2b2e..f664c05 100644
--- a/packages/SystemUI/res/layout/bubble_expanded_view.xml
+++ b/packages/SystemUI/res/layout/bubble_expanded_view.xml
@@ -14,7 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<com.android.systemui.bubbles.BubbleExpandedViewContainer
+<com.android.systemui.bubbles.BubbleExpandedView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
@@ -27,48 +27,70 @@
android:layout_height="@dimen/bubble_pointer_height"
/>
- <LinearLayout
- android:id="@+id/header_layout"
- android:layout_height="@dimen/bubble_expanded_header_height"
- android:layout_width="match_parent"
- android:orientation="horizontal"
+ <FrameLayout
+ android:id="@+id/header_permission_wrapper"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:animateLayoutChanges="true"
android:background="@drawable/bubble_expanded_header_bg">
- <TextView
- android:id="@+id/header_text"
- android:textAppearance="@*android:style/TextAppearance.Material.Title"
- android:textSize="18sp"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:gravity="start|center_vertical"
- android:singleLine="true"
- android:paddingLeft="@dimen/bubble_expanded_header_horizontal_padding"
- android:paddingRight="@dimen/bubble_expanded_header_horizontal_padding"
+ <LinearLayout
+ android:id="@+id/header_layout"
+ android:layout_height="@dimen/bubble_expanded_header_height"
+ android:layout_width="match_parent"
+ android:animateLayoutChanges="true"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/header_text"
+ android:textAppearance="@*android:style/TextAppearance.Material.Title"
+ android:textSize="18sp"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:gravity="start|center_vertical"
+ android:singleLine="true"
+ android:paddingLeft="@dimen/bubble_expanded_header_horizontal_padding"
+ android:paddingRight="@dimen/bubble_expanded_header_horizontal_padding"
+ />
+
+ <ImageButton
+ android:id="@+id/deep_link_button"
+ android:layout_width="@dimen/bubble_header_icon_size"
+ android:layout_height="@dimen/bubble_header_icon_size"
+ android:gravity="end|center_vertical"
+ android:src="@drawable/ic_open_in_new"
+ android:scaleType="center"
+ android:tint="?android:attr/colorForeground"
+ android:background="?android:attr/selectableItemBackground"
+ />
+
+ <ImageButton
+ android:id="@id/settings_button"
+ android:layout_width="@dimen/bubble_header_icon_size"
+ android:layout_height="@dimen/bubble_header_icon_size"
+ android:src="@drawable/ic_settings"
+ android:gravity="end|center_vertical"
+ android:scaleType="center"
+ android:tint="?android:attr/colorForeground"
+ android:background="?android:attr/selectableItemBackground"
+ />
+
+ </LinearLayout>
+
+ <include layout="@layout/bubble_permission_view"
+ android:id="@+id/permission_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
/>
- <ImageButton
- android:id="@+id/deep_link_button"
- android:layout_width="@dimen/bubble_header_icon_size"
- android:layout_height="@dimen/bubble_header_icon_size"
- android:gravity="end|center_vertical"
- android:src="@drawable/ic_open_in_new"
- android:scaleType="center"
- android:tint="?android:attr/colorForeground"
- android:background="?android:attr/selectableItemBackground"
- />
+ <View
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_gravity="bottom"
+ android:background="?android:attr/dividerHorizontal"/>
- <ImageButton
- android:id="@id/settings_button"
- android:layout_width="@dimen/bubble_header_icon_size"
- android:layout_height="@dimen/bubble_header_icon_size"
- android:src="@drawable/ic_settings"
- android:gravity="end|center_vertical"
- android:scaleType="center"
- android:tint="?android:attr/colorForeground"
- android:background="?android:attr/selectableItemBackground"
- />
+ </FrameLayout>
- </LinearLayout>
-
-</com.android.systemui.bubbles.BubbleExpandedViewContainer>
+</com.android.systemui.bubbles.BubbleExpandedView>
diff --git a/packages/SystemUI/res/layout/bubble_permission_view.xml b/packages/SystemUI/res/layout/bubble_permission_view.xml
new file mode 100644
index 0000000..7fbb78a
--- /dev/null
+++ b/packages/SystemUI/res/layout/bubble_permission_view.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2019, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:animateLayoutChanges="true"
+ android:orientation="vertical"
+ android:paddingStart="@dimen/bubble_expanded_header_horizontal_padding"
+ android:paddingEnd="@dimen/bubble_expanded_header_horizontal_padding">
+
+ <!-- App info -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginTop="@dimen/bubble_expanded_header_horizontal_padding" >
+
+ <ImageView
+ android:id="@+id/pkgicon"
+ android:layout_width="@dimen/bubble_permission_icon_size"
+ android:layout_height="@dimen/bubble_permission_icon_size"
+ android:layout_centerVertical="true"
+ android:layout_marginEnd="3dp"
+ />
+
+ <TextView
+ android:id="@+id/pkgname"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:textAppearance="@*android:style/TextAppearance.Material.Body2"
+ android:layout_marginStart="3dp"
+ android:layout_marginEnd="2dp"
+ android:singleLine="true"
+ android:gravity="center_vertical"
+ android:layout_centerVertical="true"
+ />
+ </LinearLayout>
+
+ <!-- Actual permission -->
+ <TextView
+ android:id="@+id/prompt"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:text="@string/bubbles_prompt"
+ style="@*android:style/TextAppearance.Material.Body1" />
+
+ <!-- Buttons -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="end"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/no_bubbles_button"
+ android:text="@string/no_bubbles"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:background="@drawable/ripple_drawable"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ <TextView
+ android:id="@+id/yes_bubbles_button"
+ android:text="@string/yes_bubbles"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:background="@drawable/ripple_drawable"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
deleted file mode 100644
index 11d73a9..0000000
--- a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-precision mediump float;
-
-uniform sampler2D uTexture;
-uniform float uCenterReveal;
-uniform float uReveal;
-uniform float uAod2Opacity;
-uniform int uAodMode;
-varying vec2 vTextureCoordinates;
-
-vec3 luminosity(vec3 color) {
- float lum = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
- return vec3(lum);
-}
-
-vec4 transform(vec3 diffuse) {
- // TODO: Add well comments here, tracking on b/123615467.
- vec3 lum = luminosity(diffuse);
- diffuse = mix(diffuse, lum, smoothstep(0., uCenterReveal, uReveal));
- float val = mix(uReveal, uCenterReveal, step(uCenterReveal, uReveal));
- diffuse = smoothstep(val, 1.0, diffuse);
- diffuse *= uAod2Opacity * (1. - smoothstep(uCenterReveal, 1., uReveal));
- return vec4(diffuse.r, diffuse.g, diffuse.b, 1.);
-}
-
-void main() {
- vec4 fragColor = texture2D(uTexture, vTextureCoordinates);
- // TODO: Remove the branch logic here, tracking on b/123615467.
- if (uAodMode != 0) {
- gl_FragColor = transform(fragColor.rgb);
- } else {
- gl_FragColor = fragColor;
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl
deleted file mode 100644
index 4393e2b..0000000
--- a/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl
+++ /dev/null
@@ -1,8 +0,0 @@
-attribute vec4 aPosition;
-attribute vec2 aTextureCoordinates;
-varying vec2 vTextureCoordinates;
-
-void main() {
- vTextureCoordinates = aTextureCoordinates;
- gl_Position = aPosition;
-}
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1060211..0344535 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -23,8 +23,9 @@
<dimen name="navigation_bar_size">@*android:dimen/navigation_bar_height</dimen>
<!-- Minimum swipe distance to catch the swipe gestures to invoke assist or switch tasks. -->
<dimen name="navigation_bar_min_swipe_distance">48dp</dimen>
- <!-- The distance from a side of device of the navigation bar to start an edge swipe -->
- <dimen name="navigation_bar_edge_swipe_threshold">48dp</dimen>
+ <!-- The default distance from a side of the device to start an edge swipe from -->
+ <dimen name="navigation_bar_default_edge_width">48dp</dimen>
+ <dimen name="navigation_bar_default_edge_height">500dp</dimen>
<!-- thickness (height) of the dead zone at the top of the navigation bar,
reducing false presses on navbar buttons; approx 2mm -->
@@ -83,6 +84,9 @@
<!-- Increased height of a small notification in the status bar -->
<dimen name="notification_min_height_increased">146dp</dimen>
+ <!-- Increased height of a collapsed media notification in the status bar -->
+ <dimen name="notification_min_height_media">160dp</dimen>
+
<!-- Height of a small notification in the status bar which was used before android N -->
<dimen name="notification_min_height_legacy">64dp</dimen>
@@ -1037,4 +1041,6 @@
<dimen name="bubble_stack_starting_offset_y">100dp</dimen>
<!-- Size of image buttons in the bubble header -->
<dimen name="bubble_header_icon_size">48dp</dimen>
+ <!-- Size of the app icon shown in the bubble permission view -->
+ <dimen name="bubble_permission_icon_size">24dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 56d9bf4c..db4a6cc 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1829,6 +1829,9 @@
<!-- SysUI Tuner: Button that leads to the navigation bar customization screen [CHAR LIMIT=60] -->
<string name="nav_bar">Navigation bar</string>
+ <!-- Label for navigation edge panel for gestures [CHAR LIMIT=60] -->
+ <string name="nav_bar_edge_panel" translatable="false">Navigation bar Edge Panel</string>
+
<!-- SysUI Tuner: Button that controls layout of navigation bar [CHAR LIMIT=60] -->
<string name="nav_bar_layout">Layout</string>
@@ -2353,5 +2356,12 @@
<!-- Text used for content description of settings button in the header of expanded bubble
view. [CHAR_LIMIT=NONE] -->
<string name="bubbles_settings_button_description">Open notification settings for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g></string>
+ <!-- Text for asking the user whether bubbles (floating app content) should be enabled for an
+ app. [CHAR LIMIT=NONE] -->
+ <string name="bubbles_prompt">Allow bubbles from this app?</string>
+ <!-- Text used for button allowing user to opt out of bubbles [CHAR LIMIT=20] -->
+ <string name="no_bubbles">Block</string>
+ <!-- Text used for button allowing user to approve / enable bubbles [CHAR LIMIT=20] -->
+ <string name="yes_bubbles">Allow</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 2ce6965..d5bd2b2 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -21,12 +21,15 @@
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
+import android.os.Handler;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.settingslib.WirelessUtils;
@@ -206,6 +209,7 @@
protected void updateCarrierText() {
boolean allSimsMissing = true;
boolean anySimReadyAndInService = false;
+ boolean missingSimsWithSubs = false;
CharSequence displayText = null;
List<SubscriptionInfo> subs = mKeyguardUpdateMonitor.getSubscriptionInfo(false);
@@ -252,6 +256,7 @@
// described above.
displayText = makeCarrierStringOnEmergencyCapable(
getMissingSimMessage(), subs.get(0).getCarrierName());
+ missingSimsWithSubs = true;
} else {
// We don't have a SubscriptionInfo to get the emergency calls only from.
// Grab it from the old sticky broadcast if possible instead. We can use it
@@ -288,12 +293,14 @@
displayText = getAirplaneModeMessage();
}
+ Handler handler = Dependency.get(Dependency.MAIN_HANDLER);
+ final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo(
+ displayText,
+ displayText.toString().split(mSeparator.toString()),
+ anySimReadyAndInService && !missingSimsWithSubs,
+ subsIds);
if (mCarrierTextCallback != null) {
- mCarrierTextCallback.updateCarrierInfo(new CarrierTextCallbackInfo(
- displayText,
- displayText.toString().split(mSeparator.toString()),
- anySimReadyAndInService,
- subsIds));
+ handler.post(() -> mCarrierTextCallback.updateCarrierInfo(info));
}
}
@@ -487,7 +494,8 @@
public final boolean anySimReady;
public final int[] subscriptionIds;
- CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
+ @VisibleForTesting
+ public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
boolean anySimReady, int[] subscriptionIds) {
this.carrierText = carrierText;
this.listOfCarriers = listOfCarriers;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 64c5b17..261f391 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -264,7 +264,8 @@
*/
private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
final boolean shouldIncludeAuxiliarySubtypes) {
- final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
+ final List<InputMethodInfo> enabledImis =
+ imm.getEnabledInputMethodListAsUser(KeyguardUpdateMonitor.getCurrentUser());
// Number of the filtered IMEs
int filteredImisCount = 0;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 0970c21..f277c43 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -205,6 +205,7 @@
private boolean mKeyguardGoingAway;
private boolean mGoingToSleep;
private boolean mBouncer;
+ private boolean mAuthInterruptActive;
private boolean mBootCompleted;
private boolean mNeedsSlowUnlockTransition;
private boolean mHasLockscreenWallpaper;
@@ -1565,10 +1566,15 @@
}
/**
- * Request passive authentication, when sensors detect that a user might be present.
+ * Called whenever passive authentication is requested or aborted by a sensor.
+ * @param active If the interrupt started or ended.
*/
- public void onAuthInterruptDetected() {
- if (DEBUG) Log.d(TAG, "onAuthInterruptDetected()");
+ public void onAuthInterruptDetected(boolean active) {
+ if (DEBUG) Log.d(TAG, "onAuthInterruptDetected(" + active + ")");
+ if (mAuthInterruptActive == active) {
+ return;
+ }
+ mAuthInterruptActive = active;
updateFaceListeningState();
}
@@ -1612,7 +1618,7 @@
final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
final int user = getCurrentUser();
- return (mBouncer || awakeKeyguard || shouldListenForFaceAssistant())
+ return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
&& !mSwitchingUser && !getUserCanSkipBouncer(user) && !isFaceDisabled(user)
&& !mKeyguardGoingAway && !mFaceLockedOut && mFaceSettingEnabledForUser
&& mUserManager.isUserUnlocked(user);
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockInfo.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockInfo.java
new file mode 100644
index 0000000..812f215
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockInfo.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.graphics.Bitmap;
+
+import java.util.function.Supplier;
+
+/**
+ * Metadata about an available clock face.
+ */
+final class ClockInfo {
+
+ private final String mName;
+ private final String mTitle;
+ private final String mId;
+ private final Supplier<Bitmap> mThumbnail;
+ private final Supplier<Bitmap> mPreview;
+
+ private ClockInfo(String name, String title, String id,
+ Supplier<Bitmap> thumbnail, Supplier<Bitmap> preview) {
+ mName = name;
+ mTitle = title;
+ mId = id;
+ mThumbnail = thumbnail;
+ mPreview = preview;
+ }
+
+ /**
+ * Gets the non-internationalized name for the clock face.
+ */
+ String getName() {
+ return mName;
+ }
+
+ /**
+ * Gets the name (title) of the clock face to be shown in the picker app.
+ */
+ String getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Gets the ID of the clock face, used by the picker to set the current selection.
+ */
+ String getId() {
+ return mId;
+ }
+
+ /**
+ * Gets a thumbnail image of the clock.
+ */
+ Bitmap getThumbnail() {
+ return mThumbnail.get();
+ }
+
+ /**
+ * Gets a potentially realistic preview image of the clock face.
+ */
+ Bitmap getPreview() {
+ return mPreview.get();
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+
+ static class Builder {
+ private String mName;
+ private String mTitle;
+ private String mId;
+ private Supplier<Bitmap> mThumbnail;
+ private Supplier<Bitmap> mPreview;
+
+ public ClockInfo build() {
+ return new ClockInfo(mName, mTitle, mId, mThumbnail, mPreview);
+ }
+
+ public Builder setName(String name) {
+ mName = name;
+ return this;
+ }
+
+ public Builder setTitle(String title) {
+ mTitle = title;
+ return this;
+ }
+
+ public Builder setId(String id) {
+ mId = id;
+ return this;
+ }
+
+ public Builder setThumbnail(Supplier<Bitmap> thumbnail) {
+ mThumbnail = thumbnail;
+ return this;
+ }
+
+ public Builder setPreview(Supplier<Bitmap> preview) {
+ mPreview = preview;
+ return this;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
index 3217ca6..9598142 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
@@ -17,12 +17,15 @@
import android.content.ContentResolver;
import android.content.Context;
+import android.content.res.Resources;
import android.database.ContentObserver;
+import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.view.LayoutInflater;
+import com.android.keyguard.R;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.ExtensionController.Extension;
@@ -45,6 +48,7 @@
private final LayoutInflater mLayoutInflater;
private final ContentResolver mContentResolver;
+ private final List<ClockInfo> mClockInfos = new ArrayList<>();
/**
* Observe settings changes to know when to switch the clock face.
*/
@@ -76,6 +80,36 @@
mExtensionController = extensionController;
mLayoutInflater = LayoutInflater.from(context);
mContentResolver = context.getContentResolver();
+
+ Resources res = context.getResources();
+ mClockInfos.add(ClockInfo.builder()
+ .setName("default")
+ .setTitle(res.getString(R.string.clock_title_default))
+ .setId("default")
+ .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.default_thumbnail))
+ .setPreview(() -> BitmapFactory.decodeResource(res, R.drawable.default_preview))
+ .build());
+ mClockInfos.add(ClockInfo.builder()
+ .setName("bubble")
+ .setTitle(res.getString(R.string.clock_title_bubble))
+ .setId(BubbleClockController.class.getName())
+ .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.bubble_thumbnail))
+ .setPreview(() -> BitmapFactory.decodeResource(res, R.drawable.bubble_preview))
+ .build());
+ mClockInfos.add(ClockInfo.builder()
+ .setName("stretch")
+ .setTitle(res.getString(R.string.clock_title_stretch))
+ .setId(StretchAnalogClockController.class.getName())
+ .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.stretch_thumbnail))
+ .setPreview(() -> BitmapFactory.decodeResource(res, R.drawable.stretch_preview))
+ .build());
+ mClockInfos.add(ClockInfo.builder()
+ .setName("type")
+ .setTitle(res.getString(R.string.clock_title_type))
+ .setId(TypeClockController.class.getName())
+ .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.type_thumbnail))
+ .setPreview(() -> BitmapFactory.decodeResource(res, R.drawable.type_preview))
+ .build());
}
/**
@@ -101,6 +135,13 @@
}
}
+ /**
+ * Get information about available clock faces.
+ */
+ List<ClockInfo> getClockInfos() {
+ return mClockInfos;
+ }
+
private void setClockPlugin(ClockPlugin plugin) {
for (int i = 0; i < mListeners.size(); i++) {
// It probably doesn't make sense to supply the same plugin instances to multiple
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java
new file mode 100644
index 0000000..5ef35be
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Dependency;
+
+import java.io.FileNotFoundException;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * Exposes custom clock face options and provides realistic preview images.
+ *
+ * APIs:
+ *
+ * /list_options: List the available clock faces, which has the following columns
+ * name: name of the clock face
+ * title: title of the clock face
+ * id: value used to set the clock face
+ * thumbnail: uri of the thumbnail image, should be /thumbnail/{name}
+ * preview: uri of the preview image, should be /preview/{name}
+ *
+ * /thumbnail/{id}: Opens a file stream for the thumbnail image for clock face {id}.
+ *
+ * /preview/{id}: Opens a file stream for the preview image for clock face {id}.
+ */
+public final class ClockOptionsProvider extends ContentProvider {
+
+ private static final String TAG = "ClockOptionsProvider";
+ private static final String KEY_LIST_OPTIONS = "/list_options";
+ private static final String KEY_PREVIEW = "preview";
+ private static final String KEY_THUMBNAIL = "thumbnail";
+ private static final String COLUMN_NAME = "name";
+ private static final String COLUMN_TITLE = "title";
+ private static final String COLUMN_ID = "id";
+ private static final String COLUMN_THUMBNAIL = "thumbnail";
+ private static final String COLUMN_PREVIEW = "preview";
+ private static final String MIME_TYPE_PNG = "image/png";
+ private static final String CONTENT_SCHEME = "content";
+ private static final String AUTHORITY = "com.android.keyguard.clock";
+
+ private final Supplier<List<ClockInfo>> mClocksSupplier;
+
+ public ClockOptionsProvider() {
+ this(() -> Dependency.get(ClockManager.class).getClockInfos());
+ }
+
+ @VisibleForTesting
+ ClockOptionsProvider(Supplier<List<ClockInfo>> clocksSupplier) {
+ mClocksSupplier = clocksSupplier;
+ }
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ List<String> segments = uri.getPathSegments();
+ if (segments.size() > 0 && (KEY_PREVIEW.equals(segments.get(0))
+ || KEY_THUMBNAIL.equals(segments.get(0)))) {
+ return MIME_TYPE_PNG;
+ }
+ return "vnd.android.cursor.dir/clock_faces";
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ if (!KEY_LIST_OPTIONS.equals(uri.getPath())) {
+ return null;
+ }
+ MatrixCursor cursor = new MatrixCursor(new String[] {
+ COLUMN_NAME, COLUMN_TITLE, COLUMN_ID, COLUMN_THUMBNAIL, COLUMN_PREVIEW});
+ List<ClockInfo> clocks = mClocksSupplier.get();
+ for (int i = 0; i < clocks.size(); i++) {
+ ClockInfo clock = clocks.get(i);
+ cursor.newRow()
+ .add(COLUMN_NAME, clock.getName())
+ .add(COLUMN_TITLE, clock.getTitle())
+ .add(COLUMN_ID, clock.getId())
+ .add(COLUMN_THUMBNAIL, createThumbnailUri(clock))
+ .add(COLUMN_PREVIEW, createPreviewUri(clock));
+ }
+ return cursor;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues initialValues) {
+ return null;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ List<String> segments = uri.getPathSegments();
+ if (segments.size() != 2 || !(KEY_PREVIEW.equals(segments.get(0))
+ || KEY_THUMBNAIL.equals(segments.get(0)))) {
+ throw new FileNotFoundException("Invalid preview url");
+ }
+ String id = segments.get(1);
+ if (TextUtils.isEmpty(id)) {
+ throw new FileNotFoundException("Invalid preview url, missing id");
+ }
+ ClockInfo clock = null;
+ List<ClockInfo> clocks = mClocksSupplier.get();
+ for (int i = 0; i < clocks.size(); i++) {
+ if (id.equals(clocks.get(i).getId())) {
+ clock = clocks.get(i);
+ break;
+ }
+ }
+ if (clock == null) {
+ throw new FileNotFoundException("Invalid preview url, id not found");
+ }
+ return openPipeHelper(uri, MIME_TYPE_PNG, null, KEY_PREVIEW.equals(segments.get(0))
+ ? clock.getPreview() : clock.getThumbnail(), new MyWriter());
+ }
+
+ private Uri createThumbnailUri(ClockInfo clock) {
+ return new Uri.Builder()
+ .scheme(CONTENT_SCHEME)
+ .authority(AUTHORITY)
+ .appendPath(KEY_THUMBNAIL)
+ .appendPath(clock.getId())
+ .build();
+ }
+
+ private Uri createPreviewUri(ClockInfo clock) {
+ return new Uri.Builder()
+ .scheme(CONTENT_SCHEME)
+ .authority(AUTHORITY)
+ .appendPath(KEY_PREVIEW)
+ .appendPath(clock.getId())
+ .build();
+ }
+
+ private static class MyWriter implements ContentProvider.PipeDataWriter<Bitmap> {
+ @Override
+ public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
+ Bundle opts, Bitmap bitmap) {
+ try (AutoCloseOutputStream os = new AutoCloseOutputStream(output)) {
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
+ } catch (Exception e) {
+ Log.w(TAG, "fail to write to pipe", e);
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java
index 5f9da3e..8feae53 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java
@@ -17,9 +17,14 @@
import android.content.Context;
import android.content.res.Resources;
+import android.text.Annotation;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannedString;
+import android.text.TextUtils;
import android.text.format.DateFormat;
+import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
-import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.keyguard.R;
@@ -31,13 +36,14 @@
/**
* Clock that presents the time in words.
*/
-public class TypographicClock extends LinearLayout {
+public class TypographicClock extends TextView {
+ private static final String ANNOTATION_COLOR = "color";
+
+ private final Resources mResources;
private final String[] mHours;
private final String[] mMinutes;
- private TextView mHeaderText;
- private TextView mHourText;
- private TextView mMinuteText;
+ private final int mAccentColor;
private Calendar mTime;
private String mDescFormat;
private TimeZone mTimeZone;
@@ -54,9 +60,10 @@
super(context, attrs, defStyleAttr);
mTime = Calendar.getInstance();
mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern();
- Resources res = context.getResources();
- mHours = res.getStringArray(R.array.type_clock_hours);
- mMinutes = res.getStringArray(R.array.type_clock_minutes);
+ mResources = context.getResources();
+ mHours = mResources.getStringArray(R.array.type_clock_hours);
+ mMinutes = mResources.getStringArray(R.array.type_clock_minutes);
+ mAccentColor = mResources.getColor(R.color.typeClockAccentColor, null);
}
/**
@@ -65,11 +72,28 @@
public void onTimeChanged() {
mTime.setTimeInMillis(System.currentTimeMillis());
setContentDescription(DateFormat.format(mDescFormat, mTime));
- final int hour = mTime.get(Calendar.HOUR);
- mHourText.setText(mHours[hour % 12]);
- final int minute = mTime.get(Calendar.MINUTE);
- mMinuteText.setText(mMinutes[minute % 60]);
- invalidate();
+ final int hour = mTime.get(Calendar.HOUR) % 12;
+ final int minute = mTime.get(Calendar.MINUTE) % 60;
+
+ // Get the quantity based on the hour for languages like Portuguese and Czech.
+ SpannedString typeTemplate = (SpannedString) mResources.getQuantityText(
+ R.plurals.type_clock_header, hour);
+
+ // Find the "color" annotation and set the foreground color to the accent color.
+ Annotation[] annotations = typeTemplate.getSpans(0, typeTemplate.length(),
+ Annotation.class);
+ SpannableString spanType = new SpannableString(typeTemplate);
+ for (int i = 0; i < annotations.length; i++) {
+ Annotation annotation = annotations[i];
+ String key = annotation.getValue();
+ if (ANNOTATION_COLOR.equals(key)) {
+ spanType.setSpan(new ForegroundColorSpan(mAccentColor),
+ spanType.getSpanStart(annotation), spanType.getSpanEnd(annotation),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ }
+
+ setText(TextUtils.expandTemplate(spanType, mHours[hour], mMinutes[minute]));
}
/**
@@ -82,25 +106,6 @@
mTime.setTimeZone(timeZone);
}
- /**
- * Set the color of the text used to display the time.
- *
- * This is necessary when the wallpaper shown behind the clock on the
- * lock screen changes.
- */
- public void setTextColor(int color) {
- mHourText.setTextColor(color);
- mMinuteText.setTextColor(color);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mHeaderText = findViewById(R.id.header);
- mHourText = findViewById(R.id.hour);
- mMinuteText = findViewById(R.id.minute);
- }
-
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 5040942..2aecc24 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -19,11 +19,8 @@
import static android.view.Display.DEFAULT_DISPLAY;
import android.app.WallpaperManager;
-import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.RecordingCanvas;
@@ -31,9 +28,7 @@
import android.graphics.RectF;
import android.graphics.Region.Op;
import android.hardware.display.DisplayManager;
-import android.opengl.GLSurfaceView;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.Handler;
import android.os.Trace;
import android.service.wallpaper.WallpaperService;
@@ -44,7 +39,6 @@
import android.view.SurfaceHolder;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.glwallpaper.ImageWallpaperRenderer;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -57,17 +51,12 @@
public class ImageWallpaper extends WallpaperService {
private static final String TAG = "ImageWallpaper";
private static final String GL_LOG_TAG = "ImageWallpaperGL";
- // TODO: Testing purpose, need to remove later, b/123616712.
- private static final String SENSOR_EVENT_AWAKE = "systemui.test.event.awake";
- // TODO: Testing purpose, need to remove later, b/123616712.
- private static final String SENSOR_EVENT_SLEEP = "systemui.test.event.sleep";
private static final boolean DEBUG = false;
private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu";
private static final long DELAY_FORGET_WALLPAPER = 5000;
private WallpaperManager mWallpaperManager;
private DrawableEngine mEngine;
- private GLEngine mGlEngine;
@Override
public void onCreate() {
@@ -84,112 +73,10 @@
@Override
public Engine onCreateEngine() {
- mGlEngine = new GLEngine(this);
- return mGlEngine;
+ mEngine = new DrawableEngine();
+ return mEngine;
}
- class GLEngine extends Engine {
- private GLWallpaperSurfaceView mWallpaperSurfaceView;
-
- GLEngine(Context context) {
- mWallpaperSurfaceView = new GLWallpaperSurfaceView(context);
- mWallpaperSurfaceView.setRenderer(
- new ImageWallpaperRenderer(context, mWallpaperSurfaceView));
- mWallpaperSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
- setOffsetNotificationsEnabled(true);
- }
-
- @Override
- public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
- if (mWallpaperSurfaceView != null) {
- mWallpaperSurfaceView.notifyAmbientModeChanged(inAmbientMode);
- }
- }
-
- @Override
- public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
- float yOffsetStep, int xPixelOffset, int yPixelOffset) {
- if (mWallpaperSurfaceView != null) {
- mWallpaperSurfaceView.notifyOffsetsChanged(xOffset, yOffset);
- }
- }
-
- private class GLWallpaperSurfaceView extends GLSurfaceView implements ImageGLView {
- private SensorEventListener mEventListener;
- private WallpaperStatusListener mWallpaperChangedListener;
-
- // TODO: Testing purpose, need to remove later, b/123616712.
- /**
- * For testing only: adb shell am broadcast -a <INTENT>
- */
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent == null) {
- return;
- }
- switch (intent.getAction()) {
- case SENSOR_EVENT_AWAKE:
- notifySensorEvents(true);
- break;
- case SENSOR_EVENT_SLEEP:
- notifySensorEvents(false);
- break;
- }
- }
- };
-
- GLWallpaperSurfaceView(Context context) {
- super(context);
- setEGLContextClientVersion(2);
- // TODO: Testing purpose, need to remove later, b/123616712.
- if (Build.IS_DEBUGGABLE) {
- IntentFilter filter = new IntentFilter();
- filter.addAction(SENSOR_EVENT_AWAKE);
- filter.addAction(SENSOR_EVENT_SLEEP);
- registerReceiver(mReceiver, filter);
- }
- }
-
- @Override
- public SurfaceHolder getHolder() {
- return getSurfaceHolder();
- }
-
- @Override
- public void setRenderer(Renderer renderer) {
- super.setRenderer(renderer);
- mEventListener = (SensorEventListener) renderer;
- mWallpaperChangedListener = (WallpaperStatusListener) renderer;
- }
-
- private void notifySensorEvents(boolean reach) {
- if (mEventListener != null) {
- mEventListener.onSensorEvent(reach);
- }
- }
-
- private void notifyAmbientModeChanged(boolean inAmbient) {
- if (mWallpaperChangedListener != null) {
- mWallpaperChangedListener.onAmbientModeChanged(inAmbient);
- }
- }
-
- private void notifyOffsetsChanged(float xOffset, float yOffset) {
- if (mWallpaperChangedListener != null) {
- mWallpaperChangedListener.onOffsetsChanged(
- xOffset, yOffset, getHolder().getSurfaceFrame());
- }
- }
-
- @Override
- public void render() {
- requestRender();
- }
- }
- }
-
- // TODO: Remove this engine, tracking on b/123617158.
class DrawableEngine extends Engine {
private final Runnable mUnloadWallpaperCallback = () -> {
unloadWallpaper(false /* forgetSize */);
@@ -677,46 +564,4 @@
}
}
}
-
- /**
- * A listener to trace sensor event.
- */
- public interface SensorEventListener {
-
- /**
- * Called back while sensor event comes.
- * @param reach The status of sensor.
- */
- void onSensorEvent(boolean reach);
- }
-
- /**
- * A listener to trace status of image wallpaper.
- */
- public interface WallpaperStatusListener {
-
- /**
- * Called back while ambient mode changes.
- * @param inAmbientMode true if is in ambient mode, false otherwise.
- */
- void onAmbientModeChanged(boolean inAmbientMode);
-
- /**
- * Called back while wallpaper offsets.
- * @param xOffset The offset portion along x.
- * @param yOffset The offset portion along y.
- */
- void onOffsetsChanged(float xOffset, float yOffset, Rect frame);
- }
-
- /**
- * An abstraction for view of GLRenderer.
- */
- public interface ImageGLView {
-
- /**
- * Ask the view to render.
- */
- void render();
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 404f2e5..6877f5e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -16,6 +16,10 @@
package com.android.systemui.bubbles;
+import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
+import static android.util.StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING;
+import static android.util.StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE;
+import static android.util.StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__DOCUMENT_LAUNCH_NOT_ALWAYS;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -26,17 +30,16 @@
import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
-import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.graphics.Rect;
-import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.Log;
+import android.util.StatsLog;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -70,7 +73,7 @@
* The controller manages addition, removal, and visible state of bubbles on screen.
*/
@Singleton
-public class BubbleController {
+public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListener {
private static final int MAX_BUBBLES = 5; // TODO: actually enforce this
private static final String TAG = "BubbleController";
@@ -186,7 +189,12 @@
* Set a listener to be notified of bubble expand events.
*/
public void setExpandListener(BubbleExpandListener listener) {
- mExpandListener = listener;
+ mExpandListener = ((isExpanding, key) -> {
+ if (listener != null) {
+ listener.onBubbleExpandChanged(isExpanding, key);
+ }
+ mStatusBarWindowController.setBubbleExpanded(isExpanding);
+ });
if (mStackView != null) {
mStackView.setExpandListener(mExpandListener);
}
@@ -261,6 +269,7 @@
if (mExpandListener != null) {
mStackView.setExpandListener(mExpandListener);
}
+ mStackView.setOnBlockedListener(this);
}
// It's new
BubbleView bubble = (BubbleView) mInflater.inflate(
@@ -297,6 +306,19 @@
updateVisibility();
}
+ @Override
+ public void onBubbleBlocked(NotificationEntry entry) {
+ Object[] bubbles = mBubbles.values().toArray();
+ for (int i = 0; i < bubbles.length; i++) {
+ NotificationEntry e = ((BubbleView) bubbles[i]).getEntry();
+ boolean samePackage = entry.notification.getPackageName().equals(
+ e.notification.getPackageName());
+ if (samePackage) {
+ removeBubble(entry.key);
+ }
+ }
+ }
+
@SuppressWarnings("FieldCanBeLocal")
private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
@Override
@@ -408,11 +430,15 @@
@Nullable
private PendingIntent getValidBubbleIntent(NotificationEntry notif) {
Notification notification = notif.notification.getNotification();
+ String packageName = notif.notification.getPackageName();
Notification.BubbleMetadata data = notif.getBubbleMetadata();
- if (data != null && canLaunchInActivityView(data.getIntent())) {
+ if (data != null && canLaunchInActivityView(data.getIntent(),
+ true /* enable logging for bubbles */, packageName)) {
return data.getIntent();
- } else if (shouldUseContentIntent(mContext)
- && canLaunchInActivityView(notification.contentIntent)) {
+ }
+ if (shouldUseContentIntent(mContext)
+ && canLaunchInActivityView(notification.contentIntent,
+ false /* disable logging for notifications */, packageName)) {
Log.d(TAG, "[addBubble " + notif.key
+ "]: No appOverlayIntent, using contentIntent.");
return notification.contentIntent;
@@ -423,16 +449,41 @@
/**
* Whether an intent is properly configured to display in an {@link android.app.ActivityView}.
+ *
+ * @param intent the pending intent of the bubble.
+ * @param enableLogging whether bubble developer error should be logged.
+ * @param packageName the notification package name for this bubble.
+ * @return
*/
- private boolean canLaunchInActivityView(PendingIntent intent) {
+ private boolean canLaunchInActivityView(PendingIntent intent, boolean enableLogging,
+ String packageName) {
if (intent == null) {
return false;
}
ActivityInfo info =
intent.getIntent().resolveActivityInfo(mContext.getPackageManager(), 0);
- return info != null
- && ActivityInfo.isResizeableMode(info.resizeMode)
- && (info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) != 0;
+ if (info == null) {
+ if (enableLogging) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING);
+ }
+ return false;
+ }
+ if (!ActivityInfo.isResizeableMode(info.resizeMode)) {
+ if (enableLogging) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE);
+ }
+ return false;
+ }
+ if (info.documentLaunchMode != DOCUMENT_LAUNCH_ALWAYS) {
+ if (enableLogging) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__DOCUMENT_LAUNCH_NOT_ALWAYS);
+ }
+ return false;
+ }
+ return (info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) != 0;
}
/**
@@ -441,20 +492,9 @@
@VisibleForTesting
protected boolean shouldBubble(NotificationEntry entry) {
StatusBarNotification n = entry.notification;
- boolean canAppOverlay = false;
- try {
- canAppOverlay = mNotificationManagerService.areBubblesAllowedForPackage(
- n.getPackageName(), n.getUid());
- } catch (RemoteException e) {
- Log.w(TAG, "Error calling NoMan to determine if app can overlay", e);
- }
-
- NotificationChannel channel = mNotificationEntryManager.getNotificationData().getChannel(
- entry.key);
- boolean canChannelOverlay = channel != null && channel.canBubble();
boolean hasOverlayIntent = n.getNotification().getBubbleMetadata() != null
&& n.getNotification().getBubbleMetadata().getIntent() != null;
- return hasOverlayIntent && canChannelOverlay && canAppOverlay;
+ return hasOverlayIntent && entry.canBubble;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
new file mode 100644
index 0000000..bf9d7ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bubbles;
+
+import android.animation.LayoutTransition;
+import android.animation.ObjectAnimator;
+import android.annotation.Nullable;
+import android.app.INotificationManager;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+import com.android.systemui.recents.TriangleShape;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+/**
+ * Container for the expanded bubble view, handles rendering the caret and header of the view.
+ */
+public class BubbleExpandedView extends LinearLayout implements View.OnClickListener {
+ private static final String TAG = "BubbleExpandedView";
+
+ // The triangle pointing to the expanded view
+ private View mPointerView;
+
+ // Header
+ private View mHeaderView;
+ private TextView mHeaderTextView;
+ private ImageButton mDeepLinkIcon;
+ private ImageButton mSettingsIcon;
+
+ // Permission view
+ private View mPermissionView;
+
+ // The view that is being displayed for the expanded state
+ private View mExpandedView;
+
+ private NotificationEntry mEntry;
+ private PackageManager mPm;
+ private String mAppName;
+ private Drawable mAppIcon;
+
+ private INotificationManager mNotificationManagerService;
+
+ // Need reference to let it know to collapse when new task is launched
+ private BubbleStackView mStackView;
+
+ private OnBubbleBlockedListener mOnBubbleBlockedListener;
+
+ public BubbleExpandedView(Context context) {
+ this(context, null);
+ }
+
+ public BubbleExpandedView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public BubbleExpandedView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public BubbleExpandedView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ mPm = context.getPackageManager();
+ try {
+ mNotificationManagerService = INotificationManager.Stub.asInterface(
+ ServiceManager.getServiceOrThrow(Context.NOTIFICATION_SERVICE));
+ } catch (ServiceManager.ServiceNotFoundException e) {
+ Log.w(TAG, e);
+ }
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ Resources res = getResources();
+ mPointerView = findViewById(R.id.pointer_view);
+ int width = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
+ int height = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
+
+ TypedArray ta = getContext().obtainStyledAttributes(
+ new int[] {android.R.attr.colorBackgroundFloating});
+ int bgColor = ta.getColor(0, Color.WHITE);
+ ta.recycle();
+
+ ShapeDrawable triangleDrawable = new ShapeDrawable(
+ TriangleShape.create(width, height, true /* pointUp */));
+ triangleDrawable.setTint(bgColor);
+ mPointerView.setBackground(triangleDrawable);
+
+ FrameLayout viewWrapper = findViewById(R.id.header_permission_wrapper);
+ LayoutTransition transition = new LayoutTransition();
+ transition.setDuration(200);
+
+ ObjectAnimator appearAnimator = ObjectAnimator.ofFloat(null, View.ALPHA, 0f, 1f);
+ transition.setAnimator(LayoutTransition.APPEARING, appearAnimator);
+ transition.setInterpolator(LayoutTransition.APPEARING, Interpolators.ALPHA_IN);
+
+ ObjectAnimator disappearAnimator = ObjectAnimator.ofFloat(null, View.ALPHA, 1f, 0f);
+ transition.setAnimator(LayoutTransition.DISAPPEARING, disappearAnimator);
+ transition.setInterpolator(LayoutTransition.DISAPPEARING, Interpolators.ALPHA_OUT);
+
+ transition.setAnimateParentHierarchy(false);
+ viewWrapper.setLayoutTransition(transition);
+ viewWrapper.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
+
+ mHeaderView = findViewById(R.id.header_layout);
+ mHeaderTextView = findViewById(R.id.header_text);
+ mDeepLinkIcon = findViewById(R.id.deep_link_button);
+ mSettingsIcon = findViewById(R.id.settings_button);
+ mDeepLinkIcon.setOnClickListener(this);
+ mSettingsIcon.setOnClickListener(this);
+
+ mPermissionView = findViewById(R.id.permission_layout);
+ findViewById(R.id.no_bubbles_button).setOnClickListener(this);
+ findViewById(R.id.yes_bubbles_button).setOnClickListener(this);
+ }
+
+ /**
+ * Sets the listener to notify when a bubble has been blocked.
+ */
+ public void setOnBlockedListener(OnBubbleBlockedListener listener) {
+ mOnBubbleBlockedListener = listener;
+ }
+
+ /**
+ * Sets the notification entry used to populate this view.
+ */
+ public void setEntry(NotificationEntry entry, BubbleStackView stackView) {
+ mStackView = stackView;
+ mEntry = entry;
+
+ ApplicationInfo info;
+ try {
+ info = mPm.getApplicationInfo(
+ entry.notification.getPackageName(),
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE);
+ if (info != null) {
+ mAppName = String.valueOf(mPm.getApplicationLabel(info));
+ mAppIcon = mPm.getApplicationIcon(info);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Ahh... just use package name
+ mAppName = entry.notification.getPackageName();
+ }
+ if (mAppIcon == null) {
+ mAppIcon = mPm.getDefaultActivityIcon();
+ }
+ updateHeaderView();
+ updatePermissionView();
+ }
+
+ private void updateHeaderView() {
+ mSettingsIcon.setContentDescription(getResources().getString(
+ R.string.bubbles_settings_button_description, mAppName));
+ mDeepLinkIcon.setContentDescription(getResources().getString(
+ R.string.bubbles_deep_link_button_description, mAppName));
+ if (mEntry != null && mEntry.getBubbleMetadata() != null) {
+ mHeaderTextView.setText(mEntry.getBubbleMetadata().getTitle());
+ } else {
+ // This should only happen if we're auto-bubbling notification content that isn't
+ // explicitly a bubble
+ mHeaderTextView.setText(mAppName);
+ }
+ }
+
+ private void updatePermissionView() {
+ boolean hasUserApprovedBubblesForPackage = false;
+ try {
+ hasUserApprovedBubblesForPackage =
+ mNotificationManagerService.hasUserApprovedBubblesForPackage(
+ mEntry.notification.getPackageName(), mEntry.notification.getUid());
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ }
+ if (hasUserApprovedBubblesForPackage) {
+ mHeaderView.setVisibility(VISIBLE);
+ mPermissionView.setVisibility(GONE);
+ } else {
+ mHeaderView.setVisibility(GONE);
+ mPermissionView.setVisibility(VISIBLE);
+ ((ImageView) mPermissionView.findViewById(R.id.pkgicon)).setImageDrawable(mAppIcon);
+ ((TextView) mPermissionView.findViewById(R.id.pkgname)).setText(mAppName);
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (mEntry == null) {
+ return;
+ }
+ Notification n = mEntry.notification.getNotification();
+ int id = view.getId();
+ if (id == R.id.deep_link_button) {
+ mStackView.collapseStack(() -> {
+ try {
+ n.contentIntent.send();
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "Failed to send intent for bubble with key: "
+ + (mEntry != null ? mEntry.key : " null entry"));
+ }
+ });
+ } else if (id == R.id.settings_button) {
+ Intent intent = getSettingsIntent(mEntry.notification.getPackageName(),
+ mEntry.notification.getUid());
+ mStackView.collapseStack(() -> mContext.startActivity(intent));
+ } else if (id == R.id.no_bubbles_button) {
+ setBubblesAllowed(false);
+ } else if (id == R.id.yes_bubbles_button) {
+ setBubblesAllowed(true);
+ }
+ }
+
+ private void setBubblesAllowed(boolean allowed) {
+ try {
+ mNotificationManagerService.setBubblesAllowed(
+ mEntry.notification.getPackageName(),
+ mEntry.notification.getUid(),
+ allowed);
+ if (allowed) {
+ mPermissionView.setVisibility(GONE);
+ mHeaderView.setVisibility(VISIBLE);
+ } else if (mOnBubbleBlockedListener != null) {
+ mOnBubbleBlockedListener.onBubbleBlocked(mEntry);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ }
+ }
+
+ /**
+ * Set the x position that the tip of the triangle should point to.
+ */
+ public void setPointerPosition(int x) {
+ // Adjust for the pointer size
+ x -= (mPointerView.getWidth() / 2);
+ mPointerView.setTranslationX(x);
+ }
+
+ /**
+ * Set the view to display for the expanded state. Passing null will clear the view.
+ */
+ public void setExpandedView(View view) {
+ if (mExpandedView == view) {
+ return;
+ }
+ if (mExpandedView != null) {
+ removeView(mExpandedView);
+ }
+ mExpandedView = view;
+ if (mExpandedView != null) {
+ addView(mExpandedView);
+ }
+ }
+
+ /**
+ * @return the view containing the expanded content, can be null.
+ */
+ @Nullable
+ public View getExpandedView() {
+ return mExpandedView;
+ }
+
+ private Intent getSettingsIntent(String packageName, final int appUid) {
+ final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
+ intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
+ intent.putExtra(Settings.EXTRA_APP_UID, appUid);
+ intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return intent;
+ }
+
+ /**
+ * Listener that is notified when a bubble is blocked.
+ */
+ public interface OnBubbleBlockedListener {
+ /**
+ * Called when a bubble is blocked for the provided entry.
+ */
+ void onBubbleBlocked(NotificationEntry entry);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java
deleted file mode 100644
index 67b18fd..0000000
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.bubbles;
-
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.graphics.drawable.ShapeDrawable;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.TriangleShape;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-/**
- * Container for the expanded bubble view, handles rendering the caret and header of the view.
- */
-public class BubbleExpandedViewContainer extends LinearLayout implements View.OnClickListener {
- private static final String TAG = "BubbleExpandedView";
-
- // The triangle pointing to the expanded view
- private View mPointerView;
- // The view displayed between the pointer and the expanded view
- private TextView mHeaderView;
- // Tappable header icon deeplinking into the app
- private ImageButton mDeepLinkIcon;
- // Tappable header icon deeplinking into notification settings
- private ImageButton mSettingsIcon;
- // The view that is being displayed for the expanded state
- private View mExpandedView;
-
- private NotificationEntry mEntry;
- private PackageManager mPm;
- private String mAppName;
-
- // Need reference to let it know to collapse when new task is launched
- private BubbleStackView mStackView;
-
- public BubbleExpandedViewContainer(Context context) {
- this(context, null);
- }
-
- public BubbleExpandedViewContainer(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public BubbleExpandedViewContainer(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public BubbleExpandedViewContainer(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- mPm = context.getPackageManager();
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- Resources res = getResources();
- mPointerView = findViewById(R.id.pointer_view);
- int width = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
- int height = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
-
- TypedArray ta = getContext().obtainStyledAttributes(
- new int[] {android.R.attr.colorBackgroundFloating});
- int bgColor = ta.getColor(0, Color.WHITE);
- ta.recycle();
-
- ShapeDrawable triangleDrawable = new ShapeDrawable(
- TriangleShape.create(width, height, true /* pointUp */));
- triangleDrawable.setTint(bgColor);
- mPointerView.setBackground(triangleDrawable);
-
- mHeaderView = findViewById(R.id.header_text);
- mDeepLinkIcon = findViewById(R.id.deep_link_button);
- mSettingsIcon = findViewById(R.id.settings_button);
- mDeepLinkIcon.setOnClickListener(this);
- mSettingsIcon.setOnClickListener(this);
- }
-
- /**
- * Sets the notification entry used to populate this view.
- */
- public void setEntry(NotificationEntry entry, BubbleStackView stackView) {
- mStackView = stackView;
- mEntry = entry;
-
- ApplicationInfo info;
- try {
- info = mPm.getApplicationInfo(
- entry.notification.getPackageName(),
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_DIRECT_BOOT_AWARE);
- if (info != null) {
- mAppName = String.valueOf(mPm.getApplicationLabel(info));
- }
- } catch (PackageManager.NameNotFoundException e) {
- // Ahh... just use package name
- mAppName = entry.notification.getPackageName();
- }
-
- updateHeaderView();
- }
-
- private void updateHeaderView() {
- mSettingsIcon.setContentDescription(getResources().getString(
- R.string.bubbles_settings_button_description, mAppName));
- mDeepLinkIcon.setContentDescription(getResources().getString(
- R.string.bubbles_deep_link_button_description, mAppName));
- if (mEntry != null && mEntry.getBubbleMetadata() != null) {
- setHeaderText(mEntry.getBubbleMetadata().getTitle());
- } else {
- // This should only happen if we're auto-bubbling notification content that isn't
- // explicitly a bubble
- setHeaderText(mAppName);
- }
- }
-
- @Override
- public void onClick(View view) {
- if (mEntry == null) {
- return;
- }
- Notification n = mEntry.notification.getNotification();
- int id = view.getId();
- if (id == R.id.deep_link_button) {
- mStackView.collapseStack(() -> {
- try {
- n.contentIntent.send();
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG, "Failed to send intent for bubble with key: "
- + (mEntry != null ? mEntry.key : " null entry"));
- }
- });
- } else if (id == R.id.settings_button) {
- Intent intent = getSettingsIntent(mEntry.notification.getPackageName(),
- mEntry.notification.getUid());
- mStackView.collapseStack(() -> mContext.startActivity(intent));
- }
- }
-
- /**
- * Set the x position that the tip of the triangle should point to.
- */
- public void setPointerPosition(int x) {
- // Adjust for the pointer size
- x -= (mPointerView.getWidth() / 2);
- mPointerView.setTranslationX(x);
- }
-
- /**
- * Set the text displayed within the header.
- */
- private void setHeaderText(CharSequence text) {
- mHeaderView.setText(text);
- mHeaderView.setVisibility(TextUtils.isEmpty(text) ? GONE : VISIBLE);
- }
-
- /**
- * Set the view to display for the expanded state. Passing null will clear the view.
- */
- public void setExpandedView(View view) {
- if (mExpandedView == view) {
- return;
- }
- if (mExpandedView != null) {
- removeView(mExpandedView);
- }
- mExpandedView = view;
- if (mExpandedView != null) {
- addView(mExpandedView);
- }
- }
-
- /**
- * @return the view containing the expanded content, can be null.
- */
- @Nullable
- public View getExpandedView() {
- return mExpandedView;
- }
-
- private Intent getSettingsIntent(String packageName, final int appUid) {
- final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
- intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
- intent.putExtra(Settings.EXTRA_APP_UID, appUid);
- intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- return intent;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index b6acd63..305f866 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -94,7 +94,7 @@
private StackAnimationController mStackAnimationController;
private ExpandedAnimationController mExpandedAnimationController;
- private BubbleExpandedViewContainer mExpandedViewContainer;
+ private BubbleExpandedView mExpandedViewContainer;
private int mBubbleSize;
private int mBubblePadding;
@@ -173,7 +173,7 @@
mBubbleContainer.setClipChildren(false);
addView(mBubbleContainer, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
- mExpandedViewContainer = (BubbleExpandedViewContainer)
+ mExpandedViewContainer = (BubbleExpandedView)
LayoutInflater.from(context).inflate(R.layout.bubble_expanded_view,
this /* parent */, false /* attachToRoot */);
mExpandedViewContainer.setElevation(elevation);
@@ -224,6 +224,13 @@
}
/**
+ * Sets the listener to notify when a bubble is blocked.
+ */
+ public void setOnBlockedListener(BubbleExpandedView.OnBubbleBlockedListener listener) {
+ mExpandedViewContainer.setOnBlockedListener(listener);
+ }
+
+ /**
* Whether the stack of bubbles is expanded or not.
*/
public boolean isExpanded() {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index 4f870f6..1644064 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -38,6 +38,12 @@
extends PhysicsAnimationLayout.PhysicsAnimationController {
/**
+ * How much to translate the bubbles when they're animating in/out. This value is multiplied by
+ * the bubble size.
+ */
+ private static final int ANIMATE_TRANSLATION_FACTOR = 4;
+
+ /**
* The stack position from which the bubbles were expanded. Saved in {@link #expandFromStack}
* and used to return to stack form in {@link #collapseBackToStack}.
*/
@@ -125,7 +131,10 @@
Set<DynamicAnimation.ViewProperty> getAnimatedProperties() {
return Sets.newHashSet(
DynamicAnimation.TRANSLATION_X,
- DynamicAnimation.TRANSLATION_Y);
+ DynamicAnimation.TRANSLATION_Y,
+ DynamicAnimation.SCALE_X,
+ DynamicAnimation.SCALE_Y,
+ DynamicAnimation.ALPHA);
}
@Override
@@ -147,13 +156,55 @@
@Override
void onChildAdded(View child, int index) {
- // TODO: Animate the new bubble into the row, and push the other bubbles out of the way.
- child.setTranslationY(getExpandedY());
+ // Pop in from the top.
+ // TODO: Reverse this when bubbles are at the bottom.
+ child.setTranslationX(getXForChildAtIndex(index));
+ child.setTranslationY(getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR);
+ mLayout.animateValueForChild(DynamicAnimation.TRANSLATION_Y, child, getExpandedY());
+
+ // Animate the remaining bubbles to the correct X position.
+ for (int i = index + 1; i < mLayout.getChildCount(); i++) {
+ mLayout.animateValueForChildAtIndex(
+ DynamicAnimation.TRANSLATION_X, i, getXForChildAtIndex(i));
+ }
}
@Override
- void onChildToBeRemoved(View child, int index, Runnable actuallyRemove) {
- // TODO: Animate the bubble out, and pull the other bubbles into its position.
- actuallyRemove.run();
+ void onChildRemoved(View child, int index, Runnable finishRemoval) {
+ // Bubble pops out to the top.
+ // TODO: Reverse this when bubbles are at the bottom.
+ mLayout.animateValueForChild(
+ DynamicAnimation.ALPHA, child, 0f, finishRemoval);
+ mLayout.animateValueForChild(
+ DynamicAnimation.TRANSLATION_Y,
+ child,
+ getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR);
+
+ // Animate the remaining bubbles to the correct X position.
+ for (int i = index; i < mLayout.getChildCount(); i++) {
+ mLayout.animateValueForChildAtIndex(
+ DynamicAnimation.TRANSLATION_X, i, getXForChildAtIndex(i));
+ }
+ }
+
+ @Override
+ protected void setChildVisibility(View child, int index, int visibility) {
+ if (visibility == View.VISIBLE) {
+ // Set alpha to 0 but then become visible immediately so the animation is visible.
+ child.setAlpha(0f);
+ child.setVisibility(View.VISIBLE);
+ }
+
+ // Fade in.
+ mLayout.animateValueForChild(
+ DynamicAnimation.ALPHA,
+ child,
+ /* value */ visibility == View.GONE ? 0f : 1f,
+ () -> super.setChildVisibility(child, index, visibility));
+ }
+
+ /** Returns the appropriate X translation value for a bubble at the given index. */
+ private float getXForChildAtIndex(int index) {
+ return mBubblePaddingPx + (mBubbleSizePx + mBubblePaddingPx) * index;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
index e4e6bc9..a4ddbf7 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
@@ -92,14 +92,18 @@
abstract void onChildAdded(View child, int index);
/**
- * Called when a child is to be removed from the layout. Controllers can use this
- * opportunity to animate out the new view before calling the provided callback to actually
- * remove it.
+ * Called with a child view that has been removed from the layout, from the given index. The
+ * passed view has been removed from the layout and added back as a transient view, which
+ * renders normally, but is not part of the normal view hierarchy and will not be considered
+ * by getChildAt() and getChildCount().
*
- * Controllers should be careful to ensure that actuallyRemove is called on all code paths
- * or child views will never be removed.
+ * The controller can perform animations on the child (either manually, or by using
+ * {@link #animateValueForChild}), and then call finishRemoval when complete.
+ *
+ * finishRemoval must be called by implementations of this method, or transient views will
+ * never be removed.
*/
- abstract void onChildToBeRemoved(View child, int index, Runnable actuallyRemove);
+ abstract void onChildRemoved(View child, int index, Runnable finishRemoval);
protected PhysicsAnimationLayout mLayout;
@@ -112,6 +116,15 @@
protected PhysicsAnimationLayout getLayout() {
return mLayout;
}
+
+ /**
+ * Sets the child's visibility when it moves beyond or within the limits set by a call to
+ * {@link PhysicsAnimationLayout#setMaxRenderedChildren}. This can be overridden to animate
+ * this transition.
+ */
+ protected void setChildVisibility(View child, int index, int visibility) {
+ child.setVisibility(visibility);
+ }
}
/**
@@ -236,7 +249,7 @@
// Tell the controller to animate this view out, and call the callback when it's
// finished.
- mController.onChildToBeRemoved(view, index, () -> {
+ mController.onChildRemoved(view, index, () -> {
// Done animating, remove the transient view.
removeTransientView(view);
@@ -457,11 +470,16 @@
/** Hides children beyond the max rendering count. */
private void setChildrenVisibility() {
for (int i = 0; i < getChildCount(); i++) {
- getChildAt(i).setVisibility(
- // Ignore views that are animating out when calculating whether to hide the
- // view. That is, if we're supposed to render 5 views, but 4 are animating out
- // and will soon be removed, render up to 9 views temporarily.
- i < mMaxRenderedChildren ? View.VISIBLE : View.GONE);
+ final int targetVisibility = i < mMaxRenderedChildren ? View.VISIBLE : View.GONE;
+ final View targetView = getChildAt(i);
+
+ if (targetView.getVisibility() != targetVisibility) {
+ if (mController != null) {
+ mController.setChildVisibility(targetView, i, targetVisibility);
+ } else {
+ targetView.setVisibility(targetVisibility);
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
index 23c6fd3..0c089a75 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
@@ -316,10 +316,10 @@
}
@Override
- void onChildToBeRemoved(View child, int index, Runnable actuallyRemove) {
+ void onChildRemoved(View child, int index, Runnable finishRemoval) {
// Animate the child out, actually removing it once its alpha is zero.
mLayout.animateValueForChild(
- DynamicAnimation.ALPHA, child, 0f, actuallyRemove);
+ DynamicAnimation.ALPHA, child, 0f, finishRemoval);
mLayout.animateValueForChild(DynamicAnimation.SCALE_X, child, ANIMATE_IN_STARTING_SCALE);
mLayout.animateValueForChild(DynamicAnimation.SCALE_Y, child, ANIMATE_IN_STARTING_SCALE);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index e338a34..3250182 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -71,7 +71,7 @@
new DozeScreenState(wrappedService, handler, params, wakeLock),
createDozeScreenBrightness(context, wrappedService, sensorManager, host, params,
handler),
- new DozeWallpaperState(context),
+ new DozeWallpaperState(context, machine),
new DozeDockHandler(context, machine, host, config, handler, dockManager)
});
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 4557b4d..d06feed 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -110,7 +110,8 @@
@Override
public void requestWakeUp() {
PowerManager pm = getSystemService(PowerManager.class);
- pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
+ pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ "com.android.systemui:NODOZE");
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
index be504ef..ca9f24f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
@@ -37,17 +37,20 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final IWallpaperManager mWallpaperManagerService;
- private boolean mIsAmbientMode;
private final DozeParameters mDozeParameters;
+ private final DozeMachine mMachine;
+ private boolean mIsAmbientMode;
- public DozeWallpaperState(Context context) {
- this(IWallpaperManager.Stub.asInterface(
+ public DozeWallpaperState(Context context, DozeMachine machine) {
+ this(machine, IWallpaperManager.Stub.asInterface(
ServiceManager.getService(Context.WALLPAPER_SERVICE)),
DozeParameters.getInstance(context));
}
@VisibleForTesting
- DozeWallpaperState(IWallpaperManager wallpaperManagerService, DozeParameters parameters) {
+ DozeWallpaperState(DozeMachine machine, IWallpaperManager wallpaperManagerService,
+ DozeParameters parameters) {
+ mMachine = machine;
mWallpaperManagerService = wallpaperManagerService;
mDozeParameters = parameters;
}
@@ -61,10 +64,13 @@
case DOZE_AOD_PAUSING:
case DOZE_AOD_PAUSED:
case DOZE_REQUEST_PULSE:
- case DOZE_PULSING:
case DOZE_PULSE_DONE:
isAmbientMode = true;
break;
+ case DOZE_PULSING:
+ isAmbientMode =
+ mMachine.getPulseReason() != DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
+ break;
default:
isAmbientMode = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLProgram.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLProgram.java
deleted file mode 100644
index d03b00b..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLProgram.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.glwallpaper;
-
-import static android.opengl.GLES20.GL_FRAGMENT_SHADER;
-import static android.opengl.GLES20.GL_VERTEX_SHADER;
-import static android.opengl.GLES20.glAttachShader;
-import static android.opengl.GLES20.glCompileShader;
-import static android.opengl.GLES20.glCreateProgram;
-import static android.opengl.GLES20.glCreateShader;
-import static android.opengl.GLES20.glGetAttribLocation;
-import static android.opengl.GLES20.glGetUniformLocation;
-import static android.opengl.GLES20.glLinkProgram;
-import static android.opengl.GLES20.glShaderSource;
-import static android.opengl.GLES20.glUseProgram;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * This class takes charge of linking shader codes and then return a handle for OpenGL ES program.
- */
-class ImageGLProgram {
- private static final String TAG = ImageGLProgram.class.getSimpleName();
-
- private Context mContext;
- private int mProgramHandle;
-
- ImageGLProgram(Context context) {
- mContext = context.getApplicationContext();
- }
-
- private int loadShaderProgram(int vertexId, int fragmentId) {
- final String vertexSrc = getShaderResource(vertexId);
- final String fragmentSrc = getShaderResource(fragmentId);
- final int vertexHandle = getShaderHandle(GL_VERTEX_SHADER, vertexSrc);
- final int fragmentHandle = getShaderHandle(GL_FRAGMENT_SHADER, fragmentSrc);
- return getProgramHandle(vertexHandle, fragmentHandle);
- }
-
- private String getShaderResource(int shaderId) {
- Resources res = mContext.getResources();
- StringBuilder code = new StringBuilder();
-
- try (BufferedReader reader = new BufferedReader(
- new InputStreamReader(res.openRawResource(shaderId)))) {
- String nextLine;
- while ((nextLine = reader.readLine()) != null) {
- code.append(nextLine).append("\n");
- }
- } catch (IOException | Resources.NotFoundException ex) {
- Log.d(TAG, "Can not read the shader source", ex);
- code = null;
- }
-
- return code == null ? "" : code.toString();
- }
-
- private int getShaderHandle(int type, String src) {
- final int shader = glCreateShader(type);
- if (shader == 0) {
- Log.d(TAG, "Create shader failed, type=" + type);
- return 0;
- }
- glShaderSource(shader, src);
- glCompileShader(shader);
- return shader;
- }
-
- private int getProgramHandle(int vertexHandle, int fragmentHandle) {
- final int program = glCreateProgram();
- if (program == 0) {
- Log.d(TAG, "Can not create OpenGL ES program");
- return 0;
- }
-
- glAttachShader(program, vertexHandle);
- glAttachShader(program, fragmentHandle);
- glLinkProgram(program);
- return program;
- }
-
- boolean useGLProgram(int vertexResId, int fragmentResId) {
- mProgramHandle = loadShaderProgram(vertexResId, fragmentResId);
- glUseProgram(mProgramHandle);
- return true;
- }
-
- int getAttributeHandle(String name) {
- return glGetAttribLocation(mProgramHandle, name);
- }
-
- int getUniformHandle(String name) {
- return glGetUniformLocation(mProgramHandle, name);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
deleted file mode 100644
index 4e07872..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.glwallpaper;
-
-import static android.opengl.GLES20.GL_FLOAT;
-import static android.opengl.GLES20.GL_LINEAR;
-import static android.opengl.GLES20.GL_TEXTURE0;
-import static android.opengl.GLES20.GL_TEXTURE_2D;
-import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER;
-import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER;
-import static android.opengl.GLES20.GL_TRIANGLES;
-import static android.opengl.GLES20.glActiveTexture;
-import static android.opengl.GLES20.glBindTexture;
-import static android.opengl.GLES20.glDrawArrays;
-import static android.opengl.GLES20.glEnableVertexAttribArray;
-import static android.opengl.GLES20.glGenTextures;
-import static android.opengl.GLES20.glTexParameteri;
-import static android.opengl.GLES20.glUniform1i;
-import static android.opengl.GLES20.glVertexAttribPointer;
-
-import android.graphics.Bitmap;
-import android.opengl.GLUtils;
-import android.util.Log;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-
-/**
- * This class takes charge of the geometry data like vertices and texture coordinates.
- * It delivers these data to opengl runtime and triggers draw calls if necessary.
- */
-class ImageGLWallpaper {
- private static final String TAG = ImageGLWallpaper.class.getSimpleName();
-
- static final String A_POSITION = "aPosition";
- static final String A_TEXTURE_COORDINATES = "aTextureCoordinates";
- static final String U_CENTER_REVEAL = "uCenterReveal";
- static final String U_REVEAL = "uReveal";
- static final String U_AOD2OPACITY = "uAod2Opacity";
- static final String U_TEXTURE = "uTexture";
- static final String U_AOD_MODE = "uAodMode";
-
- private static final int HANDLE_UNDEFINED = -1;
- private static final int POSITION_COMPONENT_COUNT = 2;
- private static final int TEXTURE_COMPONENT_COUNT = 2;
- private static final int BYTES_PER_FLOAT = 4;
-
- // Vertices to define the square with 2 triangles.
- private static final float[] VERTICES = {
- -1.0f, -1.0f,
- +1.0f, -1.0f,
- +1.0f, +1.0f,
- +1.0f, +1.0f,
- -1.0f, +1.0f,
- -1.0f, -1.0f
- };
-
- // Texture coordinates that maps to vertices.
- private static final float[] TEXTURES = {
- 0f, 1f,
- 1f, 1f,
- 1f, 0f,
- 1f, 0f,
- 0f, 0f,
- 0f, 1f
- };
-
- private final FloatBuffer mVertexBuffer;
- private final FloatBuffer mTextureBuffer;
- private final ImageGLProgram mProgram;
-
- private int mAttrPosition;
- private int mAttrTextureCoordinates;
- private int mUniAod2Opacity;
- private int mUniAodMode;
- private int mUniCenterReveal;
- private int mUniReveal;
- private int mUniTexture;
- private int mTextureId;
-
- ImageGLWallpaper(ImageGLProgram program) {
- mProgram = program;
-
- // Create an float array in opengles runtime (native) and put vertex data.
- mVertexBuffer = ByteBuffer.allocateDirect(VERTICES.length * BYTES_PER_FLOAT)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer();
- mVertexBuffer.put(VERTICES);
- mVertexBuffer.position(0);
-
- // Create an float array in opengles runtime (native) and put texture data.
- mTextureBuffer = ByteBuffer.allocateDirect(TEXTURES.length * BYTES_PER_FLOAT)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer();
- mTextureBuffer.put(TEXTURES);
- mTextureBuffer.position(0);
- }
-
- void setup() {
- setupAttributes();
- setupUniforms();
- }
-
- private void setupAttributes() {
- mAttrPosition = mProgram.getAttributeHandle(A_POSITION);
- mVertexBuffer.position(0);
- glVertexAttribPointer(mAttrPosition, POSITION_COMPONENT_COUNT, GL_FLOAT,
- false, 0, mVertexBuffer);
- glEnableVertexAttribArray(mAttrPosition);
-
- mAttrTextureCoordinates = mProgram.getAttributeHandle(A_TEXTURE_COORDINATES);
- mTextureBuffer.position(0);
- glVertexAttribPointer(mAttrTextureCoordinates, TEXTURE_COMPONENT_COUNT, GL_FLOAT,
- false, 0, mTextureBuffer);
- glEnableVertexAttribArray(mAttrTextureCoordinates);
- }
-
- private void setupUniforms() {
- mUniAod2Opacity = mProgram.getUniformHandle(U_AOD2OPACITY);
- mUniAodMode = mProgram.getUniformHandle(U_AOD_MODE);
- mUniCenterReveal = mProgram.getUniformHandle(U_CENTER_REVEAL);
- mUniReveal = mProgram.getUniformHandle(U_REVEAL);
- mUniTexture = mProgram.getUniformHandle(U_TEXTURE);
- }
-
- int getHandle(String name) {
- switch (name) {
- case A_POSITION:
- return mAttrPosition;
- case A_TEXTURE_COORDINATES:
- return mAttrTextureCoordinates;
- case U_AOD2OPACITY:
- return mUniAod2Opacity;
- case U_AOD_MODE:
- return mUniAodMode;
- case U_CENTER_REVEAL:
- return mUniCenterReveal;
- case U_REVEAL:
- return mUniReveal;
- case U_TEXTURE:
- return mUniTexture;
- default:
- return HANDLE_UNDEFINED;
- }
- }
-
- void draw() {
- glDrawArrays(GL_TRIANGLES, 0, VERTICES.length / 2);
- }
-
- void setupTexture(Bitmap bitmap) {
- final int[] tids = new int[1];
-
- if (bitmap == null) {
- Log.w(TAG, "setupTexture: invalid bitmap");
- return;
- }
-
- // Generate one texture object and store the id in tids[0].
- glGenTextures(1, tids, 0);
- if (tids[0] == 0) {
- Log.w(TAG, "setupTexture: glGenTextures() failed");
- return;
- }
-
- // Bind a named texture to a texturing target.
- glBindTexture(GL_TEXTURE_2D, tids[0]);
- // Load the bitmap data and copy it over into the texture object that is currently bound.
- GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
- // Use bilinear texture filtering when minification.
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- // Use bilinear texture filtering when magnification.
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- mTextureId = tids[0];
- }
-
- void useTexture() {
- // Set the active texture unit to texture unit 0.
- glActiveTexture(GL_TEXTURE0);
- // Bind the texture to this unit.
- glBindTexture(GL_TEXTURE_2D, mTextureId);
- // Let the texture sampler in fragment shader to read form this texture unit.
- glUniform1i(mUniTexture, 0);
- }
-
- void adjustTextureCoordinates(Bitmap bitmap, int surfaceWidth, int surfaceHeight,
- float xOffset, float yOffset) {
- if (bitmap == null) {
- Log.d(TAG, "adjustTextureCoordinates: invalid bitmap");
- return;
- }
-
- float ratioW = 1f;
- float ratioH = 1f;
- int bitmapWidth = bitmap.getWidth();
- int bitmapHeight = bitmap.getHeight();
-
- boolean adjustWidth = bitmapWidth > surfaceWidth;
- if (adjustWidth) {
- ratioW = (float) surfaceWidth / bitmapWidth;
- float referenceX = xOffset + ratioW > 1f ? 1f - ratioW : xOffset;
- for (int i = 0; i < TEXTURES.length; i += 2) {
- if (i == 2 || i == 4 || i == 6) {
- TEXTURES[i] = Math.min(1f, referenceX + ratioW);
- } else {
- TEXTURES[i] = referenceX;
- }
- }
- }
-
- boolean adjustHeight = bitmapHeight > surfaceHeight;
- if (adjustHeight) {
- ratioH = (float) surfaceHeight / bitmapHeight;
- float referenceY = yOffset + ratioH > 1f ? 1f - ratioH : yOffset;
- for (int i = 1; i < TEXTURES.length; i += 2) {
- if (i == 1 || i == 3 || i == 11) {
- TEXTURES[i] = Math.min(1f, referenceY + ratioH);
- } else {
- TEXTURES[i] = referenceY;
- }
- }
- }
-
- if (adjustWidth || adjustHeight) {
- mTextureBuffer.put(TEXTURES);
- mTextureBuffer.position(0);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
deleted file mode 100644
index 477e7d7e..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.glwallpaper;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Handler.Callback;
-import android.os.Message;
-import android.util.Log;
-
-/**
- * A helper class that computes histogram and percentile 85 from a bitmap.
- * Percentile 85 will be computed each time the user picks a new image wallpaper.
- */
-class ImageProcessHelper {
- private static final String TAG = ImageProcessHelper.class.getSimpleName();
- private static final float DEFAULT_PER85 = 0.8f;
- private static final int MSG_UPDATE_PER85 = 1;
-
- /**
- * This color matrix will be applied to each pixel to get luminance from rgb by below formula:
- * Luminance = .2126f * r + .7152f * g + .0722f * b.
- */
- private static final float[] LUMINOSITY_MATRIX = new float[] {
- .2126f, .0000f, .0000f, .0000f, .0000f,
- .0000f, .7152f, .0000f, .0000f, .0000f,
- .0000f, .0000f, .0722f, .0000f, .0000f,
- .0000f, .0000f, .0000f, 1.000f, .0000f
- };
-
- private final Handler mHandler = new Handler(new Callback() {
- @Override
- public boolean handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_UPDATE_PER85:
- mPer85 = (float) msg.obj;
- return true;
- default:
- return false;
- }
- }
- });
-
- private float mPer85 = DEFAULT_PER85;
-
- void startComputingPercentile85(Bitmap bitmap) {
- new Per85ComputeTask(mHandler).execute(bitmap);
- }
-
- float getPercentile85() {
- return mPer85;
- }
-
- private static class Per85ComputeTask extends AsyncTask<Bitmap, Void, Float> {
- private Handler mUpdateHandler;
-
- Per85ComputeTask(Handler handler) {
- super(handler);
- mUpdateHandler = handler;
- }
-
- @Override
- protected Float doInBackground(Bitmap... bitmaps) {
- Bitmap bitmap = bitmaps[0];
- if (bitmap != null) {
- int[] histogram = processHistogram(bitmap);
- return computePercentile85(bitmap, histogram);
- }
- Log.e(TAG, "Per85ComputeTask: Can't get bitmap");
- return DEFAULT_PER85;
- }
-
- @Override
- protected void onPostExecute(Float result) {
- Message msg = mUpdateHandler.obtainMessage(MSG_UPDATE_PER85, result);
- mUpdateHandler.sendMessage(msg);
- }
-
- private int[] processHistogram(Bitmap bitmap) {
- int width = bitmap.getWidth();
- int height = bitmap.getHeight();
-
- Bitmap target = Bitmap.createBitmap(width, height, bitmap.getConfig());
- Canvas canvas = new Canvas(target);
- ColorMatrix cm = new ColorMatrix(LUMINOSITY_MATRIX);
- Paint paint = new Paint();
- paint.setColorFilter(new ColorMatrixColorFilter(cm));
- canvas.drawBitmap(bitmap, new Matrix(), paint);
-
- // TODO: Fine tune the performance here, tracking on b/123615079.
- int[] histogram = new int[256];
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- int pixel = target.getPixel(col, row);
- int y = Color.red(pixel) + Color.green(pixel) + Color.blue(pixel);
- histogram[y]++;
- }
- }
-
- return histogram;
- }
-
- private float computePercentile85(Bitmap bitmap, int[] histogram) {
- float per85 = DEFAULT_PER85;
- int pixelCount = bitmap.getWidth() * bitmap.getHeight();
- float[] acc = new float[256];
- for (int i = 0; i < acc.length; i++) {
- acc[i] = (float) histogram[i] / pixelCount;
- float prev = i == 0 ? 0f : acc[i - 1];
- float next = acc[i];
- float idx = (float) (i + 1) / 255;
- float sum = prev + next;
- if (prev < 0.85f && sum >= 0.85f) {
- per85 = idx;
- }
- if (i > 0) {
- acc[i] += acc[i - 1];
- }
- }
- return per85;
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
deleted file mode 100644
index 787972c..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.glwallpaper;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-
-import com.android.systemui.Interpolators;
-
-/**
- * Use ValueAnimator and appropriate interpolator to control the progress of reveal transition.
- * The transition will happen while getting awake and quit events.
- */
-class ImageRevealHelper {
- private static final String TAG = ImageRevealHelper.class.getSimpleName();
- private static final float MAX_REVEAL = 0f;
- private static final float MIN_REVEAL = 1f;
- private static final int REVEAL_DURATION = 1000;
-
- private final ValueAnimator mAnimator;
- private final RevealStateListener mRevealListener;
- private float mReveal = MIN_REVEAL;
- private boolean mAwake = false;
-
- ImageRevealHelper(RevealStateListener listener) {
- mRevealListener = listener;
- mAnimator = ValueAnimator.ofFloat();
- mAnimator.setDuration(REVEAL_DURATION);
- mAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- mAnimator.addUpdateListener(animator -> {
- mReveal = (float) animator.getAnimatedValue();
- if (mRevealListener != null) {
- mRevealListener.onRevealStateChanged();
- }
- });
- mAnimator.addListener(new AnimatorListenerAdapter() {
- private boolean mIsCanceled;
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mIsCanceled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mIsCanceled) {
- mAwake = !mAwake;
- }
- mIsCanceled = false;
- }
- });
- }
-
- private void animate() {
- mAnimator.cancel();
- mAnimator.setFloatValues(mReveal, !mAwake ? MIN_REVEAL : MAX_REVEAL);
- mAnimator.start();
- }
-
- public float getReveal() {
- return mReveal;
- }
-
- public boolean isAwake() {
- return mAwake;
- }
-
- void updateAwake(boolean awake) {
- mAwake = awake;
- animate();
- }
-
- void sleep() {
- mReveal = MIN_REVEAL;
- mAwake = false;
- }
-
- /**
- * A listener to trace value changes of reveal.
- */
- public interface RevealStateListener {
-
- /**
- * Called back while reveal status changes.
- */
- void onRevealStateChanged();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
deleted file mode 100644
index 8916b28..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.glwallpaper;
-
-import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
-import static android.opengl.GLES20.glClear;
-import static android.opengl.GLES20.glClearColor;
-import static android.opengl.GLES20.glUniform1f;
-import static android.opengl.GLES20.glUniform1i;
-import static android.opengl.GLES20.glViewport;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.opengl.GLSurfaceView;
-import android.util.Log;
-
-import com.android.systemui.ImageWallpaper;
-import com.android.systemui.ImageWallpaper.ImageGLView;
-import com.android.systemui.R;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-/**
- * A GL renderer for image wallpaper.
- */
-public class ImageWallpaperRenderer implements GLSurfaceView.Renderer,
- ImageWallpaper.SensorEventListener, ImageWallpaper.WallpaperStatusListener,
- ImageRevealHelper.RevealStateListener {
- private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
-
- private final WallpaperManager mWallpaperManager;
- private final ImageGLProgram mProgram;
- private final ImageGLWallpaper mWallpaper;
- private final ImageProcessHelper mImageProcessHelper;
- private final ImageRevealHelper mImageRevealHelper;
- private final ImageGLView mGLView;
- private boolean mIsInAmbientMode;
- private float mXOffset = 0f;
- private float mYOffset = 0f;
-
- public ImageWallpaperRenderer(Context context, ImageGLView glView) {
- mWallpaperManager = context.getSystemService(WallpaperManager.class);
- if (mWallpaperManager == null) {
- Log.w(TAG, "WallpaperManager not available");
- }
-
- mProgram = new ImageGLProgram(context);
- mWallpaper = new ImageGLWallpaper(mProgram);
- mImageProcessHelper = new ImageProcessHelper();
- mImageRevealHelper = new ImageRevealHelper(this);
- mGLView = glView;
-
- if (mWallpaperManager != null) {
- // Compute per85 as transition threshold, this is an async work.
- mImageProcessHelper.startComputingPercentile85(mWallpaperManager.getBitmap());
- }
- }
-
- @Override
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- glClearColor(0f, 0f, 0f, 1.0f);
- mProgram.useGLProgram(
- R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader);
- mWallpaper.setup();
- mWallpaper.setupTexture(mWallpaperManager.getBitmap());
- }
-
- @Override
- public void onSurfaceChanged(GL10 gl, int width, int height) {
- glViewport(0, 0, width, height);
- mWallpaper.adjustTextureCoordinates(mWallpaperManager.getBitmap(),
- width, height, mXOffset, mYOffset);
- }
-
- @Override
- public void onDrawFrame(GL10 gl) {
- float threshold = mImageProcessHelper.getPercentile85();
- float reveal = mImageRevealHelper.getReveal();
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), .25f);
- glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_CENTER_REVEAL), threshold);
- glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
- glUniform1i(mWallpaper.getHandle(ImageGLWallpaper.U_AOD_MODE), mIsInAmbientMode ? 1 : 0);
-
- mWallpaper.useTexture();
- mWallpaper.draw();
- }
-
- @Override
- public void onSensorEvent(boolean awake) {
- mImageRevealHelper.updateAwake(awake);
- }
-
- @Override
- public void onAmbientModeChanged(boolean inAmbientMode) {
- mIsInAmbientMode = inAmbientMode;
- if (inAmbientMode) {
- mImageRevealHelper.sleep();
- }
- requestRender();
- }
-
- @Override
- public void onOffsetsChanged(float xOffset, float yOffset, Rect frame) {
- if (frame == null || mWallpaperManager == null
- || (xOffset == mXOffset && yOffset == mYOffset)) {
- return;
- }
-
- Bitmap bitmap = mWallpaperManager.getBitmap();
- if (bitmap == null) {
- return;
- }
-
- int width = frame.width();
- int height = frame.height();
- mXOffset = xOffset;
- mYOffset = yOffset;
-
- mWallpaper.adjustTextureCoordinates(bitmap, width, height, mXOffset, mYOffset);
- requestRender();
- }
-
- @Override
- public void onRevealStateChanged() {
- requestRender();
- }
-
- private void requestRender() {
- if (mGLView != null) {
- mGLView.render();
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4527f73..66cfadf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -884,6 +884,7 @@
// Just to make sure, make sure the device is awake.
mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_CAMERA_LAUNCH,
"com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
mPendingLock = false;
mPendingReset = false;
@@ -1854,8 +1855,9 @@
// It's possible that the device was unlocked in a dream state. It's time to wake up.
if (mAodShowing) {
- PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:BOUNCER_DOZING");
+ PowerManager pm = mContext.getSystemService(PowerManager.class);
+ pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ "com.android.systemui:BOUNCER_DOZING");
}
synchronized (KeyguardViewMediator.this) {
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
index fa1426e..cff7fe4 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
@@ -69,7 +69,7 @@
setPositiveButton(R.string.ongoing_privacy_dialog_ok, null)
setNeutralButton(R.string.ongoing_privacy_dialog_open_settings,
object : DialogInterface.OnClickListener {
- val intent = Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS).putExtra(
+ val intent = Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra(
Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1))
@Suppress("DEPRECATION")
@@ -167,7 +167,7 @@
// Check if package exists
context.packageManager.getPackageInfo(app.packageName, 0)
item.setOnClickListener(object : View.OnClickListener {
- val intent = Intent(Intent.ACTION_REVIEW_APP_PERMISSION_USAGE)
+ val intent = Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS)
.putExtra(Intent.EXTRA_PACKAGE_NAME, app.packageName)
.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(app.uid))
override fun onClick(v: View?) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index c0ed4b9..b865ce8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -54,6 +54,7 @@
import com.android.settingslib.Utils;
import com.android.settingslib.drawable.UserIconDrawable;
import com.android.settingslib.graph.SignalDrawable;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.R.dimen;
import com.android.systemui.plugins.ActivityStarter;
@@ -134,6 +135,15 @@
mDeviceProvisionedController = deviceProvisionedController;
}
+ @VisibleForTesting
+ public QSFooterImpl(Context context, AttributeSet attrs) {
+ this(context, attrs,
+ Dependency.get(ActivityStarter.class),
+ Dependency.get(UserInfoController.class),
+ Dependency.get(NetworkController.class),
+ Dependency.get(DeviceProvisionedController.class));
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -476,32 +486,62 @@
mInfos[0].visible && mInfos[1].visible ? View.VISIBLE : View.GONE);
}
+ @VisibleForTesting
+ protected int getSlotIndex(int subscriptionId) {
+ return SubscriptionManager.getSlotIndex(subscriptionId);
+ }
+
@Override
public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
if (info.anySimReady) {
boolean[] slotSeen = new boolean[SIM_SLOTS];
- for (int i = 0; i < SIM_SLOTS && i < info.listOfCarriers.length; i++) {
- int slot = SubscriptionManager.getSlotIndex(info.subscriptionIds[i]);
- mInfos[slot].visible = true;
- slotSeen[slot] = true;
- mCarrierTexts[slot].setText(info.listOfCarriers[i].toString().trim());
- mCarrierGroups[slot].setVisibility(View.VISIBLE);
- }
- for (int i = 0; i < SIM_SLOTS; i++) {
- if (!slotSeen[i]) {
+ if (info.listOfCarriers.length == info.subscriptionIds.length) {
+ for (int i = 0; i < SIM_SLOTS && i < info.listOfCarriers.length; i++) {
+ int slot = getSlotIndex(info.subscriptionIds[i]);
+ if (slot >= SIM_SLOTS) {
+ Log.w(TAG, "updateInfoCarrier - slot: " + slot);
+ continue;
+ }
+ if (slot == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+ Log.e(TAG,
+ "Invalid SIM slot index for subscription: "
+ + info.subscriptionIds[i]);
+ continue;
+ }
+ mInfos[slot].visible = true;
+ slotSeen[slot] = true;
+ mCarrierTexts[slot].setText(info.listOfCarriers[i].toString().trim());
+ mCarrierGroups[slot].setVisibility(View.VISIBLE);
+ }
+ for (int i = 0; i < SIM_SLOTS; i++) {
+ if (!slotSeen[i]) {
+ mInfos[i].visible = false;
+ mCarrierGroups[i].setVisibility(View.GONE);
+ }
+ }
+ } else {
+ // If there are sims ready but there are not the same number of carrier names as
+ // subscription ids, just show the full text in the first slot
+ mInfos[0].visible = true;
+ mCarrierTexts[0].setText(info.carrierText);
+ mCarrierGroups[0].setVisibility(View.VISIBLE);
+ for (int i = 1; i < SIM_SLOTS; i++) {
mInfos[i].visible = false;
+ mCarrierTexts[i].setText("");
mCarrierGroups[i].setVisibility(View.GONE);
}
}
- handleUpdateState();
} else {
mInfos[0].visible = false;
- mInfos[1].visible = false;
mCarrierTexts[0].setText(info.carrierText);
mCarrierGroups[0].setVisibility(View.VISIBLE);
- mCarrierGroups[1].setVisibility(View.GONE);
- handleUpdateState();
+ for (int i = 1; i < SIM_SLOTS; i++) {
+ mInfos[i].visible = false;
+ mCarrierTexts[i].setText("");
+ mCarrierGroups[i].setVisibility(View.GONE);
+ }
}
+ handleUpdateState();
}
@Override
@@ -510,9 +550,14 @@
int qsType, boolean activityIn, boolean activityOut,
String typeContentDescription,
String description, boolean isWide, int subId, boolean roaming) {
- int slotIndex = SubscriptionManager.getSlotIndex(subId);
+ int slotIndex = getSlotIndex(subId);
if (slotIndex >= SIM_SLOTS) {
- Log.e(TAG, "setMobileDataIndicators - slot: " + slotIndex);
+ Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex);
+ return;
+ }
+ if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+ Log.e(TAG, "Invalid SIM slot index for subscription: " + subId);
+ return;
}
mInfos[slotIndex].visible = statusIcon.visible;
mInfos[slotIndex].mobileSignalIconId = statusIcon.icon;
@@ -539,7 +584,6 @@
boolean roaming;
}
-
/**
* TextView that changes its ellipsize value with its visibility.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 2d64ecd..74e82b2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -67,6 +67,7 @@
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.privacy.OngoingPrivacyChip;
import com.android.systemui.privacy.OngoingPrivacyDialog;
+import com.android.systemui.privacy.PrivacyDialogBuilder;
import com.android.systemui.privacy.PrivacyItem;
import com.android.systemui.privacy.PrivacyItemController;
import com.android.systemui.qs.QSDetail.Callback;
@@ -534,10 +535,12 @@
mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
AlarmClock.ACTION_SHOW_ALARMS),0);
} else if (v == mPrivacyChip) {
+ // Makes sure that the builder is grabbed as soon as the chip is pressed
+ PrivacyDialogBuilder builder = mPrivacyChip.getBuilder();
+ if (builder.getAppsAndTypes().size() == 0) return;
Handler mUiHandler = new Handler(Looper.getMainLooper());
mUiHandler.post(() -> {
- Dialog mDialog = new OngoingPrivacyDialog(mContext,
- mPrivacyChip.getBuilder()).createDialog();
+ Dialog mDialog = new OngoingPrivacyDialog(mContext, builder).createDialog();
mDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
SystemUIDialog.setShowForAllUsers(mDialog, true);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 31d1621..b820dc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -54,6 +54,7 @@
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry.EditedSuggestionInfo;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -131,7 +132,8 @@
@Override
public boolean onClickHandler(
View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) {
- mShadeController.get().wakeUpIfDozing(SystemClock.uptimeMillis(), view);
+ mShadeController.get().wakeUpIfDozing(SystemClock.uptimeMillis(), view,
+ "NOTIFICATION_CLICK");
if (handleRemoteInput(view, pendingIntent)) {
return true;
@@ -231,7 +233,8 @@
return false;
}
- return activateRemoteInput(view, inputs, input, pendingIntent);
+ return activateRemoteInput(view, inputs, input, pendingIntent,
+ null /* editedSuggestionInfo */);
}
};
@@ -291,6 +294,19 @@
}
try {
mBarService.onNotificationDirectReplied(entry.notification.getKey());
+ if (entry.editedSuggestionInfo != null) {
+ boolean modifiedBeforeSending =
+ !TextUtils.equals(entry.remoteInputText,
+ entry.editedSuggestionInfo.originalText);
+ mBarService.onNotificationSmartReplySent(
+ entry.notification.getKey(),
+ entry.editedSuggestionInfo.index,
+ entry.editedSuggestionInfo.originalText,
+ NotificationLogger
+ .getNotificationLocation(entry)
+ .toMetricsEventEnum(),
+ modifiedBeforeSending);
+ }
} catch (RemoteException e) {
// Nothing to do, system going down
}
@@ -310,10 +326,12 @@
* @param inputs The remote inputs that need to be sent to the app.
* @param input The remote input that needs to be activated.
* @param pendingIntent The pending intent to be sent to the app.
+ * @param editedSuggestionInfo The smart reply that should be inserted in the remote input, or
+ * {@code null} if the user is not editing a smart reply.
* @return Whether the {@link RemoteInput} was activated.
*/
public boolean activateRemoteInput(View view, RemoteInput[] inputs, RemoteInput input,
- PendingIntent pendingIntent) {
+ PendingIntent pendingIntent, @Nullable EditedSuggestionInfo editedSuggestionInfo) {
ViewParent p = view.getParent();
RemoteInputView riv = null;
@@ -386,7 +404,7 @@
riv.setRevealParameters(cx, cy, r);
riv.setPendingIntent(pendingIntent);
- riv.setRemoteInput(inputs, input);
+ riv.setRemoteInput(inputs, input, editedSuggestionInfo);
riv.focusAnimated();
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
index 5a8f71d..736b9eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
@@ -56,13 +56,12 @@
* Notifies StatusBarService a smart reply is sent.
*/
public void smartReplySent(NotificationEntry entry, int replyIndex, CharSequence reply,
- boolean generatedByAssistant, int notificationLocation) {
+ int notificationLocation, boolean modifiedBeforeSending) {
mCallback.onSmartReplySent(entry, reply);
mSendingKeys.add(entry.key);
try {
- mBarService.onNotificationSmartReplySent(
- entry.notification.getKey(), replyIndex, reply, generatedByAssistant,
- notificationLocation);
+ mBarService.onNotificationSmartReplySent(entry.notification.getKey(), replyIndex, reply,
+ notificationLocation, modifiedBeforeSending);
} catch (RemoteException e) {
// Nothing to do, system going down
}
@@ -100,10 +99,10 @@
* Smart Replies and Actions have been added to the UI.
*/
public void smartSuggestionsAdded(final NotificationEntry entry, int replyCount,
- int actionCount, boolean generatedByAssistant) {
+ int actionCount, boolean generatedByAssistant, boolean editBeforeSending) {
try {
- mBarService.onNotificationSmartSuggestionsAdded(
- entry.notification.getKey(), replyCount, actionCount, generatedByAssistant);
+ mBarService.onNotificationSmartSuggestionsAdded(entry.notification.getKey(), replyCount,
+ actionCount, generatedByAssistant, editBeforeSending);
} catch (RemoteException e) {
// Nothing to do, system going down
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index 49f1a8d..b788f53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -52,7 +52,7 @@
return;
}
- mShadeController.wakeUpIfDozing(SystemClock.uptimeMillis(), v);
+ mShadeController.wakeUpIfDozing(SystemClock.uptimeMillis(), v, "NOTIFICATION_CLICK");
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
final StatusBarNotification sbn = row.getStatusBarNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 5c62005..81d0e25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -47,6 +47,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* NotificationEntryManager is responsible for the adding, removing, and updating of notifications.
@@ -64,6 +65,9 @@
@VisibleForTesting
protected final HashMap<String, NotificationEntry> mPendingNotifications = new HashMap<>();
+ private final Map<NotificationEntry, NotificationLifetimeExtender> mRetainedNotifications =
+ new ArrayMap<>();
+
// Lazily retrieved dependencies
private NotificationRemoteInputManager mRemoteInputManager;
private NotificationRowBinder mNotificationRowBinder;
@@ -89,6 +93,16 @@
pw.println(entry.notification);
}
}
+ pw.println(" Lifetime-extended notifications:");
+ if (mRetainedNotifications.isEmpty()) {
+ pw.println(" None");
+ } else {
+ for (Map.Entry<NotificationEntry, NotificationLifetimeExtender> entry
+ : mRetainedNotifications.entrySet()) {
+ pw.println(" " + entry.getKey().notification + " retained by "
+ + entry.getValue().getClass().getName());
+ }
+ }
}
public NotificationEntryManager(Context context) {
@@ -244,7 +258,7 @@
for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) {
if (extender.shouldExtendLifetime(entry)) {
mLatestRankingMap = ranking;
- extender.setShouldManageLifetime(entry, true /* shouldManage */);
+ extendLifetime(entry, extender);
lifetimeExtended = true;
break;
}
@@ -255,9 +269,7 @@
// At this point, we are guaranteed the notification will be removed
// Ensure any managers keeping the lifetime extended stop managing the entry
- for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) {
- extender.setShouldManageLifetime(entry, false /* shouldManage */);
- }
+ cancelLifetimeExtension(entry);
if (entry.rowExists()) {
entry.removeRow();
@@ -368,9 +380,7 @@
// Notification is updated so it is essentially re-added and thus alive again. Don't need
// to keep its lifetime extended.
- for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) {
- extender.setShouldManageLifetime(entry, false /* shouldManage */);
- }
+ cancelLifetimeExtension(entry);
mNotificationData.update(entry, ranking, notification);
@@ -464,4 +474,20 @@
public Iterable<NotificationEntry> getPendingNotificationsIterator() {
return mPendingNotifications.values();
}
+
+ private void extendLifetime(NotificationEntry entry, NotificationLifetimeExtender extender) {
+ NotificationLifetimeExtender activeExtender = mRetainedNotifications.get(entry);
+ if (activeExtender != null && activeExtender != extender) {
+ activeExtender.setShouldManageLifetime(entry, false);
+ }
+ mRetainedNotifications.put(entry, extender);
+ extender.setShouldManageLifetime(entry, true);
+ }
+
+ private void cancelLifetimeExtension(NotificationEntry entry) {
+ NotificationLifetimeExtender activeExtender = mRetainedNotifications.remove(entry);
+ if (activeExtender != null) {
+ activeExtender.setShouldManageLifetime(entry, false);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index db9fcc8..f74de5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -105,6 +105,14 @@
/** Smart replies provided by the NotificationAssistantService. */
@NonNull
public CharSequence[] systemGeneratedSmartReplies = new CharSequence[0];
+
+ /**
+ * If {@link android.app.RemoteInput#getEditChoicesBeforeSending} is enabled, and the user is
+ * currently editing a choice (smart reply), then this field contains the information about the
+ * suggestion being edited. Otherwise <code>null</code>.
+ */
+ public EditedSuggestionInfo editedSuggestionInfo;
+
@VisibleForTesting
public int suppressedVisualEffects;
public boolean suspended;
@@ -143,6 +151,12 @@
private boolean mIsBubble;
/**
+ * Whether this notification has been approved globally, at the app level, and at the channel
+ * level for bubbling.
+ */
+ public boolean canBubble;
+
+ /**
* Whether this notification should be shown in the shade when it is also displayed as a bubble.
*
* <p>When a notification is a bubble we don't show it in the shade once the bubble has been
@@ -189,6 +203,7 @@
: ranking.getSmartReplies().toArray(new CharSequence[0]);
suppressedVisualEffects = ranking.getSuppressedVisualEffects();
suspended = ranking.isSuspended();
+ canBubble = ranking.canBubble();
}
public void setInterruption() {
@@ -746,4 +761,23 @@
private static boolean isCategory(String category, Notification n) {
return Objects.equals(n.category, category);
}
+
+ /** Information about a suggestion that is being edited. */
+ public static class EditedSuggestionInfo {
+
+ /**
+ * The value of the suggestion (before any user edits).
+ */
+ public final CharSequence originalText;
+
+ /**
+ * The index of the suggestion that is being edited.
+ */
+ public final int index;
+
+ public EditedSuggestionInfo(CharSequence originalText, int index) {
+ this.originalText = originalText;
+ this.index = index;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index bed2426..b8e33a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -90,6 +90,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
import com.android.systemui.statusbar.notification.row.NotificationInflater.InflationFlag;
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationMediaTemplateViewWrapper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
@@ -144,6 +145,7 @@
private int mNotificationMinHeightBeforeP;
private int mNotificationMinHeight;
private int mNotificationMinHeightLarge;
+ private int mNotificationMinHeightMedia;
private int mNotificationMaxHeight;
private int mIncreasedPaddingBetweenElements;
private int mNotificationLaunchHeight;
@@ -652,8 +654,15 @@
boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
boolean beforeP = mEntry.targetSdk < Build.VERSION_CODES.P;
int minHeight;
+
+ View expandedView = layout.getExpandedChild();
+ boolean isMediaLayout = expandedView != null
+ && expandedView.findViewById(com.android.internal.R.id.media_actions) != null;
+
if (customView && beforeP && !mIsSummaryWithChildren) {
minHeight = beforeN ? mNotificationMinHeightBeforeN : mNotificationMinHeightBeforeP;
+ } else if (isMediaLayout && !NotificationMediaTemplateViewWrapper.HIDE_COMPACT_SCRUBBER) {
+ minHeight = mNotificationMinHeightMedia;
} else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) {
minHeight = mNotificationMinHeightLarge;
} else {
@@ -1642,6 +1651,8 @@
R.dimen.notification_min_height);
mNotificationMinHeightLarge = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_min_height_increased);
+ mNotificationMinHeightMedia = NotificationUtils.getFontScaledHeight(mContext,
+ R.dimen.notification_min_height_media);
mNotificationMaxHeight = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_max_height);
mMaxHeadsUpHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 878d533..8095615 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -1509,8 +1509,13 @@
boolean fromAssistant = smartRepliesAndActions.smartReplies == null
? smartRepliesAndActions.smartActions.fromAssistant
: smartRepliesAndActions.smartReplies.fromAssistant;
+ boolean editBeforeSending = smartRepliesAndActions.smartReplies != null
+ && mSmartReplyConstants.getEffectiveEditChoicesBeforeSending(
+ smartRepliesAndActions.smartReplies.remoteInput
+ .getEditChoicesBeforeSending());
+
mSmartReplyController.smartSuggestionsAdded(entry, numSmartReplies,
- numSmartActions, fromAssistant);
+ numSmartActions, fromAssistant, editBeforeSending);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index b6948fc..c7b2fab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -537,7 +537,7 @@
mChosenImportance = IMPORTANCE_LOW;
confirmationText.setText(R.string.notification_channel_silenced);
} else {
- mChosenImportance = IMPORTANCE_HIGH;
+ mChosenImportance = IMPORTANCE_DEFAULT;
confirmationText.setText(R.string.notification_channel_unsilenced);
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index 5a9a568..ddda3e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -16,26 +16,222 @@
package com.android.systemui.statusbar.notification.row.wrapper;
-import android.content.Context;
-import android.view.View;
+import static com.android.systemui.Dependency.MAIN_HANDLER;
+import android.app.Notification;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.media.MediaMetadata;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.PlaybackState;
+import android.os.Handler;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewStub;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.android.internal.R;
+import com.android.systemui.Dependency;
import com.android.systemui.statusbar.TransformableView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import java.util.Timer;
+import java.util.TimerTask;
+
/**
* Wraps a notification containing a media template
*/
public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper {
+ private static final String TAG = "NotificationMediaTVW";
+ private static final long PROGRESS_UPDATE_INTERVAL = 1000; // 1s
+ private static final String COMPACT_MEDIA_TAG = "media";
+ private final Handler mHandler = Dependency.get(MAIN_HANDLER);
+ private Timer mSeekBarTimer;
+ private View mActions;
+ private SeekBar mSeekBar;
+ private TextView mSeekBarElapsedTime;
+ private TextView mSeekBarTotalTime;
+ private long mDuration = 0;
+ private MediaController mMediaController;
+ private View mSeekBarView;
+ private Context mContext;
+
+ // TODO: implement as phenotype flag
+ public static final boolean HIDE_COMPACT_SCRUBBER = true;
+
+ private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ if (mMediaController != null && canSeekMedia()) {
+ mMediaController.getTransportControls().seekTo(mSeekBar.getProgress());
+ }
+ }
+ };
+
+ private MediaController.Callback mMediaCallback = new MediaController.Callback() {
+ @Override
+ public void onSessionDestroyed() {
+ clearTimer();
+ mMediaController.unregisterCallback(this);
+ }
+
+ @Override
+ public void onPlaybackStateChanged(PlaybackState state) {
+ if (state.getState() != PlaybackState.STATE_PLAYING) {
+ clearTimer();
+ } else if (mSeekBarTimer == null) {
+ startTimer();
+ }
+ }
+ };
+
protected NotificationMediaTemplateViewWrapper(Context ctx, View view,
ExpandableNotificationRow row) {
super(ctx, view, row);
+ mContext = ctx;
}
- View mActions;
-
private void resolveViews() {
mActions = mView.findViewById(com.android.internal.R.id.media_actions);
+
+ final MediaSession.Token token = mRow.getEntry().notification.getNotification().extras
+ .getParcelable(Notification.EXTRA_MEDIA_SESSION);
+
+ if (token == null || (COMPACT_MEDIA_TAG.equals(mView.getTag()) && HIDE_COMPACT_SCRUBBER)) {
+ if (mSeekBarView != null) {
+ mSeekBarView.setVisibility(View.GONE);
+ }
+ return;
+ }
+
+ // Check for existing media controller and clean up / create as necessary
+ if (mMediaController == null || !mMediaController.getSessionToken().equals(token)) {
+ if (mMediaController != null) {
+ mMediaController.unregisterCallback(mMediaCallback);
+ }
+ mMediaController = new MediaController(mContext, token);
+ }
+
+ if (mMediaController.getMetadata() != null) {
+ long duration = mMediaController.getMetadata().getLong(
+ MediaMetadata.METADATA_KEY_DURATION);
+ if (duration <= 0) {
+ // Don't include the seekbar if this is a livestream
+ Log.d(TAG, "removing seekbar");
+ if (mSeekBarView != null) {
+ mSeekBarView.setVisibility(View.GONE);
+ }
+ return;
+ } else {
+ // Otherwise, make sure the seekbar is visible
+ if (mSeekBarView != null) {
+ mSeekBarView.setVisibility(View.VISIBLE);
+ }
+ }
+ }
+
+ // Inflate the seekbar template
+ ViewStub stub = mView.findViewById(R.id.notification_media_seekbar_container);
+ if (stub instanceof ViewStub) {
+ LayoutInflater layoutInflater = LayoutInflater.from(stub.getContext());
+ stub.setLayoutInflater(layoutInflater);
+ stub.setLayoutResource(R.layout.notification_material_media_seekbar);
+ mSeekBarView = stub.inflate();
+
+ mSeekBar = mSeekBarView.findViewById(R.id.notification_media_progress_bar);
+ mSeekBar.setOnSeekBarChangeListener(mSeekListener);
+
+ mSeekBarElapsedTime = mSeekBarView.findViewById(R.id.notification_media_elapsed_time);
+ mSeekBarTotalTime = mSeekBarView.findViewById(R.id.notification_media_total_time);
+
+ if (mSeekBarTimer == null) {
+ // Disable seeking if it is not supported for this media session
+ if (!canSeekMedia()) {
+ mSeekBar.getThumb().setAlpha(0);
+ mSeekBar.setEnabled(false);
+ } else {
+ mSeekBar.getThumb().setAlpha(255);
+ mSeekBar.setEnabled(true);
+ }
+
+ startTimer();
+
+ mMediaController.registerCallback(mMediaCallback);
+ }
+ }
+ updateSeekBarTint(mSeekBarView);
+ }
+
+ private void startTimer() {
+ clearTimer();
+ mSeekBarTimer = new Timer(true /* isDaemon */);
+ mSeekBarTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ mHandler.post(mUpdatePlaybackUi);
+ }
+ }, 0, PROGRESS_UPDATE_INTERVAL);
+ }
+
+ private void clearTimer() {
+ if (mSeekBarTimer != null) {
+ // TODO: also trigger this when the notification panel is collapsed
+ mSeekBarTimer.cancel();
+ mSeekBarTimer.purge();
+ mSeekBarTimer = null;
+ }
+ }
+
+ private boolean canSeekMedia() {
+ if (mMediaController == null || mMediaController.getPlaybackState() == null) {
+ return false;
+ }
+
+ long actions = mMediaController.getPlaybackState().getActions();
+ return (actions == 0 || (actions & PlaybackState.ACTION_SEEK_TO) != 0);
+ }
+
+ protected final Runnable mUpdatePlaybackUi = new Runnable() {
+ @Override
+ public void run() {
+ if (mMediaController != null && mMediaController.getMetadata() != null
+ && mSeekBar != null) {
+ long position = mMediaController.getPlaybackState().getPosition();
+ long duration = mMediaController.getMetadata().getLong(
+ MediaMetadata.METADATA_KEY_DURATION);
+
+ if (mDuration != duration) {
+ mDuration = duration;
+ mSeekBar.setMax((int) mDuration);
+ mSeekBarTotalTime.setText(millisecondsToTimeString(duration));
+ }
+ mSeekBar.setProgress((int) position);
+
+ mSeekBarElapsedTime.setText(millisecondsToTimeString(position));
+ } else {
+ // We no longer have a media session / notification
+ clearTimer();
+ }
+ }
+ };
+
+ private String millisecondsToTimeString(long milliseconds) {
+ long seconds = milliseconds / 1000;
+ String text = DateUtils.formatElapsedTime(seconds);
+ return text;
}
@Override
@@ -46,6 +242,27 @@
super.onContentUpdated(row);
}
+ private void updateSeekBarTint(View seekBarContainer) {
+ if (seekBarContainer == null) {
+ return;
+ }
+
+ if (this.getNotificationHeader() == null) {
+ return;
+ }
+
+ int tintColor = getNotificationHeader().getOriginalIconColor();
+ mSeekBarElapsedTime.setTextColor(tintColor);
+ mSeekBarTotalTime.setTextColor(tintColor);
+
+ ColorStateList tintList = ColorStateList.valueOf(tintColor);
+ mSeekBar.setThumbTintList(tintList);
+ tintList = tintList.withAlpha(192); // 75%
+ mSeekBar.setProgressTintList(tintList);
+ tintList = tintList.withAlpha(128); // 50%
+ mSeekBar.setProgressBackgroundTintList(tintList);
+ }
+
@Override
protected void updateTransformedTypes() {
// This also clears the existing types
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 63b34d1..855cfd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -599,6 +599,16 @@
updateFooter();
}
+ @Override
+ public void onOverlayChanged() {
+ int newRadius = mContext.getResources().getDimensionPixelSize(
+ Utils.getThemeAttr(mContext, android.R.attr.dialogCornerRadius));
+ if (mCornerRadius != newRadius) {
+ mCornerRadius = newRadius;
+ invalidate();
+ }
+ }
+
@VisibleForTesting
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void updateFooter() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 304d2ee..2162ea7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -232,7 +232,8 @@
if (DEBUG_BIO_WAKELOCK) {
Log.i(TAG, "bio wakelock: Authenticated, waking up...");
}
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.policy:BIOMETRIC");
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ "android.policy:BIOMETRIC");
}
if (delayWakeUp) {
mKeyguardViewMediator.onWakeAndUnlocking();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
new file mode 100644
index 0000000..dae4da7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.R;
+
+public class NavigationBarEdgePanel extends View {
+ private static final String TAG = "NavigationBarEdgePanel";
+
+ public static NavigationBarEdgePanel create(@NonNull Context context, int width, int height,
+ int gravity) {
+ final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+ WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+ PixelFormat.TRANSLUCENT);
+ lp.gravity = gravity;
+ lp.setTitle(TAG + context.getDisplayId());
+ lp.accessibilityTitle = context.getString(R.string.nav_bar_edge_panel);
+ lp.windowAnimations = 0;
+ NavigationBarEdgePanel panel = new NavigationBarEdgePanel(context);
+ panel.setLayoutParams(lp);
+ return panel;
+ }
+
+ private NavigationBarEdgePanel(Context context) {
+ super(context);
+ }
+
+ public void setWindowFlag(int flags, boolean enable) {
+ WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
+ if (lp == null || enable == ((lp.flags & flags) != 0)) {
+ return;
+ }
+ if (enable) {
+ lp.flags |= flags;
+ } else {
+ lp.flags &= ~flags;
+ }
+ updateLayout(lp);
+ }
+
+ public void setDimensions(int width, int height) {
+ final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
+ if (lp.width != width || lp.height != height) {
+ lp.width = width;
+ lp.height = height;
+ updateLayout(lp);
+ }
+ }
+
+ private void updateLayout(WindowManager.LayoutParams lp) {
+ WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+ wm.updateViewLayout(this, lp);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 02683c1..651670c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -18,6 +18,8 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
@@ -35,6 +37,8 @@
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.DrawableRes;
+import android.annotation.IntDef;
+import android.annotation.SuppressLint;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
@@ -51,6 +55,7 @@
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
@@ -87,12 +92,21 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.function.Consumer;
public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> {
final static boolean DEBUG = false;
final static String TAG = "StatusBar/NavBarView";
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({WINDOW_TARGET_BOTTOM, WINDOW_TARGET_LEFT, WINDOW_TARGET_RIGHT})
+ public @interface WindowTarget{}
+ public static final int WINDOW_TARGET_BOTTOM = 0;
+ public static final int WINDOW_TARGET_LEFT = 1;
+ public static final int WINDOW_TARGET_RIGHT = 2;
+
// slippery nav bar when everything is disabled, e.g. during setup
final static boolean SLIPPERY_WHEN_DISABLED = true;
@@ -109,6 +123,7 @@
int mNavigationIconHints = 0;
private @NavigationBarCompat.HitTarget int mDownHitTarget = HIT_TARGET_NONE;
+ private @WindowTarget int mWindowHitTarget = WINDOW_TARGET_BOTTOM;
private Rect mHomeButtonBounds = new Rect();
private Rect mBackButtonBounds = new Rect();
private Rect mRecentsButtonBounds = new Rect();
@@ -160,6 +175,9 @@
private NavigationAssistantAction mAssistantAction;
private NavigationNotificationPanelAction mNotificationPanelAction;
+ private NavigationBarEdgePanel mLeftEdgePanel;
+ private NavigationBarEdgePanel mRightEdgePanel;
+
/**
* Helper that is responsible for showing the right toast when a disallowed activity operation
* occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
@@ -222,6 +240,18 @@
}
};
+ private final OnTouchListener mEdgePanelTouchListener = new OnTouchListener() {
+ @SuppressLint("ClickableViewAccessibility")
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getActionMasked() == ACTION_DOWN) {
+ mWindowHitTarget = v == mLeftEdgePanel ? WINDOW_TARGET_LEFT : WINDOW_TARGET_RIGHT;
+ mDownHitTarget = HIT_TARGET_NONE;
+ }
+ return mGestureHelper.onTouchEvent(event);
+ }
+ };
+
private class H extends Handler {
public void handleMessage(Message m) {
switch (m.what) {
@@ -297,6 +327,16 @@
mColorAdaptionController.end();
}
}
+
+ @Override
+ public void onEdgeSensitivityChanged(int width, int height) {
+ if (mLeftEdgePanel != null) {
+ mLeftEdgePanel.setDimensions(width, height);
+ }
+ if (mRightEdgePanel != null) {
+ mRightEdgePanel.setDimensions(width, height);
+ }
+ }
};
public NavigationBarView(Context context, AttributeSet attrs) {
@@ -433,6 +473,7 @@
int x = (int) event.getX();
int y = (int) event.getY();
mDownHitTarget = HIT_TARGET_NONE;
+ mWindowHitTarget = WINDOW_TARGET_BOTTOM;
if (deadZoneConsumed) {
mDownHitTarget = HIT_TARGET_DEAD_ZONE;
} else if (getBackButton().isVisible() && mBackButtonBounds.contains(x, y)) {
@@ -483,6 +524,10 @@
return mDownHitTarget;
}
+ public @WindowTarget int getWindowTarget() {
+ return mWindowHitTarget;
+ }
+
public void abortCurrentGesture() {
getHomeButton().abortCurrentGesture();
}
@@ -837,24 +882,32 @@
}
private void setSlippery(boolean slippery) {
- boolean changed = false;
+ setWindowFlag(WindowManager.LayoutParams.FLAG_SLIPPERY, slippery);
+ }
+
+ public void setWindowTouchable(boolean flag) {
+ setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag);
+ if (mLeftEdgePanel != null) {
+ mLeftEdgePanel.setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag);
+ }
+ if (mRightEdgePanel != null) {
+ mRightEdgePanel.setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag);
+ }
+ }
+
+ private void setWindowFlag(int flags, boolean enable) {
final ViewGroup navbarView = ((ViewGroup) getParent());
- final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView
- .getLayoutParams();
- if (lp == null) {
+ WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView.getLayoutParams();
+ if (lp == null || enable == ((lp.flags & flags) != 0)) {
return;
}
- if (slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) == 0) {
- lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
- changed = true;
- } else if (!slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) != 0) {
- lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
- changed = true;
+ if (enable) {
+ lp.flags |= flags;
+ } else {
+ lp.flags &= ~flags;
}
- if (changed) {
- WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
- wm.updateViewLayout(navbarView, lp);
- }
+ WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+ wm.updateViewLayout(navbarView, lp);
}
public void setMenuVisibility(final boolean show) {
@@ -1016,6 +1069,17 @@
} catch (RemoteException e) {
Slog.e(TAG, "Failed to get nav bar position.", e);
}
+
+ // For landscape, hide the panel that would interfere with navigation bar layout
+ if (mLeftEdgePanel != null && mRightEdgePanel != null) {
+ mLeftEdgePanel.setVisibility(VISIBLE);
+ mRightEdgePanel.setVisibility(VISIBLE);
+ if (navBarPos == NAV_BAR_LEFT) {
+ mLeftEdgePanel.setVisibility(GONE);
+ } else if (navBarPos == NAV_BAR_RIGHT) {
+ mRightEdgePanel.setVisibility(GONE);
+ }
+ }
mGestureHelper.setBarState(isRtl, navBarPos);
}
@@ -1142,6 +1206,21 @@
NavGesture.class, false /* Only one */);
setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
mColorAdaptionController.start();
+
+ if (mPrototypeController.isEnabled()) {
+ WindowManager wm = (WindowManager) getContext()
+ .getSystemService(Context.WINDOW_SERVICE);
+ int width = mPrototypeController.getEdgeSensitivityWidth();
+ int height = mPrototypeController.getEdgeSensitivityHeight();
+ mLeftEdgePanel = NavigationBarEdgePanel.create(getContext(), width, height,
+ Gravity.START | Gravity.BOTTOM);
+ mRightEdgePanel = NavigationBarEdgePanel.create(getContext(), width, height,
+ Gravity.END | Gravity.BOTTOM);
+ mLeftEdgePanel.setOnTouchListener(mEdgePanelTouchListener);
+ mRightEdgePanel.setOnTouchListener(mEdgePanelTouchListener);
+ wm.addView(mLeftEdgePanel, mLeftEdgePanel.getLayoutParams());
+ wm.addView(mRightEdgePanel, mRightEdgePanel.getLayoutParams());
+ }
}
@Override
@@ -1157,6 +1236,17 @@
for (int i = 0; i < mButtonDispatchers.size(); ++i) {
mButtonDispatchers.valueAt(i).onDestroy();
}
+
+ if (mPrototypeController.isEnabled()) {
+ WindowManager wm = (WindowManager) getContext()
+ .getSystemService(Context.WINDOW_SERVICE);
+ if (mLeftEdgePanel != null) {
+ wm.removeView(mLeftEdgePanel);
+ }
+ if (mRightEdgePanel != null) {
+ wm.removeView(mRightEdgePanel);
+ }
+ }
}
private void setUpSwipeUpOnboarding(boolean connectedToOverviewProxy) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
index b4feb25..8421e23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.content.Context;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
@@ -34,7 +35,12 @@
public class NavigationPrototypeController extends ContentObserver {
private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback";
private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome";
+ private static final String PROTOTYPE_ENABLED = "prototype_enabled";
+ private static final String EDGE_SENSITIVITY_HEIGHT_SETTING =
+ "quickstepcontroller_edge_height_sensitivity";
+ public static final String EDGE_SENSITIVITY_WIDTH_SETTING =
+ "quickstepcontroller_edge_width_sensitivity";
private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map";
public static final String NAV_COLOR_ADAPT_ENABLE_SETTING = "navbar_color_adapt_enable";
@@ -79,6 +85,8 @@
registerObserver(HIDE_HOME_BUTTON_SETTING);
registerObserver(GESTURE_MATCH_SETTING);
registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING);
+ registerObserver(EDGE_SENSITIVITY_WIDTH_SETTING);
+ registerObserver(EDGE_SENSITIVITY_HEIGHT_SETTING);
}
/**
@@ -106,10 +114,26 @@
} else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) {
mListener.onColorAdaptChanged(
NavBarTintController.isEnabled(mContext));
+ } else if (path.endsWith(EDGE_SENSITIVITY_WIDTH_SETTING)
+ || path.endsWith(EDGE_SENSITIVITY_HEIGHT_SETTING)) {
+ mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(),
+ getEdgeSensitivityHeight());
}
}
}
+ public int getEdgeSensitivityWidth() {
+ return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 0));
+ }
+
+ public int getEdgeSensitivityHeight() {
+ return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_HEIGHT_SETTING, 0));
+ }
+
+ public boolean isEnabled() {
+ return getGlobalBool(PROTOTYPE_ENABLED, false);
+ }
+
/**
* Retrieve the action map to apply to the quick step controller
* @return an action map
@@ -144,15 +168,24 @@
return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal ? 1 : 0) == 1;
}
+ private int getGlobalInt(String name, int defaultVal) {
+ return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal);
+ }
+
private void registerObserver(String name) {
mContext.getContentResolver()
.registerContentObserver(Settings.Global.getUriFor(name), false, this);
}
+ private static int convertDpToPixel(float dp) {
+ return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
+ }
+
public interface OnPrototypeChangedListener {
void onGestureRemap(@GestureAction int[] actions);
void onBackButtonVisibilityChanged(boolean visible);
void onHomeButtonVisibilityChanged(boolean visible);
void onColorAdaptChanged(boolean enabled);
+ void onEdgeSensitivityChanged(int width, int height);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index d5d283c..84f1cef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -28,9 +28,12 @@
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
+import static com.android.systemui.statusbar.phone.NavigationBarView.WINDOW_TARGET_BOTTOM;
+import static com.android.systemui.statusbar.phone.NavigationPrototypeController.EDGE_SENSITIVITY_WIDTH_SETTING;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
@@ -42,12 +45,9 @@
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
+import android.view.ViewConfiguration;
import android.view.ViewPropertyAnimator;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -72,6 +72,7 @@
/** Experiment to swipe home button left to execute a back key press */
private static final String HIDE_BACK_BUTTON_PROP = "quickstepcontroller_hideback";
private static final String ENABLE_CLICK_THROUGH_NAV_PROP = "quickstepcontroller_clickthrough";
+ private static final String GESTURE_REGION_THRESHOLD_SETTING = "gesture_region_threshold";
private static final long BACK_BUTTON_FADE_IN_ALPHA = 150;
private static final long CLICK_THROUGH_TAP_DELAY = 70;
private static final long CLICK_THROUGH_TAP_RESET_DELAY = 100;
@@ -109,10 +110,10 @@
private float mMaxDragLimit;
private float mMinDragLimit;
private float mDragDampeningFactor;
- private float mEdgeSwipeThreshold;
private boolean mClickThroughPressed;
private float mClickThroughPressX;
private float mClickThroughPressY;
+ private int mGestureRegionThreshold;
private NavigationGestureAction mCurrentAction;
private NavigationGestureAction[] mGestureActions = new NavigationGestureAction[MAX_GESTURES];
@@ -139,7 +140,7 @@
};
private final Runnable mClickThroughResetTap = () -> {
- setWindowTouchable(true);
+ mNavigationBarView.setWindowTouchable(true);
mClickThroughPressed = false;
};
@@ -210,7 +211,8 @@
// The same down event was just sent on intercept and therefore can be ignored here
final boolean ignoreProxyDownEvent = event.getAction() == MotionEvent.ACTION_DOWN
- && mOverviewEventSender.getProxy() != null;
+ && mOverviewEventSender.getProxy() != null
+ && mNavigationBarView.getWindowTarget() == WINDOW_TARGET_BOTTOM;
return ignoreProxyDownEvent || handleTouchEvent(event);
}
@@ -268,12 +270,15 @@
mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix);
mAllowGestureDetection = true;
mNotificationsVisibleOnDown = !mNavigationBarView.isNotificationsFullyCollapsed();
- mEdgeSwipeThreshold = mContext.getResources()
- .getDimensionPixelSize(R.dimen.navigation_bar_edge_swipe_threshold);
+ final int defaultRegionThreshold = mContext.getResources()
+ .getDimensionPixelOffset(R.dimen.navigation_bar_default_edge_width);
+ mGestureRegionThreshold = convertDpToPixel(getIntGlobalSetting(mContext,
+ EDGE_SENSITIVITY_WIDTH_SETTING, defaultRegionThreshold));
break;
}
case MotionEvent.ACTION_MOVE: {
- if (!mAllowGestureDetection) {
+ if (!mAllowGestureDetection
+ || mNavigationBarView.getWindowTarget() != WINDOW_TARGET_BOTTOM) {
break;
}
int x = (int) event.getX();
@@ -330,18 +335,12 @@
} else if (exceededSwipeHorizontalTouchSlop) {
if (mDragHPositive ? (posH < touchDownH) : (posH > touchDownH)) {
// Swiping left (rtl) gesture
- int index = mGestureActions[ACTION_SWIPE_LEFT_FROM_EDGE_INDEX] != null
- && isEdgeSwipeAlongNavBar(touchDownH, !mDragHPositive)
- ? ACTION_SWIPE_LEFT_FROM_EDGE_INDEX : ACTION_SWIPE_LEFT_INDEX;
- tryToStartGesture(mGestureActions[index], true /* alignedWithNavBar */,
- event);
+ tryToStartGesture(mGestureActions[ACTION_SWIPE_LEFT_INDEX],
+ true /* alignedWithNavBar */, event);
} else {
// Swiping right (ltr) gesture
- int index = mGestureActions[ACTION_SWIPE_RIGHT_FROM_EDGE_INDEX] != null
- && isEdgeSwipeAlongNavBar(touchDownH, mDragHPositive)
- ? ACTION_SWIPE_RIGHT_FROM_EDGE_INDEX : ACTION_SWIPE_RIGHT_INDEX;
- tryToStartGesture(mGestureActions[index], true /* alignedWithNavBar */,
- event);
+ tryToStartGesture(mGestureActions[ACTION_SWIPE_RIGHT_INDEX],
+ true /* alignedWithNavBar */, event);
}
}
}
@@ -354,24 +353,34 @@
case MotionEvent.ACTION_UP:
if (mCurrentAction != null) {
mCurrentAction.endGesture();
- } else if (action == MotionEvent.ACTION_UP
- && getBoolGlobalSetting(mContext, ENABLE_CLICK_THROUGH_NAV_PROP)
- && !mClickThroughPressed) {
- // Enable click through functionality where no gesture has been detected and not
- // passed the drag slop so inject a touch event at the same location
- // after making the navigation bar window untouchable. After a some time, the
- // navigation bar will be able to take input events again
- float diffX = Math.abs(event.getX() - mTouchDownX);
- float diffY = Math.abs(event.getY() - mTouchDownY);
+ } else if (action == MotionEvent.ACTION_UP) {
+ if (canTriggerEdgeSwipe(event)) {
+ int index = mNavigationBarView.getWindowTarget() == NAV_BAR_LEFT
+ ? ACTION_SWIPE_RIGHT_FROM_EDGE_INDEX
+ : ACTION_SWIPE_LEFT_FROM_EDGE_INDEX;
+ tryToStartGesture(mGestureActions[index], false /* alignedWithNavBar */,
+ event);
+ if (mCurrentAction != null) {
+ mCurrentAction.endGesture();
+ }
+ } else if (getBoolGlobalSetting(mContext, ENABLE_CLICK_THROUGH_NAV_PROP)
+ && !mClickThroughPressed) {
+ // Enable click through functionality where no gesture has been detected and
+ // not passed the drag slop so inject a touch event at the same location
+ // after making the navigation bar window untouchable. After a some time,
+ // the navigation bar will be able to take input events again
+ float diffX = Math.abs(event.getX() - mTouchDownX);
+ float diffY = Math.abs(event.getY() - mTouchDownY);
- if ((diffX <= NavigationBarCompat.getQuickStepDragSlopPx()
- && diffY <= NavigationBarCompat.getQuickStepDragSlopPx())) {
- setWindowTouchable(false);
- mClickThroughPressX = event.getRawX();
- mClickThroughPressY = event.getRawY();
- mClickThroughPressed = true;
- mNavigationBarView.postDelayed(mClickThroughSendTap,
- CLICK_THROUGH_TAP_DELAY);
+ if ((diffX <= NavigationBarCompat.getQuickStepDragSlopPx()
+ && diffY <= NavigationBarCompat.getQuickStepDragSlopPx())) {
+ mNavigationBarView.setWindowTouchable(false);
+ mClickThroughPressX = event.getRawX();
+ mClickThroughPressY = event.getRawY();
+ mClickThroughPressed = true;
+ mNavigationBarView.postDelayed(mClickThroughSendTap,
+ CLICK_THROUGH_TAP_DELAY);
+ }
}
}
@@ -403,30 +412,6 @@
return mCurrentAction != null || deadZoneConsumed;
}
- private void setWindowTouchable(boolean flag) {
- final WindowManager.LayoutParams lp = (WindowManager.LayoutParams)
- ((ViewGroup) mNavigationBarView.getParent()).getLayoutParams();
- if (flag) {
- lp.flags &= ~LayoutParams.FLAG_NOT_TOUCHABLE;
- } else {
- lp.flags |= LayoutParams.FLAG_NOT_TOUCHABLE;
- }
- final WindowManager wm = (WindowManager) mNavigationBarView.getContext()
- .getSystemService(Context.WINDOW_SERVICE);
- wm.updateViewLayout((View) mNavigationBarView.getParent(), lp);
- }
-
- private boolean isEdgeSwipeAlongNavBar(int touchDown, boolean dragPositiveDirection) {
- // Detect edge swipe from side of 0 -> threshold
- if (dragPositiveDirection) {
- return touchDown < mEdgeSwipeThreshold;
- }
- // Detect edge swipe from side of size -> (size - threshold)
- final int largeSide = isNavBarVertical()
- ? mNavigationBarView.getHeight() : mNavigationBarView.getWidth();
- return touchDown > largeSide - mEdgeSwipeThreshold;
- }
-
private void handleDragHitTarget(int position, int touchDown) {
// Drag the hit target if gesture action requires it
if (mHitTarget != null && (mGestureVerticalDragsButton || mGestureHorizontalDragsButton)) {
@@ -448,6 +433,10 @@
}
private boolean shouldProxyEvents(int action) {
+ // Do not send events for side navigation bar panels
+ if (mNavigationBarView.getWindowTarget() != WINDOW_TARGET_BOTTOM) {
+ return false;
+ }
final boolean actionValid = (mCurrentAction == null
|| !mCurrentAction.disableProxyEvents());
if (actionValid && !mIsInScreenPinning) {
@@ -619,6 +608,32 @@
}
}
+ /**
+ * To trigger an edge swipe, the user must start from the left or right edges of certain height
+ * from the bottom then past the drag slope towards the center of the screen, followed by either
+ * a timed trigger for fast swipes or distance if held on the screen longer.
+ * For time, user must swipe up quickly before the Tap Timeout (typically 100ms) and for
+ * distance, the user can drag back to cancel if the touch up has not past the threshold.
+ * @param event Touch up event
+ * @return whether or not edge swipe gesture occurs
+ */
+ private boolean canTriggerEdgeSwipe(MotionEvent event) {
+ if (mNavigationBarView.getWindowTarget() == WINDOW_TARGET_BOTTOM) {
+ return false;
+ }
+ int x = (int) event.getX();
+ int y = (int) event.getY();
+ int xDiff = Math.abs(x - mTouchDownX);
+ int yDiff = Math.abs(y - mTouchDownY);
+ final boolean exceededSwipeTouchSlop = xDiff > NavigationBarCompat.getQuickStepDragSlopPx()
+ && xDiff > yDiff;
+ if (exceededSwipeTouchSlop) {
+ long timeDiff = event.getEventTime() - event.getDownTime();
+ return xDiff > mGestureRegionThreshold || timeDiff < ViewConfiguration.getTapTimeout();
+ }
+ return false;
+ }
+
private boolean canPerformAnyAction() {
for (NavigationGestureAction action: mGestureActions) {
if (action != null && action.isEnabled()) {
@@ -684,10 +699,18 @@
return mNavBarPosition == NAV_BAR_LEFT || mNavBarPosition == NAV_BAR_RIGHT;
}
+ private static int convertDpToPixel(float dp) {
+ return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
+ }
+
static boolean getBoolGlobalSetting(Context context, String key) {
return Settings.Global.getInt(context.getContentResolver(), key, 0) != 0;
}
+ static int getIntGlobalSetting(Context context, String key, int defaultValue) {
+ return Settings.Global.getInt(context.getContentResolver(), key, defaultValue);
+ }
+
public static boolean shouldhideBackButton(Context context) {
return getBoolGlobalSetting(context, HIDE_BACK_BUTTON_PROP);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java
index 40f2392..974de4b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java
@@ -22,7 +22,6 @@
import android.annotation.NonNull;
import android.graphics.Rect;
import android.os.RemoteException;
-import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
@@ -34,7 +33,6 @@
*/
public class QuickSwitchAction extends NavigationGestureAction {
private static final String TAG = "QuickSwitchAction";
- private static final String QUICKSWITCH_ENABLED_SETTING = "QUICK_SWITCH";
protected final Rect mDragOverRect = new Rect();
@@ -71,10 +69,6 @@
@Override
protected void onGestureStart(MotionEvent event) {
- // Temporarily enable launcher to allow quick switch instead of quick scrub
- Settings.Global.putInt(mNavigationBarView.getContext().getContentResolver(),
- QUICKSWITCH_ENABLED_SETTING, 1 /* enabled */);
-
startQuickGesture(event);
}
@@ -105,10 +99,6 @@
@Override
protected void onGestureEnd() {
endQuickGesture(true /* animate */);
-
- // Disable launcher to use quick switch instead of quick scrub
- Settings.Global.putInt(mNavigationBarView.getContext().getContentResolver(),
- QUICKSWITCH_ENABLED_SETTING, 0 /* disabled */);
}
protected void startQuickGesture(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index bf143c8..ee1e3c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -272,9 +272,8 @@
// AOD wallpapers should fade away after a while.
// Docking pulses may take a long time, wallpapers should also fade away after a while.
- if (mWallpaperSupportsAmbientMode && (
- mDozeParameters.getAlwaysOn() && mState == ScrimState.AOD
- || mState == ScrimState.PULSING && mCallback != null)) {
+ if (mWallpaperSupportsAmbientMode && mDozeParameters.getAlwaysOn()
+ && mState == ScrimState.AOD) {
if (!mWallpaperVisibilityTimedOut) {
mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 11a2d32..0f85c18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -128,7 +128,8 @@
public void prepare(ScrimState previousState) {
mCurrentInFrontAlpha = 0f;
if (mPulseReason == DozeLog.PULSE_REASON_NOTIFICATION
- || mPulseReason == DozeLog.PULSE_REASON_DOCKING) {
+ || mPulseReason == DozeLog.PULSE_REASON_DOCKING
+ || mPulseReason == DozeLog.PULSE_REASON_INTENT) {
mCurrentBehindAlpha = previousState.getBehindAlpha();
mCurrentBehindTint = Color.BLACK;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
index f926218..234a968 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
@@ -14,6 +14,7 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.NonNull;
import android.view.View;
import com.android.systemui.statusbar.StatusBarState;
@@ -96,8 +97,9 @@
*
* @param time when to wake up
* @param view the view requesting the wakeup
+ * @param why the reason for the wake up
*/
- void wakeUpIfDozing(long time, View view);
+ void wakeUpIfDozing(long time, View view, @NonNull String why);
/**
* If secure with redaction: Show bouncer, go to unlocked shade.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index c129143..37a0610 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -482,7 +482,8 @@
updateAodMaskVisibility(deviceSupportsAodWallpaper && aodImageWallpaperEnabled);
// If WallpaperInfo is null, it must be ImageWallpaper.
final boolean supportsAmbientMode = deviceSupportsAodWallpaper
- && (info == null || info.supportsAmbientMode());
+ && (info == null && aodImageWallpaperEnabled
+ || info != null && info.supportsAmbientMode());
mStatusBarWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
@@ -551,7 +552,7 @@
private final View.OnClickListener mGoToLockedShadeListener = v -> {
if (mState == StatusBarState.KEYGUARD) {
- wakeUpIfDozing(SystemClock.uptimeMillis(), v);
+ wakeUpIfDozing(SystemClock.uptimeMillis(), v, "SHADE_CLICK");
goToLockedShade(null);
}
};
@@ -1090,10 +1091,10 @@
}
@Override
- public void wakeUpIfDozing(long time, View where) {
+ public void wakeUpIfDozing(long time, View where, String why) {
if (mDozing) {
- PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- pm.wakeUp(time, "com.android.systemui:NODOZE");
+ PowerManager pm = mContext.getSystemService(PowerManager.class);
+ pm.wakeUp(time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
mWakeUpComingFromTouch = true;
where.getLocationInWindow(mTmpInt2);
mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
@@ -3729,7 +3730,8 @@
}
if (!mDeviceInteractive) {
PowerManager pm = mContext.getSystemService(PowerManager.class);
- pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
+ pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
+ "com.android.systemui:CAMERA_GESTURE");
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
}
vibrateForCameraGesture();
@@ -3890,16 +3892,13 @@
public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
mScrimController.setPulseReason(reason);
if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) {
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ "com.android.systemui:LONG_PRESS");
startAssist(new Bundle());
return;
}
- if (mKeyguardUpdateMonitor != null
- && reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
- mKeyguardUpdateMonitor.onAuthInterruptDetected();
- }
-
+ boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
// Set the state to pulsing, so ScrimController will know what to do once we ask it to
// execute the transition. The pulse callback will then be invoked when the scrims
// are black, indicating that StatusBar is ready to present the rest of the UI.
@@ -3925,6 +3924,9 @@
mNotificationPanel.setPulsing(pulsing);
mVisualStabilityManager.setPulsing(pulsing);
mIgnoreTouchWhilePulsing = false;
+ if (mKeyguardUpdateMonitor != null && passiveAuthInterrupt) {
+ mKeyguardUpdateMonitor.onAuthInterruptDetected(pulsing /* active */);
+ }
updateScrimController();
}
}, reason);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index ffaa236..86e17f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -202,7 +202,8 @@
private void applyFocusableFlag(State state) {
boolean panelFocusable = state.statusBarFocusable && state.panelExpanded;
if (state.bouncerShowing && (state.keyguardOccluded || state.keyguardNeedsInput)
- || ENABLE_REMOTE_INPUT && state.remoteInputActive) {
+ || ENABLE_REMOTE_INPUT && state.remoteInputActive
+ || state.bubbleExpanded) {
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
@@ -486,6 +487,21 @@
return mCurrentState.bubblesShowing;
}
+ /**
+ * Sets if there is a bubble being expanded on the screen.
+ */
+ public void setBubbleExpanded(boolean bubbleExpanded) {
+ mCurrentState.bubbleExpanded = bubbleExpanded;
+ apply(mCurrentState);
+ }
+
+ /**
+ * The bubble is shown in expanded state for the status bar.
+ */
+ public boolean getBubbleExpanded() {
+ return mCurrentState.bubbleExpanded;
+ }
+
public void setStateListener(OtherwisedCollapsedListener listener) {
mListener = listener;
}
@@ -539,6 +555,7 @@
boolean wallpaperSupportsAmbientMode;
boolean notTouchable;
boolean bubblesShowing;
+ boolean bubbleExpanded;
/**
* The {@link StatusBar} state from the status bar.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 8b25c34..c39e172 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -112,7 +112,7 @@
mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
mFalsingManager = FalsingManager.getInstance(context);
mDoubleTapHelper = new DoubleTapHelper(this, active -> {}, () -> {
- mService.wakeUpIfDozing(SystemClock.uptimeMillis(), this);
+ mService.wakeUpIfDozing(SystemClock.uptimeMillis(), this, "DOUBLE_TAP");
return true;
}, null, null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 7881df9..1e09063 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -18,6 +18,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
@@ -59,6 +60,7 @@
import com.android.systemui.R;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry.EditedSuggestionInfo;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
@@ -269,10 +271,24 @@
mPendingIntent = pendingIntent;
}
- public void setRemoteInput(RemoteInput[] remoteInputs, RemoteInput remoteInput) {
+ /**
+ * Sets the remote input for this view.
+ *
+ * @param remoteInputs The remote inputs that need to be sent to the app.
+ * @param remoteInput The remote input that needs to be activated.
+ * @param editedSuggestionInfo The smart reply that should be inserted in the remote input, or
+ * {@code null} if the user is not editing a smart reply.
+ */
+ public void setRemoteInput(RemoteInput[] remoteInputs, RemoteInput remoteInput,
+ @Nullable EditedSuggestionInfo editedSuggestionInfo) {
mRemoteInputs = remoteInputs;
mRemoteInput = remoteInput;
mEditText.setHint(mRemoteInput.getLabel());
+
+ mEntry.editedSuggestionInfo = editedSuggestionInfo;
+ if (editedSuggestionInfo != null) {
+ mEntry.remoteInputText = editedSuggestionInfo.originalText;
+ }
}
public void focusAnimated() {
@@ -389,7 +405,7 @@
public void stealFocusFrom(RemoteInputView other) {
other.close();
setPendingIntent(other.mPendingIntent);
- setRemoteInput(other.mRemoteInputs, other.mRemoteInput);
+ setRemoteInput(other.mRemoteInputs, other.mRemoteInput, mEntry.editedSuggestionInfo);
setRevealParameters(other.mRevealCx, other.mRevealCy, other.mRevealR);
focus();
}
@@ -429,7 +445,7 @@
continue;
}
setPendingIntent(a.actionIntent);
- setRemoteInput(inputs, input);
+ setRemoteInput(inputs, input, null /* editedSuggestionInfo*/);
return true;
}
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 1d2d6f7..45d215e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -38,6 +38,7 @@
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry.EditedSuggestionInfo;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
@@ -252,16 +253,17 @@
OnDismissAction action = () -> {
if (mConstants.getEffectiveEditChoicesBeforeSending(
smartReplies.remoteInput.getEditChoicesBeforeSending())) {
- entry.remoteInputText = choice;
+ EditedSuggestionInfo editedSuggestionInfo =
+ new EditedSuggestionInfo(choice, replyIndex);
mRemoteInputManager.activateRemoteInput(b,
new RemoteInput[] { smartReplies.remoteInput }, smartReplies.remoteInput,
- smartReplies.pendingIntent);
+ smartReplies.pendingIntent, editedSuggestionInfo);
return false;
}
smartReplyController.smartReplySent(entry, replyIndex, b.getText(),
- smartReplies.fromAssistant,
- NotificationLogger.getNotificationLocation(entry).toMetricsEventEnum());
+ NotificationLogger.getNotificationLocation(entry).toMetricsEventEnum(),
+ false /* modifiedBeforeSending */);
Bundle results = new Bundle();
results.putString(smartReplies.remoteInput.getResultKey(), choice.toString());
Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
diff --git a/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java b/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java
index dd1d0ca..52cabe2 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java
@@ -156,8 +156,6 @@
private boolean checkIfNeedMask() {
// We need mask for ImageWallpaper / LockScreen Wallpaper (Music album art).
- // Because of conflicting with another wallpaper feature,
- // we only support LockScreen wallpaper currently.
return mWallpaperManager.getWallpaperInfo() == null || ScrimState.AOD.hasBackdrop();
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockInfoTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockInfoTest.java
new file mode 100644
index 0000000..d2b2654
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockInfoTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Bitmap;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.function.Supplier;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public final class ClockInfoTest extends SysuiTestCase {
+
+ @Mock
+ private Supplier<Bitmap> mMockSupplier;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testGetName() {
+ final String name = "name";
+ ClockInfo info = ClockInfo.builder().setName(name).build();
+ assertThat(info.getName()).isEqualTo(name);
+ }
+
+ @Test
+ public void testGetTitle() {
+ final String title = "title";
+ ClockInfo info = ClockInfo.builder().setTitle(title).build();
+ assertThat(info.getTitle()).isEqualTo(title);
+ }
+
+ @Test
+ public void testGetId() {
+ final String id = "id";
+ ClockInfo info = ClockInfo.builder().setId(id).build();
+ assertThat(info.getId()).isEqualTo(id);
+ }
+
+ @Test
+ public void testGetThumbnail() {
+ ClockInfo info = ClockInfo.builder().setThumbnail(mMockSupplier).build();
+ info.getThumbnail();
+ verify(mMockSupplier).get();
+ }
+
+ @Test
+ public void testGetPreview() {
+ ClockInfo info = ClockInfo.builder().setPreview(mMockSupplier).build();
+ info.getPreview();
+ verify(mMockSupplier).get();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockOptionsProviderTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockOptionsProviderTest.java
new file mode 100644
index 0000000..0cd6f9a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockOptionsProviderTest.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public final class ClockOptionsProviderTest extends SysuiTestCase {
+
+ private static final String CONTENT_SCHEME = "content";
+ private static final String AUTHORITY = "com.android.keyguard.clock";
+ private static final String LIST_OPTIONS = "list_options";
+ private static final String PREVIEW = "preview";
+ private static final String THUMBNAIL = "thumbnail";
+ private static final String MIME_TYPE_LIST_OPTIONS = "vnd.android.cursor.dir/clock_faces";
+ private static final String MIME_TYPE_PNG = "image/png";
+ private static final String NAME_COLUMN = "name";
+ private static final String TITLE_COLUMN = "title";
+ private static final String ID_COLUMN = "id";
+ private static final String PREVIEW_COLUMN = "preview";
+ private static final String THUMBNAIL_COLUMN = "thumbnail";
+
+ private ClockOptionsProvider mProvider;
+ private Supplier<List<ClockInfo>> mMockSupplier;
+ private List<ClockInfo> mClocks;
+ private Uri mListOptionsUri;
+ @Mock
+ private Supplier<Bitmap> mMockBitmapSupplier;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mClocks = new ArrayList<>();
+ mProvider = new ClockOptionsProvider(() -> mClocks);
+ mListOptionsUri = new Uri.Builder()
+ .scheme(CONTENT_SCHEME)
+ .authority(AUTHORITY)
+ .appendPath(LIST_OPTIONS)
+ .build();
+ }
+
+ @Test
+ public void testGetType_listOptions() {
+ Uri uri = new Uri.Builder()
+ .scheme(CONTENT_SCHEME)
+ .authority(AUTHORITY)
+ .appendPath(LIST_OPTIONS)
+ .build();
+ assertThat(mProvider.getType(uri)).isEqualTo(MIME_TYPE_LIST_OPTIONS);
+ }
+
+ @Test
+ public void testGetType_preview() {
+ Uri uri = new Uri.Builder()
+ .scheme(CONTENT_SCHEME)
+ .authority(AUTHORITY)
+ .appendPath(PREVIEW)
+ .appendPath("id")
+ .build();
+ assertThat(mProvider.getType(uri)).isEqualTo(MIME_TYPE_PNG);
+ }
+
+ @Test
+ public void testGetType_thumbnail() {
+ Uri uri = new Uri.Builder()
+ .scheme(CONTENT_SCHEME)
+ .authority(AUTHORITY)
+ .appendPath(THUMBNAIL)
+ .appendPath("id")
+ .build();
+ assertThat(mProvider.getType(uri)).isEqualTo(MIME_TYPE_PNG);
+ }
+
+ @Test
+ public void testQuery_noClocks() {
+ Cursor cursor = mProvider.query(mListOptionsUri, null, null, null);
+ assertThat(cursor.getCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void testQuery_listOptions() {
+ mClocks.add(ClockInfo.builder()
+ .setName("name_a")
+ .setTitle("title_a")
+ .setId("id_a")
+ .build());
+ mClocks.add(ClockInfo.builder()
+ .setName("name_b")
+ .setTitle("title_b")
+ .setId("id_b")
+ .build());
+ Cursor cursor = mProvider.query(mListOptionsUri, null, null, null);
+ assertThat(cursor.getCount()).isEqualTo(2);
+ cursor.moveToFirst();
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(NAME_COLUMN))).isEqualTo("name_a");
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(TITLE_COLUMN))).isEqualTo("title_a");
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(ID_COLUMN))).isEqualTo("id_a");
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(PREVIEW_COLUMN)))
+ .isEqualTo("content://com.android.keyguard.clock/preview/id_a");
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(THUMBNAIL_COLUMN)))
+ .isEqualTo("content://com.android.keyguard.clock/thumbnail/id_a");
+ cursor.moveToNext();
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(NAME_COLUMN))).isEqualTo("name_b");
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(TITLE_COLUMN))).isEqualTo("title_b");
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(ID_COLUMN))).isEqualTo("id_b");
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(PREVIEW_COLUMN)))
+ .isEqualTo("content://com.android.keyguard.clock/preview/id_b");
+ assertThat(cursor.getString(
+ cursor.getColumnIndex(THUMBNAIL_COLUMN)))
+ .isEqualTo("content://com.android.keyguard.clock/thumbnail/id_b");
+ }
+
+ @Test
+ public void testOpenFile_preview() throws Exception {
+ mClocks.add(ClockInfo.builder()
+ .setId("id")
+ .setPreview(mMockBitmapSupplier)
+ .build());
+ Uri uri = new Uri.Builder()
+ .scheme(CONTENT_SCHEME)
+ .authority(AUTHORITY)
+ .appendPath(PREVIEW)
+ .appendPath("id")
+ .build();
+ mProvider.openFile(uri, "r").close();
+ verify(mMockBitmapSupplier).get();
+ }
+
+ @Test
+ public void testOpenFile_thumbnail() throws Exception {
+ mClocks.add(ClockInfo.builder()
+ .setId("id")
+ .setThumbnail(mMockBitmapSupplier)
+ .build());
+ Uri uri = new Uri.Builder()
+ .scheme(CONTENT_SCHEME)
+ .authority(AUTHORITY)
+ .appendPath(THUMBNAIL)
+ .appendPath("id")
+ .build();
+ mProvider.openFile(uri, "r").close();
+ verify(mMockBitmapSupplier).get();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index e32d48d..2742577 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -168,12 +168,14 @@
// We should have bubbles & their notifs should show in the shade
assertTrue(mBubbleController.hasBubbles());
assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mStatusBarWindowController.getBubbleExpanded());
// Expand the stack
BubbleStackView stackView = mBubbleController.getStackView();
stackView.expandStack();
assertTrue(mBubbleController.isStackExpanded());
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
+ assertTrue(mStatusBarWindowController.getBubbleExpanded());
// Make sure it's no longer in the shade
assertFalse(mRow.getEntry().showInShadeWhenBubble());
@@ -182,6 +184,7 @@
stackView.collapseStack();
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().key);
assertFalse(mBubbleController.isStackExpanded());
+ assertFalse(mStatusBarWindowController.getBubbleExpanded());
}
@Test
@@ -291,11 +294,6 @@
assertTrue(mRow.getEntry().showInShadeWhenBubble());
}
- @Test
- public void testNotificationWithoutChannel() {
- assertFalse(mBubbleController.shouldBubble(mNoChannelRow.getEntry()));
- }
-
static class TestableBubbleController extends BubbleController {
TestableBubbleController(Context context,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
index 1bb7ef4..c0aac7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
@@ -55,11 +55,12 @@
mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
mBubblePadding = res.getDimensionPixelSize(R.dimen.bubble_padding);
mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
+
+ mExpansionPoint = new PointF(100, 100);
}
@Test
public void testExpansionAndCollapse() throws InterruptedException {
- mExpansionPoint = new PointF(100, 100);
Runnable afterExpand = Mockito.mock(Runnable.class);
mExpandedController.expandFromStack(mExpansionPoint, afterExpand);
@@ -77,27 +78,48 @@
Mockito.verify(afterExpand).run();
}
+ @Test
+ public void testOnChildRemoved() throws InterruptedException {
+ Runnable afterExpand = Mockito.mock(Runnable.class);
+ mExpandedController.expandFromStack(mExpansionPoint, afterExpand);
+ waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
+ testExpanded();
+
+ // Remove some views and see if the remaining child views still pass the expansion test.
+ mLayout.removeView(mViews.get(0));
+ mLayout.removeView(mViews.get(3));
+ waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
+ testExpanded();
+ }
+
/** Check that children are in the correct positions for being stacked. */
private void testStackedAtPosition(float x, float y, int offsetMultiplier) {
// Make sure the rest of the stack moved again, including the first bubble not moving, and
// is stacked to the right now that we're on the right side of the screen.
for (int i = 0; i < mLayout.getChildCount(); i++) {
assertEquals(x + i * offsetMultiplier * mStackOffset,
- mViews.get(i).getTranslationX(), 2f);
- assertEquals(y, mViews.get(i).getTranslationY(), 2f);
+ mLayout.getChildAt(i).getTranslationX(), 2f);
+ assertEquals(y, mLayout.getChildAt(i).getTranslationY(), 2f);
+
+ if (i < mMaxRenderedBubbles) {
+ assertEquals(1f, mLayout.getChildAt(i).getAlpha(), .01f);
+ }
}
}
/** Check that children are in the correct positions for being expanded. */
private void testExpanded() {
- // Make sure the rest of the stack moved again, including the first bubble not moving, and
- // is stacked to the right now that we're on the right side of the screen.
- for (int i = 0; i < mLayout.getChildCount(); i++) {
+ // Check all the visible bubbles to see if they're in the right place.
+ for (int i = 0; i < Math.min(mLayout.getChildCount(), mMaxRenderedBubbles); i++) {
assertEquals(mBubblePadding + (i * (mBubbleSize + mBubblePadding)),
- mViews.get(i).getTranslationX(),
+ mLayout.getChildAt(i).getTranslationX(),
2f);
assertEquals(mBubblePadding + mCutoutInsetSize,
- mViews.get(i).getTranslationY(), 2f);
+ mLayout.getChildAt(i).getTranslationY(), 2f);
+
+ if (i < mMaxRenderedBubbles) {
+ assertEquals(1f, mLayout.getChildAt(i).getAlpha(), .01f);
+ }
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
index 5be991f..c3214040 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
@@ -25,6 +25,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
import android.os.SystemClock;
import android.support.test.filters.SmallTest;
@@ -100,9 +101,9 @@
mTestableController.setRemoveImmediately(true);
mLayout.removeView(mViews.get(1));
mLayout.removeView(mViews.get(2));
- Mockito.verify(mTestableController).onChildToBeRemoved(
+ Mockito.verify(mTestableController).onChildRemoved(
eq(mViews.get(1)), eq(1), any());
- Mockito.verify(mTestableController).onChildToBeRemoved(
+ Mockito.verify(mTestableController).onChildRemoved(
eq(mViews.get(2)), eq(1), any());
// Make sure we still get view added notifications after doing some removals.
@@ -345,6 +346,24 @@
assertTrue(mViews.get(0).getTranslationY() < 1000);
}
+ @Test
+ public void testSetChildVisibility() throws InterruptedException {
+ mLayout.setController(mTestableController);
+ addOneMoreThanRenderLimitBubbles();
+
+ // The last view should have been set to GONE by the controller, since we added one more
+ // than the limit and it got pushed off. None of the first children should have been set
+ // VISIBLE, since they would have been animated in by onChildAdded.
+ Mockito.verify(mTestableController).setChildVisibility(
+ mViews.get(mViews.size() - 1), 5, View.GONE);
+ Mockito.verify(mTestableController, never()).setChildVisibility(
+ any(View.class), anyInt(), eq(View.VISIBLE));
+
+ // Remove the first view, which should cause the last view to become visible again.
+ mLayout.removeView(mViews.get(0));
+ Mockito.verify(mTestableController).setChildVisibility(
+ mViews.get(mViews.size() - 1), 4, View.VISIBLE);
+ }
/** Standard test of chained translation animations. */
private void testChainedTranslationAnimations() throws InterruptedException {
@@ -440,10 +459,15 @@
void onChildAdded(View child, int index) {}
@Override
- void onChildToBeRemoved(View child, int index, Runnable actuallyRemove) {
+ void onChildRemoved(View child, int index, Runnable finishRemoval) {
if (mRemoveImmediately) {
- actuallyRemove.run();
+ finishRemoval.run();
}
}
+
+ @Override
+ protected void setChildVisibility(View child, int index, int visibility) {
+ super.setChildVisibility(child, index, visibility);
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
index ec2319d..9eb94f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
@@ -44,11 +44,12 @@
private DozeWallpaperState mDozeWallpaperState;
@Mock IWallpaperManager mIWallpaperManager;
@Mock DozeParameters mDozeParameters;
+ @Mock DozeMachine mMachine;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mDozeParameters);
+ mDozeWallpaperState = new DozeWallpaperState(mMachine, mIWallpaperManager, mDozeParameters);
}
@Test
@@ -108,14 +109,28 @@
}
@Test
- public void testTransitionTo_pulseIsAmbientMode() throws RemoteException {
+ public void testTransitionTo_notificationPulseIsAmbientMode() throws RemoteException {
+ when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_NOTIFICATION);
mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
DozeMachine.State.DOZE_PULSING);
verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(0L));
}
@Test
+ public void testTransitionTo_wakeFromPulseIsNotAmbientMode() throws RemoteException {
+ when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN);
+ mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD,
+ DozeMachine.State.DOZE_REQUEST_PULSE);
+ reset(mIWallpaperManager);
+
+ mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
+ DozeMachine.State.DOZE_PULSING);
+ verify(mIWallpaperManager).setInAmbientMode(eq(false), anyLong());
+ }
+
+ @Test
public void testTransitionTo_animatesWhenWakingUpFromPulse() throws RemoteException {
+ when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_NOTIFICATION);
mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
DozeMachine.State.DOZE_PULSING);
reset(mIWallpaperManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java
index 8503962..374a73c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java
@@ -16,27 +16,35 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.support.test.filters.SmallTest;
+import android.telephony.SubscriptionManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
import android.view.View;
+import com.android.keyguard.CarrierTextController.CarrierTextCallbackInfo;
import com.android.systemui.R;
import com.android.systemui.R.id;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@@ -68,4 +76,117 @@
// Verify Settings wasn't launched.
verify(mActivityStarter, never()).startActivity(any(), anyBoolean());
}
+
+ @Test // throws no Exception
+ public void testUpdateCarrierText_sameLengts() {
+ QSFooterImpl spiedFooter = Mockito.spy(mFooter);
+ when(spiedFooter.getSlotIndex(anyInt())).thenAnswer(
+ new Answer<Integer>() {
+ @Override
+ public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
+ return invocationOnMock.getArgument(0);
+ }
+ });
+
+ // listOfCarriers length 1, subscriptionIds length 1, anySims false
+ CarrierTextCallbackInfo c1 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{""},
+ false,
+ new int[]{0});
+ spiedFooter.updateCarrierInfo(c1);
+
+ // listOfCarriers length 1, subscriptionIds length 1, anySims true
+ CarrierTextCallbackInfo c2 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{""},
+ true,
+ new int[]{0});
+ spiedFooter.updateCarrierInfo(c2);
+
+ // listOfCarriers length 2, subscriptionIds length 2, anySims false
+ CarrierTextCallbackInfo c3 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{"", ""},
+ false,
+ new int[]{0, 1});
+ spiedFooter.updateCarrierInfo(c3);
+
+ // listOfCarriers length 2, subscriptionIds length 2, anySims true
+ CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{"", ""},
+ true,
+ new int[]{0, 1});
+ spiedFooter.updateCarrierInfo(c4);
+ }
+
+ @Test // throws no Exception
+ public void testUpdateCarrierText_differentLength() {
+ QSFooterImpl spiedFooter = Mockito.spy(mFooter);
+ when(spiedFooter.getSlotIndex(anyInt())).thenAnswer(
+ new Answer<Integer>() {
+ @Override
+ public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
+ return invocationOnMock.getArgument(0);
+ }
+ });
+
+ // listOfCarriers length 2, subscriptionIds length 1, anySims false
+ CarrierTextCallbackInfo c1 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{"", ""},
+ false,
+ new int[]{0});
+ spiedFooter.updateCarrierInfo(c1);
+
+ // listOfCarriers length 2, subscriptionIds length 1, anySims true
+ CarrierTextCallbackInfo c2 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{"", ""},
+ true,
+ new int[]{0});
+ spiedFooter.updateCarrierInfo(c2);
+
+ // listOfCarriers length 1, subscriptionIds length 2, anySims false
+ CarrierTextCallbackInfo c3 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{""},
+ false,
+ new int[]{0, 1});
+ spiedFooter.updateCarrierInfo(c3);
+
+ // listOfCarriers length 1, subscriptionIds length 2, anySims true
+ CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{""},
+ true,
+ new int[]{0, 1});
+ spiedFooter.updateCarrierInfo(c4);
+ }
+
+ @Test // throws no Exception
+ public void testUpdateCarrierText_invalidSim() {
+ QSFooterImpl spiedFooter = Mockito.spy(mFooter);
+ when(spiedFooter.getSlotIndex(anyInt())).thenReturn(
+ SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+ CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo(
+ "",
+ new CharSequence[]{"", ""},
+ true,
+ new int[]{0, 1});
+ spiedFooter.updateCarrierInfo(c4);
+ }
+
+ @Test // throws no Exception
+ public void testSetMobileDataIndicators_invalidSim() {
+ QSFooterImpl spiedFooter = Mockito.spy(mFooter);
+ when(spiedFooter.getSlotIndex(anyInt())).thenReturn(
+ SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+ spiedFooter.setMobileDataIndicators(
+ mock(NetworkController.IconState.class),
+ mock(NetworkController.IconState.class),
+ 0, 0, true, true, "", "", true, 0, true);
+ }
+
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index f34e1a6..31cd280 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -98,8 +98,8 @@
@Test
public void testSendSmartReply_updatesRemoteInput() {
- mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, false,
- MetricsEvent.LOCATION_UNKNOWN);
+ mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
+ MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);
// Sending smart reply should make calls to NotificationEntryManager
// to update the notification with reply and spinner.
@@ -109,48 +109,49 @@
@Test
public void testSendSmartReply_logsToStatusBar() throws RemoteException {
- mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, false,
- MetricsEvent.LOCATION_UNKNOWN);
+ mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
+ MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);
// Check we log the result to the status bar service.
verify(mIStatusBarService).onNotificationSmartReplySent(mSbn.getKey(),
- TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, false, MetricsEvent.LOCATION_UNKNOWN);
+ TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, MetricsEvent.LOCATION_UNKNOWN, false);
}
@Test
- public void testSendSmartReply_logsToStatusBar_generatedByAssistant() throws RemoteException {
- mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, true,
- MetricsEvent.LOCATION_UNKNOWN);
+ public void testSendSmartReply_logsToStatusBar_modifiedBeforeSending() throws RemoteException {
+ mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
+ MetricsEvent.LOCATION_UNKNOWN, true /* modifiedBeforeSending */);
// Check we log the result to the status bar service.
verify(mIStatusBarService).onNotificationSmartReplySent(mSbn.getKey(),
- TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, true, MetricsEvent.LOCATION_UNKNOWN);
+ TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, MetricsEvent.LOCATION_UNKNOWN, true);
}
@Test
public void testShowSmartSuggestions_logsToStatusBar() throws RemoteException {
final boolean generatedByAsssistant = true;
+ final boolean editBeforeSending = true;
mSmartReplyController.smartSuggestionsAdded(mEntry, TEST_CHOICE_COUNT, TEST_ACTION_COUNT,
- generatedByAsssistant);
+ generatedByAsssistant, editBeforeSending);
// Check we log the result to the status bar service.
verify(mIStatusBarService).onNotificationSmartSuggestionsAdded(mSbn.getKey(),
- TEST_CHOICE_COUNT, TEST_ACTION_COUNT, generatedByAsssistant);
+ TEST_CHOICE_COUNT, TEST_ACTION_COUNT, generatedByAsssistant, editBeforeSending);
}
@Test
public void testSendSmartReply_reportsSending() {
- mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, false,
- MetricsEvent.LOCATION_UNKNOWN);
+ mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
+ MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);
assertTrue(mSmartReplyController.isSendingSmartReply(mSbn.getKey()));
}
@Test
public void testSendingSmartReply_afterRemove_shouldReturnFalse() {
- mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, false,
- MetricsEvent.LOCATION_UNKNOWN);
+ mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
+ MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);
mSmartReplyController.stopSending(mEntry);
assertFalse(mSmartReplyController.isSendingSmartReply(mSbn.getKey()));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 9ce6ae1..cad1a96 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -45,8 +45,11 @@
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.util.ArraySet;
import android.widget.FrameLayout;
+import androidx.annotation.NonNull;
+
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Dependency;
import com.android.systemui.ForegroundServiceController;
@@ -84,6 +87,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -166,7 +170,7 @@
0,
NotificationManager.IMPORTANCE_DEFAULT,
null, null,
- null, null, null, true, sentiment, false, -1, false, null, null);
+ null, null, null, true, sentiment, false, -1, false, null, null, false);
return true;
}).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
}
@@ -185,7 +189,7 @@
null, null,
null, null, null, true,
NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL, false, -1,
- false, smartActions, null);
+ false, smartActions, null, false);
return true;
}).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
}
@@ -348,28 +352,6 @@
}
@Test
- public void testRemoveNotification_blockedByLifetimeExtender() {
- com.android.systemui.util.Assert.isNotMainThread();
-
- NotificationLifetimeExtender extender = mock(NotificationLifetimeExtender.class);
- when(extender.shouldExtendLifetime(mEntry)).thenReturn(true);
-
- ArrayList<NotificationLifetimeExtender> extenders = mEntryManager.getLifetimeExtenders();
- extenders.clear();
- extenders.add(extender);
-
- mEntry.setRow(mRow);
- mEntryManager.getNotificationData().add(mEntry);
-
- mEntryManager.removeNotification(mSbn.getKey(), mRankingMap);
-
- assertNotNull(mEntryManager.getNotificationData().get(mSbn.getKey()));
- verify(extender).setShouldManageLifetime(mEntry, true /* shouldManage */);
- verify(mEntryListener, never()).onEntryRemoved(
- mEntry, null, false /* removedByUser */);
- }
-
- @Test
public void testRemoveNotification_onEntryRemoveNotFiredIfEntryDoesntExist() {
com.android.systemui.util.Assert.isNotMainThread();
@@ -453,10 +435,142 @@
assertEquals("action", mEntry.systemGeneratedSmartActions.get(0).title);
}
+ @Test
+ public void testLifetimeExtenders_ifNotificationIsRetainedItIsntRemoved() {
+ // GIVEN an entry manager with a notification
+ mEntryManager.setRowBinder(mMockedRowBinder);
+ mEntryManager.getNotificationData().add(mEntry);
+
+ // GIVEN a lifetime extender that always tries to extend lifetime
+ NotificationLifetimeExtender extender = mock(NotificationLifetimeExtender.class);
+ when(extender.shouldExtendLifetime(mEntry)).thenReturn(true);
+ mEntryManager.addNotificationLifetimeExtender(extender);
+
+ // WHEN the notification is removed
+ mEntryManager.removeNotification(mEntry.key, mRankingMap);
+
+ // THEN the extender is asked to manage the lifetime
+ verify(extender).setShouldManageLifetime(mEntry, true);
+ // THEN the notification is retained
+ assertNotNull(mEntryManager.getNotificationData().get(mSbn.getKey()));
+ verify(mEntryListener, never()).onEntryRemoved(mEntry, null, false);
+ }
+
+ @Test
+ public void testLifetimeExtenders_whenRetentionEndsNotificationIsRemoved() {
+ // GIVEN an entry manager with a notification whose life has been extended
+ mEntryManager.setRowBinder(mMockedRowBinder);
+ mEntryManager.getNotificationData().add(mEntry);
+ final FakeNotificationLifetimeExtender extender = new FakeNotificationLifetimeExtender();
+ mEntryManager.addNotificationLifetimeExtender(extender);
+ mEntryManager.removeNotification(mEntry.key, mRankingMap);
+ assertTrue(extender.isManaging(mEntry.key));
+
+ // WHEN the extender finishes its extension
+ extender.setExtendLifetimes(false);
+ extender.getCallback().onSafeToRemove(mEntry.key);
+
+ // THEN the notification is removed
+ assertNull(mEntryManager.getNotificationData().get(mSbn.getKey()));
+ verify(mEntryListener).onEntryRemoved(mEntry, null, false);
+ }
+
+ @Test
+ public void testLifetimeExtenders_whenNotificationUpdatedRetainersAreCanceled() {
+ // GIVEN an entry manager with a notification whose life has been extended
+ mEntryManager.setRowBinder(mMockedRowBinder);
+ mEntryManager.getNotificationData().add(mEntry);
+ NotificationLifetimeExtender extender = mock(NotificationLifetimeExtender.class);
+ when(extender.shouldExtendLifetime(mEntry)).thenReturn(true);
+ mEntryManager.addNotificationLifetimeExtender(extender);
+ mEntryManager.removeNotification(mEntry.key, mRankingMap);
+
+ // WHEN the notification is updated
+ mEntryManager.updateNotification(mEntry.notification, mRankingMap);
+
+ // THEN the lifetime extension is canceled
+ verify(extender).setShouldManageLifetime(mEntry, false);
+ }
+
+ @Test
+ public void testLifetimeExtenders_whenNewExtenderTakesPrecedenceOldExtenderIsCanceled() {
+ // GIVEN an entry manager with a notification
+ mEntryManager.setRowBinder(mMockedRowBinder);
+ mEntryManager.getNotificationData().add(mEntry);
+
+ // GIVEN two lifetime extenders, the first which never extends and the second which
+ // always extends
+ NotificationLifetimeExtender extender1 = mock(NotificationLifetimeExtender.class);
+ when(extender1.shouldExtendLifetime(mEntry)).thenReturn(false);
+ NotificationLifetimeExtender extender2 = mock(NotificationLifetimeExtender.class);
+ when(extender2.shouldExtendLifetime(mEntry)).thenReturn(true);
+ mEntryManager.addNotificationLifetimeExtender(extender1);
+ mEntryManager.addNotificationLifetimeExtender(extender2);
+
+ // GIVEN a notification was lifetime-extended and extender2 is managing it
+ mEntryManager.removeNotification(mEntry.key, mRankingMap);
+ verify(extender1, never()).setShouldManageLifetime(mEntry, true);
+ verify(extender2).setShouldManageLifetime(mEntry, true);
+
+ // WHEN the extender1 changes its mind and wants to extend the lifetime of the notif
+ when(extender1.shouldExtendLifetime(mEntry)).thenReturn(true);
+ mEntryManager.removeNotification(mEntry.key, mRankingMap);
+
+ // THEN extender2 stops managing the notif and extender1 starts managing it
+ verify(extender1).setShouldManageLifetime(mEntry, true);
+ verify(extender2).setShouldManageLifetime(mEntry, false);
+ }
+
private Notification.Action createAction() {
return new Notification.Action.Builder(
Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
"action",
PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0)).build();
}
+
+ private static class FakeNotificationLifetimeExtender implements NotificationLifetimeExtender {
+ private NotificationSafeToRemoveCallback mCallback;
+ private boolean mExtendLifetimes = true;
+ private Set<String> mManagedNotifs = new ArraySet<>();
+
+ @Override
+ public void setCallback(@NonNull NotificationSafeToRemoveCallback callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public boolean shouldExtendLifetime(@NonNull NotificationEntry entry) {
+ return mExtendLifetimes;
+ }
+
+ @Override
+ public void setShouldManageLifetime(
+ @NonNull NotificationEntry entry,
+ boolean shouldManage) {
+ final boolean hasEntry = mManagedNotifs.contains(entry.key);
+ if (shouldManage) {
+ if (hasEntry) {
+ throw new RuntimeException("Already managing this entry: " + entry.key);
+ }
+ mManagedNotifs.add(entry.key);
+ } else {
+ if (!hasEntry) {
+ throw new RuntimeException("Not managing this entry: " + entry.key);
+ }
+ mManagedNotifs.remove(entry.key);
+ }
+ }
+
+ public void setExtendLifetimes(boolean extendLifetimes) {
+ mExtendLifetimes = extendLifetimes;
+ }
+
+ public NotificationSafeToRemoveCallback getCallback() {
+ return mCallback;
+ }
+
+ public boolean isManaging(String notificationKey) {
+ return mManagedNotifs.contains(notificationKey);
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index b507692..ba2aec0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -377,7 +377,7 @@
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
outRanking.canShowBadge(), outRanking.getUserSentiment(), true,
- -1, false, null, null);
+ -1, false, null, null, outRanking.canBubble());
} else if (key.equals(TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY)) {
outRanking.populate(key, outRanking.getRank(),
outRanking.matchesInterruptionFilter(),
@@ -385,7 +385,7 @@
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
outRanking.canShowBadge(), outRanking.getUserSentiment(), true, -1,
- false, null, null);
+ false, null, null, outRanking.canBubble());
} else {
outRanking.populate(key, outRanking.getRank(),
outRanking.matchesInterruptionFilter(),
@@ -393,7 +393,7 @@
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), NOTIFICATION_CHANNEL, null, null,
outRanking.canShowBadge(), outRanking.getUserSentiment(), false, -1,
- false, null, null);
+ false, null, null, outRanking.canBubble());
}
return true;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 2a64445..105bd9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -18,7 +18,6 @@
import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_NONE;
@@ -1067,7 +1066,7 @@
anyString(), eq(TEST_UID), updated.capture());
assertTrue((updated.getValue().getUserLockedFields()
& USER_LOCKED_IMPORTANCE) != 0);
- assertEquals(IMPORTANCE_HIGH, updated.getValue().getImportance());
+ assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
}
@Test
@@ -1111,7 +1110,7 @@
anyString(), eq(TEST_UID), updated.capture());
assertTrue((updated.getValue().getUserLockedFields()
& USER_LOCKED_IMPORTANCE) != 0);
- assertEquals(IMPORTANCE_HIGH, updated.getValue().getImportance());
+ assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
index 382dde9..dbf00a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
@@ -23,6 +23,7 @@
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_DEAD_ZONE;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
+import static com.android.systemui.statusbar.phone.NavigationBarView.WINDOW_TARGET_BOTTOM;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -63,7 +64,6 @@
public class QuickStepControllerTest extends SysuiTestCase {
private static final int NAVBAR_WIDTH = 1000;
private static final int NAVBAR_HEIGHT = 300;
- private static final int EDGE_THRESHOLD = 100;
private QuickStepController mController;
private NavigationBarView mNavigationBarView;
@@ -77,8 +77,6 @@
MockitoAnnotations.initMocks(this);
final ButtonDispatcher backButton = mock(ButtonDispatcher.class);
mResources = mock(Resources.class);
- doReturn(EDGE_THRESHOLD).when(mResources)
- .getDimensionPixelSize(R.dimen.navigation_bar_edge_swipe_threshold);
mProxyService = mock(OverviewProxyService.class);
mProxy = mock(IOverviewProxy.Stub.class);
@@ -95,6 +93,7 @@
doReturn(true).when(mNavigationBarView).isNotificationsFullyCollapsed();
doReturn(true).when(mNavigationBarView).isQuickScrubEnabled();
doReturn(HIT_TARGET_NONE).when(mNavigationBarView).getDownHitTarget();
+ doReturn(WINDOW_TARGET_BOTTOM).when(mNavigationBarView).getWindowTarget();
doReturn(backButton).when(mNavigationBarView).getBackButton();
doReturn(mResources).when(mNavigationBarView).getResources();
doReturn(mContext).when(mNavigationBarView).getContext();
@@ -196,10 +195,8 @@
NavigationGestureAction swipeDown = mockAction(true);
NavigationGestureAction swipeLeft = mockAction(true);
NavigationGestureAction swipeRight = mockAction(true);
- NavigationGestureAction swipeLeftFromEdge = mockAction(true);
- NavigationGestureAction swipeRightFromEdge = mockAction(true);
- mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight, swipeLeftFromEdge,
- swipeRightFromEdge);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
+ null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
// Swipe Up
assertGestureTriggersAction(swipeUp, 1, 100, 5, 1);
@@ -209,10 +206,6 @@
assertGestureTriggersAction(swipeLeft, NAVBAR_WIDTH / 2, 1, 5, 1);
// Swipe Right
assertGestureTriggersAction(swipeRight, NAVBAR_WIDTH / 2, 1, NAVBAR_WIDTH, 5);
- // Swipe Left from Edge
- assertGestureTriggersAction(swipeLeftFromEdge, NAVBAR_WIDTH, 1, 5, 1);
- // Swipe Right from Edge
- assertGestureTriggersAction(swipeRightFromEdge, 0, 1, NAVBAR_WIDTH, 5);
}
@Test
@@ -224,10 +217,8 @@
NavigationGestureAction swipeDown = mockAction(true);
NavigationGestureAction swipeLeft = mockAction(true);
NavigationGestureAction swipeRight = mockAction(true);
- NavigationGestureAction swipeLeftFromEdge = mockAction(true);
- NavigationGestureAction swipeRightFromEdge = mockAction(true);
- mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight, swipeLeftFromEdge,
- swipeRightFromEdge);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
+ null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
// In landscape
mController.setBarState(false /* isRTL */, NAV_BAR_RIGHT);
@@ -240,10 +231,6 @@
assertGestureTriggersAction(swipeUp, 100, 1, 5, 1);
// Swipe Right
assertGestureTriggersAction(swipeDown, 1, 1, 100, 5);
- // Swipe Up from Edge
- assertGestureTriggersAction(swipeRightFromEdge, 1, NAVBAR_WIDTH, 5, 0);
- // Swipe Down from Edge
- assertGestureTriggersAction(swipeLeftFromEdge, 0, 1, 0, NAVBAR_WIDTH);
}
@Test
@@ -256,10 +243,8 @@
NavigationGestureAction swipeDown = mockAction(true);
NavigationGestureAction swipeLeft = mockAction(true);
NavigationGestureAction swipeRight = mockAction(true);
- NavigationGestureAction swipeLeftFromEdge = mockAction(true);
- NavigationGestureAction swipeRightFromEdge = mockAction(true);
- mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight, swipeLeftFromEdge,
- swipeRightFromEdge);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
+ null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
// Swipe Up
assertGestureTriggersAction(swipeLeft, 1, NAVBAR_WIDTH / 2, 5, 1);
@@ -269,10 +254,6 @@
assertGestureTriggersAction(swipeDown, 100, 1, 5, 1);
// Swipe Right
assertGestureTriggersAction(swipeUp, 1, 1, 100, 5);
- // Swipe Up from Edge
- assertGestureTriggersAction(swipeLeftFromEdge, 1, NAVBAR_WIDTH, 5, 0);
- // Swipe Down from Edge
- assertGestureTriggersAction(swipeRightFromEdge, 0, 1, 0, NAVBAR_WIDTH);
}
@Test
@@ -286,10 +267,8 @@
NavigationGestureAction swipeDown = mockAction(true);
NavigationGestureAction swipeLeft = mockAction(true);
NavigationGestureAction swipeRight = mockAction(true);
- NavigationGestureAction swipeLeftFromEdge = mockAction(true);
- NavigationGestureAction swipeRightFromEdge = mockAction(true);
- mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight, swipeLeftFromEdge,
- swipeRightFromEdge);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
+ null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
// Swipe Up in RTL
assertGestureTriggersAction(swipeUp, 1, 100, 5, 1);
@@ -299,10 +278,6 @@
assertGestureTriggersAction(swipeRight, NAVBAR_WIDTH / 2, 1, 5, 1);
// Swipe Right in RTL
assertGestureTriggersAction(swipeLeft, NAVBAR_WIDTH / 2, 1, NAVBAR_WIDTH, 0);
- // Swipe Left from Edge
- assertGestureTriggersAction(swipeRightFromEdge, NAVBAR_WIDTH, 1, 5, 1);
- // Swipe Right from Edge
- assertGestureTriggersAction(swipeLeftFromEdge, 0, 1, NAVBAR_WIDTH, 5);
}
@Test
@@ -316,10 +291,8 @@
NavigationGestureAction swipeDown = mockAction(true);
NavigationGestureAction swipeLeft = mockAction(true);
NavigationGestureAction swipeRight = mockAction(true);
- NavigationGestureAction swipeLeftFromEdge = mockAction(true);
- NavigationGestureAction swipeRightFromEdge = mockAction(true);
- mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight, swipeLeftFromEdge,
- swipeRightFromEdge);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
+ null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
// Swipe Up
assertGestureTriggersAction(swipeLeft, 1, NAVBAR_WIDTH / 2, 5, 1);
@@ -329,10 +302,6 @@
assertGestureTriggersAction(swipeUp, 100, 1, 5, 1);
// Swipe Right
assertGestureTriggersAction(swipeDown, 1, 1, 100, 5);
- // Swipe Up from Edge
- assertGestureTriggersAction(swipeLeftFromEdge, 1, NAVBAR_WIDTH, 5, 0);
- // Swipe Down from Edge
- assertGestureTriggersAction(swipeRightFromEdge, 0, 1, 0, NAVBAR_WIDTH);
}
@Test
@@ -346,10 +315,8 @@
NavigationGestureAction swipeDown = mockAction(true);
NavigationGestureAction swipeLeft = mockAction(true);
NavigationGestureAction swipeRight = mockAction(true);
- NavigationGestureAction swipeLeftFromEdge = mockAction(true);
- NavigationGestureAction swipeRightFromEdge = mockAction(true);
- mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight, swipeLeftFromEdge,
- swipeRightFromEdge);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
+ null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
// Swipe Up
assertGestureTriggersAction(swipeRight, 1, NAVBAR_WIDTH / 2, 5, 1);
@@ -359,10 +326,6 @@
assertGestureTriggersAction(swipeDown, 100, 1, 5, 1);
// Swipe Right
assertGestureTriggersAction(swipeUp, 1, 1, 100, 5);
- // Swipe Up from Edge
- assertGestureTriggersAction(swipeRightFromEdge, 1, NAVBAR_WIDTH, 5, 0);
- // Swipe Down from Edge
- assertGestureTriggersAction(swipeLeftFromEdge, 0, 1, 0, NAVBAR_WIDTH);
}
@Test
@@ -602,25 +565,6 @@
assertGestureDragsHitTargetAllDirections(buttonView, true /* isRTL */, NAV_BAR_LEFT);
}
- @Test
- public void testNoEdgeActionsTriggerNormalActions() {
- doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getWidth();
- doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getHeight();
-
- NavigationGestureAction swipeUp = mockAction(true);
- NavigationGestureAction swipeDown = mockAction(true);
- NavigationGestureAction swipeLeft = mockAction(true);
- NavigationGestureAction swipeRight = mockAction(true);
- mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
- null /* swipeLeftFromEdgeAction */,
- null /* swipeLeftFromEdgeAction */);
-
- // Swipe Left from Edge
- assertGestureTriggersAction(swipeLeft, NAVBAR_WIDTH, 1, 5, 1);
- // Swipe Right from Edge
- assertGestureTriggersAction(swipeRight, 0, 1, NAVBAR_WIDTH, 5);
- }
-
private void assertGestureDragsHitTargetAllDirections(View buttonView, boolean isRTL,
int navPos) {
mController.setBarState(isRTL, navPos);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 49fcafd..036e57acb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -655,13 +655,19 @@
DozeLog.REASON_SENSOR_DOUBLE_TAP,
DozeLog.REASON_SENSOR_TAP));
+ doAnswer(invocation -> {
+ DozeHost.PulseCallback callback = invocation.getArgument(0);
+ callback.onPulseStarted();
+ return null;
+ }).when(mDozeScrimController).pulse(any(), anyInt());
+
for (int i = 0; i < DozeLog.REASONS; i++) {
reset(mKeyguardUpdateMonitor);
mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class), i);
if (reasonsWantingAuth.contains(i)) {
- verify(mKeyguardUpdateMonitor).onAuthInterruptDetected();
+ verify(mKeyguardUpdateMonitor).onAuthInterruptDetected(eq(true));
} else if (reasonsSkippingAuth.contains(i) || reasonsThatDontPulse.contains(i)) {
- verify(mKeyguardUpdateMonitor, never()).onAuthInterruptDetected();
+ verify(mKeyguardUpdateMonitor, never()).onAuthInterruptDetected(eq(true));
} else {
throw new AssertionError("Reason " + i + " isn't specified as wanting or skipping"
+ " passive auth. Please consider how this pulse reason should behave.");
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index ed98c62..568ff55f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -96,7 +96,7 @@
RemoteInput input = new RemoteInput.Builder(TEST_RESULT_KEY).build();
view.setPendingIntent(pendingIntent);
- view.setRemoteInput(new RemoteInput[]{input}, input);
+ view.setRemoteInput(new RemoteInput[]{input}, input, null /* editedSuggestionInfo */);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 5570122..6793eca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -191,15 +191,7 @@
setSmartReplies(TEST_CHOICES);
mView.getChildAt(2).performClick();
verify(mLogger).smartReplySent(mEntry, 2, TEST_CHOICES[2],
- false /* generatedByAsssitant */, MetricsEvent.LOCATION_UNKNOWN);
- }
-
- @Test
- public void testSendSmartReply_controllerCalled_generatedByAssistant() {
- setSmartReplies(TEST_CHOICES, true);
- mView.getChildAt(2).performClick();
- verify(mLogger).smartReplySent(mEntry, 2, TEST_CHOICES[2],
- true /* generatedByAsssitant */, MetricsEvent.LOCATION_UNKNOWN);
+ MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);
}
@Test
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index 9fb3306..1294dbb 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -16,16 +16,39 @@
include $(CLEAR_VARS)
LOCAL_MODULE := frameworks-base-overlays
+LOCAL_REQUIRED_MODULES := \
+ AccentColorBlackOverlay \
+ AccentColorGreenOverlay \
+ AccentColorPurpleOverlay \
+ DisplayCutoutEmulationCornerOverlay \
+ DisplayCutoutEmulationDoubleOverlay \
+ DisplayCutoutEmulationTallOverlay \
+ FontNotoSerifSourceOverlay \
+ IconPackCircularAndroidOverlay \
+ IconPackCircularSettingsOverlay \
+ IconPackCircularSystemUIOverlay \
+ IconPackFilledAndroidOverlay \
+ IconPackFilledSettingsOverlay \
+ IconPackFilledSystemUIOverlay \
+ IconPackRoundedAndroidOverlay \
+ IconPackRoundedSettingsOverlay \
+ IconPackRoundedSystemUIOverlay \
+ IconShapeRoundedRectOverlay \
+ IconShapeSquareOverlay \
+ IconShapeSquircleOverlay \
+ IconShapeTeardropOverlay
+include $(BUILD_PHONY_PACKAGE)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := frameworks-base-overlays-debug
LOCAL_REQUIRED_MODULES := \
ExperimentNavigationBarFloatingOverlay \
ExperimentNavigationBarDefaultOverlay \
ExperimentNavigationBarSlimOverlay32 \
ExperimentNavigationBarSlimOverlay40 \
ExperimentNavigationBarLargeOverlay56 \
- ExperimentNavigationBarLargeOverlay64 \
- IconShapeSquareOverlay \
+ ExperimentNavigationBarLargeOverlay64
include $(BUILD_PHONY_PACKAGE)
-
include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/Android.mk b/packages/overlays/IconPackCircularSettingsOverlay/Android.mk
new file mode 100644
index 0000000..ad7324d
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2019, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := IconPackCircularSettings
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := IconPackCircularSettingsOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/AndroidManifest.xml b/packages/overlays/IconPackCircularSettingsOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..c1a5698
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.icon_pack.circular.settings"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="com.android.settings" android:category="android.theme.customization.icon_pack.settings" android:priority="1"/>
+ <application android:label="Circular" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml
new file mode 100644
index 0000000..dbac48d
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml
@@ -0,0 +1,54 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M6,4A2,2,0,0,0,6,8H7.5A0.5 0.5 ,0,0,0,8,7.5V6A2,2,0,0,0,6,4Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,8h1.5a0.5 0.5 ,0,0,0,0.5-0.5V6a2,2,0,1,0-2,2Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M20,6a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M6,14H7.5a0.5 0.5 ,0,0,0,0.5-0.5V12a2,2,0,1,0-2,2Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,14h1.5a0.5 0.5 ,0,0,0,0.5-0.5V12a2,2,0,1,0-2,2Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M20,12a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M6,20H7.5a0.5 0.5 ,0,0,0,0.5-0.5V18a2,2,0,1,0-2,2Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,20h1.5a0.5 0.5 ,0,0,0,0.5-0.5V18a2,2,0,1,0-2,2Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M20,18a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
new file mode 100644
index 0000000..a407bd6
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -0,0 +1,36 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M2,16.5A2.5,2.5,0,0,0,4.5,19h2a0.5 0.5 ,0,0,0,0-1h-2A1.5,1.5,0,0,1,3,16.5v-9A1.5,1.5,0,0,1,4.5,6h17a0.5 0.5 ,0,0,0,0-1H4.5A2.5,2.5,0,0,0,2,7.5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M14,16a3,3,0,1,0-3,3A3,3,0,0,0,14,16ZM9,16a2,2,0,1,1,2,2A2,2,0,0,1,9,16Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M22,17V10a2,2,0,0,0-2-2H17a2,2,0,0,0-2,2v7a2,2,0,0,0,2,2h3A2,2,0,0,0,22,17Zm-6,0V10a1,1,0,0,1,1-1h3a1,1,0,0,1,1,1v7a1,1,0,0,1-1,1H17A1,1,0,0,1,16,17Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml
new file mode 100644
index 0000000..c906847
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml
@@ -0,0 +1,36 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,22h0A10,10,0,0,0,22,12v0A10,10,0,1,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M8.62,9.65a0.5 0.5 ,0,0,0,0.61-0.37,2.94,2.94,0,0,1,5-1.41A2.64,2.64,0,0,1,15,10a2.27,2.27,0,0,1-1,1.69l-0.44 0.26 a3.21,3.21,0,0,0-1.91,2.47A0.49 0.49 ,0,0,0,12,15h0.08a0.5 0.5 ,0,0,0,0.49-0.42A2.25,2.25,0,0,1,14,12.81l0.5-0.29A3.27,3.27,0,0,0,16,10.09,3.62,3.62,0,0,0,14.9,7.16a4,4,0,0,0-5.6,0A4.06,4.06,0,0,0,8.25,9.05 0.5 0.5,0,0,0,8.62,9.65Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 16.25 C 12.4142135624 16.25 12.75 16.5857864376 12.75 17 C 12.75 17.4142135624 12.4142135624 17.75 12 17.75 C 11.5857864376 17.75 11.25 17.4142135624 11.25 17 C 11.25 16.5857864376 11.5857864376 16.25 12 16.25 Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml
new file mode 100644
index 0000000..f3419d4
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -0,0 +1,36 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15,22a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H9A3,3,0,0,0,6,5V19a3,3,0,0,0,3,3ZM7,6H17V18H7ZM9,3h6a2,2,0,0,1,2,2H7A2,2,0,0,1,9,3ZM7,19H17a2,2,0,0,1-2,2H9A2,2,0,0,1,7,19Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,10.5a0.5 0.5 ,0,0,0-0.5 0.5 v4.5a0.5 0.5 ,0,0,0,1,0V11A0.5 0.5 ,0,0,0,12,10.5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 8 C 12.4142135624 8 12.75 8.33578643763 12.75 8.75 C 12.75 9.16421356237 12.4142135624 9.5 12 9.5 C 11.5857864376 9.5 11.25 9.16421356237 11.25 8.75 C 11.25 8.33578643763 11.5857864376 8 12 8 Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml
new file mode 100644
index 0000000..8a8ddec
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -0,0 +1,42 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M21,5.35A0.51 0.51 ,0,0,0,20.37,5,37.25,37.25,0,0,1,3.63,5,0.51 0.51 ,0,0,0,3,5.35 0.51 0.51,0,0,0,3.37,6,32.05,32.05,0,0,0,9,6.87V20a0.5 0.5 ,0,0,0,1,0V13.5h4V20a0.5 0.5 ,0,0,0,1,0V6.87A32.05,32.05,0,0,0,20.63,6,0.51 0.51 ,0,0,0,21,5.35Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 1 C 13.1045694997 1 14 1.89543050034 14 3 C 14 4.10456949966 13.1045694997 5 12 5 C 10.8954305003 5 10 4.10456949966 10 3 C 10 1.89543050034 10.8954305003 1 12 1 Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml
new file mode 100644
index 0000000..01fc4b9
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -0,0 +1,33 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22Zm0-1a9,9,0,0,1-7-3.31,10.37,10.37,0,0,1,13.94,0A9,9,0,0,1,12,21ZM3,12a9,9,0,0,1,18,0,8.88,8.88,0,0,1-1.45,4.88,11.35,11.35,0,0,0-15.1,0A8.83,8.83,0,0,1,3,12Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15.5,9.5A3.5,3.5,0,1,0,12,13,3.5,3.5,0,0,0,15.5,9.5Zm-6,0A2.5,2.5,0,1,1,12,12,2.5,2.5,0,0,1,9.5,9.5Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml
new file mode 100644
index 0000000..b43923f
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -0,0 +1,30 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M14,4a1,1,0,0,0-1-1H11a1,1,0,0,0-1,1H9A2,2,0,0,0,7,6V19a2,2,0,0,0,2,2h6a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml
new file mode 100644
index 0000000..580271b
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -0,0 +1,33 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M3.41,14.72A2,2,0,0,1,4,16.14V18a2,2,0,0,0,2,2H7.86a2,2,0,0,1,1.42 0.59 l1.31,1.31a2,2,0,0,0,2.82,0l1.31-1.31A2,2,0,0,1,16.14,20H18a2,2,0,0,0,2-2V16.14a2,2,0,0,1,0.59-1.42l1.31-1.31a2,2,0,0,0,0-2.82L20.59,9.28A2,2,0,0,1,20,7.86V6a2,2,0,0,0-2-2H16.14a2,2,0,0,1-1.42-0.59L13.41,2.1a2,2,0,0,0-2.82,0L9.28,3.41A2,2,0,0,1,7.86,4H6A2,2,0,0,0,4,6V7.86a2,2,0,0,1-0.59,1.42L2.1,10.59a2,2,0,0,0,0,2.82Zm-0.6-3.43L4.12,10A3,3,0,0,0,5,7.86V6A1,1,0,0,1,6,5H7.86A3,3,0,0,0,10,4.12l1.31-1.31a1,1,0,0,1,1.42,0L14,4.12A3,3,0,0,0,16.14,5H18a1,1,0,0,1,1,1V7.86A3,3,0,0,0,19.88,10l1.31,1.31a1,1,0,0,1,0,1.42L19.88,14A3,3,0,0,0,19,16.14V18a1,1,0,0,1-1,1H16.14a3,3,0,0,0-2.12 0.88 l-1.31,1.31a1,1,0,0,1-1.42,0L10,19.88A3,3,0,0,0,7.86,19H6a1,1,0,0,1-1-1V16.14A3,3,0,0,0,4.12,14L2.81,12.71a1,1,0,0,1,0-1.42Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M17,12a5,5,0,0,0-5-5V17A5,5,0,0,0,17,12Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml
new file mode 100644
index 0000000..37d5576
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -0,0 +1,33 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,21.5s7-5.34,7-11.25A7.13,7.13,0,0,0,12,3a7.13,7.13,0,0,0-7,7.25C5,16.16,12,21.5,12,21.5ZM12,4a6.13,6.13,0,0,1,6,6.25c0,4.37-4.37,8.54-6,10-1.63-1.4-6-5.57-6-9.95A6.13,6.13,0,0,1,12,4Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-5,0a2,2,0,1,1,2,2A2,2,0,0,1,10,10Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml
new file mode 100644
index 0000000..32f9e53
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -0,0 +1,36 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,17a9.48,9.48,0,0,1-8.92-5.5A9.48,9.48,0,0,1,12,6a9.5,9.5,0,0,1,8.65,5h1.13A10.5,10.5,0,0,0,12,5,10.47,10.47,0,0,0,2,11.5,10.47,10.47,0,0,0,12,18a11.48,11.48,0,0,0,4-0.7V16.22A10.48,10.48,0,0,1,12,17Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,8a3.5,3.5,0,1,0,3.5,3.5A3.5,3.5,0,0,0,12,8Zm0,6a2.5,2.5,0,1,1,2.5-2.5A2.5,2.5,0,0,1,12,14Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M22,15V14a2,2,0,0,0-4,0v1a1,1,0,0,0-1,1v3a1,1,0,0,0,1,1h4a1,1,0,0,0,1-1V16A1,1,0,0,0,22,15Zm-3,0V14a1,1,0,0,1,2,0v1Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml
new file mode 100644
index 0000000..71d427a
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -0,0 +1,33 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,12a1.5,1.5,0,0,0-0.5,2.91V16.5a0.5 0.5 ,0,0,0,1,0V14.91A1.5,1.5,0,0,0,12,12Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M23,5a4,4,0,0,0-8,0V8H6A1,1,0,0,0,5,9v9a3,3,0,0,0,3,3h8a3,3,0,0,0,3-3V9a1,1,0,0,0-1-1H16V5a3,3,0,0,1,6,0,0.5 0.5 ,0,0,0,1,0ZM18,9v9a2,2,0,0,1-2,2H8a2,2,0,0,1-2-2V9H18Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
new file mode 100644
index 0000000..f4b29ae
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -0,0 +1,36 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,11a0.5 0.5 ,0,0,0-0.5 0.5 v5a0.5 0.5 ,0,0,0,1,0v-5A0.5 0.5 ,0,0,0,12,11Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
new file mode 100644
index 0000000..85abfff
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
@@ -0,0 +1,39 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M2.15,8.15a0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7A13.77,13.77,0,0,0,2.15,8.15Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.07,5.07,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml
new file mode 100644
index 0000000..ea7a97f
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -0,0 +1,45 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M3,5V7A1,1,0,0,0,4,8H20a1,1,0,0,0,1-1V5a2,2,0,0,0-2-2H5A2,2,0,0,0,3,5ZM20,5V7H4V5A1,1,0,0,1,5,4H19A1,1,0,0,1,20,5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M3,19a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V17a2,2,0,0,0-2-2H5a2,2,0,0,0-2,2Zm1-2a1,1,0,0,1,1-1H19a1,1,0,0,1,1,1v2H4Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M3,13a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V11a2,2,0,0,0-2-2H5a2,2,0,0,0-2,2Zm1-2a1,1,0,0,1,1-1H19a1,1,0,0,1,1,1v2H4Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 6.01 4.75 C 6.42421356237 4.75 6.76 5.08578643763 6.76 5.5 C 6.76 5.91421356237 6.42421356237 6.25 6.01 6.25 C 5.59578643763 6.25 5.26 5.91421356237 5.26 5.5 C 5.26 5.08578643763 5.59578643763 4.75 6.01 4.75 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 6.01 10.75 C 6.42421356237 10.75 6.76 11.0857864376 6.76 11.5 C 6.76 11.9142135624 6.42421356237 12.25 6.01 12.25 C 5.59578643763 12.25 5.26 11.9142135624 5.26 11.5 C 5.26 11.0857864376 5.59578643763 10.75 6.01 10.75 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 6.01 16.75 C 6.42421356237 16.75 6.76 17.0857864376 6.76 17.5 C 6.76 17.9142135624 6.42421356237 18.25 6.01 18.25 C 5.59578643763 18.25 5.26 17.9142135624 5.26 17.5 C 5.26 17.0857864376 5.59578643763 16.75 6.01 16.75 Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
new file mode 100644
index 0000000..7ed248d
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -0,0 +1,36 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M13.79,13.79a0.5 0.5 ,0,0,0,0.21,1,0.54 0.54 ,0,0,0,0.21-0.05,2.92,2.92,0,0,0,0-5.39 0.49 0.49,0,0,0-0.66 0.24 0.5 0.5 ,0,0,0,0.24 0.67 ,1.93,1.93,0,0,1,0,3.58Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M13.89,17.67a0.5 0.5 ,0,0,0,0.11,1l0.11,0a6.78,6.78,0,0,0,0-13.28 0.5 0.5,0,1,0-0.22,1,5.79,5.79,0,0,1,0,11.34Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M5,15H7l4.15,4.15a0.47 0.47 ,0,0,0,0.35 0.14 0.5 0.5 ,0,0,0,0.5-0.5V5.21a0.5 0.5 ,0,0,0-0.5-0.5 0.47 0.47,0,0,0-0.35 0.14 L7,9H5a2,2,0,0,0-2,2v2A2,2,0,0,0,5,15ZM4,11a1,1,0,0,1,1-1H7.41l0.3-0.29L11,6.41V17.59l-3.29-3.3L7.41,14H5a1,1,0,0,1-1-1Z" />
+</vector>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml
new file mode 100644
index 0000000..10c1592
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml
@@ -0,0 +1,36 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15.18,16.39a0.51 0.51 ,0,0,0,0.71,0,5.5,5.5,0,0,0,0-7.78,5.52,5.52,0,0,0-7.78,0,5.5,5.5,0,0,0,0,7.78 0.5 0.5,0,0,0,0.35 0.15 0.51 0.51 ,0,0,0,0.36-0.15 0.51 0.51,0,0,0,0-0.71,4.5,4.5,0,1,1,6.36,0A0.51 0.51 ,0,0,0,15.18,16.39Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M18,19.22a0.49 0.49 ,0,0,0,0.35 0.14 0.5 0.5 ,0,0,0,0.36-0.14,9.5,9.5,0,1,0-13.44,0,0.51 0.51 ,0,0,0,0.71,0,0.5 0.5 ,0,0,0,0-0.71,8.5,8.5,0,0,1,12-12,8.5,8.5,0,0,1,0,12A0.5 0.5 ,0,0,0,18,19.22Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/Android.mk b/packages/overlays/IconPackFilledSettingsOverlay/Android.mk
new file mode 100644
index 0000000..0443560
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2019, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := IconPackFilledSettings
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := IconPackFilledSettingsOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/AndroidManifest.xml b/packages/overlays/IconPackFilledSettingsOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..de81e21
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.icon_pack.filled.settings"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="com.android.settings" android:category="android.theme.customization.icon_pack.settings" android:priority="1"/>
+ <application android:label="Filled" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml
new file mode 100644
index 0000000..015e73e
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml
@@ -0,0 +1,52 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 4.5 4 L 7.5 4 Q 8 4 8 4.5 L 8 7.5 Q 8 8 7.5 8 L 4.5 8 Q 4 8 4 7.5 L 4 4.5 Q 4 4 4.5 4 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 10.5 4 L 13.5 4 Q 14 4 14 4.5 L 14 7.5 Q 14 8 13.5 8 L 10.5 8 Q 10 8 10 7.5 L 10 4.5 Q 10 4 10.5 4 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 16.5 4 L 19.5 4 Q 20 4 20 4.5 L 20 7.5 Q 20 8 19.5 8 L 16.5 8 Q 16 8 16 7.5 L 16 4.5 Q 16 4 16.5 4 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 4.5 10 L 7.5 10 Q 8 10 8 10.5 L 8 13.5 Q 8 14 7.5 14 L 4.5 14 Q 4 14 4 13.5 L 4 10.5 Q 4 10 4.5 10 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 10.5 10 L 13.5 10 Q 14 10 14 10.5 L 14 13.5 Q 14 14 13.5 14 L 10.5 14 Q 10 14 10 13.5 L 10 10.5 Q 10 10 10.5 10 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 16.5 10 L 19.5 10 Q 20 10 20 10.5 L 20 13.5 Q 20 14 19.5 14 L 16.5 14 Q 16 14 16 13.5 L 16 10.5 Q 16 10 16.5 10 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 4.5 16 L 7.5 16 Q 8 16 8 16.5 L 8 19.5 Q 8 20 7.5 20 L 4.5 20 Q 4 20 4 19.5 L 4 16.5 Q 4 16 4.5 16 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 10.5 16 L 13.5 16 Q 14 16 14 16.5 L 14 19.5 Q 14 20 13.5 20 L 10.5 20 Q 10 20 10 19.5 L 10 16.5 Q 10 16 10.5 16 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 16.5 16 L 19.5 16 Q 20 16 20 16.5 L 20 19.5 Q 20 20 19.5 20 L 16.5 20 Q 16 20 16 19.5 L 16 16.5 Q 16 16 16.5 16 Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
new file mode 100644
index 0000000..0b12655
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M3,20H6a1,1,0,0,0,0-2H3V6H20a1,1,0,0,0,0-2H3A2,2,0,0,0,1,6V18A2,2,0,0,0,3,20Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M23,19V9a1.08,1.08,0,0,0-1-1H16a1.08,1.08,0,0,0-1,1V19a1.08,1.08,0,0,0,1,1h6A1.08,1.08,0,0,0,23,19Zm-2-1H17V10h4Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M9,12v1.78a3,3,0,0,0,0,4.44V20h4V18.22a3,3,0,0,0,0-4.44V12Zm2,5.5A1.5,1.5,0,1,1,12.5,16,1.5,1.5,0,0,1,11,17.5Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml
new file mode 100644
index 0000000..097894d
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm0,16.81a1.3,1.3,0,1,1,1.3-1.3A1.3,1.3,0,0,1,12,18.81Zm1.07-4.62a1,1,0,0,1-1.13 0.79 ,1,1,0,0,1-0.83-1.23c0.52-2.61,2.66-2.84,2.87-4.5a2,2,0,0,0-1.34-2.17,2,2,0,0,0-2.55,1.37,1,1,0,1,1-1.93-0.53A4,4,0,0,1,16,9.13C15.92,11.57,13.5,11.74,13.07,14.19Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml
new file mode 100644
index 0000000..80f3d1e7
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M7,1A2,2,0,0,0,5,3V21a2,2,0,0,0,2,2H17a2,2,0,0,0,2-2V3a2,2,0,0,0-2-2ZM17,19H7V5H17Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,11.62a1,1,0,0,0-1,0.9v3.59a1,1,0,0,0,2,0V12.52A1,1,0,0,0,12,11.62Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 7.06 C 12.6903559373 7.06 13.25 7.61964406271 13.25 8.31 C 13.25 9.00035593729 12.6903559373 9.56 12 9.56 C 11.3096440627 9.56 10.75 9.00035593729 10.75 8.31 C 10.75 7.61964406271 11.3096440627 7.06 12 7.06 Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml
new file mode 100644
index 0000000..9c8287b
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -0,0 +1,40 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M20.76,5l0-0.06a1,1,0,0,0-1.2-0.72A35.66,35.66,0,0,1,12,5a35.66,35.66,0,0,1-7.54-0.76A1,1,0,0,0,3.26,5l0,0.06A1,1,0,0,0,4,6.24,37,37,0,0,0,9,7V19a1,1,0,0,0,2,0V14h2v5a1,1,0,0,0,2,0V7a37,37,0,0,0,5-0.76A1,1,0,0,0,20.76,5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml
new file mode 100644
index 0000000..ea418a8
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -0,0 +1,31 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,4a8,8,0,0,1,6.36,12.83c-1.43-1.74-4.9-2.33-6.36-2.33s-4.93 0.59 -6.36,2.33A8,8,0,0,1,12,4Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 6 C 13.9329966244 6 15.5 7.56700337559 15.5 9.5 C 15.5 11.4329966244 13.9329966244 13 12 13 C 10.0670033756 13 8.5 11.4329966244 8.5 9.5 C 8.5 7.56700337559 10.0670033756 6 12 6 Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml
new file mode 100644
index 0000000..1c5df00
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M10,2V4H8.33A1.34,1.34,0,0,0,7,5.33V20.66A1.34,1.34,0,0,0,8.33,22h7.33A1.34,1.34,0,0,0,17,20.67V5.33A1.34,1.34,0,0,0,15.67,4H14V2Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml
new file mode 100644
index 0000000..02e15d2
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M4,15.3V19a1,1,0,0,0,1,1H8.69l2.6,2.6a1,1,0,0,0,1.41,0L15.3,20H19a1,1,0,0,0,1-1V15.31l2.6-2.6a1,1,0,0,0,0-1.41L20,8.69V5a1,1,0,0,0-1-1H15.31l-2.6-2.6a1,1,0,0,0-1.41,0L8.69,4H5A1,1,0,0,0,4,5V8.69l-2.6,2.6a1,1,0,0,0,0,1.41ZM12,6a6,6,0,0,1,0,12Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml
new file mode 100644
index 0000000..818236b
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,2A7,7,0,0,0,5,9c0,4.17,4.42,9.92,6.24,12.11a1,1,0,0,0,1.53,0C14.58,18.92,19,13.17,19,9A7,7,0,0,0,12,2Zm0,9.5A2.5,2.5,0,1,1,14.5,9,2.5,2.5,0,0,1,12,11.5Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml
new file mode 100644
index 0000000..b080882
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,19a12,12,0,0,0,2-0.17v-2A10.13,10.13,0,0,1,12,17a9.77,9.77,0,0,1-8.82-5.5,9.82,9.82,0,0,1,17.64,0H23a11.82,11.82,0,0,0-22,0A11.83,11.83,0,0,0,12,19Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M16.5,11.5a4.55,4.55,0,1,0-2.38,3.95,5,5,0,0,1,2.31-3.22A4.4,4.4,0,0,0,16.5,11.5ZM12,14.2a2.7,2.7,0,1,1,2.7-2.7A2.7,2.7,0,0,1,12,14.2Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M23,21V17a1.08,1.08,0,0,0-1-1v-0.5a2.5,2.5,0,0,0-5,0V16a1.08,1.08,0,0,0-1,1v4a1.08,1.08,0,0,0,1,1h5A1.08,1.08,0,0,0,23,21Zm-2.5-5h-2v-0.5a1,1,0,0,1,2,0Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml
new file mode 100644
index 0000000..39ac0d7
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M23,6a1,1,0,0,0,0.92-1.2A5,5,0,0,0,18.57,1a5.15,5.15,0,0,0-4.51,5.19V8H6a2,2,0,0,0-2,2V20a2,2,0,0,0,2,2H18a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2H16V6.12A3.18,3.18,0,0,1,18.44,3a3.1,3.1,0,0,1,3.62,2.27A1,1,0,0,0,23,6ZM12,17a2,2,0,1,1,2-2A2,2,0,0,1,12,17Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
new file mode 100644
index 0000000..3c29998
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M2,12A10,10,0,1,0,12,2,10,10,0,0,0,2,12Zm11,5.42a1,1,0,0,1-2,0V10.68a1,1,0,0,1,2,0ZM12,5.58a1.35,1.35,0,1,1-1.35,1.35A1.34,1.34,0,0,1,12,5.58Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
new file mode 100644
index 0000000..8fa846e
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M11.29,19.29a1,1,0,0,0,1.42,0L14,18a1,1,0,0,0-0.22-1.58A3.92,3.92,0,0,0,12,16a4,4,0,0,0-1.77 0.41 A1,1,0,0,0,10,18Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M17.6,14.39l0.71-0.71a1,1,0,0,0-0.08-1.49,10,10,0,0,0-12.44,0,1,1,0,0,0-0.08,1.49l0.7 0.72 a1,1,0,0,0,1.32 0.08 A6.91,6.91,0,0,1,12,13a7,7,0,0,1,4.29,1.47A1,1,0,0,0,17.6,14.39Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M21.83,10.16l0.71-0.71A1,1,0,0,0,22.48,8a15.79,15.79,0,0,0-20.92,0,1,1,0,0,0-0.07,1.47l0.71 0.71 a1,1,0,0,0,1.35 0.07 ,12.79,12.79,0,0,1,16.94,0A1,1,0,0,0,21.83,10.16Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml
new file mode 100644
index 0000000..82733b6
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M4,14H20a2,2,0,0,0,0-4H4a2,2,0,0,0,0,4Zm1-3.1A1.1,1.1,0,1,1,3.9,12,1.1,1.1,0,0,1,5,10.9Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M4,8H20a2,2,0,0,0,0-4H4A2,2,0,0,0,4,8ZM5,4.9A1.1,1.1,0,1,1,3.9,6,1.1,1.1,0,0,1,5,4.9Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M4,20H20a2,2,0,0,0,0-4H4a2,2,0,0,0,0,4Zm1-3.1A1.1,1.1,0,1,1,3.9,18,1.1,1.1,0,0,1,5,16.9Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
new file mode 100644
index 0000000..9587e54
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M10.29,5.7,7,9H4a1,1,0,0,0-1,1v4a1,1,0,0,0,1,1H7l3.29,3.29A1,1,0,0,0,12,17.58V6.41A1,1,0,0,0,10.29,5.7Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M16.5,12A4.5,4.5,0,0,0,14,8V16A4.47,4.47,0,0,0,16.5,12Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M14,19.54a0.91 0.91 ,0,0,0,1.22 0.86 ,9,9,0,0,0,0-16.8A0.91 0.91 ,0,0,0,14,4.46v0.19a0.92 0.92 ,0,0,0,0.61 0.85 ,7,7,0,0,1,0,13,0.92 0.92 ,0,0,0-0.61 0.85 Z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml
new file mode 100644
index 0000000..84c347b
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15.46,16.46h0A1,1,0,0,0,17,16.35,5.9,5.9,0,0,0,18,13,6,6,0,1,0,7,16.35a1,1,0,0,0,1.51 0.11 h0a1,1,0,0,0,0.11-1.29A3.9,3.9,0,0,1,8,12.44a4,4,0,1,1,7.32,2.73A1,1,0,0,0,15.46,16.46Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M10.86,3.06A10,10,0,0,0,4.19,19.25a1,1,0,0,0,1.49 0.07 A1,1,0,0,0,5.75,18a8.05,8.05,0,0,1-1.59-6.61A8,8,0,0,1,20,13a7.89,7.89,0,0,1-1.77,5,1,1,0,0,0,0.08,1.31h0a1,1,0,0,0,1.49-0.07A9.9,9.9,0,0,0,22,13,10,10,0,0,0,10.86,3.06Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M10,13a2,2,0,1,0,2-2A2,2,0,0,0,10,13Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/Android.mk b/packages/overlays/IconPackRoundedSettingsOverlay/Android.mk
new file mode 100644
index 0000000..44ac6dd
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2019, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := IconPackRoundedSettings
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := IconPackRoundedSettingsOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/AndroidManifest.xml b/packages/overlays/IconPackRoundedSettingsOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..df71e15
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.icon_pack.rounded.settings"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="com.android.settings" android:category="android.theme.customization.icon_pack.settings" android:priority="1"/>
+ <application android:label="Rounded" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml
new file mode 100644
index 0000000..62acfc6
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml
@@ -0,0 +1,52 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 5.5 4 L 6.5 4 Q 8 4 8 5.5 L 8 6.5 Q 8 8 6.5 8 L 5.5 8 Q 4 8 4 6.5 L 4 5.5 Q 4 4 5.5 4 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 11.5 4 L 12.5 4 Q 14 4 14 5.5 L 14 6.5 Q 14 8 12.5 8 L 11.5 8 Q 10 8 10 6.5 L 10 5.5 Q 10 4 11.5 4 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 17.5 4 L 18.5 4 Q 20 4 20 5.5 L 20 6.5 Q 20 8 18.5 8 L 17.5 8 Q 16 8 16 6.5 L 16 5.5 Q 16 4 17.5 4 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 5.5 10 L 6.5 10 Q 8 10 8 11.5 L 8 12.5 Q 8 14 6.5 14 L 5.5 14 Q 4 14 4 12.5 L 4 11.5 Q 4 10 5.5 10 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 11.5 10 L 12.5 10 Q 14 10 14 11.5 L 14 12.5 Q 14 14 12.5 14 L 11.5 14 Q 10 14 10 12.5 L 10 11.5 Q 10 10 11.5 10 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 17.5 10 L 18.5 10 Q 20 10 20 11.5 L 20 12.5 Q 20 14 18.5 14 L 17.5 14 Q 16 14 16 12.5 L 16 11.5 Q 16 10 17.5 10 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 5.5 16 L 6.5 16 Q 8 16 8 17.5 L 8 18.5 Q 8 20 6.5 20 L 5.5 20 Q 4 20 4 18.5 L 4 17.5 Q 4 16 5.5 16 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 11.5 16 L 12.5 16 Q 14 16 14 17.5 L 14 18.5 Q 14 20 12.5 20 L 11.5 20 Q 10 20 10 18.5 L 10 17.5 Q 10 16 11.5 16 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 17.5 16 L 18.5 16 Q 20 16 20 17.5 L 20 18.5 Q 20 20 18.5 20 L 17.5 20 Q 16 20 16 18.5 L 16 17.5 Q 16 16 17.5 16 Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
new file mode 100644
index 0000000..be7f297
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M22,18V10a1.5,1.5,0,0,0-1.5-1.5h-4A1.5,1.5,0,0,0,15,10v8a1.5,1.5,0,0,0,1.5,1.5h4A1.5,1.5,0,0,0,22,18Zm-5.5-8h4v8h-4Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M13,17a2.5,2.5,0,1,0-2.5,2.5A2.5,2.5,0,0,0,13,17ZM9.5,17a1,1,0,1,1,1,1A1,1,0,0,1,9.5,17Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M21.25,4H3.5A1.5,1.5,0,0,0,2,5.5V18a1.5,1.5,0,0,0,1.5,1.5H5.25a0.75 0.75 ,0,0,0,0-1.5H3.5V5.5H21.25a0.75 0.75 ,0,0,0,0-1.5Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml
new file mode 100644
index 0000000..e8c3e47
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,22h0A10,10,0,0,0,22,12v0A10,10,0,1,0,12,22ZM12,3.5A8.51,8.51,0,0,1,20.5,12h0.75l-0.75,0A8.49,8.49,0,0,1,12,20.5h0a8.5,8.5,0,0,1,0-17Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M8.67,10a0.77 0.77 ,0,0,0,0.91-0.56,2.48,2.48,0,0,1,0.65-1.19,2.57,2.57,0,0,1,3.54,0A2.2,2.2,0,0,1,14.43,10a1.81,1.81,0,0,1-0.84,1.37c-0.13 0.09 -0.26 0.16 -0.4 0.24 a3.3,3.3,0,0,0-1.93,2.51 0.76 0.76,0,0,0,0.62 0.87 H12a0.75 0.75 ,0,0,0,0.74-0.62,1.84,1.84,0,0,1,1.19-1.46l0.49-0.29a3.32,3.32,0,0,0,1.5-2.48,3.71,3.71,0,0,0-1.09-3,4.1,4.1,0,0,0-5.66,0,4,4,0,0,0-1.05,1.9A0.75 0.75 ,0,0,0,8.67,10Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml
new file mode 100644
index 0000000..e5e57d4
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M8,1A3,3,0,0,0,5,4V20a3,3,0,0,0,3,3h8a3,3,0,0,0,3-3V4a3,3,0,0,0-3-3Zm8,20.5H8A1.5,1.5,0,0,1,6.5,20h11A1.5,1.5,0,0,1,16,21.5Zm1.5-3H6.5V5.5h11ZM17.5,4H6.5A1.5,1.5,0,0,1,8,2.5h8A1.5,1.5,0,0,1,17.5,4Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,11.25a0.76 0.76 ,0,0,0-0.75 0.75 v4a0.75 0.75 ,0,0,0,1.5,0V12A0.76 0.76 ,0,0,0,12,11.25Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml
new file mode 100644
index 0000000..1ac58b5
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -0,0 +1,40 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M14.25,2.5A2.25,2.25,0,1,0,12,4.75,2.25,2.25,0,0,0,14.25,2.5Zm-3,0a0.75 0.75 ,0,1,1,0.75 0.75 A0.76 0.76 ,0,0,1,11.25,2.5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M20.72,5.28a0.77 0.77 ,0,0,0-0.94-0.5,29.53,29.53,0,0,1-7.78,1,29.72,29.72,0,0,1-7.78-1,0.75 0.75 ,0,0,0-0.44,1.44A28.14,28.14,0,0,0,9,7.12V19a0.75 0.75 ,0,0,0,1.5,0V14h3v5A0.75 0.75 ,0,0,0,15,19V7.12a28.14,28.14,0,0,0,5.22-0.9A0.76 0.76 ,0,0,0,20.72,5.28Zm-7.22,2V12.5h-3V7.25Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml
new file mode 100644
index 0000000..90da97f
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -0,0 +1,31 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M6.21,20.14l0.08 0.06 A10,10,0,0,0,12,22h0a10,10,0,0,0,5.76-1.84h0A10,10,0,0,0,22,12v0A10,10,0,1,0,6.21,20.14Zm5.8 0.36 h0a8.45,8.45,0,0,1-4.5-1.3V15.75A0.76 0.76 ,0,0,1,8.25,15h7.5a0.76 0.76 ,0,0,1,0.75 0.75 V19.2A8.39,8.39,0,0,1,12,20.5Zm0-17A8.51,8.51,0,0,1,20.5,12h0.75l-0.75,0A8.47,8.47,0,0,1,18,18V15.75a2.25,2.25,0,0,0-2.25-2.25H8.25A2.25,2.25,0,0,0,6,15.75V18A8.49,8.49,0,0,1,12,3.5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,12h0A3,3,0,1,0,9,9H9A3,3,0,0,0,12,12ZM10.5,9A1.5,1.5,0,1,1,12,10.5h0A1.5,1.5,0,0,1,10.5,9Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml
new file mode 100644
index 0000000..3f3b95a
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M13,2.49H11a1,1,0,0,0-1,1V4H7A1,1,0,0,0,6,5V21a1,1,0,0,0,1,1H17a1,1,0,0,0,1-1V5a1,1,0,0,0-1-1H14V3.49A1,1,0,0,0,13,2.49Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
new file mode 100644
index 0000000..54993e2
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -0,0 +1,52 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M19.5,12h0A7.5,7.5,0,1,0,12,19.5h0A7.49,7.49,0,0,0,19.5,12ZM12,18h0a6,6,0,1,1,6-6h0a6,6,0,0,1-6,6Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 1.5 C 12.4142135624 1.5 12.75 1.83578643763 12.75 2.25 C 12.75 2.66421356237 12.4142135624 3 12 3 C 11.5857864376 3 11.25 2.66421356237 11.25 2.25 C 11.25 1.83578643763 11.5857864376 1.5 12 1.5 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 5.1 4.35 C 5.51421356237 4.35 5.85 4.68578643763 5.85 5.1 C 5.85 5.51421356237 5.51421356237 5.85 5.1 5.85 C 4.68578643763 5.85 4.35 5.51421356237 4.35 5.1 C 4.35 4.68578643763 4.68578643763 4.35 5.1 4.35 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 2.25 11.25 C 2.66421356237 11.25 3 11.5857864376 3 12 C 3 12.4142135624 2.66421356237 12.75 2.25 12.75 C 1.83578643763 12.75 1.5 12.4142135624 1.5 12 C 1.5 11.5857864376 1.83578643763 11.25 2.25 11.25 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 5.1 18.15 C 5.51421356237 18.15 5.85 18.4857864376 5.85 18.9 C 5.85 19.3142135624 5.51421356237 19.65 5.1 19.65 C 4.68578643763 19.65 4.35 19.3142135624 4.35 18.9 C 4.35 18.4857864376 4.68578643763 18.15 5.1 18.15 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 21 C 12.4142135624 21 12.75 21.3357864376 12.75 21.75 C 12.75 22.1642135624 12.4142135624 22.5 12 22.5 C 11.5857864376 22.5 11.25 22.1642135624 11.25 21.75 C 11.25 21.3357864376 11.5857864376 21 12 21 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 18.9 18.15 C 19.3142135624 18.15 19.65 18.4857864376 19.65 18.9 C 19.65 19.3142135624 19.3142135624 19.65 18.9 19.65 C 18.4857864376 19.65 18.15 19.3142135624 18.15 18.9 C 18.15 18.4857864376 18.4857864376 18.15 18.9 18.15 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 21.75 11.25 C 22.1642135624 11.25 22.5 11.5857864376 22.5 12 C 22.5 12.4142135624 22.1642135624 12.75 21.75 12.75 C 21.3357864376 12.75 21 12.4142135624 21 12 C 21 11.5857864376 21.3357864376 11.25 21.75 11.25 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 18.9 4.35 C 19.3142135624 4.35 19.65 4.68578643763 19.65 5.1 C 19.65 5.51421356237 19.3142135624 5.85 18.9 5.85 C 18.4857864376 5.85 18.15 5.51421356237 18.15 5.1 C 18.15 4.68578643763 18.4857864376 4.35 18.9 4.35 Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml
new file mode 100644
index 0000000..26aa308
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -0,0 +1,31 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-4.5,0A1.5,1.5,0,1,1,12,11.5,1.5,1.5,0,0,1,10.5,10Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M11.37,21.76A1,1,0,0,0,12,22a1,1,0,0,0,0.62-0.22C14.5,20.26,20,15.5,20,10a8,8,0,0,0-8-8,7.89,7.89,0,0,0-8,8C4,15.5,9.48,20.25,11.37,21.76ZM12,3.51A6.5,6.5,0,0,1,18.5,10c0,4.4-4.31,8.53-6.5,10.34C9.82,18.54,5.5,14.4,5.5,10A6.43,6.43,0,0,1,12,3.51Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml
new file mode 100644
index 0000000..a6619bd
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,8a4,4,0,0,0,0,8,3.94,3.94,0,0,0,2.23-0.68,5.06,5.06,0,0,1,1.67-2.47A4,4,0,0,0,16,12,4,4,0,0,0,12,8Zm0,6.5A2.5,2.5,0,1,1,14.5,12,2.5,2.5,0,0,1,12,14.5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M1.55,12.27C1.67,12.58,4.58,20,12,20a10.57,10.57,0,0,0,2-0.21V18.27a8.44,8.44,0,0,1-2,0.23c-5.72,0-8.37-5.22-8.94-6.5C3.63,10.75,6.33,5.5,12,5.5s8.38,5.22,9,6.5l-0.06 0.12 a4.84,4.84,0,0,1,1.28 0.8 c0.17-0.36 0.27 -0.6 0.29 -0.65a0.72 0.72 ,0,0,0,0-0.54C22.34,11.42,19.43,4,12,4S1.67,11.42,1.55,11.73A0.72 0.72 ,0,0,0,1.55,12.27Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M21.25,16.5v-0.66a2.26,2.26,0,0,0-4.5,0v0.66H16V22h6V16.5Zm-3,0v-0.66c0-0.29 0.38 -0.59 0.75 -0.59s0.75 0.3 0.75 0.59 v0.66Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml
new file mode 100644
index 0000000..d769f4f
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -0,0 +1,31 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M18.51,3A2.32,2.32,0,0,1,21,5.15a0.79 0.79 ,0,0,0,0.76 0.74 0.75 0.75 ,0,0,0,0.74-0.77,3.8,3.8,0,0,0-4-3.66,3.83,3.83,0,0,0-4,3.68V8.5h-9A1.5,1.5,0,0,0,4,10V20a1.5,1.5,0,0,0,1.5,1.5h13A1.5,1.5,0,0,0,20,20V10a1.5,1.5,0,0,0-1.5-1.5H16V5.15A2.35,2.35,0,0,1,18.51,3Zm0,17H5.5V10h13Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
new file mode 100644
index 0000000..ee990f9
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M19.07,4.93A10,10,0,1,0,22,12,10,10,0,0,0,19.07,4.93ZM18,18a8.5,8.5,0,1,1,2.5-6A8.53,8.53,0,0,1,18,18Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,10a0.76 0.76 ,0,0,0-0.75 0.75 v5.5a0.75 0.75 ,0,0,0,1.5,0v-5.5A0.76 0.76 ,0,0,0,12,10Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
new file mode 100644
index 0000000..ffd2c64
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
@@ -0,0 +1,37 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15.78,14.82a0.57 0.57 ,0,0,0,0.16 0.15 0.75 0.75 ,0,0,0,1-0.2 0.76 0.76,0,0,0-0.2-1,6.77,6.77,0,0,0-9.55,0,0.76 0.76 ,0,0,0,0,1,0.75 0.75 ,0,0,0,1.06,0h0a5.24,5.24,0,0,1,7.42,0A0.08 0.08 ,0,0,0,15.78,14.82Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M20,11.79a0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.77 0.77,0,0,0,0,1.07 0.76 0.76,0,0,0,1.07,0,10.12,10.12,0,0,1,7-3,10.12,10.12,0,0,1,7,3A0.75 0.75 ,0,0,0,20,11.79Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,2.75A14.76,14.76,0,0,0,1.22,7.2a0.77 0.77 ,0,0,0,0,1,0.75 0.75 ,0,0,0,1.06,0,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.73 0.73 ,0,0,0,1,0,0.75 0.75 ,0,0,0,0.05-1.06A14.76,14.76,0,0,0,12,2.75Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml
new file mode 100644
index 0000000..e6125db
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -0,0 +1,43 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M21,2.75A0.76 0.76 ,0,0,0,20.25,2H3.75A0.76 0.76 ,0,0,0,3,2.75v4.5A0.76 0.76 ,0,0,0,3.75,8h16.5A0.76 0.76 ,0,0,0,21,7.25ZM19.5,6.5H4.5v-3h15Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 5.25 4.25 H 6.75 V 5.75 H 5.25 V 4.25 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M21,9.75A0.76 0.76 ,0,0,0,20.25,9H3.75A0.76 0.76 ,0,0,0,3,9.75v4.5a0.76 0.76 ,0,0,0,0.75 0.75 h16.5a0.76 0.76 ,0,0,0,0.75-0.75ZM19.5,13.5H4.5v-3h15Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 5.25 11.25 H 6.75 V 12.75 H 5.25 V 11.25 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M21,21.25v-4.5a0.76 0.76 ,0,0,0-0.75-0.75H3.75a0.76 0.76 ,0,0,0-0.75 0.75 v4.5a0.76 0.76 ,0,0,0,0.75 0.75 h16.5A0.76 0.76 ,0,0,0,21,21.25Zm-1.5-0.75H4.5v-3h15Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 5.25 18.25 H 6.75 V 19.75 H 5.25 V 18.25 Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
new file mode 100644
index 0000000..76d3e5f
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M5.69,16l5,5a0.77 0.77 ,0,0,0,0.53 0.22 0.75 0.75 ,0,0,0,0.29-0.06A0.74 0.74 ,0,0,0,12,20.5V3.5A0.75 0.75 ,0,0,0,10.72,3l-5,5H3.49A1.52,1.52,0,0,0,2,9.5v5A1.5,1.5,0,0,0,3.5,16ZM3.5,9.5H6a0.75 0.75 ,0,0,0,0.53-0.22l4-4V18.69l-4-4A0.75 0.75 ,0,0,0,6,14.5H3.5Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M13.52,20.64a0.77 0.77 ,0,0,0,0.73 0.56 0.63 0.63 ,0,0,0,0.19,0,9.48,9.48,0,0,0,0-18.34 0.75 0.75,0,0,0-0.92 0.53 0.76 0.76 ,0,0,0,0.54 0.92 ,8,8,0,0,1,0,15.44A0.76 0.76 ,0,0,0,13.52,20.64Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M13.85,15a0.76 0.76 ,0,0,0-0.24,1,0.78 0.78 ,0,0,0,0.64 0.35 0.83 0.83 ,0,0,0,0.4-0.11,5,5,0,0,0,1.6-6.88,5.2,5.2,0,0,0-1.6-1.6A0.75 0.75 ,0,1,0,13.85,9,3.33,3.33,0,0,1,15,10.16,3.47,3.47,0,0,1,13.85,15Z" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml
new file mode 100644
index 0000000..eadd300
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml
@@ -0,0 +1,34 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M15,16.57a0.75 0.75 ,0,0,0,1.06,0,5.75,5.75,0,1,0-8.14,0,0.79 0.79 ,0,0,0,0.53 0.22 A0.75 0.75 ,0,0,0,9,16.57a0.74 0.74 ,0,0,0,0-1.06,4.25,4.25,0,1,1,6,0A0.75 0.75 ,0,0,0,15,16.57Z" />
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M18.36,19.61a0.71 0.71 ,0,0,0,0.53-0.22A9.74,9.74,0,0,0,5.11,5.61a9.73,9.73,0,0,0,0,13.78 0.74 0.74,0,0,0,1.06,0,0.75 0.75 ,0,0,0,0-1.06A8.24,8.24,0,0,1,17.83,6.67a8.23,8.23,0,0,1,0,11.66 0.75 0.75,0,0,0,0,1.06A0.74 0.74 ,0,0,0,18.36,19.61Z" />
+</vector>
diff --git a/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml b/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml
index 138c283..c5bb5e9 100644
--- a/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml
+++ b/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml
@@ -21,6 +21,10 @@
<string name="config_icon_mask" translatable="false">"M50,0L88,0 C94.4,0 100,5.4 100 12 L100,88 C100,94.6 94.6 100 88 100 L12,100 C5.4,100 0,94.6 0,88 L0 12 C0 5.4 5.4 0 12 0 L50,0 Z"</string>
<!-- Flag indicating whether round icons should be parsed from the application manifest. -->
<bool name="config_useRoundIcon">false</bool>
+ <!-- Corner radius of system dialogs -->
+ <dimen name="config_dialogCornerRadius">2dp</dimen>
+ <!-- Corner radius for bottom sheet system dialogs -->
+ <dimen name="config_bottomDialogCornerRadius">4dp</dimen>
</resources>
diff --git a/packages/overlays/IconShapeSquircleOverlay/res/values/config.xml b/packages/overlays/IconShapeSquircleOverlay/res/values/config.xml
index eaf7de3..7692aa6 100644
--- a/packages/overlays/IconShapeSquircleOverlay/res/values/config.xml
+++ b/packages/overlays/IconShapeSquircleOverlay/res/values/config.xml
@@ -21,6 +21,10 @@
<string name="config_icon_mask" translatable="false">"M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z"</string>
<!-- Flag indicating whether round icons should be parsed from the application manifest. -->
<bool name="config_useRoundIcon">false</bool>
+ <!-- Corner radius of system dialogs -->
+ <dimen name="config_dialogCornerRadius">4dp</dimen>
+ <!-- Corner radius for bottom sheet system dialogs -->
+ <dimen name="config_bottomDialogCornerRadius">8dp</dimen>
</resources>
diff --git a/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml b/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml
index 818e696..b6ee412 100644
--- a/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml
+++ b/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml
@@ -21,6 +21,10 @@
<string name="config_icon_mask" translatable="false">"M50,0 C77.6,0 100,22.4 100,50 L100,88 C100,94.6 94.6,100 88,100 L50,100 C22.4 100 0 77.6 0 50C0 22.4 22.4 0 50 0 Z"</string>
<!-- Flag indicating whether round icons should be parsed from the application manifest. -->
<bool name="config_useRoundIcon">false</bool>
+ <!-- Corner radius of system dialogs -->
+ <dimen name="config_dialogCornerRadius">8dp</dimen>
+ <!-- Corner radius for bottom sheet system dialogs -->
+ <dimen name="config_bottomDialogCornerRadius">16dp</dimen>
</resources>
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 76bb24d..3c91069 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -6936,6 +6936,45 @@
// OS: Q
ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = 1646;
+ // Tagged data for SMART_REPLY_VISIBLE and SMART_REPLY_ACTION.
+ // Whether the smart reply was / is to be sent via direct reply because
+ // getEditChoicesBeforeSending was enabled.
+ // OS: Q
+ NOTIFICATION_SMART_REPLY_EDIT_BEFORE_SENDING = 1647;
+
+ // Tagged data for SMART_REPLY_ACTION.
+ // Whether the smart reply was modified by the user via the direct reply field (implies that
+ // getEditChoicesBeforeSending was enabled).
+ // actions/replies.
+ // OS: Q
+ NOTIFICATION_SMART_REPLY_MODIFIED_BEFORE_SENDING = 1648;
+
+ // CATEGORY: ACTION_ACTIVITY_CHOOSER_SHOWN
+ // Field to add the mimetype for a ChooserActivity
+ // OS:Q
+ FIELD_SHARESHEET_MIMETYPE = 1649;
+
+ // CATEGORY: ACTION_ACTIVITY_CHOOSER_SHOWN
+ // Sharesheet direct targets are ready to show.
+ // OS:Q
+ ACTION_ACTIVITY_CHOOSER_SHOWN_DIRECT_TARGET = 1650;
+
+ // CATEGORY: ACTION_SHARESHEET_SCROLL
+ // Sharesheet are either expanded, scrolling through them or compacted again.
+ // OS:Q
+ // Subtype 1 means collapsed, 0 expanded
+ ACTION_SHARESHEET_COLLAPSED_CHANGED = 1651;
+
+ // ACTION: Share with screenshot extra
+ // OS: Q
+ ACTION_SHARE_WITH_PREVIEW = 1652;
+
+ // CATEGORY: ACTION_ACTIVITY_CHOOSER_SHOWN
+ // OS:Q
+ // The time elapsed from triggering the share to displaying the app targets
+ // formerly: histogram system_cost_for_smart_sharing
+ FIELD_TIME_TO_APP_TARGETS = 1653;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 8886ee2..1bce11ee 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -180,7 +180,7 @@
mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(master.getContext(),
com.android.internal.R.string.config_defaultAugmentedAutofillService);
mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
- (u, s) -> updateRemoteAugmentedAutofillService());
+ (u, s) -> updateRemoteAugmentedAutofillService(s));
updateLocked(disabled);
}
@@ -1048,8 +1048,12 @@
componentName, mUserId, new RemoteAugmentedAutofillServiceCallbacks() {
@Override
public void onServiceDied(@NonNull RemoteAugmentedAutofillService service) {
- // TODO(b/123100811): properly implement
Slog.w(TAG, "remote augmented autofill service died");
+ final RemoteAugmentedAutofillService remoteService =
+ mRemoteAugmentedAutofillService;
+ if (remoteService != null) {
+ remoteService.destroy();
+ }
}
}, mMaster.isInstantServiceAllowed(), mMaster.verbose);
}
@@ -1060,8 +1064,7 @@
/**
* Called when the {@link #mAugmentedAutofillResolver} changed (among other places).
*/
- private void updateRemoteAugmentedAutofillService() {
- final String serviceName = mAugmentedAutofillResolver.getServiceName(mUserId);
+ private void updateRemoteAugmentedAutofillService(@Nullable String serviceName) {
if (serviceName == null) {
if (sVerbose) Slog.v(TAG, "updateRemoteAugmentedAutofillService(): time's up!");
if (mRemoteAugmentedAutofillService != null) {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 14322ec..0dd1ded 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -41,6 +41,7 @@
import android.os.ParcelFileDescriptor;
import android.os.Trace;
import android.os.UserHandle;
+import android.os.UserManager;
import android.util.Slog;
import android.util.SparseArray;
@@ -433,8 +434,46 @@
getServiceForUserIfCallerHasPermission(userId, "getConfigurationIntent()");
return userBackupManagerService == null
- ? null
- : userBackupManagerService.getConfigurationIntent(transportName);
+ ? null
+ : userBackupManagerService.getConfigurationIntent(transportName);
+ }
+
+ /**
+ * Sets the ancestral work profile for the calling user.
+ *
+ * <p> The ancestral work profile corresponds to the profile that was used to restore to the
+ * callers profile.
+ */
+ public void setAncestralSerialNumber(long ancestralSerialNumber) {
+ UserBackupManagerService userBackupManagerService =
+ getServiceForUserIfCallerHasPermission(
+ Binder.getCallingUserHandle().getIdentifier(),
+ "setAncestralSerialNumber()");
+
+ if (userBackupManagerService != null) {
+ userBackupManagerService.setAncestralSerialNumber(ancestralSerialNumber);
+ }
+ }
+
+ /**
+ * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the
+ * serial number of the its ancestral work profile.
+ *
+ * <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)}
+ * and it corresponds to the profile that was used to restore to the callers profile.
+ */
+ @Nullable
+ public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
+ for (UserHandle handle : mContext.getSystemService(UserManager.class).getUserProfiles()) {
+ UserBackupManagerService userBackupManagerService = getServiceUsers().get(
+ handle.getIdentifier());
+ if (userBackupManagerService != null) {
+ if (userBackupManagerService.getAncestralSerialNumber() == ancestralSerialNumber) {
+ return handle;
+ }
+ }
+ }
+ return null;
}
/**
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 87872e8..17e9b35 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -760,6 +760,21 @@
}
@Override
+ @Nullable public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
+ if (mService != null) {
+ return mService.getUserForAncestralSerialNumber(ancestralSerialNumber);
+ }
+ return null;
+ }
+
+ @Override
+ public void setAncestralSerialNumber(long ancestralSerialNumber) {
+ if (mService != null) {
+ mService.setAncestralSerialNumber(ancestralSerialNumber);
+ }
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
int userId = binderGetCallingUserId();
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 8b2c1b9..b2afbc3 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -244,6 +244,8 @@
private static final long BUSY_BACKOFF_MIN_MILLIS = 1000 * 60 * 60; // one hour
private static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2; // two hours
+ private static final String SERIAL_ID_FILE = "serial_id";
+
private final @UserIdInt int mUserId;
private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
private final TransportManager mTransportManager;
@@ -360,6 +362,8 @@
private Set<String> mAncestralPackages = null;
private long mAncestralToken = 0;
private long mCurrentToken = 0;
+ @Nullable private File mAncestralSerialNumberFile;
+
/**
* Creates an instance of {@link UserBackupManagerService} and initializes state for it. This
@@ -2308,6 +2312,55 @@
}
}
+ /**
+ * Sets the work profile serial number of the ancestral work profile.
+ */
+ public void setAncestralSerialNumber(long ancestralSerialNumber) {
+ mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
+ "setAncestralSerialNumber");
+ Slog.v(TAG, "Setting ancestral work profile id to " + ancestralSerialNumber);
+ try (RandomAccessFile af = getAncestralSerialNumberFile()) {
+ af.writeLong(ancestralSerialNumber);
+ } catch (IOException e) {
+ Slog.w(TAG, "Unable to write to work profile serial mapping file:", e);
+ }
+ }
+
+ /**
+ * Returns the work profile serial number of the ancestral device. This will be set by
+ * {@link #setAncestralSerialNumber(long)}. Will return {@code -1} if not set.
+ */
+ public long getAncestralSerialNumber() {
+ try (RandomAccessFile af = getAncestralSerialNumberFile()) {
+ return af.readLong();
+ } catch (IOException e) {
+ Slog.w(TAG, "Unable to write to work profile serial number file:", e);
+ return -1;
+ }
+ }
+
+ private RandomAccessFile getAncestralSerialNumberFile() throws FileNotFoundException {
+ if (mAncestralSerialNumberFile == null) {
+ mAncestralSerialNumberFile = new File(
+ UserBackupManagerFiles.getBaseStateDir(getUserId()),
+ SERIAL_ID_FILE);
+ if (!mAncestralSerialNumberFile.exists()) {
+ try {
+ mAncestralSerialNumberFile.createNewFile();
+ } catch (IOException e) {
+ Slog.w(TAG, "serial number mapping file creation failed", e);
+ }
+ }
+ }
+ return new RandomAccessFile(mAncestralSerialNumberFile, "rwd");
+ }
+
+ @VisibleForTesting
+ void setAncestralSerialNumberFile(File ancestralSerialNumberFile) {
+ mAncestralSerialNumberFile = ancestralSerialNumberFile;
+ }
+
+
/** Clear the given package's backup data from the current transport. */
public void clearBackupData(String transportName, String packageName) {
if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java b/services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java
new file mode 100644
index 0000000..004d9e3
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import com.android.internal.util.Preconditions;
+
+/** Representation of a range of bytes to be downloaded. */
+final class ByteRange {
+ private final long mStart;
+ private final long mEnd;
+
+ /** Creates a range of bytes which includes {@code mStart} and {@code mEnd}. */
+ ByteRange(long start, long end) {
+ Preconditions.checkArgument(start >= 0);
+ Preconditions.checkArgument(end >= start);
+ mStart = start;
+ mEnd = end;
+ }
+
+ /** Returns the start of the {@code ByteRange}. The start is included in the range. */
+ long getStart() {
+ return mStart;
+ }
+
+ /** Returns the end of the {@code ByteRange}. The end is included in the range. */
+ long getEnd() {
+ return mEnd;
+ }
+
+ /** Returns the number of bytes included in the {@code ByteRange}. */
+ int getLength() {
+ return (int) (mEnd - mStart + 1);
+ }
+
+ /** Creates a new {@link ByteRange} from {@code mStart} to {@code mEnd + length}. */
+ ByteRange extend(long length) {
+ Preconditions.checkArgument(length > 0);
+ return new ByteRange(mStart, mEnd + length);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ByteRange)) {
+ return false;
+ }
+
+ ByteRange byteRange = (ByteRange) o;
+ return (mEnd == byteRange.mEnd && mStart == byteRange.mStart);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + (int) (mStart ^ (mStart >>> 32));
+ result = 31 * result + (int) (mEnd ^ (mEnd >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ByteRange{mStart=%d, mEnd=%d}", mStart, mEnd);
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java b/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
new file mode 100644
index 0000000..69fb5cb
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/** Writes backup data to a diff script, using a {@link SingleStreamDiffScriptWriter}. */
+public class DiffScriptBackupWriter implements BackupWriter {
+ /**
+ * The maximum size of a chunk in the diff script. The diff script writer {@code mWriter} will
+ * buffer this many bytes in memory.
+ */
+ private static final int ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES = 1024 * 1024;
+
+ private final SingleStreamDiffScriptWriter mWriter;
+ private long mBytesWritten;
+
+ /**
+ * Constructs a new writer which writes the diff script to the given output stream, using the
+ * maximum new chunk size {@code ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES}.
+ */
+ public static DiffScriptBackupWriter newInstance(OutputStream outputStream) {
+ SingleStreamDiffScriptWriter writer =
+ new SingleStreamDiffScriptWriter(
+ outputStream, ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES);
+ return new DiffScriptBackupWriter(writer);
+ }
+
+ @VisibleForTesting
+ DiffScriptBackupWriter(SingleStreamDiffScriptWriter writer) {
+ mWriter = writer;
+ }
+
+ @Override
+ public void writeBytes(byte[] bytes) throws IOException {
+ for (byte b : bytes) {
+ mWriter.writeByte(b);
+ }
+
+ mBytesWritten += bytes.length;
+ }
+
+ @Override
+ public void writeChunk(long start, int length) throws IOException {
+ mWriter.writeChunk(start, length);
+ mBytesWritten += length;
+ }
+
+ @Override
+ public long getBytesWritten() {
+ return mBytesWritten;
+ }
+
+ @Override
+ public void flush() throws IOException {
+ mWriter.flush();
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java b/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
new file mode 100644
index 0000000..49d1571
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/** Writer that formats a Diff Script and writes it to an output source. */
+interface DiffScriptWriter {
+ /** Adds a new byte to the diff script. */
+ void writeByte(byte b) throws IOException;
+
+ /** Adds a known chunk to the diff script. */
+ void writeChunk(long chunkStart, int chunkLength) throws IOException;
+
+ /** Indicates that no more bytes or chunks will be added to the diff script. */
+ void flush() throws IOException;
+
+ interface Factory {
+ DiffScriptWriter create(OutputStream outputStream);
+ }
+}
diff --git a/core/java/android/app/ISmsAppService.aidl b/services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
similarity index 65%
copy from core/java/android/app/ISmsAppService.aidl
copy to services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
index 1ac2ec6..4aea601 100644
--- a/core/java/android/app/ISmsAppService.aidl
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
@@ -14,10 +14,12 @@
* limitations under the License.
*/
-package android.app;
+package com.android.server.backup.encryption.chunking;
-/**
- * @hide
- */
-interface ISmsAppService {
+import java.io.OutputStream;
+
+/** An interface that wraps one {@link OutputStream} with another for filtration purposes. */
+public interface OutputStreamWrapper {
+ /** Wraps a given {@link OutputStream}. */
+ OutputStream wrap(OutputStream outputStream);
}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java b/services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
new file mode 100644
index 0000000..0e4bd58
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import android.annotation.Nullable;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.util.Locale;
+
+/**
+ * A {@link DiffScriptWriter} that writes an entire diff script to a single {@link OutputStream}.
+ */
+public class SingleStreamDiffScriptWriter implements DiffScriptWriter {
+ static final byte LINE_SEPARATOR = 0xA;
+ private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ private final int mMaxNewByteChunkSize;
+ private final OutputStream mOutputStream;
+ private final byte[] mByteBuffer;
+ private int mBufferSize = 0;
+ // Each chunk could be written immediately to the output stream. However,
+ // it is possible that chunks may overlap. We therefore cache the most recent
+ // reusable chunk and try to merge it with future chunks.
+ private ByteRange mReusableChunk;
+
+ public SingleStreamDiffScriptWriter(OutputStream outputStream, int maxNewByteChunkSize) {
+ mOutputStream = outputStream;
+ mMaxNewByteChunkSize = maxNewByteChunkSize;
+ mByteBuffer = new byte[maxNewByteChunkSize];
+ }
+
+ @Override
+ public void writeByte(byte b) throws IOException {
+ if (mReusableChunk != null) {
+ writeReusableChunk();
+ }
+ mByteBuffer[mBufferSize++] = b;
+ if (mBufferSize == mMaxNewByteChunkSize) {
+ writeByteBuffer();
+ }
+ }
+
+ @Override
+ public void writeChunk(long chunkStart, int chunkLength) throws IOException {
+ Preconditions.checkArgument(chunkStart >= 0);
+ Preconditions.checkArgument(chunkLength > 0);
+ if (mBufferSize != 0) {
+ writeByteBuffer();
+ }
+
+ if (mReusableChunk != null && mReusableChunk.getEnd() + 1 == chunkStart) {
+ // The new chunk overlaps the old, so combine them into a single byte range.
+ mReusableChunk = mReusableChunk.extend(chunkLength);
+ } else {
+ writeReusableChunk();
+ mReusableChunk = new ByteRange(chunkStart, chunkStart + chunkLength - 1);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ Preconditions.checkState(!(mBufferSize != 0 && mReusableChunk != null));
+ if (mBufferSize != 0) {
+ writeByteBuffer();
+ }
+ if (mReusableChunk != null) {
+ writeReusableChunk();
+ }
+ mOutputStream.flush();
+ }
+
+ private void writeByteBuffer() throws IOException {
+ mOutputStream.write(Integer.toString(mBufferSize).getBytes(UTF_8));
+ mOutputStream.write(LINE_SEPARATOR);
+ mOutputStream.write(mByteBuffer, 0, mBufferSize);
+ mOutputStream.write(LINE_SEPARATOR);
+ mBufferSize = 0;
+ }
+
+ private void writeReusableChunk() throws IOException {
+ if (mReusableChunk != null) {
+ mOutputStream.write(
+ String.format(
+ Locale.US,
+ "%d-%d",
+ mReusableChunk.getStart(),
+ mReusableChunk.getEnd())
+ .getBytes(UTF_8));
+ mOutputStream.write(LINE_SEPARATOR);
+ mReusableChunk = null;
+ }
+ }
+
+ /** A factory that creates {@link SingleStreamDiffScriptWriter}s. */
+ public static class Factory implements DiffScriptWriter.Factory {
+ private final int mMaxNewByteChunkSize;
+ private final OutputStreamWrapper mOutputStreamWrapper;
+
+ public Factory(int maxNewByteChunkSize, @Nullable OutputStreamWrapper outputStreamWrapper) {
+ mMaxNewByteChunkSize = maxNewByteChunkSize;
+ mOutputStreamWrapper = outputStreamWrapper;
+ }
+
+ @Override
+ public SingleStreamDiffScriptWriter create(OutputStream outputStream) {
+ if (mOutputStreamWrapper != null) {
+ outputStream = mOutputStreamWrapper.wrap(outputStream);
+ }
+ return new SingleStreamDiffScriptWriter(outputStream, mMaxNewByteChunkSize);
+ }
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index 7ee3047..593bb2c4 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -20,6 +20,7 @@
import static com.android.server.backup.BackupManagerService.TAG;
import static com.android.server.backup.UserBackupManagerService.PACKAGE_MANAGER_SENTINEL;
import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import android.annotation.Nullable;
import android.app.AppGlobals;
@@ -40,11 +41,18 @@
import com.android.internal.util.ArrayUtils;
import com.android.server.backup.transport.TransportClient;
+import com.google.android.collect.Sets;
+
+import java.util.Set;
+
/**
* Utility methods wrapping operations on ApplicationInfo and PackageInfo.
*/
public class AppBackupUtils {
private static final boolean DEBUG = false;
+ // Whitelist of system packages that are eligible for backup in non-system users.
+ private static final Set<String> systemPackagesWhitelistedForAllUsers =
+ Sets.newArraySet(PACKAGE_MANAGER_SENTINEL, PLATFORM_PACKAGE_NAME);
/**
* Returns whether app is eligible for backup.
@@ -72,9 +80,9 @@
// 2. they run as a system-level uid
if (UserHandle.isCore(app.uid)) {
- // and the backup is happening for non-system user
- if (userId != UserHandle.USER_SYSTEM && !app.packageName.equals(
- PACKAGE_MANAGER_SENTINEL)) {
+ // and the backup is happening for non-system user on a non-whitelisted package.
+ if (userId != UserHandle.USER_SYSTEM
+ && !systemPackagesWhitelistedForAllUsers.contains(app.packageName)) {
return false;
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
index 2f78276..39d5c9d 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
@@ -77,6 +77,15 @@
pw.println(" Temporarily (for DURATION ms) changes the service implemtation.");
pw.println(" To reset, call with just the USER_ID argument.");
pw.println("");
+ pw.println("");
+ pw.println(" set default-service-enabled USER_ID [true|false]");
+ pw.println(" Enable / disable the default service for the user.");
+ pw.println("");
+ pw.println("");
+ pw.println(" get default-service-enabled USER_ID");
+ pw.println(" Checks whether the default service is enabled for the user.");
+ pw.println("");
+ pw.println("");
pw.println(" list sessions [--user USER_ID]");
pw.println(" Lists all pending sessions.");
pw.println("");
@@ -91,6 +100,8 @@
switch(what) {
case "bind-instant-service-allowed":
return getBindInstantService(pw);
+ case "default-service-enabled":
+ return getDefaultServiceEnabled(pw);
default:
pw.println("Invalid set: " + what);
return -1;
@@ -105,6 +116,8 @@
return setBindInstantService(pw);
case "temporary-service":
return setTemporaryService(pw);
+ case "default-service-enabled":
+ return setDefaultServiceEnabled();
default:
pw.println("Invalid set: " + what);
return -1;
@@ -149,6 +162,20 @@
return 0;
}
+ private int setDefaultServiceEnabled() {
+ final int userId = getNextIntArgRequired();
+ final boolean enabled = Boolean.parseBoolean(getNextArg());
+ mService.setDefaultServiceEnabled(userId, enabled);
+ return 0;
+ }
+
+ private int getDefaultServiceEnabled(PrintWriter pw) {
+ final int userId = getNextIntArgRequired();
+ final boolean enabled = mService.isDefaultServiceEnabled(userId);
+ pw.println(enabled);
+ return 0;
+ }
+
private int requestDestroy(PrintWriter pw) {
if (!isNextArgSessions(pw)) {
return -1;
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index c8a27f1..7102b82 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -416,36 +416,5 @@
// TODO(b/122595322): implement
// TODO(b/119613670): log metrics
}
-
- @Override
- public void setActivityContentCaptureEnabled(ComponentName activity, boolean enabled) {
- if (mMaster.verbose) {
- Log.v(TAG, "setActivityContentCaptureEnabled(activity=" + activity + ", enabled="
- + enabled + ")");
- }
- // TODO(b/122595322): implement
- // TODO(b/119613670): log metrics
- }
-
- @Override
- public void setPackageContentCaptureEnabled(String packageName, boolean enabled) {
- if (mMaster.verbose) {
- Log.v(TAG,
- "setPackageContentCaptureEnabled(packageName=" + packageName + ", enabled="
- + enabled + ")");
- }
- // TODO(b/122595322): implement
- // TODO(b/119613670): log metrics
- }
-
- @Override
- public void getContentCaptureDisabledActivities(IResultReceiver receiver) {
- // TODO(b/122595322): implement
- }
-
- @Override
- public void getContentCaptureDisabledPackages(IResultReceiver receiver) {
- // TODO(b/122595322): implement
- }
}
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index f9de554..259aa50 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -19,7 +19,6 @@
":storaged_aidl",
":vold_aidl",
":gsiservice_aidl",
- ":mediaupdateservice_aidl",
"java/com/android/server/EventLogTags.logtags",
"java/com/android/server/am/EventLogTags.logtags",
],
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1cb2c4a..fe4411c 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1833,14 +1833,20 @@
"ConnectivityService");
}
- private void enforceAnyPermissionOf(String... permissions) {
+ private boolean checkAnyPermissionOf(String... permissions) {
for (String permission : permissions) {
if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
- return;
+ return true;
}
}
- throw new SecurityException(
- "Requires one of the following permissions: " + String.join(", ", permissions) + ".");
+ return false;
+ }
+
+ private void enforceAnyPermissionOf(String... permissions) {
+ if (!checkAnyPermissionOf(permissions)) {
+ throw new SecurityException("Requires one of the following permissions: "
+ + String.join(", ", permissions) + ".");
+ }
}
private void enforceInternetPermission() {
@@ -1860,19 +1866,22 @@
}
private void enforceSettingsPermission() {
- mContext.enforceCallingOrSelfPermission(
+ enforceAnyPermissionOf(
android.Manifest.permission.NETWORK_SETTINGS,
- "ConnectivityService");
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private boolean checkSettingsPermission() {
- return PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.NETWORK_SETTINGS);
+ return checkAnyPermissionOf(
+ android.Manifest.permission.NETWORK_SETTINGS,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private boolean checkSettingsPermission(int pid, int uid) {
return PERMISSION_GRANTED == mContext.checkPermission(
- android.Manifest.permission.NETWORK_SETTINGS, pid, uid);
+ android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
+ || PERMISSION_GRANTED == mContext.checkPermission(
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
}
private void enforceTetherAccessPermission() {
@@ -1882,9 +1891,9 @@
}
private void enforceConnectivityInternalPermission() {
- mContext.enforceCallingOrSelfPermission(
+ enforceAnyPermissionOf(
android.Manifest.permission.CONNECTIVITY_INTERNAL,
- "ConnectivityService");
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private void enforceControlAlwaysOnVpnPermission() {
@@ -1895,20 +1904,16 @@
private void enforceNetworkStackSettingsOrSetup() {
enforceAnyPermissionOf(
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK);
- }
-
- private void enforceNetworkStackPermission() {
- mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_SETUP_WIZARD,
android.Manifest.permission.NETWORK_STACK,
- "ConnectivityService");
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private boolean checkNetworkStackPermission() {
- return PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.NETWORK_STACK);
+ return checkAnyPermissionOf(
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private void enforceConnectivityRestrictedNetworksPermission() {
@@ -3240,6 +3245,25 @@
});
}
+ /**
+ * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this
+ * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself.
+ * @param appExtras Bundle to use as intent extras for the captive portal application.
+ * Must be treated as opaque to avoid preventing the captive portal app to
+ * update its arguments.
+ */
+ @Override
+ public void startCaptivePortalAppInternal(Bundle appExtras) {
+ mContext.checkCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+
+ final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
+ appIntent.putExtras(appExtras);
+ appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ Binder.withCleanCallingIdentity(() ->
+ mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
+ }
+
public boolean avoidBadWifi() {
return mMultinetworkPolicyTracker.getAvoidBadWifi();
}
@@ -6377,6 +6401,14 @@
}
@Override
+ public void startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds,
+ Messenger messenger, IBinder binder) {
+ enforceKeepalivePermission();
+ mKeepaliveTracker.startTcpKeepalive(
+ getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, messenger, binder);
+ }
+
+ @Override
public void stopKeepalive(Network network, int slot) {
mHandler.sendMessage(mHandler.obtainMessage(
NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, slot, SocketKeepalive.SUCCESS, network));
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 33c6dd2..4834ce0 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -92,6 +92,7 @@
import com.android.internal.util.Preconditions;
import com.android.server.location.AbstractLocationProvider;
import com.android.server.location.ActivityRecognitionProxy;
+import com.android.server.location.CallerIdentity;
import com.android.server.location.GeocoderProxy;
import com.android.server.location.GeofenceManager;
import com.android.server.location.GeofenceProxy;
@@ -113,6 +114,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -223,10 +225,10 @@
private final ArraySet<String> mIgnoreSettingsPackageWhitelist = new ArraySet<>();
@GuardedBy("mLock")
- private final ArrayMap<IBinder, Identity> mGnssMeasurementsListeners = new ArrayMap<>();
+ private final ArrayMap<IBinder, CallerIdentity> mGnssMeasurementsListeners = new ArrayMap<>();
@GuardedBy("mLock")
- private final ArrayMap<IBinder, Identity>
+ private final ArrayMap<IBinder, CallerIdentity>
mGnssNavigationMessageListeners = new ArrayMap<>();
// current active user on the device - other users are denied location data
@@ -456,7 +458,7 @@
ArrayList<Receiver> deadReceivers = null;
for (Receiver receiver : mReceivers.values()) {
- if (receiver.mIdentity.mPackageName.equals(packageName)) {
+ if (receiver.mCallerIdentity.mPackageName.equals(packageName)) {
if (deadReceivers == null) {
deadReceivers = new ArrayList<>();
}
@@ -479,7 +481,7 @@
for (Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
String provider = entry.getKey();
for (UpdateRecord record : entry.getValue()) {
- if (record.mReceiver.mIdentity.mUid == uid
+ if (record.mReceiver.mCallerIdentity.mUid == uid
&& record.mIsForegroundUid != foreground) {
if (D) {
Log.d(TAG, "request from uid " + uid + " is now "
@@ -487,7 +489,7 @@
}
record.updateForeground(foreground);
- if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
+ if (!isThrottlingExemptLocked(record.mReceiver.mCallerIdentity)) {
affectedProviders.add(provider);
}
}
@@ -497,8 +499,8 @@
applyRequirementsLocked(provider);
}
- for (Entry<IBinder, Identity> entry : mGnssMeasurementsListeners.entrySet()) {
- Identity callerIdentity = entry.getValue();
+ for (Entry<IBinder, CallerIdentity> entry : mGnssMeasurementsListeners.entrySet()) {
+ CallerIdentity callerIdentity = entry.getValue();
if (callerIdentity.mUid == uid) {
if (D) {
Log.d(TAG, "gnss measurements listener from uid " + uid
@@ -507,7 +509,7 @@
if (foreground || isThrottlingExemptLocked(entry.getValue())) {
mGnssMeasurementsProvider.addListener(
IGnssMeasurementsListener.Stub.asInterface(entry.getKey()),
- callerIdentity.mUid, callerIdentity.mPackageName);
+ callerIdentity);
} else {
mGnssMeasurementsProvider.removeListener(
IGnssMeasurementsListener.Stub.asInterface(entry.getKey()));
@@ -515,8 +517,8 @@
}
}
- for (Entry<IBinder, Identity> entry : mGnssNavigationMessageListeners.entrySet()) {
- Identity callerIdentity = entry.getValue();
+ for (Entry<IBinder, CallerIdentity> entry : mGnssNavigationMessageListeners.entrySet()) {
+ CallerIdentity callerIdentity = entry.getValue();
if (callerIdentity.mUid == uid) {
if (D) {
Log.d(TAG, "gnss navigation message listener from uid "
@@ -526,7 +528,7 @@
if (foreground || isThrottlingExemptLocked(entry.getValue())) {
mGnssNavigationMessageProvider.addListener(
IGnssNavigationMessageListener.Stub.asInterface(entry.getKey()),
- callerIdentity.mUid, callerIdentity.mPackageName);
+ callerIdentity);
} else {
mGnssNavigationMessageProvider.removeListener(
IGnssNavigationMessageListener.Stub.asInterface(entry.getKey()));
@@ -668,7 +670,7 @@
// create a passive location provider, which is always enabled
LocationProvider passiveProviderManager = new LocationProvider(PASSIVE_PROVIDER);
addProviderLocked(passiveProviderManager);
- mPassiveProvider = new PassiveProvider(passiveProviderManager);
+ mPassiveProvider = new PassiveProvider(mContext, passiveProviderManager);
passiveProviderManager.attachLocked(mPassiveProvider);
if (GnssLocationProvider.isSupported()) {
@@ -790,7 +792,7 @@
String[] testProviderStrings = resources.getStringArray(
com.android.internal.R.array.config_testLocationProviders);
for (String testProviderString : testProviderStrings) {
- String fragments[] = testProviderString.split(",");
+ String[] fragments = testProviderString.split(",");
String name = fragments[0].trim();
ProviderProperties properties = new ProviderProperties(
Boolean.parseBoolean(fragments[1]) /* requiresNetwork */,
@@ -804,7 +806,7 @@
Integer.parseInt(fragments[9]) /* accuracy */);
LocationProvider testProviderManager = new LocationProvider(name);
addProviderLocked(testProviderManager);
- new MockProvider(testProviderManager, properties);
+ new MockProvider(mContext, testProviderManager, properties);
}
}
@@ -814,12 +816,6 @@
return;
}
- // this call has the side effect of forcing a write to the LOCATION_MODE setting in an OS
- // upgrade case, and ensures that if anyone checks the LOCATION_MODE setting directly, they
- // will see it in an appropriate state (at least after that user becomes foreground for the
- // first time...)
- isLocationEnabledForUser(userId);
-
// let providers know the current user is on the way out before changing the user
for (LocationProvider p : mProviders) {
p.onUserChangingLocked();
@@ -835,18 +831,6 @@
onProviderAllowedChangedLocked(false);
}
- private static final class Identity {
- final int mUid;
- final int mPid;
- final String mPackageName;
-
- Identity(int uid, int pid, String packageName) {
- mUid = uid;
- mPid = pid;
- mPackageName = packageName;
- }
- }
-
private class LocationProvider implements AbstractLocationProvider.LocationProviderManager {
private final String mName;
@@ -906,15 +890,12 @@
}
@GuardedBy("mLock")
- @Nullable
- public String getPackageLocked() {
+ public List<String> getPackagesLocked() {
if (mProvider == null) {
- return null;
- } else if (mProvider instanceof LocationProviderProxy) {
- // safe to not clear binder context since this doesn't call into the actual provider
- return ((LocationProviderProxy) mProvider).getConnectedPackageName();
+ return Collections.emptyList();
} else {
- return mContext.getPackageName();
+ // safe to not clear binder context since this doesn't call into the real provider
+ return mProvider.getProviderPackages();
}
}
@@ -947,17 +928,22 @@
@GuardedBy("mLock")
public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(mName + " provider:");
+ pw.print(" " + mName + " provider");
if (isMock()) {
- pw.println(" mock=true");
+ pw.print(" [mock]");
}
- pw.println(" attached=" + (mProvider != null));
- if (mIsManagedBySettings) {
- pw.println(" allowed=" + mAllowed);
+ pw.println(":");
+
+ pw.println(" useable=" + mUseable);
+ if (!mUseable) {
+ pw.println(" attached=" + (mProvider != null));
+ if (mIsManagedBySettings) {
+ pw.println(" allowed=" + mAllowed);
+ }
+ pw.println(" enabled=" + mEnabled);
}
- pw.println(" enabled=" + mEnabled);
- pw.println(" useable=" + mUseable);
- pw.println(" properties=" + mProperties);
+
+ pw.println(" properties=" + mProperties);
if (mProvider != null) {
long identity = Binder.clearCallingIdentity();
@@ -1234,7 +1220,7 @@
*/
private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished {
private static final long WAKELOCK_TIMEOUT_MILLIS = 60 * 1000;
- final Identity mIdentity;
+ final CallerIdentity mCallerIdentity;
private final int mAllowedResolutionLevel; // resolution level allowed to receiver
private final ILocationListener mListener;
@@ -1262,7 +1248,7 @@
mKey = intent;
}
mAllowedResolutionLevel = getAllowedResolutionLevel(pid, uid);
- mIdentity = new Identity(uid, pid, packageName);
+ mCallerIdentity = new CallerIdentity(uid, pid, packageName);
if (workSource != null && workSource.isEmpty()) {
workSource = null;
}
@@ -1274,7 +1260,7 @@
// construct/configure wakelock
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
if (workSource == null) {
- workSource = new WorkSource(mIdentity.mUid, mIdentity.mPackageName);
+ workSource = new WorkSource(mCallerIdentity.mUid, mCallerIdentity.mPackageName);
}
mWakeLock.setWorkSource(workSource);
@@ -1377,14 +1363,14 @@
int op) {
if (!currentlyMonitoring) {
if (allowMonitoring) {
- return mAppOps.startOpNoThrow(op, mIdentity.mUid, mIdentity.mPackageName)
- == AppOpsManager.MODE_ALLOWED;
+ return mAppOps.startOpNoThrow(op, mCallerIdentity.mUid,
+ mCallerIdentity.mPackageName) == AppOpsManager.MODE_ALLOWED;
}
} else {
if (!allowMonitoring
- || mAppOps.noteOpNoThrow(op, mIdentity.mUid, mIdentity.mPackageName)
- != AppOpsManager.MODE_ALLOWED) {
- mAppOps.finishOp(op, mIdentity.mUid, mIdentity.mPackageName);
+ || mAppOps.checkOpNoThrow(op, mCallerIdentity.mUid,
+ mCallerIdentity.mPackageName) != AppOpsManager.MODE_ALLOWED) {
+ mAppOps.finishOp(op, mCallerIdentity.mUid, mCallerIdentity.mPackageName);
return false;
}
}
@@ -1410,14 +1396,10 @@
public boolean callStatusChangedLocked(String provider, int status, Bundle extras) {
if (mListener != null) {
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mListener.onStatusChanged(provider, status, extras);
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mListener.onStatusChanged(provider, status, extras);
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (RemoteException e) {
return false;
}
@@ -1426,16 +1408,12 @@
statusChanged.putExtras(new Bundle(extras));
statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status);
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mPendingIntent.send(mContext, 0, statusChanged, this, mHandler,
- getResolutionPermission(mAllowedResolutionLevel),
- PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mPendingIntent.send(mContext, 0, statusChanged, this, mHandler,
+ getResolutionPermission(mAllowedResolutionLevel),
+ PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (PendingIntent.CanceledException e) {
return false;
}
@@ -1446,14 +1424,10 @@
public boolean callLocationChangedLocked(Location location) {
if (mListener != null) {
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mListener.onLocationChanged(new Location(location));
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mListener.onLocationChanged(new Location(location));
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (RemoteException e) {
return false;
}
@@ -1462,16 +1436,12 @@
locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED,
new Location(location));
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mPendingIntent.send(mContext, 0, locationChanged, this, mHandler,
- getResolutionPermission(mAllowedResolutionLevel),
- PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mPendingIntent.send(mContext, 0, locationChanged, this, mHandler,
+ getResolutionPermission(mAllowedResolutionLevel),
+ PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (PendingIntent.CanceledException e) {
return false;
}
@@ -1486,18 +1456,14 @@
if (mListener != null) {
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- if (enabled) {
- mListener.onProviderEnabled(provider);
- } else {
- mListener.onProviderDisabled(provider);
- }
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
+ if (enabled) {
+ mListener.onProviderEnabled(provider);
+ } else {
+ mListener.onProviderDisabled(provider);
}
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (RemoteException e) {
return false;
}
@@ -1505,16 +1471,12 @@
Intent providerIntent = new Intent();
providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled);
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mPendingIntent.send(mContext, 0, providerIntent, this, mHandler,
- getResolutionPermission(mAllowedResolutionLevel),
- PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mPendingIntent.send(mContext, 0, providerIntent, this, mHandler,
+ getResolutionPermission(mAllowedResolutionLevel),
+ PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (PendingIntent.CanceledException e) {
return false;
}
@@ -1528,8 +1490,6 @@
synchronized (mLock) {
removeUpdatesLocked(this);
- }
- synchronized (this) {
clearPendingBroadcastsLocked();
}
}
@@ -1537,7 +1497,7 @@
@Override
public void onSendFinished(PendingIntent pendingIntent, Intent intent,
int resultCode, String resultData, Bundle resultExtras) {
- synchronized (this) {
+ synchronized (mLock) {
decrementPendingBroadcastsLocked();
}
}
@@ -1546,13 +1506,25 @@
// containing the sending of the broadcaset
private void incrementPendingBroadcastsLocked() {
mPendingBroadcasts++;
- mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
+ // so wakelock calls will succeed
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
private void decrementPendingBroadcastsLocked() {
if (--mPendingBroadcasts == 0) {
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
+ // so wakelock calls will succeed
+ long identity = Binder.clearCallingIdentity();
+ try {
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
}
@@ -1560,8 +1532,14 @@
public void clearPendingBroadcastsLocked() {
if (mPendingBroadcasts > 0) {
mPendingBroadcasts = 0;
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
+ // so wakelock calls will succeed
+ long identity = Binder.clearCallingIdentity();
+ try {
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
}
@@ -1574,18 +1552,9 @@
//LocationListener was removed when it had a pending broadcast and should
//not be added back.
synchronized (mLock) {
- IBinder binder = listener.asBinder();
- Receiver receiver = mReceivers.get(binder);
+ Receiver receiver = mReceivers.get(listener.asBinder());
if (receiver != null) {
- synchronized (receiver) {
- // so wakelock calls will succeed
- long identity = Binder.clearCallingIdentity();
- try {
- receiver.decrementPendingBroadcastsLocked();
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
+ receiver.decrementPendingBroadcastsLocked();
}
}
}
@@ -1722,7 +1691,6 @@
}
}
-
@Override
public void flushGnssBatch(String packageName) {
mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE,
@@ -1918,7 +1886,7 @@
int allowedResolutionLevel) {
int op = resolutionLevelToOp(allowedResolutionLevel);
if (op >= 0) {
- if (mAppOps.noteOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
+ if (mAppOps.checkOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
return false;
}
}
@@ -2014,7 +1982,7 @@
if (records != null) {
for (UpdateRecord record : records) {
if (!isCurrentProfileLocked(
- UserHandle.getUserId(record.mReceiver.mIdentity.mUid))) {
+ UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
continue;
}
@@ -2073,24 +2041,31 @@
providerRequest.lowPowerMode = true;
for (UpdateRecord record : records) {
if (!isCurrentProfileLocked(
- UserHandle.getUserId(record.mReceiver.mIdentity.mUid))) {
+ UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
continue;
}
if (!checkLocationAccess(
- record.mReceiver.mIdentity.mPid,
- record.mReceiver.mIdentity.mUid,
- record.mReceiver.mIdentity.mPackageName,
+ record.mReceiver.mCallerIdentity.mPid,
+ record.mReceiver.mCallerIdentity.mUid,
+ record.mReceiver.mCallerIdentity.mPackageName,
record.mReceiver.mAllowedResolutionLevel)) {
continue;
}
- if (!provider.isUseableLocked() && !isSettingsExemptLocked(record)) {
- continue;
+ if (!provider.isUseableLocked()) {
+ if (isSettingsExemptLocked(record)) {
+ providerRequest.forceLocation = true;
+ providerRequest.lowPowerMode = false;
+ } else {
+ continue;
+ }
}
LocationRequest locationRequest = record.mRealRequest;
long interval = locationRequest.getInterval();
- if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
+ // if we're forcing location, don't apply any throttling
+ if (!providerRequest.forceLocation && !isThrottlingExemptLocked(
+ record.mReceiver.mCallerIdentity)) {
if (!record.mIsForegroundUid) {
interval = Math.max(interval, backgroundThrottleInterval);
}
@@ -2120,7 +2095,7 @@
long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2;
for (UpdateRecord record : records) {
if (isCurrentProfileLocked(
- UserHandle.getUserId(record.mReceiver.mIdentity.mUid))) {
+ UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
LocationRequest locationRequest = record.mRequest;
// Don't assign battery blame for update records whose
@@ -2137,8 +2112,8 @@
// Assign blame to caller if there's no WorkSource associated with
// the request or if it's invalid.
worksource.add(
- record.mReceiver.mIdentity.mUid,
- record.mReceiver.mIdentity.mPackageName);
+ record.mReceiver.mCallerIdentity.mUid,
+ record.mReceiver.mCallerIdentity.mPackageName);
}
}
}
@@ -2175,22 +2150,17 @@
}
@GuardedBy("mLock")
- private boolean isThrottlingExemptLocked(Identity identity) {
- if (identity.mUid == Process.SYSTEM_UID) {
+ private boolean isThrottlingExemptLocked(CallerIdentity callerIdentity) {
+ if (callerIdentity.mUid == Process.SYSTEM_UID) {
return true;
}
- if (mBackgroundThrottlePackageWhitelist.contains(identity.mPackageName)) {
+ if (mBackgroundThrottlePackageWhitelist.contains(callerIdentity.mPackageName)) {
return true;
}
- for (LocationProvider provider : mProviders) {
- if (identity.mPackageName.equals(provider.getPackageLocked())) {
- return true;
- }
- }
+ return isProviderPackage(callerIdentity.mPackageName);
- return false;
}
@GuardedBy("mLock")
@@ -2199,17 +2169,13 @@
return false;
}
- if (mIgnoreSettingsPackageWhitelist.contains(record.mReceiver.mIdentity.mPackageName)) {
+ if (mIgnoreSettingsPackageWhitelist.contains(
+ record.mReceiver.mCallerIdentity.mPackageName)) {
return true;
}
- for (LocationProvider provider : mProviders) {
- if (record.mReceiver.mIdentity.mPackageName.equals(provider.getPackageLocked())) {
- return true;
- }
- }
+ return isProviderPackage(record.mReceiver.mCallerIdentity.mPackageName);
- return false;
}
private class UpdateRecord {
@@ -2230,7 +2196,7 @@
mRequest = request;
mReceiver = receiver;
mIsForegroundUid = isImportanceForeground(
- mActivityManager.getPackageImportance(mReceiver.mIdentity.mPackageName));
+ mActivityManager.getPackageImportance(mReceiver.mCallerIdentity.mPackageName));
ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
if (records == null) {
@@ -2243,7 +2209,7 @@
// Update statistics for historical location requests by package/provider
mRequestStatistics.startRequesting(
- mReceiver.mIdentity.mPackageName, provider, request.getInterval(),
+ mReceiver.mCallerIdentity.mPackageName, provider, request.getInterval(),
mIsForegroundUid);
}
@@ -2253,14 +2219,14 @@
private void updateForeground(boolean isForeground) {
mIsForegroundUid = isForeground;
mRequestStatistics.updateForeground(
- mReceiver.mIdentity.mPackageName, mProvider, isForeground);
+ mReceiver.mCallerIdentity.mPackageName, mProvider, isForeground);
}
/**
* Method to be called when a record will no longer be used.
*/
private void disposeLocked(boolean removeReceiver) {
- mRequestStatistics.stopRequesting(mReceiver.mIdentity.mPackageName, mProvider);
+ mRequestStatistics.stopRequesting(mReceiver.mCallerIdentity.mPackageName, mProvider);
// remove from mRecordsByProvider
ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider);
@@ -2282,8 +2248,8 @@
@Override
public String toString() {
- return "UpdateRecord[" + mProvider + " " + mReceiver.mIdentity.mPackageName
- + "(" + mReceiver.mIdentity.mUid + (mIsForegroundUid ? " foreground"
+ return "UpdateRecord[" + mProvider + " " + mReceiver.mCallerIdentity.mPackageName
+ + "(" + mReceiver.mCallerIdentity.mUid + (mIsForegroundUid ? " foreground"
: " background")
+ ")" + " " + mRealRequest + " "
+ mReceiver.mWorkSource + "]";
@@ -2458,7 +2424,7 @@
Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver))
+ " " + name + " " + request + " from " + packageName + "(" + uid + " "
+ (record.mIsForegroundUid ? "foreground" : "background")
- + (isThrottlingExemptLocked(receiver.mIdentity)
+ + (isThrottlingExemptLocked(receiver.mCallerIdentity)
? " [whitelisted]" : "") + ")");
}
@@ -2517,9 +2483,7 @@
if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
- synchronized (receiver) {
- receiver.clearPendingBroadcastsLocked();
- }
+ receiver.clearPendingBroadcastsLocked();
}
receiver.updateMonitoring(false);
@@ -2566,13 +2530,6 @@
return null;
}
- if (!reportLocationAccessNoThrow(pid, uid, packageName, allowedResolutionLevel)) {
- if (D) {
- Log.d(TAG, "not returning last loc for no op app: "
- + packageName);
- }
- return null;
- }
// Figure out the provider. Either its explicitly request (deprecated API's),
// or use the fused provider
@@ -2582,8 +2539,8 @@
if (provider == null) return null;
// only the current user or location providers may get location this way
- if (!isCurrentProfileLocked(UserHandle.getUserId(uid)) && !isLocationProviderLocked(
- uid)) {
+ if (!isCurrentProfileLocked(UserHandle.getUserId(uid)) && !isProviderPackage(
+ packageName)) {
return null;
}
@@ -2616,16 +2573,27 @@
return null;
}
+ Location lastLocation = null;
if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) {
Location noGPSLocation = location.getExtraLocation(
Location.EXTRA_NO_GPS_LOCATION);
if (noGPSLocation != null) {
- return new Location(mLocationFudger.getOrCreate(noGPSLocation));
+ lastLocation = new Location(mLocationFudger.getOrCreate(noGPSLocation));
}
} else {
- return new Location(location);
+ lastLocation = new Location(location);
}
- return null;
+ // Don't report location access if there is no last location to deliver.
+ if (lastLocation != null) {
+ if (!reportLocationAccessNoThrow(
+ pid, uid, packageName, allowedResolutionLevel)) {
+ if (D) {
+ Log.d(TAG, "not returning last loc for no op app: " + packageName);
+ }
+ lastLocation = null;
+ }
+ }
+ return lastLocation;
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2691,7 +2659,6 @@
// geo-fence manager uses the public location API, need to clear identity
int uid = Binder.getCallingUid();
- // TODO: http://b/23822629
if (UserHandle.getUserId(uid) != UserHandle.USER_SYSTEM) {
// temporary measure until geofences work for secondary users
Log.w(TAG, "proximity alerts are currently available only to the primary user");
@@ -2732,9 +2699,8 @@
return false;
}
- // TODO(b/120449926): The GNSS status listeners should be handled similar to the GNSS
- // measurements listeners.
- return mGnssStatusProvider.addListener(callback, Binder.getCallingUid(), packageName);
+ return mGnssStatusProvider.addListener(callback, new CallerIdentity(Binder.getCallingUid(),
+ Binder.getCallingPid(), packageName));
}
@Override
@@ -2750,17 +2716,15 @@
}
synchronized (mLock) {
- Identity callerIdentity
- = new Identity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
- // TODO(b/120481270): Register for client death notification and update map.
+ CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(),
+ Binder.getCallingPid(), packageName);
mGnssMeasurementsListeners.put(listener.asBinder(), callerIdentity);
long identity = Binder.clearCallingIdentity();
try {
if (isThrottlingExemptLocked(callerIdentity)
|| isImportanceForeground(
mActivityManager.getPackageImportance(packageName))) {
- return mGnssMeasurementsProvider.addListener(listener,
- callerIdentity.mUid, callerIdentity.mPackageName);
+ return mGnssMeasurementsProvider.addListener(listener, callerIdentity);
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -2777,9 +2741,9 @@
android.Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to inject GNSS measurement corrections.");
if (!hasGnssPermissions(packageName) || mGnssMeasurementsProvider == null) {
- mGnssMeasurementsProvider.injectGnssMeasurementCorrections(measurementCorrections);
- } else {
Slog.e(TAG, "Can not inject GNSS corrections due to no permission.");
+ } else {
+ mGnssMeasurementsProvider.injectGnssMeasurementCorrections(measurementCorrections);
}
}
@@ -2815,18 +2779,16 @@
}
synchronized (mLock) {
- Identity callerIdentity
- = new Identity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
+ CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(),
+ Binder.getCallingPid(), packageName);
- // TODO(b/120481270): Register for client death notification and update map.
mGnssNavigationMessageListeners.put(listener.asBinder(), callerIdentity);
long identity = Binder.clearCallingIdentity();
try {
if (isThrottlingExemptLocked(callerIdentity)
|| isImportanceForeground(
mActivityManager.getPackageImportance(packageName))) {
- return mGnssNavigationMessageProvider.addListener(listener,
- callerIdentity.mUid, callerIdentity.mPackageName);
+ return mGnssNavigationMessageProvider.addListener(listener, callerIdentity);
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -2900,13 +2862,15 @@
}
@Override
- public String getNetworkProviderPackage() {
+ public boolean isProviderPackage(String packageName) {
synchronized (mLock) {
- LocationProvider provider = getLocationProviderLocked(NETWORK_PROVIDER);
- if (provider == null) {
- return null;
+ for (LocationProvider provider : mProviders) {
+ if (provider.getPackagesLocked().contains(packageName)) {
+ return true;
+ }
}
- return provider.getPackageLocked();
+
+ return false;
}
}
@@ -2988,28 +2952,6 @@
}
@GuardedBy("mLock")
- private boolean isLocationProviderLocked(int uid) {
- if (uid == Process.SYSTEM_UID) {
- return true;
- }
-
- String[] packageNames = mPackageManager.getPackagesForUid(uid);
- if (packageNames == null) {
- return false;
- }
- for (LocationProvider provider : mProviders) {
- String packageName = provider.getPackageLocked();
- if (packageName == null) {
- continue;
- }
- if (ArrayUtils.contains(packageNames, packageName)) {
- return true;
- }
- }
- return false;
- }
-
- @GuardedBy("mLock")
private static boolean shouldBroadcastSafeLocked(
Location loc, Location lastLoc, UpdateRecord record, long now) {
// Always broadcast the first update
@@ -3109,33 +3051,33 @@
continue;
}
- int receiverUserId = UserHandle.getUserId(receiver.mIdentity.mUid);
+ int receiverUserId = UserHandle.getUserId(receiver.mCallerIdentity.mUid);
if (!isCurrentProfileLocked(receiverUserId)
- && !isLocationProviderLocked(receiver.mIdentity.mUid)) {
+ && !isProviderPackage(receiver.mCallerIdentity.mPackageName)) {
if (D) {
Log.d(TAG, "skipping loc update for background user " + receiverUserId +
" (current user: " + mCurrentUserId + ", app: " +
- receiver.mIdentity.mPackageName + ")");
+ receiver.mCallerIdentity.mPackageName + ")");
}
continue;
}
- if (mBlacklist.isBlacklisted(receiver.mIdentity.mPackageName)) {
+ if (mBlacklist.isBlacklisted(receiver.mCallerIdentity.mPackageName)) {
if (D) {
Log.d(TAG, "skipping loc update for blacklisted app: " +
- receiver.mIdentity.mPackageName);
+ receiver.mCallerIdentity.mPackageName);
}
continue;
}
if (!reportLocationAccessNoThrow(
- receiver.mIdentity.mPid,
- receiver.mIdentity.mUid,
- receiver.mIdentity.mPackageName,
+ receiver.mCallerIdentity.mPid,
+ receiver.mCallerIdentity.mUid,
+ receiver.mCallerIdentity.mPackageName,
receiver.mAllowedResolutionLevel)) {
if (D) {
Log.d(TAG, "skipping loc update for no op app: " +
- receiver.mIdentity.mPackageName);
+ receiver.mCallerIdentity.mPackageName);
}
continue;
}
@@ -3271,7 +3213,7 @@
// Mock Providers
private boolean canCallerAccessMockLocation(String opPackageName) {
- return mAppOps.noteOp(AppOpsManager.OP_MOCK_LOCATION, Binder.getCallingUid(),
+ return mAppOps.checkOp(AppOpsManager.OP_MOCK_LOCATION, Binder.getCallingUid(),
opPackageName) == AppOpsManager.MODE_ALLOWED;
}
@@ -3300,7 +3242,8 @@
MockLocationProvider mockProviderManager = new MockLocationProvider(name);
addProviderLocked(mockProviderManager);
- mockProviderManager.attachLocked(new MockProvider(mockProviderManager, properties));
+ mockProviderManager.attachLocked(
+ new MockProvider(mContext, mockProviderManager, properties));
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -3411,7 +3354,9 @@
return;
}
pw.println("Current Location Manager state:");
- pw.println(" Location Mode: " + isLocationEnabled());
+ pw.println(" Current user: " + mCurrentUserId + " " + Arrays.toString(
+ mCurrentUserProfiles));
+ pw.println(" Location mode: " + isLocationEnabled());
pw.println(" Location Listeners:");
for (Receiver receiver : mReceivers.values()) {
pw.println(" " + receiver);
@@ -3424,22 +3369,16 @@
}
}
pw.println(" Active GnssMeasurement Listeners:");
- for (Identity identity : mGnssMeasurementsListeners.values()) {
- pw.println(" " + identity.mPid + " " + identity.mUid + " "
- + identity.mPackageName + ": " + isThrottlingExemptLocked(identity));
+ for (CallerIdentity callerIdentity : mGnssMeasurementsListeners.values()) {
+ pw.println(" " + callerIdentity.mPid + " " + callerIdentity.mUid + " "
+ + callerIdentity.mPackageName + ": "
+ + isThrottlingExemptLocked(callerIdentity));
}
pw.println(" Active GnssNavigationMessage Listeners:");
- for (Identity identity : mGnssNavigationMessageListeners.values()) {
- pw.println(" " + identity.mPid + " " + identity.mUid + " "
- + identity.mPackageName + ": " + isThrottlingExemptLocked(identity));
- }
- pw.println(" Overlay Provider Packages:");
- for (LocationProvider provider : mProviders) {
- if (provider.mProvider instanceof LocationProviderProxy) {
- pw.println(" " + provider.getName() + ": "
- + ((LocationProviderProxy) provider.mProvider)
- .getConnectedPackageName());
- }
+ for (CallerIdentity callerIdentity : mGnssNavigationMessageListeners.values()) {
+ pw.println(" " + callerIdentity.mPid + " " + callerIdentity.mUid + " "
+ + callerIdentity.mPackageName + ": "
+ + isThrottlingExemptLocked(callerIdentity));
}
pw.println(" Historical Records by Provider:");
for (Map.Entry<PackageProviderKey, PackageStatistics> entry
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 1b1e6ad..6b57fcd 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -37,6 +37,8 @@
import android.os.Binder;
import android.os.Handler;
import android.os.PowerManager;
+import android.os.PowerManager.ServiceType;
+import android.os.PowerManagerInternal;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -161,9 +163,6 @@
case Intent.ACTION_BATTERY_CHANGED:
mCharging = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
break;
- case PowerManager.ACTION_POWER_SAVE_MODE_CHANGING:
- mPowerSave = intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false);
- break;
}
synchronized (mLock) {
if (mSystemReady) {
@@ -208,9 +207,24 @@
context.registerReceiver(mDockModeReceiver,
new IntentFilter(Intent.ACTION_DOCK_EVENT));
IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
- batteryFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
context.registerReceiver(mBatteryReceiver, batteryFilter);
+ PowerManagerInternal localPowerManager =
+ LocalServices.getService(PowerManagerInternal.class);
+ mPowerSave = localPowerManager.getLowPowerState(ServiceType.NIGHT_MODE).batterySaverEnabled;
+ localPowerManager.registerLowPowerModeObserver(ServiceType.NIGHT_MODE,
+ state -> {
+ synchronized (mLock) {
+ if (mPowerSave == state.batterySaverEnabled) {
+ return;
+ }
+ mPowerSave = state.batterySaverEnabled;
+ if (mSystemReady) {
+ updateLocked(0, 0);
+ }
+ }
+ });
+
mConfiguration.setToDefaults();
final Resources res = context.getResources();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 2f1f91e..026430b 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -333,7 +333,8 @@
}
r.delayed = false;
try {
- startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
+ startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true,
+ false);
} catch (TransactionTooLargeException e) {
// Ignore, nobody upstack cares.
}
@@ -643,7 +644,8 @@
SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
}
}
- ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
+ ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
+ allowBackgroundActivityStarts);
return cmp;
}
@@ -702,7 +704,8 @@
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
- boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
+ boolean callerFg, boolean addToStarting, boolean allowBackgroundActivityStarts)
+ throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
@@ -713,7 +716,8 @@
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
- String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
+ String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false,
+ allowBackgroundActivityStarts);
if (error != null) {
return new ComponentName("!!", error);
}
@@ -1645,7 +1649,7 @@
try {
bringUpServiceLocked(serviceRecord,
serviceIntent.getFlags(),
- callerFg, false, false);
+ callerFg, false, false, false);
} catch (RemoteException e) {
/* ignore - local call */
}
@@ -1748,7 +1752,7 @@
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
- permissionsReviewRequired) != null) {
+ permissionsReviewRequired, false) != null) {
return 0;
}
}
@@ -2418,7 +2422,8 @@
return;
}
try {
- bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false);
+ bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false,
+ false);
} catch (TransactionTooLargeException e) {
// Ignore, it's been logged and nothing upstack cares.
}
@@ -2463,8 +2468,8 @@
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
- boolean whileRestarting, boolean permissionsReviewRequired)
- throws TransactionTooLargeException {
+ boolean whileRestarting, boolean permissionsReviewRequired,
+ boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
//Slog.i(TAG, "Bring up service:");
//r.dump(" ");
@@ -2575,6 +2580,13 @@
}
}
+ if (app != null && allowBackgroundActivityStarts) {
+ app.addAllowBackgroundActivityStartsToken(r);
+ // schedule removal of the whitelisting token after the timeout
+ removeAllowBackgroundActivityStartsServiceToken(app, r,
+ SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
+ }
+
if (r.fgRequired) {
if (DEBUG_FOREGROUND_SERVICE) {
Slog.v(TAG, "Whitelisting " + UserHandle.formatUid(r.appInfo.uid)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 94fc552..5932f99 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3495,7 +3495,7 @@
if (!app.killedByAm) {
reportUidInfoMessageLocked(TAG,
"Process " + app.processName + " (pid " + pid + ") has died: "
- + ProcessList.makeOomAdjString(app.setAdj)
+ + ProcessList.makeOomAdjString(app.setAdj, true) + " "
+ ProcessList.makeProcStateString(app.setProcState), app.info.uid);
mAllowLowerMemLevel = true;
} else {
@@ -10029,7 +10029,7 @@
pw.print(" #");
pw.print(index);
pw.print(": ");
- pw.print(ProcessList.makeOomAdjString(proc.setAdj));
+ pw.print(ProcessList.makeOomAdjString(proc.setAdj, false));
pw.print(" ");
pw.print(ProcessList.makeProcStateString(proc.getCurProcState()));
pw.print(" ");
@@ -11334,7 +11334,7 @@
for (int i = list.size() - 1; i >= 0; i--) {
ProcessRecord r = list.get(i).first;
long token = proto.start(fieldId);
- String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
+ String oomAdj = ProcessList.makeOomAdjString(r.setAdj, true);
proto.write(ProcessOomProto.PERSISTENT, r.isPersistent());
proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
@@ -11434,7 +11434,7 @@
for (int i=list.size()-1; i>=0; i--) {
ProcessRecord r = list.get(i).first;
- String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
+ String oomAdj = ProcessList.makeOomAdjString(r.setAdj, false);
char schedGroup;
switch (r.setSchedGroup) {
case ProcessList.SCHED_GROUP_BACKGROUND:
@@ -12871,7 +12871,7 @@
private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
long memtrack, String name) {
sb.append(" ");
- sb.append(ProcessList.makeOomAdjString(oomAdj));
+ sb.append(ProcessList.makeOomAdjString(oomAdj, false));
sb.append(' ');
sb.append(ProcessList.makeProcStateString(procState));
sb.append(' ');
@@ -14997,7 +14997,7 @@
oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
oldRecord.intent,
Activity.RESULT_CANCELED, null, null,
- false, false, oldRecord.userId);
+ false, false, oldRecord.userId, oldRecord);
} catch (RemoteException e) {
Slog.w(TAG, "Failure ["
+ queue.mQueueName + "] sending broadcast result of "
diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/AppCompactor.java
index 1118014..502f078 100644
--- a/services/core/java/com/android/server/am/AppCompactor.java
+++ b/services/core/java/com/android/server/am/AppCompactor.java
@@ -170,6 +170,9 @@
updateCompactionThrottles();
updateStatsdSampleRate();
}
+ Process.setThreadGroupAndCpuset(mCompactionThread.getThreadId(),
+ Process.THREAD_GROUP_SYSTEM);
+
}
/**
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index a11ebfd..f0b137a 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -74,6 +74,9 @@
static final int MAX_BROADCAST_SUMMARY_HISTORY
= ActivityManager.isLowRamDeviceStatic() ? 25 : 300;
+ // For how long after a whitelisted receiver's start its process can start a background activity
+ private static final int RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS = 10_000;
+
final ActivityManagerService mService;
/**
@@ -551,13 +554,23 @@
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
- boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
+ boolean ordered, boolean sticky, int sendingUser, BroadcastRecord br)
+ throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
if (app.thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
try {
+ if (br.allowBackgroundActivityStarts) {
+ app.addAllowBackgroundActivityStartsToken(br);
+ // schedule removal of the whitelisting token after the timeout
+ mHandler.postDelayed(() -> {
+ if (app != null) {
+ app.removeAllowBackgroundActivityStartsToken(br);
+ }
+ }, RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS);
+ }
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
// TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
@@ -783,7 +796,7 @@
} else {
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
- r.resultExtras, r.ordered, r.initialSticky, r.userId);
+ r.resultExtras, r.ordered, r.initialSticky, r.userId, r);
}
if (ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
@@ -1082,7 +1095,7 @@
}
performReceiveLocked(r.callerApp, r.resultTo,
new Intent(r.intent), r.resultCode,
- r.resultData, r.resultExtras, false, false, r.userId);
+ r.resultData, r.resultExtras, false, false, r.userId, r);
// Set this to null so that the reference
// (local and remote) isn't kept in the mBroadcastHistory.
r.resultTo = null;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 4985c52..7035698 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -412,14 +412,14 @@
mNumCachedHiddenProcs++;
numCached++;
if (app.connectionGroup != 0) {
- if (lastCachedGroupUid == app.uid
+ if (lastCachedGroupUid == app.info.uid
&& lastCachedGroup == app.connectionGroup) {
// If this process is the next in the same group, we don't
// want it to count against our limit of the number of cached
// processes, so bump up the group count to account for it.
numCachedExtraGroup++;
} else {
- lastCachedGroupUid = app.uid;
+ lastCachedGroupUid = app.info.uid;
lastCachedGroup = app.connectionGroup;
}
} else {
@@ -1709,8 +1709,9 @@
(app.curAdj == ProcessList.PREVIOUS_APP_ADJ ||
app.curAdj == ProcessList.HOME_APP_ADJ)) {
mAppCompact.compactAppSome(app);
- } else if (app.setAdj < ProcessList.CACHED_APP_MIN_ADJ &&
- app.curAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+ } else if (app.setAdj < ProcessList.CACHED_APP_MIN_ADJ
+ && app.curAdj >= ProcessList.CACHED_APP_MIN_ADJ
+ && app.curAdj <= ProcessList.CACHED_APP_MAX_ADJ) {
mAppCompact.compactAppFull(app);
}
}
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 0b27a8a..af56352 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -384,6 +384,9 @@
final boolean allowTrampoline = uid != callingUid
&& controller.mAtmInternal.isUidForeground(callingUid);
+ // note: we on purpose don't pass in the information about the PendingIntent's creator,
+ // like pid or ProcessRecord, to the ActivityTaskManagerInternal calls below, because
+ // it's not unusual for the creator's process to not be alive at this time
switch (key.type) {
case ActivityManager.INTENT_SENDER_ACTIVITY:
try {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index f90c0ca..69cf54b 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -679,47 +679,65 @@
return totalProcessLimit/2;
}
- private static String buildOomTag(String prefix, String space, int val, int base) {
+ private static String buildOomTag(String prefix, String compactPrefix, String space, int val,
+ int base, boolean compact) {
final int diff = val - base;
if (diff == 0) {
+ if (compact) {
+ return compactPrefix;
+ }
if (space == null) return prefix;
return prefix + space;
}
if (diff < 10) {
- return prefix + "+ " + Integer.toString(diff);
+ return prefix + (compact ? "+" : "+ ") + Integer.toString(diff);
}
return prefix + "+" + Integer.toString(diff);
}
- public static String makeOomAdjString(int setAdj) {
+ public static String makeOomAdjString(int setAdj, boolean compact) {
if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
- return buildOomTag("cch", " ", setAdj, ProcessList.CACHED_APP_MIN_ADJ);
+ return buildOomTag("cch", "cch", " ", setAdj,
+ ProcessList.CACHED_APP_MIN_ADJ, compact);
} else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
- return buildOomTag("svcb ", null, setAdj, ProcessList.SERVICE_B_ADJ);
+ return buildOomTag("svcb ", "svcb", null, setAdj,
+ ProcessList.SERVICE_B_ADJ, compact);
} else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
- return buildOomTag("prev ", null, setAdj, ProcessList.PREVIOUS_APP_ADJ);
+ return buildOomTag("prev ", "prev", null, setAdj,
+ ProcessList.PREVIOUS_APP_ADJ, compact);
} else if (setAdj >= ProcessList.HOME_APP_ADJ) {
- return buildOomTag("home ", null, setAdj, ProcessList.HOME_APP_ADJ);
+ return buildOomTag("home ", "home", null, setAdj,
+ ProcessList.HOME_APP_ADJ, compact);
} else if (setAdj >= ProcessList.SERVICE_ADJ) {
- return buildOomTag("svc ", null, setAdj, ProcessList.SERVICE_ADJ);
+ return buildOomTag("svc ", "svc", null, setAdj,
+ ProcessList.SERVICE_ADJ, compact);
} else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
- return buildOomTag("hvy ", null, setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
+ return buildOomTag("hvy ", "hvy", null, setAdj,
+ ProcessList.HEAVY_WEIGHT_APP_ADJ, compact);
} else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
- return buildOomTag("bkup ", null, setAdj, ProcessList.BACKUP_APP_ADJ);
+ return buildOomTag("bkup ", "bkup", null, setAdj,
+ ProcessList.BACKUP_APP_ADJ, compact);
} else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
- return buildOomTag("prcp ", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
+ return buildOomTag("prcp ", "prcp", null, setAdj,
+ ProcessList.PERCEPTIBLE_APP_ADJ, compact);
} else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
- return buildOomTag("vis", " ", setAdj, ProcessList.VISIBLE_APP_ADJ);
+ return buildOomTag("vis", "vis", " ", setAdj,
+ ProcessList.VISIBLE_APP_ADJ, compact);
} else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
- return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
+ return buildOomTag("fore ", "fore", null, setAdj,
+ ProcessList.FOREGROUND_APP_ADJ, compact);
} else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
- return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
+ return buildOomTag("psvc ", "psvc", null, setAdj,
+ ProcessList.PERSISTENT_SERVICE_ADJ, compact);
} else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
- return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
+ return buildOomTag("pers ", "pers", null, setAdj,
+ ProcessList.PERSISTENT_PROC_ADJ, compact);
} else if (setAdj >= ProcessList.SYSTEM_ADJ) {
- return buildOomTag("sys ", null, setAdj, ProcessList.SYSTEM_ADJ);
+ return buildOomTag("sys ", "sys", null, setAdj,
+ ProcessList.SYSTEM_ADJ, compact);
} else if (setAdj >= ProcessList.NATIVE_ADJ) {
- return buildOomTag("ntv ", null, setAdj, ProcessList.NATIVE_ADJ);
+ return buildOomTag("ntv ", "ntv", null, setAdj,
+ ProcessList.NATIVE_ADJ, compact);
} else {
return Integer.toString(setAdj);
}
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index e731f34..cbbbe47 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -78,8 +78,10 @@
@VisibleForTesting
static final String[] sDeviceConfigScopes = new String[] {
DeviceConfig.ActivityManagerNativeBoot.NAMESPACE,
+ DeviceConfig.MediaNative.NAMESPACE,
DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
DeviceConfig.NAMESPACE_NETD_NATIVE,
+ DeviceConfig.RuntimeNativeBoot.NAMESPACE,
DeviceConfig.RuntimeNative.NAMESPACE,
};
diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING
index c84b5c7..117174a 100644
--- a/services/core/java/com/android/server/am/TEST_MAPPING
+++ b/services/core/java/com/android/server/am/TEST_MAPPING
@@ -1,17 +1,6 @@
{
"presubmit": [
{
- "name": "CtsActivityManagerDeviceSdk25TestCases",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- },
- {
"name": "CtsAppTestCases",
"options": [
{
@@ -38,20 +27,6 @@
"exclude-annotation": "androidx.test.filters.FlakyTest"
}
]
- },
- {
- "name": "WmTests",
- "options": [
- {
- "include-filter": "com.android.server.am."
- },
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
}
],
"postsubmit": [
diff --git a/services/core/java/com/android/server/appbinding/AppBindingService.java b/services/core/java/com/android/server/appbinding/AppBindingService.java
index 3131255..0b6a432 100644
--- a/services/core/java/com/android/server/appbinding/AppBindingService.java
+++ b/services/core/java/com/android/server/appbinding/AppBindingService.java
@@ -47,7 +47,7 @@
import com.android.server.SystemService;
import com.android.server.am.PersistentConnection;
import com.android.server.appbinding.finders.AppServiceFinder;
-import com.android.server.appbinding.finders.SmsAppServiceFinder;
+import com.android.server.appbinding.finders.CarrierMessagingClientServiceFinder;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -147,7 +147,7 @@
mIPackageManager = injector.getIPackageManager();
mHandler = BackgroundThread.getHandler();
- mApps.add(new SmsAppServiceFinder(context, this::onAppChanged, mHandler));
+ mApps.add(new CarrierMessagingClientServiceFinder(context, this::onAppChanged, mHandler));
// Initialize with the default value to make it non-null.
mConstants = AppBindingConstants.initializeFromString("");
diff --git a/services/core/java/com/android/server/appbinding/finders/SmsAppServiceFinder.java b/services/core/java/com/android/server/appbinding/finders/CarrierMessagingClientServiceFinder.java
similarity index 79%
rename from services/core/java/com/android/server/appbinding/finders/SmsAppServiceFinder.java
rename to services/core/java/com/android/server/appbinding/finders/CarrierMessagingClientServiceFinder.java
index fcc28f8..4c5f1a1 100644
--- a/services/core/java/com/android/server/appbinding/finders/SmsAppServiceFinder.java
+++ b/services/core/java/com/android/server/appbinding/finders/CarrierMessagingClientServiceFinder.java
@@ -19,8 +19,6 @@
import static android.provider.Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL;
import android.Manifest.permission;
-import android.app.ISmsAppService;
-import android.app.SmsAppService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -30,6 +28,8 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
+import android.service.carrier.CarrierMessagingClientService;
+import android.service.carrier.ICarrierMessagingClientService;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Slog;
@@ -41,10 +41,11 @@
import java.util.function.BiConsumer;
/**
- * Find the SmsAppService service within the default SMS app.
+ * Find the CarrierMessagingClientService service within the default SMS app.
*/
-public class SmsAppServiceFinder extends AppServiceFinder<SmsAppService, ISmsAppService> {
- public SmsAppServiceFinder(Context context,
+public class CarrierMessagingClientServiceFinder
+ extends AppServiceFinder<CarrierMessagingClientService, ICarrierMessagingClientService> {
+ public CarrierMessagingClientServiceFinder(Context context,
BiConsumer<AppServiceFinder, Integer> listener,
Handler callbackHandler) {
super(context, listener, callbackHandler);
@@ -62,23 +63,23 @@
}
@Override
- protected Class<SmsAppService> getServiceClass() {
- return SmsAppService.class;
+ protected Class<CarrierMessagingClientService> getServiceClass() {
+ return CarrierMessagingClientService.class;
}
@Override
- public ISmsAppService asInterface(IBinder obj) {
- return ISmsAppService.Stub.asInterface(obj);
+ public ICarrierMessagingClientService asInterface(IBinder obj) {
+ return ICarrierMessagingClientService.Stub.asInterface(obj);
}
@Override
protected String getServiceAction() {
- return TelephonyManager.ACTION_SMS_APP_SERVICE;
+ return TelephonyManager.ACTION_CARRIER_MESSAGING_CLIENT_SERVICE;
}
@Override
protected String getServicePermission() {
- return permission.BIND_SMS_APP_SERVICE;
+ return permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE;
}
@Override
@@ -121,7 +122,7 @@
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL.equals(intent.getAction())) {
- mListener.accept(SmsAppServiceFinder.this, getSendingUserId());
+ mListener.accept(CarrierMessagingClientServiceFinder.this, getSendingUserId());
}
}
};
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index deaa931..0dc73d9 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -15,6 +15,9 @@
*/
package com.android.server.audio;
+import static com.android.server.audio.AudioService.CONNECTION_STATE_CONNECTED;
+import static com.android.server.audio.AudioService.CONNECTION_STATE_DISCONNECTED;
+
import android.annotation.NonNull;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
@@ -43,7 +46,7 @@
/** @hide */
/*package*/ final class AudioDeviceBroker {
- private static final String TAG = "AudioDeviceBroker";
+ private static final String TAG = "AS.AudioDeviceBroker";
private static final long BROKER_WAKELOCK_TIMEOUT_MS = 5000; //5s
@@ -62,27 +65,27 @@
private int mForcedUseForCommExt;
// Manages all connected devices, only ever accessed on the message loop
- //### or make it synchronized
private final AudioDeviceInventory mDeviceInventory;
// Manages notifications to BT service
private final BtHelper mBtHelper;
//-------------------------------------------------------------------
+ // we use a different lock than mDeviceStateLock so as not to create
+ // lock contention between enqueueing a message and handling them
private static final Object sLastDeviceConnectionMsgTimeLock = new Object();
+ @GuardedBy("sLastDeviceConnectionMsgTimeLock")
private static long sLastDeviceConnectMsgTime = 0;
- private final Object mBluetoothA2dpEnabledLock = new Object();
+ // General lock to be taken whenever the state of the audio devices is to be checked or changed
+ private final Object mDeviceStateLock = new Object();
+
// Request to override default use of A2DP for media.
- @GuardedBy("mBluetoothA2dpEnabledLock")
+ @GuardedBy("mDeviceStateLock")
private boolean mBluetoothA2dpEnabled;
- // lock always taken synchronized on mConnectedDevices
- /*package*/ final Object mA2dpAvrcpLock = new Object();
- // lock always taken synchronized on mConnectedDevices
- /*package*/ final Object mHearingAidLock = new Object();
-
// lock always taken when accessing AudioService.mSetModeDeathHandlers
+ // TODO do not "share" the lock between AudioService and BtHelpr, see b/123769055
/*package*/ final Object mSetModeLock = new Object();
//-------------------------------------------------------------------
@@ -109,13 +112,17 @@
// All post* methods are asynchronous
/*package*/ void onSystemReady() {
- mBtHelper.onSystemReady();
+ synchronized (mDeviceStateLock) {
+ mBtHelper.onSystemReady();
+ }
}
/*package*/ void onAudioServerDied() {
// Restore forced usage for communications and record
- onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, "onAudioServerDied");
- onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm, "onAudioServerDied");
+ synchronized (mDeviceStateLock) {
+ onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, "onAudioServerDied");
+ onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm, "onAudioServerDied");
+ }
// restore devices
sendMsgNoDelay(MSG_RESTORE_DEVICES, SENDMSG_REPLACE);
}
@@ -130,7 +137,9 @@
}
/*package*/ void disconnectAllBluetoothProfiles() {
- mBtHelper.disconnectAllBluetoothProfiles();
+ synchronized (mDeviceStateLock) {
+ mBtHelper.disconnectAllBluetoothProfiles();
+ }
}
/**
@@ -140,11 +149,13 @@
* @param intent
*/
/*package*/ void receiveBtEvent(@NonNull Intent intent) {
- mBtHelper.receiveBtEvent(intent);
+ synchronized (mDeviceStateLock) {
+ mBtHelper.receiveBtEvent(intent);
+ }
}
/*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) {
- synchronized (mBluetoothA2dpEnabledLock) {
+ synchronized (mDeviceStateLock) {
if (mBluetoothA2dpEnabled == on) {
return;
}
@@ -158,28 +169,34 @@
}
/*package*/ void setSpeakerphoneOn(boolean on, String eventSource) {
- if (on) {
- if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
- setForceUse_Async(AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, eventSource);
+ synchronized (mDeviceStateLock) {
+ if (on) {
+ if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
+ setForceUse_Async(AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, eventSource);
+ }
+ mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
+ } else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER) {
+ mForcedUseForComm = AudioSystem.FORCE_NONE;
}
- mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
- } else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER) {
- mForcedUseForComm = AudioSystem.FORCE_NONE;
- }
- mForcedUseForCommExt = mForcedUseForComm;
- setForceUse_Async(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource);
+ mForcedUseForCommExt = mForcedUseForComm;
+ setForceUse_Async(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource);
+ }
}
/*package*/ boolean isSpeakerphoneOn() {
- return (mForcedUseForCommExt == AudioSystem.FORCE_SPEAKER);
+ synchronized (mDeviceStateLock) {
+ return (mForcedUseForCommExt == AudioSystem.FORCE_SPEAKER);
+ }
}
/*package*/ void setWiredDeviceConnectionState(int type,
@AudioService.ConnectionState int state, String address, String name,
String caller) {
//TODO move logging here just like in setBluetooth* methods
- mDeviceInventory.setWiredDeviceConnectionState(type, state, address, name, caller);
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.setWiredDeviceConnectionState(type, state, address, name, caller);
+ }
}
/*package*/ int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
@@ -192,22 +209,27 @@
+ " addr=" + device.getAddress()
+ " prof=" + profile + " supprNoisy=" + suppressNoisyIntent
+ " vol=" + a2dpVolume)).printLog(TAG));
- if (mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE,
- new BtHelper.BluetoothA2dpDeviceInfo(device))) {
- AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
- "A2DP connection state ignored"));
- return 0;
+ synchronized (mDeviceStateLock) {
+ if (mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE,
+ new BtHelper.BluetoothA2dpDeviceInfo(device))) {
+ AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
+ "A2DP connection state ignored"));
+ return 0;
+ }
+ return mDeviceInventory.setBluetoothA2dpDeviceConnectionState(
+ device, state, profile, suppressNoisyIntent,
+ AudioSystem.DEVICE_NONE, a2dpVolume);
}
- return mDeviceInventory.setBluetoothA2dpDeviceConnectionState(
- device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume);
}
/*package*/ int handleBluetoothA2dpActiveDeviceChange(
@NonNull BluetoothDevice device,
@AudioService.BtProfileConnectionState int state, int profile,
boolean suppressNoisyIntent, int a2dpVolume) {
- return mDeviceInventory.handleBluetoothA2dpActiveDeviceChange(device, state, profile,
- suppressNoisyIntent, a2dpVolume);
+ synchronized (mDeviceStateLock) {
+ return mDeviceInventory.handleBluetoothA2dpActiveDeviceChange(device, state, profile,
+ suppressNoisyIntent, a2dpVolume);
+ }
}
/*package*/ int setBluetoothHearingAidDeviceConnectionState(
@@ -218,57 +240,69 @@
+ " addr=" + device.getAddress()
+ " supprNoisy=" + suppressNoisyIntent
+ " src=" + eventSource)).printLog(TAG));
- return mDeviceInventory.setBluetoothHearingAidDeviceConnectionState(
- device, state, suppressNoisyIntent, musicDevice);
+ synchronized (mDeviceStateLock) {
+ return mDeviceInventory.setBluetoothHearingAidDeviceConnectionState(
+ device, state, suppressNoisyIntent, musicDevice);
+ }
}
// never called by system components
/*package*/ void setBluetoothScoOnByApp(boolean on) {
- mForcedUseForCommExt = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE;
+ synchronized (mDeviceStateLock) {
+ mForcedUseForCommExt = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE;
+ }
}
/*package*/ boolean isBluetoothScoOnForApp() {
- return mForcedUseForCommExt == AudioSystem.FORCE_BT_SCO;
+ synchronized (mDeviceStateLock) {
+ return mForcedUseForCommExt == AudioSystem.FORCE_BT_SCO;
+ }
}
/*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
//Log.i(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource);
- if (on) {
- // do not accept SCO ON if SCO audio is not connected
- if (!mBtHelper.isBluetoothScoOn()) {
- mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO;
- return;
+ synchronized (mDeviceStateLock) {
+ if (on) {
+ // do not accept SCO ON if SCO audio is not connected
+ if (!mBtHelper.isBluetoothScoOn()) {
+ mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO;
+ return;
+ }
+ mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
+ } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
+ mForcedUseForComm = AudioSystem.FORCE_NONE;
}
- mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
- } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
- mForcedUseForComm = AudioSystem.FORCE_NONE;
+ mForcedUseForCommExt = mForcedUseForComm;
+ AudioSystem.setParameters("BT_SCO=" + (on ? "on" : "off"));
+ sendIILMsgNoDelay(MSG_IIL_SET_FORCE_USE, SENDMSG_QUEUE,
+ AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource);
+ sendIILMsgNoDelay(MSG_IIL_SET_FORCE_USE, SENDMSG_QUEUE,
+ AudioSystem.FOR_RECORD, mForcedUseForComm, eventSource);
+ // Un-mute ringtone stream volume
+ mAudioService.setUpdateRingerModeServiceInt();
}
- mForcedUseForCommExt = mForcedUseForComm;
- AudioSystem.setParameters("BT_SCO=" + (on ? "on" : "off"));
- sendIILMsgNoDelay(MSG_IIL_SET_FORCE_USE, SENDMSG_QUEUE,
- AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource);
- sendIILMsgNoDelay(MSG_IIL_SET_FORCE_USE, SENDMSG_QUEUE,
- AudioSystem.FOR_RECORD, mForcedUseForComm, eventSource);
- // Un-mute ringtone stream volume
- mAudioService.setUpdateRingerModeServiceInt();
}
/*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
- return mDeviceInventory.startWatchingRoutes(observer);
+ synchronized (mDeviceStateLock) {
+ return mDeviceInventory.startWatchingRoutes(observer);
+ }
}
/*package*/ AudioRoutesInfo getCurAudioRoutes() {
- return mDeviceInventory.getCurAudioRoutes();
+ synchronized (mDeviceStateLock) {
+ return mDeviceInventory.getCurAudioRoutes();
+ }
}
/*package*/ boolean isAvrcpAbsoluteVolumeSupported() {
- synchronized (mA2dpAvrcpLock) {
+ synchronized (mDeviceStateLock) {
return mBtHelper.isAvrcpAbsoluteVolumeSupported();
}
}
/*package*/ boolean isBluetoothA2dpOn() {
- synchronized (mBluetoothA2dpEnabledLock) {
+ synchronized (mDeviceStateLock) {
return mBluetoothA2dpEnabled;
}
}
@@ -347,22 +381,20 @@
//---------------------------------------------------------------------
// Message handling on behalf of helper classes
- /*package*/ void broadcastScoConnectionState(int state) {
+ /*package*/ void postBroadcastScoConnectionState(int state) {
sendIMsgNoDelay(MSG_I_BROADCAST_BT_CONNECTION_STATE, SENDMSG_QUEUE, state);
}
- /*package*/ void broadcastBecomingNoisy() {
+ /*package*/ void postBroadcastBecomingNoisy() {
sendMsgNoDelay(MSG_BROADCAST_AUDIO_BECOMING_NOISY, SENDMSG_REPLACE);
}
- //###TODO unify with handleSetA2dpSinkConnectionState
/*package*/ void postA2dpSinkConnection(int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) {
sendILMsg(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE, SENDMSG_QUEUE,
state, btDeviceInfo, delay);
}
- //###TODO unify with handleSetA2dpSourceConnectionState
/*package*/ void postA2dpSourceConnection(int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) {
sendILMsg(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE,
@@ -383,6 +415,22 @@
delay);
}
+ /*package*/ void postDisconnectA2dp() {
+ sendMsgNoDelay(MSG_DISCONNECT_A2DP, SENDMSG_QUEUE);
+ }
+
+ /*package*/ void postDisconnectA2dpSink() {
+ sendMsgNoDelay(MSG_DISCONNECT_A2DP_SINK, SENDMSG_QUEUE);
+ }
+
+ /*package*/ void postDisconnectHearingAid() {
+ sendMsgNoDelay(MSG_DISCONNECT_HEARING_AID, SENDMSG_QUEUE);
+ }
+
+ /*package*/ void postDisconnectHeadset() {
+ sendMsgNoDelay(MSG_DISCONNECT_HEADSET, SENDMSG_QUEUE);
+ }
+
//---------------------------------------------------------------------
// Method forwarding between the helper classes (BtHelper, AudioDeviceInventory)
// only call from a "handle"* method or "on"* method
@@ -395,7 +443,7 @@
.append(") from u/pid:").append(Binder.getCallingUid()).append("/")
.append(Binder.getCallingPid()).append(" src:").append(source).toString();
- synchronized (mBluetoothA2dpEnabledLock) {
+ synchronized (mDeviceStateLock) {
mBluetoothA2dpEnabled = on;
mBrokerHandler.removeMessages(MSG_IIL_SET_FORCE_BT_A2DP_USE);
onSetForceUse(
@@ -407,25 +455,21 @@
/*package*/ boolean handleDeviceConnection(boolean connect, int device, String address,
String deviceName) {
- return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName);
- }
-
- /*package*/ void handleDisconnectA2dp() {
- mDeviceInventory.disconnectA2dp();
- }
- /*package*/ void handleDisconnectA2dpSink() {
- mDeviceInventory.disconnectA2dpSink();
+ synchronized (mDeviceStateLock) {
+ return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName);
+ }
}
/*package*/ void handleSetA2dpSinkConnectionState(@BluetoothProfile.BtProfileState int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) {
- final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0;
- //### DOESN'T HONOR SYNC ON DEVICES -> make a synchronized version?
- // might be ok here because called on BT thread? + sync happening in
- // checkSendBecomingNoisyIntent
- final int delay = mDeviceInventory.checkSendBecomingNoisyIntent(
- AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, intState,
- AudioSystem.DEVICE_NONE);
+ final int intState = (state == BluetoothA2dp.STATE_CONNECTED)
+ ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED;
+ final int delay;
+ synchronized (mDeviceStateLock) {
+ delay = mDeviceInventory.checkSendBecomingNoisyIntent(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, intState,
+ AudioSystem.DEVICE_NONE);
+ }
final String addr = btDeviceInfo == null ? "null" : btDeviceInfo.getBtDevice().getAddress();
if (AudioService.DEBUG_DEVICES) {
@@ -437,11 +481,7 @@
state, btDeviceInfo, delay);
}
- /*package*/ void handleDisconnectHearingAid() {
- mDeviceInventory.disconnectHearingAid();
- }
-
- /*package*/ void handleSetA2dpSourceConnectionState(@BluetoothProfile.BtProfileState int state,
+ /*package*/ void postSetA2dpSourceConnectionState(@BluetoothProfile.BtProfileState int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) {
final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0;
sendILMsgNoDelay(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE, state,
@@ -468,8 +508,6 @@
sendLMsgNoDelay(MSG_L_A2DP_ACTIVE_DEVICE_CHANGE, SENDMSG_QUEUE, btDeviceInfo);
}
- //###
- // must be called synchronized on mConnectedDevices
/*package*/ boolean hasScheduledA2dpDockTimeout() {
return mBrokerHandler.hasMessages(MSG_IL_BTA2DP_DOCK_TIMEOUT);
}
@@ -486,19 +524,19 @@
}
/*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) {
- synchronized (mA2dpAvrcpLock) {
+ synchronized (mDeviceStateLock) {
mBtHelper.setAvrcpAbsoluteVolumeSupported(supported);
}
}
/*package*/ boolean getBluetoothA2dpEnabled() {
- synchronized (mBluetoothA2dpEnabledLock) {
+ synchronized (mDeviceStateLock) {
return mBluetoothA2dpEnabled;
}
}
/*package*/ int getA2dpCodec(@NonNull BluetoothDevice device) {
- synchronized (mA2dpAvrcpLock) {
+ synchronized (mDeviceStateLock) {
return mBtHelper.getA2dpCodec(device);
}
}
@@ -579,71 +617,117 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_RESTORE_DEVICES:
- mDeviceInventory.onRestoreDevices();
- synchronized (mBluetoothA2dpEnabledLock) {
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onRestoreDevices();
mBtHelper.onAudioServerDiedRestoreA2dp();
}
break;
case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
- mDeviceInventory.onSetWiredDeviceConnectionState(
- (AudioDeviceInventory.WiredDeviceConnectionState) msg.obj);
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onSetWiredDeviceConnectionState(
+ (AudioDeviceInventory.WiredDeviceConnectionState) msg.obj);
+ }
break;
case MSG_I_BROADCAST_BT_CONNECTION_STATE:
- mBtHelper.onBroadcastScoConnectionState(msg.arg1);
+ synchronized (mDeviceStateLock) {
+ mBtHelper.onBroadcastScoConnectionState(msg.arg1);
+ }
break;
- case MSG_IIL_SET_FORCE_USE: // intented fall-through
+ case MSG_IIL_SET_FORCE_USE: // intended fall-through
case MSG_IIL_SET_FORCE_BT_A2DP_USE:
onSetForceUse(msg.arg1, msg.arg2, (String) msg.obj);
break;
case MSG_REPORT_NEW_ROUTES:
- mDeviceInventory.onReportNewRoutes();
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onReportNewRoutes();
+ }
break;
case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE:
- mDeviceInventory.onSetA2dpSinkConnectionState(
- (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onSetA2dpSinkConnectionState(
+ (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
+ }
break;
case MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE:
- mDeviceInventory.onSetA2dpSourceConnectionState(
- (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onSetA2dpSourceConnectionState(
+ (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
+ }
break;
case MSG_IL_SET_HEARING_AID_CONNECTION_STATE:
- mDeviceInventory.onSetHearingAidConnectionState(
- (BluetoothDevice) msg.obj, msg.arg1);
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onSetHearingAidConnectionState(
+ (BluetoothDevice) msg.obj, msg.arg1);
+ }
break;
case MSG_BT_HEADSET_CNCT_FAILED:
- mBtHelper.resetBluetoothSco();
+ synchronized (mDeviceStateLock) {
+ mBtHelper.resetBluetoothSco();
+ }
break;
case MSG_IL_BTA2DP_DOCK_TIMEOUT:
// msg.obj == address of BTA2DP device
- mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1);
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1);
+ }
break;
case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
final int a2dpCodec;
final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
- synchronized (mA2dpAvrcpLock) {
+ synchronized (mDeviceStateLock) {
a2dpCodec = mBtHelper.getA2dpCodec(btDevice);
+ mDeviceInventory.onBluetoothA2dpDeviceConfigChange(
+ new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec));
}
- mDeviceInventory.onBluetoothA2dpDeviceConfigChange(
- new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec));
break;
case MSG_BROADCAST_AUDIO_BECOMING_NOISY:
onSendBecomingNoisyIntent();
break;
case MSG_II_SET_HEARING_AID_VOLUME:
- mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2);
+ synchronized (mDeviceStateLock) {
+ mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2);
+ }
break;
case MSG_I_SET_AVRCP_ABSOLUTE_VOLUME:
- mBtHelper.setAvrcpAbsoluteVolumeIndex(msg.arg1);
+ synchronized (mDeviceStateLock) {
+ mBtHelper.setAvrcpAbsoluteVolumeIndex(msg.arg1);
+ }
break;
case MSG_I_DISCONNECT_BT_SCO:
- mBtHelper.disconnectBluetoothSco(msg.arg1);
+ synchronized (mDeviceStateLock) {
+ mBtHelper.disconnectBluetoothSco(msg.arg1);
+ }
break;
case MSG_TOGGLE_HDMI:
- mDeviceInventory.onToggleHdmi();
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onToggleHdmi();
+ }
break;
case MSG_L_A2DP_ACTIVE_DEVICE_CHANGE:
- mDeviceInventory.onBluetoothA2dpActiveDeviceChange(
- (BtHelper.BluetoothA2dpDeviceInfo) msg.obj);
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onBluetoothA2dpActiveDeviceChange(
+ (BtHelper.BluetoothA2dpDeviceInfo) msg.obj);
+ }
+ break;
+ case MSG_DISCONNECT_A2DP:
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.disconnectA2dp();
+ }
+ break;
+ case MSG_DISCONNECT_A2DP_SINK:
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.disconnectA2dpSink();
+ }
+ break;
+ case MSG_DISCONNECT_HEARING_AID:
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.disconnectHearingAid();
+ }
+ break;
+ case MSG_DISCONNECT_HEADSET:
+ synchronized (mDeviceStateLock) {
+ mBtHelper.disconnectHeadset();
+ }
break;
default:
Log.wtf(TAG, "Invalid message " + msg.what);
@@ -680,6 +764,10 @@
private static final int MSG_I_DISCONNECT_BT_SCO = 16;
private static final int MSG_TOGGLE_HDMI = 17;
private static final int MSG_L_A2DP_ACTIVE_DEVICE_CHANGE = 18;
+ private static final int MSG_DISCONNECT_A2DP = 19;
+ private static final int MSG_DISCONNECT_A2DP_SINK = 20;
+ private static final int MSG_DISCONNECT_HEARING_AID = 21;
+ private static final int MSG_DISCONNECT_HEADSET = 22;
private static boolean isMessageHandledUnderWakelock(int msgId) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 97649a7..37f0496 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -162,10 +162,7 @@
"A2DP sink connected: device addr=" + address + " state=" + state
+ " vol=" + a2dpVolume));
- final int a2dpCodec;
- synchronized (mDeviceBroker.mA2dpAvrcpLock) {
- a2dpCodec = btInfo.getCodec();
- }
+ final int a2dpCodec = btInfo.getCodec();
synchronized (mConnectedDevices) {
final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
@@ -508,22 +505,20 @@
/*package*/ void disconnectA2dp() {
synchronized (mConnectedDevices) {
- synchronized (mDeviceBroker.mA2dpAvrcpLock) {
- final ArraySet<String> toRemove = new ArraySet<>();
- // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices
- mConnectedDevices.values().forEach(deviceInfo -> {
- if (deviceInfo.mDeviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
- toRemove.add(deviceInfo.mDeviceAddress);
- }
- });
- if (toRemove.size() > 0) {
- final int delay = checkSendBecomingNoisyIntentInt(
- AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- 0, AudioSystem.DEVICE_NONE);
- toRemove.stream().forEach(deviceAddress ->
- makeA2dpDeviceUnavailableLater(deviceAddress, delay)
- );
+ final ArraySet<String> toRemove = new ArraySet<>();
+ // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices
+ mConnectedDevices.values().forEach(deviceInfo -> {
+ if (deviceInfo.mDeviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ toRemove.add(deviceInfo.mDeviceAddress);
}
+ });
+ if (toRemove.size() > 0) {
+ final int delay = checkSendBecomingNoisyIntentInt(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ AudioService.CONNECTION_STATE_DISCONNECTED, AudioSystem.DEVICE_NONE);
+ toRemove.stream().forEach(deviceAddress ->
+ makeA2dpDeviceUnavailableLater(deviceAddress, delay)
+ );
}
}
}
@@ -543,22 +538,20 @@
/*package*/ void disconnectHearingAid() {
synchronized (mConnectedDevices) {
- synchronized (mDeviceBroker.mHearingAidLock) {
- final ArraySet<String> toRemove = new ArraySet<>();
- // Disconnect ALL DEVICE_OUT_HEARING_AID devices
- mConnectedDevices.values().forEach(deviceInfo -> {
- if (deviceInfo.mDeviceType == AudioSystem.DEVICE_OUT_HEARING_AID) {
- toRemove.add(deviceInfo.mDeviceAddress);
- }
- });
- if (toRemove.size() > 0) {
- final int delay = checkSendBecomingNoisyIntentInt(
- AudioSystem.DEVICE_OUT_HEARING_AID, 0, AudioSystem.DEVICE_NONE);
- toRemove.stream().forEach(deviceAddress ->
- // TODO delay not used?
- makeHearingAidDeviceUnavailable(deviceAddress /*, delay*/)
- );
+ final ArraySet<String> toRemove = new ArraySet<>();
+ // Disconnect ALL DEVICE_OUT_HEARING_AID devices
+ mConnectedDevices.values().forEach(deviceInfo -> {
+ if (deviceInfo.mDeviceType == AudioSystem.DEVICE_OUT_HEARING_AID) {
+ toRemove.add(deviceInfo.mDeviceAddress);
}
+ });
+ if (toRemove.size() > 0) {
+ final int delay = checkSendBecomingNoisyIntentInt(
+ AudioSystem.DEVICE_OUT_HEARING_AID, 0, AudioSystem.DEVICE_NONE);
+ toRemove.stream().forEach(deviceAddress ->
+ // TODO delay not used?
+ makeHearingAidDeviceUnavailable(deviceAddress /*, delay*/)
+ );
}
}
}
@@ -566,7 +559,8 @@
// must be called before removing the device from mConnectedDevices
// musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying
// from AudioSystem
- /*package*/ int checkSendBecomingNoisyIntent(int device, int state, int musicDevice) {
+ /*package*/ int checkSendBecomingNoisyIntent(int device,
+ @AudioService.ConnectionState int state, int musicDevice) {
synchronized (mConnectedDevices) {
return checkSendBecomingNoisyIntentInt(device, state, musicDevice);
}
@@ -840,8 +834,9 @@
// musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying
// from AudioSystem
@GuardedBy("mConnectedDevices")
- private int checkSendBecomingNoisyIntentInt(int device, int state, int musicDevice) {
- if (state != 0) {
+ private int checkSendBecomingNoisyIntentInt(int device,
+ @AudioService.ConnectionState int state, int musicDevice) {
+ if (state != AudioService.CONNECTION_STATE_DISCONNECTED) {
return 0;
}
if ((device & mBecomingNoisyIntentDevices) == 0) {
@@ -864,7 +859,7 @@
// also checks whether media routing if affected by a dynamic policy
if (((device == musicDevice) || mDeviceBroker.isInCommunication())
&& (device == devices) && !mDeviceBroker.hasMediaDynamicPolicy()) {
- mDeviceBroker.broadcastBecomingNoisy();
+ mDeviceBroker.postBroadcastBecomingNoisy();
delay = 1000;
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 9457fe3..a6643d4 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -786,7 +786,6 @@
mPrescaleAbsoluteVolume[i] = preScale[i];
}
}
-
}
public void systemReady() {
@@ -1711,7 +1710,7 @@
Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
+ newIndex + "stream=" + streamType);
}
- mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex);
+ mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
}
// Check if volume update should be send to Hearing Aid
@@ -3821,7 +3820,6 @@
private static void sendMsg(Handler handler, int msg,
int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
-
if (existingMsgPolicy == SENDMSG_REPLACE) {
handler.removeMessages(msg);
} else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
@@ -5122,7 +5120,7 @@
if (mUserSwitchedReceived) {
// attempt to stop music playback for background user except on first user
// switch (i.e. first boot)
- mDeviceBroker.broadcastBecomingNoisy();
+ mDeviceBroker.postBroadcastBecomingNoisy();
}
mUserSwitchedReceived = true;
// the current audio focus owner is no longer valid
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index bf32501..e918997 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -16,6 +16,7 @@
package com.android.server.audio;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
@@ -35,8 +36,6 @@
import android.provider.Settings;
import android.util.Log;
-import com.android.internal.annotations.GuardedBy;
-
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
@@ -57,21 +56,40 @@
}
// List of clients having issued a SCO start request
- private final ArrayList<ScoClient> mScoClients = new ArrayList<ScoClient>();
+ private final @NonNull ArrayList<ScoClient> mScoClients = new ArrayList<ScoClient>();
// BluetoothHeadset API to control SCO connection
- private BluetoothHeadset mBluetoothHeadset;
+ private @Nullable BluetoothHeadset mBluetoothHeadset;
// Bluetooth headset device
- private BluetoothDevice mBluetoothHeadsetDevice;
+ private @Nullable BluetoothDevice mBluetoothHeadsetDevice;
+
+ private @Nullable BluetoothHearingAid mHearingAid;
+
+ // Reference to BluetoothA2dp to query for AbsoluteVolume.
+ private @Nullable BluetoothA2dp mA2dp;
+
+ // If absolute volume is supported in AVRCP device
+ private boolean mAvrcpAbsVolSupported = false;
+
+ // Current connection state indicated by bluetooth headset
+ private int mScoConnectionState;
// Indicate if SCO audio connection is currently active and if the initiator is
// audio service (internal) or bluetooth headset (external)
private int mScoAudioState;
+
+ // Indicates the mode used for SCO audio connection. The mode is virtual call if the request
+ // originated from an app targeting an API version before JB MR2 and raw audio after that.
+ private int mScoAudioMode;
+
// SCO audio state is not active
private static final int SCO_STATE_INACTIVE = 0;
// SCO audio activation request waiting for headset service to connect
private static final int SCO_STATE_ACTIVATE_REQ = 1;
+ // SCO audio state is active due to an action in BT handsfree (either voice recognition or
+ // in call audio)
+ private static final int SCO_STATE_ACTIVE_EXTERNAL = 2;
// SCO audio state is active or starting due to a request from AudioManager API
private static final int SCO_STATE_ACTIVE_INTERNAL = 3;
// SCO audio deactivation request waiting for headset service to connect
@@ -79,39 +97,19 @@
// SCO audio deactivation in progress, waiting for Bluetooth audio intent
private static final int SCO_STATE_DEACTIVATING = 5;
- // SCO audio state is active due to an action in BT handsfree (either voice recognition or
- // in call audio)
- private static final int SCO_STATE_ACTIVE_EXTERNAL = 2;
-
- // Indicates the mode used for SCO audio connection. The mode is virtual call if the request
- // originated from an app targeting an API version before JB MR2 and raw audio after that.
- private int mScoAudioMode;
// SCO audio mode is undefined
- /*package*/ static final int SCO_MODE_UNDEFINED = -1;
+ /*package*/ static final int SCO_MODE_UNDEFINED = -1;
// SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall())
/*package*/ static final int SCO_MODE_VIRTUAL_CALL = 0;
// SCO audio mode is raw audio (BluetoothHeadset.connectAudio())
private static final int SCO_MODE_RAW = 1;
// SCO audio mode is Voice Recognition (BluetoothHeadset.startVoiceRecognition())
private static final int SCO_MODE_VR = 2;
-
+ // max valid SCO audio mode values
private static final int SCO_MODE_MAX = 2;
- // Current connection state indicated by bluetooth headset
- private int mScoConnectionState;
-
private static final int BT_HEARING_AID_GAIN_MIN = -128;
- @GuardedBy("mDeviceBroker.mHearingAidLock")
- private BluetoothHearingAid mHearingAid;
-
- // Reference to BluetoothA2dp to query for AbsoluteVolume.
- @GuardedBy("mDeviceBroker.mA2dpAvrcpLock")
- private BluetoothA2dp mA2dp;
- // If absolute volume is supported in AVRCP device
- @GuardedBy("mDeviceBroker.mA2dpAvrcpLock")
- private boolean mAvrcpAbsVolSupported = false;
-
//----------------------------------------------------------------------
/*package*/ static class BluetoothA2dpDeviceInfo {
private final @NonNull BluetoothDevice mBtDevice;
@@ -144,7 +142,7 @@
//----------------------------------------------------------------------
// Interface for AudioDeviceBroker
- /*package*/ void onSystemReady() {
+ /*package*/ synchronized void onSystemReady() {
mScoConnectionState = android.media.AudioManager.SCO_AUDIO_STATE_ERROR;
resetBluetoothSco();
getBluetoothHeadset();
@@ -165,45 +163,39 @@
}
}
- @GuardedBy("mBluetoothA2dpEnabledLock")
- /*package*/ void onAudioServerDiedRestoreA2dp() {
+ /*package*/ synchronized void onAudioServerDiedRestoreA2dp() {
final int forMed = mDeviceBroker.getBluetoothA2dpEnabled()
? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP;
mDeviceBroker.setForceUse_Async(AudioSystem.FOR_MEDIA, forMed, "onAudioServerDied()");
}
- @GuardedBy("mA2dpAvrcpLock")
- /*package*/ boolean isAvrcpAbsoluteVolumeSupported() {
+ /*package*/ synchronized boolean isAvrcpAbsoluteVolumeSupported() {
return (mA2dp != null && mAvrcpAbsVolSupported);
}
- @GuardedBy("mA2dpAvrcpLock")
- /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) {
+ /*package*/ synchronized void setAvrcpAbsoluteVolumeSupported(boolean supported) {
mAvrcpAbsVolSupported = supported;
}
- /*package*/ void setAvrcpAbsoluteVolumeIndex(int index) {
- synchronized (mDeviceBroker.mA2dpAvrcpLock) {
- if (mA2dp == null) {
- if (AudioService.DEBUG_VOL) {
- Log.d(TAG, "setAvrcpAbsoluteVolumeIndex: bailing due to null mA2dp");
- return;
- }
- }
- if (!mAvrcpAbsVolSupported) {
+ /*package*/ synchronized void setAvrcpAbsoluteVolumeIndex(int index) {
+ if (mA2dp == null) {
+ if (AudioService.DEBUG_VOL) {
+ Log.d(TAG, "setAvrcpAbsoluteVolumeIndex: bailing due to null mA2dp");
return;
}
- if (AudioService.DEBUG_VOL) {
- Log.i(TAG, "setAvrcpAbsoluteVolumeIndex index=" + index);
- }
- AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent(
- AudioServiceEvents.VolumeEvent.VOL_SET_AVRCP_VOL, index / 10));
- mA2dp.setAvrcpAbsoluteVolume(index / 10);
}
+ if (!mAvrcpAbsVolSupported) {
+ return;
+ }
+ if (AudioService.DEBUG_VOL) {
+ Log.i(TAG, "setAvrcpAbsoluteVolumeIndex index=" + index);
+ }
+ AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent(
+ AudioServiceEvents.VolumeEvent.VOL_SET_AVRCP_VOL, index));
+ mA2dp.setAvrcpAbsoluteVolume(index);
}
- @GuardedBy("mA2dpAvrcpLock")
- /*package*/ int getA2dpCodec(@NonNull BluetoothDevice device) {
+ /*package*/ synchronized int getA2dpCodec(@NonNull BluetoothDevice device) {
if (mA2dp == null) {
return AudioSystem.AUDIO_FORMAT_DEFAULT;
}
@@ -218,7 +210,7 @@
return mapBluetoothCodecToAudioFormat(btCodecConfig.getCodecType());
}
- /*package*/ void receiveBtEvent(Intent intent) {
+ /*package*/ synchronized void receiveBtEvent(Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) {
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
@@ -226,53 +218,51 @@
} else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
boolean broadcast = false;
int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
- synchronized (mScoClients) {
- int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
- // broadcast intent if the connection was initated by AudioService
- if (!mScoClients.isEmpty()
- && (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL
- || mScoAudioState == SCO_STATE_ACTIVATE_REQ
- || mScoAudioState == SCO_STATE_DEACTIVATE_REQ
- || mScoAudioState == SCO_STATE_DEACTIVATING)) {
- broadcast = true;
- }
- switch (btState) {
- case BluetoothHeadset.STATE_AUDIO_CONNECTED:
- scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
- if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
- && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+ // broadcast intent if the connection was initated by AudioService
+ if (!mScoClients.isEmpty()
+ && (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL
+ || mScoAudioState == SCO_STATE_ACTIVATE_REQ
+ || mScoAudioState == SCO_STATE_DEACTIVATE_REQ
+ || mScoAudioState == SCO_STATE_DEACTIVATING)) {
+ broadcast = true;
+ }
+ switch (btState) {
+ case BluetoothHeadset.STATE_AUDIO_CONNECTED:
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
+ if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+ && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ }
+ mDeviceBroker.setBluetoothScoOn(true, "BtHelper.receiveBtEvent");
+ break;
+ case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
+ mDeviceBroker.setBluetoothScoOn(false, "BtHelper.receiveBtEvent");
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
+ // startBluetoothSco called after stopBluetoothSco
+ if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
+ if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
+ && connectBluetoothScoAudioHelper(mBluetoothHeadset,
+ mBluetoothHeadsetDevice, mScoAudioMode)) {
+ mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+ broadcast = false;
+ break;
}
- mDeviceBroker.setBluetoothScoOn(true, "BtHelper.receiveBtEvent");
- break;
- case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
- mDeviceBroker.setBluetoothScoOn(false, "BtHelper.receiveBtEvent");
- scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
- // startBluetoothSco called after stopBluetoothSco
- if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
- if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
- && connectBluetoothScoAudioHelper(mBluetoothHeadset,
- mBluetoothHeadsetDevice, mScoAudioMode)) {
- mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- broadcast = false;
- break;
- }
- }
- // Tear down SCO if disconnected from external
- clearAllScoClients(0, mScoAudioState == SCO_STATE_ACTIVE_INTERNAL);
- mScoAudioState = SCO_STATE_INACTIVE;
- break;
- case BluetoothHeadset.STATE_AUDIO_CONNECTING:
- if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
- && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
- }
- break;
- default:
- // do not broadcast CONNECTING or invalid state
- broadcast = false;
- break;
- }
+ }
+ // Tear down SCO if disconnected from external
+ clearAllScoClients(0, mScoAudioState == SCO_STATE_ACTIVE_INTERNAL);
+ mScoAudioState = SCO_STATE_INACTIVE;
+ break;
+ case BluetoothHeadset.STATE_AUDIO_CONNECTING:
+ if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+ && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ }
+ break;
+ default:
+ // do not broadcast CONNECTING or invalid state
+ broadcast = false;
+ break;
}
if (broadcast) {
broadcastScoConnectionState(scoAudioState);
@@ -289,15 +279,13 @@
*
* @return false if SCO isn't connected
*/
- /*package*/ boolean isBluetoothScoOn() {
- synchronized (mScoClients) {
- if ((mBluetoothHeadset != null)
- && (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
- != BluetoothHeadset.STATE_AUDIO_CONNECTED)) {
- Log.w(TAG, "isBluetoothScoOn(true) returning false because "
- + mBluetoothHeadsetDevice + " is not in audio connected mode");
- return false;
- }
+ /*package*/ synchronized boolean isBluetoothScoOn() {
+ if ((mBluetoothHeadset != null)
+ && (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
+ != BluetoothHeadset.STATE_AUDIO_CONNECTED)) {
+ Log.w(TAG, "isBluetoothScoOn(true) returning false because "
+ + mBluetoothHeadsetDevice + " is not in audio connected mode");
+ return false;
}
return true;
}
@@ -308,17 +296,15 @@
*
* @param exceptPid pid whose SCO connections through {@link AudioManager} should be kept
*/
- /*package*/ void disconnectBluetoothSco(int exceptPid) {
- synchronized (mScoClients) {
- checkScoAudioState();
- if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL) {
- return;
- }
- clearAllScoClients(exceptPid, true);
+ /*package*/ synchronized void disconnectBluetoothSco(int exceptPid) {
+ checkScoAudioState();
+ if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL) {
+ return;
}
+ clearAllScoClients(exceptPid, true);
}
- /*package*/ void startBluetoothScoForClient(IBinder cb, int scoAudioMode,
+ /*package*/ synchronized void startBluetoothScoForClient(IBinder cb, int scoAudioMode,
@NonNull String eventSource) {
ScoClient client = getScoClient(cb, true);
// The calling identity must be cleared before calling ScoClient.incCount().
@@ -337,7 +323,8 @@
Binder.restoreCallingIdentity(ident);
}
- /*package*/ void stopBluetoothScoForClient(IBinder cb, @NonNull String eventSource) {
+ /*package*/ synchronized void stopBluetoothScoForClient(IBinder cb,
+ @NonNull String eventSource) {
ScoClient client = getScoClient(cb, false);
// The calling identity must be cleared before calling ScoClient.decCount().
// decCount() calls requestScoState() which in turn can call BluetoothHeadset APIs
@@ -352,36 +339,29 @@
}
- /*package*/ void setHearingAidVolume(int index, int streamType) {
- synchronized (mDeviceBroker.mHearingAidLock) {
- if (mHearingAid == null) {
- if (AudioService.DEBUG_VOL) {
- Log.i(TAG, "setHearingAidVolume: null mHearingAid");
- }
- return;
- }
- //hearing aid expect volume value in range -128dB to 0dB
- int gainDB = (int) AudioSystem.getStreamVolumeDB(streamType, index / 10,
- AudioSystem.DEVICE_OUT_HEARING_AID);
- if (gainDB < BT_HEARING_AID_GAIN_MIN) {
- gainDB = BT_HEARING_AID_GAIN_MIN;
- }
+ /*package*/ synchronized void setHearingAidVolume(int index, int streamType) {
+ if (mHearingAid == null) {
if (AudioService.DEBUG_VOL) {
- Log.i(TAG, "setHearingAidVolume: calling mHearingAid.setVolume idx="
- + index + " gain=" + gainDB);
+ Log.i(TAG, "setHearingAidVolume: null mHearingAid");
}
- AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent(
- AudioServiceEvents.VolumeEvent.VOL_SET_HEARING_AID_VOL, index, gainDB));
- mHearingAid.setVolume(gainDB);
+ return;
}
+ //hearing aid expect volume value in range -128dB to 0dB
+ int gainDB = (int) AudioSystem.getStreamVolumeDB(streamType, index / 10,
+ AudioSystem.DEVICE_OUT_HEARING_AID);
+ if (gainDB < BT_HEARING_AID_GAIN_MIN) {
+ gainDB = BT_HEARING_AID_GAIN_MIN;
+ }
+ if (AudioService.DEBUG_VOL) {
+ Log.i(TAG, "setHearingAidVolume: calling mHearingAid.setVolume idx="
+ + index + " gain=" + gainDB);
+ }
+ AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent(
+ AudioServiceEvents.VolumeEvent.VOL_SET_HEARING_AID_VOL, index, gainDB));
+ mHearingAid.setVolume(gainDB);
}
- //----------------------------------------------------------------------
- private void broadcastScoConnectionState(int state) {
- mDeviceBroker.broadcastScoConnectionState(state);
- }
-
- /*package*/ void onBroadcastScoConnectionState(int state) {
+ /*package*/ synchronized void onBroadcastScoConnectionState(int state) {
if (state == mScoConnectionState) {
return;
}
@@ -393,6 +373,31 @@
mScoConnectionState = state;
}
+ /*package*/ synchronized void disconnectAllBluetoothProfiles() {
+ mDeviceBroker.postDisconnectA2dp();
+ mDeviceBroker.postDisconnectA2dpSink();
+ mDeviceBroker.postDisconnectHeadset();
+ mDeviceBroker.postDisconnectHearingAid();
+ }
+
+ /*package*/ synchronized void resetBluetoothSco() {
+ clearAllScoClients(0, false);
+ mScoAudioState = SCO_STATE_INACTIVE;
+ broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+ AudioSystem.setParameters("A2dpSuspended=false");
+ mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
+ }
+
+ /*package*/ synchronized void disconnectHeadset() {
+ setBtScoActiveDevice(null);
+ mBluetoothHeadset = null;
+ }
+
+ //----------------------------------------------------------------------
+ private void broadcastScoConnectionState(int state) {
+ mDeviceBroker.postBroadcastScoConnectionState(state);
+ }
+
private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
if (btDevice == null) {
return true;
@@ -437,25 +442,23 @@
}
private void setBtScoActiveDevice(BluetoothDevice btDevice) {
- synchronized (mScoClients) {
- Log.i(TAG, "setBtScoActiveDevice: " + mBluetoothHeadsetDevice + " -> " + btDevice);
- final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice;
- if (Objects.equals(btDevice, previousActiveDevice)) {
- return;
- }
- if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) {
- Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device "
- + previousActiveDevice);
- }
- if (!handleBtScoActiveDeviceChange(btDevice, true)) {
- Log.e(TAG, "setBtScoActiveDevice() failed to add new device " + btDevice);
- // set mBluetoothHeadsetDevice to null when failing to add new device
- btDevice = null;
- }
- mBluetoothHeadsetDevice = btDevice;
- if (mBluetoothHeadsetDevice == null) {
- resetBluetoothSco();
- }
+ Log.i(TAG, "setBtScoActiveDevice: " + mBluetoothHeadsetDevice + " -> " + btDevice);
+ final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice;
+ if (Objects.equals(btDevice, previousActiveDevice)) {
+ return;
+ }
+ if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) {
+ Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device "
+ + previousActiveDevice);
+ }
+ if (!handleBtScoActiveDeviceChange(btDevice, true)) {
+ Log.e(TAG, "setBtScoActiveDevice() failed to add new device " + btDevice);
+ // set mBluetoothHeadsetDevice to null when failing to add new device
+ btDevice = null;
+ }
+ mBluetoothHeadsetDevice = btDevice;
+ if (mBluetoothHeadsetDevice == null) {
+ resetBluetoothSco();
}
}
@@ -466,7 +469,7 @@
List<BluetoothDevice> deviceList;
switch(profile) {
case BluetoothProfile.A2DP:
- synchronized (mDeviceBroker.mA2dpAvrcpLock) {
+ synchronized (BtHelper.this) {
mA2dp = (BluetoothA2dp) proxy;
deviceList = mA2dp.getConnectedDevices();
if (deviceList.size() > 0) {
@@ -489,13 +492,13 @@
btDevice = deviceList.get(0);
final @BluetoothProfile.BtProfileState int state =
proxy.getConnectionState(btDevice);
- mDeviceBroker.handleSetA2dpSourceConnectionState(
+ mDeviceBroker.postSetA2dpSourceConnectionState(
state, new BluetoothA2dpDeviceInfo(btDevice));
}
break;
case BluetoothProfile.HEADSET:
- synchronized (mScoClients) {
+ synchronized (BtHelper.this) {
// Discard timeout message
mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService();
mBluetoothHeadset = (BluetoothHeadset) proxy;
@@ -536,17 +539,19 @@
break;
case BluetoothProfile.HEARING_AID:
- mHearingAid = (BluetoothHearingAid) proxy;
- deviceList = mHearingAid.getConnectedDevices();
- if (deviceList.size() > 0) {
- btDevice = deviceList.get(0);
- final @BluetoothProfile.BtProfileState int state =
- mHearingAid.getConnectionState(btDevice);
- mDeviceBroker.setBluetoothHearingAidDeviceConnectionState(
- btDevice, state,
- /*suppressNoisyIntent*/ false,
- /*musicDevice*/ android.media.AudioSystem.DEVICE_NONE,
- /*eventSource*/ "mBluetoothProfileServiceListener");
+ synchronized (BtHelper.this) {
+ mHearingAid = (BluetoothHearingAid) proxy;
+ deviceList = mHearingAid.getConnectedDevices();
+ if (deviceList.size() > 0) {
+ btDevice = deviceList.get(0);
+ final @BluetoothProfile.BtProfileState int state =
+ mHearingAid.getConnectionState(btDevice);
+ mDeviceBroker.setBluetoothHearingAidDeviceConnectionState(
+ btDevice, state,
+ /*suppressNoisyIntent*/ false,
+ /*musicDevice*/ android.media.AudioSystem.DEVICE_NONE,
+ /*eventSource*/ "mBluetoothProfileServiceListener");
+ }
}
break;
@@ -558,19 +563,19 @@
switch (profile) {
case BluetoothProfile.A2DP:
- mDeviceBroker.handleDisconnectA2dp();
+ mDeviceBroker.postDisconnectA2dp();
break;
case BluetoothProfile.A2DP_SINK:
- mDeviceBroker.handleDisconnectA2dpSink();
+ mDeviceBroker.postDisconnectA2dpSink();
break;
case BluetoothProfile.HEADSET:
- disconnectHeadset();
+ mDeviceBroker.postDisconnectHeadset();
break;
case BluetoothProfile.HEARING_AID:
- mDeviceBroker.handleDisconnectHearingAid();
+ mDeviceBroker.postDisconnectHearingAid();
break;
default:
@@ -579,20 +584,6 @@
}
};
- void disconnectAllBluetoothProfiles() {
- mDeviceBroker.handleDisconnectA2dp();
- mDeviceBroker.handleDisconnectA2dpSink();
- disconnectHeadset();
- mDeviceBroker.handleDisconnectHearingAid();
- }
-
- private void disconnectHeadset() {
- synchronized (mScoClients) {
- setBtScoActiveDevice(null);
- mBluetoothHeadset = null;
- }
- }
-
//----------------------------------------------------------------------
private class ScoClient implements IBinder.DeathRecipient {
private IBinder mCb; // To be notified of client's death
@@ -605,8 +596,12 @@
mStartcount = 0;
}
+ @Override
public void binderDied() {
- synchronized (mScoClients) {
+ // this is the only place the implementation of ScoClient needs to be synchronized
+ // on the instance, as all other methods are directly or indirectly called from
+ // package-private methods, which are synchronized
+ synchronized (BtHelper.this) {
Log.w(TAG, "SCO client died");
int index = mScoClients.indexOf(this);
if (index < 0) {
@@ -618,77 +613,69 @@
}
}
- public void incCount(int scoAudioMode) {
- synchronized (mScoClients) {
- requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
- if (mStartcount == 0) {
- try {
- mCb.linkToDeath(this, 0);
- } catch (RemoteException e) {
- // client has already died!
- Log.w(TAG, "ScoClient incCount() could not link to "
- + mCb + " binder death");
- }
- }
- mStartcount++;
- }
- }
-
- public void decCount() {
- synchronized (mScoClients) {
- if (mStartcount == 0) {
- Log.w(TAG, "ScoClient.decCount() already 0");
- } else {
- mStartcount--;
- if (mStartcount == 0) {
- try {
- mCb.unlinkToDeath(this, 0);
- } catch (NoSuchElementException e) {
- Log.w(TAG, "decCount() going to 0 but not registered to binder");
- }
- }
- requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
+ void incCount(int scoAudioMode) {
+ requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
+ if (mStartcount == 0) {
+ try {
+ mCb.linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ // client has already died!
+ Log.w(TAG, "ScoClient incCount() could not link to "
+ + mCb + " binder death");
}
}
+ mStartcount++;
}
- public void clearCount(boolean stopSco) {
- synchronized (mScoClients) {
- if (mStartcount != 0) {
+ void decCount() {
+ if (mStartcount == 0) {
+ Log.w(TAG, "ScoClient.decCount() already 0");
+ } else {
+ mStartcount--;
+ if (mStartcount == 0) {
try {
mCb.unlinkToDeath(this, 0);
} catch (NoSuchElementException e) {
- Log.w(TAG, "clearCount() mStartcount: "
- + mStartcount + " != 0 but not registered to binder");
+ Log.w(TAG, "decCount() going to 0 but not registered to binder");
}
}
- mStartcount = 0;
- if (stopSco) {
- requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
- }
+ requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
}
}
- public int getCount() {
+ void clearCount(boolean stopSco) {
+ if (mStartcount != 0) {
+ try {
+ mCb.unlinkToDeath(this, 0);
+ } catch (NoSuchElementException e) {
+ Log.w(TAG, "clearCount() mStartcount: "
+ + mStartcount + " != 0 but not registered to binder");
+ }
+ }
+ mStartcount = 0;
+ if (stopSco) {
+ requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
+ }
+ }
+
+ int getCount() {
return mStartcount;
}
- public IBinder getBinder() {
+ IBinder getBinder() {
return mCb;
}
- public int getPid() {
+ int getPid() {
return mCreatorPid;
}
- public int totalCount() {
- synchronized (mScoClients) {
- int count = 0;
- for (ScoClient mScoClient : mScoClients) {
- count += mScoClient.getCount();
- }
- return count;
+ private int totalCount() {
+ int count = 0;
+ for (ScoClient mScoClient : mScoClients) {
+ count += mScoClient.getCount();
}
+ return count;
}
private void requestScoState(int state, int scoAudioMode) {
@@ -705,6 +692,7 @@
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
// Accept SCO audio activation only in NORMAL audio mode or if the mode is
// currently controlled by the same client process.
+ // TODO do not sync that way, see b/123769055
synchronized (mDeviceBroker.mSetModeLock) {
int modeOwnerPid = mDeviceBroker.getSetModeDeathHandlers().isEmpty()
? 0 : mDeviceBroker.getSetModeDeathHandlers().get(0).getPid();
@@ -857,60 +845,43 @@
}
}
- /*package*/ void resetBluetoothSco() {
- synchronized (mScoClients) {
- clearAllScoClients(0, false);
- mScoAudioState = SCO_STATE_INACTIVE;
- broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
- }
- AudioSystem.setParameters("A2dpSuspended=false");
- mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
- }
-
-
private void checkScoAudioState() {
- synchronized (mScoClients) {
- if (mBluetoothHeadset != null
- && mBluetoothHeadsetDevice != null
- && mScoAudioState == SCO_STATE_INACTIVE
- && mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
- != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
- }
+ if (mBluetoothHeadset != null
+ && mBluetoothHeadsetDevice != null
+ && mScoAudioState == SCO_STATE_INACTIVE
+ && mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
+ != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
}
}
private ScoClient getScoClient(IBinder cb, boolean create) {
- synchronized (mScoClients) {
- for (ScoClient existingClient : mScoClients) {
- if (existingClient.getBinder() == cb) {
- return existingClient;
- }
+ for (ScoClient existingClient : mScoClients) {
+ if (existingClient.getBinder() == cb) {
+ return existingClient;
}
- if (create) {
- ScoClient newClient = new ScoClient(cb);
- mScoClients.add(newClient);
- return newClient;
- }
- return null;
}
+ if (create) {
+ ScoClient newClient = new ScoClient(cb);
+ mScoClients.add(newClient);
+ return newClient;
+ }
+ return null;
}
private void clearAllScoClients(int exceptPid, boolean stopSco) {
- synchronized (mScoClients) {
- ScoClient savedClient = null;
- for (ScoClient cl : mScoClients) {
- if (cl.getPid() != exceptPid) {
- cl.clearCount(stopSco);
- } else {
- savedClient = cl;
- }
+ ScoClient savedClient = null;
+ for (ScoClient cl : mScoClients) {
+ if (cl.getPid() != exceptPid) {
+ cl.clearCount(stopSco);
+ } else {
+ savedClient = cl;
}
- mScoClients.clear();
- if (savedClient != null) {
- mScoClients.add(savedClient);
- }
+ }
+ mScoClients.clear();
+ if (savedClient != null) {
+ mScoClients.add(savedClient);
}
}
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index 90342ee..017503a 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -168,6 +168,7 @@
String opPackageName, int cookie, int callingUid, int callingPid,
int callingUserId) {
checkPermission(USE_BIOMETRIC_INTERNAL);
+ updateActiveGroup(groupId, opPackageName);
final boolean restricted = true; // BiometricPrompt is always restricted
final AuthenticationClientImpl client = new FaceAuthClient(getContext(),
mDaemonWrapper, mHalDeviceId, token,
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index 62947c7..9e0a1c0c 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -192,6 +192,7 @@
IBiometricServiceReceiverInternal wrapperReceiver, String opPackageName,
int cookie, int callingUid, int callingPid, int callingUserId) {
checkPermission(MANAGE_BIOMETRIC);
+ updateActiveGroup(groupId, opPackageName);
final boolean restricted = true; // BiometricPrompt is always restricted
final AuthenticationClientImpl client = new FingerprintAuthClient(getContext(),
mDaemonWrapper, mHalDeviceId, token,
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 07e28f9..6cff57d 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -17,6 +17,8 @@
package com.android.server.connectivity;
import static android.net.NattSocketKeepalive.NATT_PORT;
+import static android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER;
+import static android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER;
import static android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE;
import static android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE;
import static android.net.NetworkAgent.EVENT_SOCKET_KEEPALIVE;
@@ -37,6 +39,9 @@
import android.net.NetworkAgent;
import android.net.NetworkUtils;
import android.net.SocketKeepalive.InvalidPacketException;
+import android.net.SocketKeepalive.InvalidSocketException;
+import android.net.TcpKeepalivePacketData;
+import android.net.TcpKeepalivePacketData.TcpSocketInfo;
import android.net.util.IpUtils;
import android.os.Binder;
import android.os.Handler;
@@ -65,7 +70,7 @@
*
* Provides methods to stop and start keepalive requests, and keeps track of keepalives across all
* networks. This class is tightly coupled to ConnectivityService. It is not thread-safe and its
- * methods must be called only from the ConnectivityService handler thread.
+ * handle* methods must be called only from the ConnectivityService handler thread.
*/
public class KeepaliveTracker {
@@ -78,9 +83,12 @@
private final HashMap <NetworkAgentInfo, HashMap<Integer, KeepaliveInfo>> mKeepalives =
new HashMap<> ();
private final Handler mConnectivityServiceHandler;
+ @NonNull
+ private final TcpKeepaliveController mTcpController;
public KeepaliveTracker(Handler handler) {
mConnectivityServiceHandler = handler;
+ mTcpController = new TcpKeepaliveController(handler);
}
/**
@@ -96,20 +104,33 @@
private final int mUid;
private final int mPid;
private final NetworkAgentInfo mNai;
+ private final int mType;
+ private final FileDescriptor mFd;
- /** Keepalive slot. A small integer that identifies this keepalive among the ones handled
- * by this network. */
+ public static final int TYPE_NATT = 1;
+ public static final int TYPE_TCP = 2;
+
+ // Keepalive slot. A small integer that identifies this keepalive among the ones handled
+ // by this network.
private int mSlot = NO_KEEPALIVE;
// Packet data.
private final KeepalivePacketData mPacket;
private final int mInterval;
- // Whether the keepalive is started or not.
- public boolean isStarted;
+ // Whether the keepalive is started or not. The initial state is NOT_STARTED.
+ private static final int NOT_STARTED = 1;
+ private static final int STARTING = 2;
+ private static final int STARTED = 3;
+ private int mStartedState = NOT_STARTED;
- public KeepaliveInfo(Messenger messenger, IBinder binder, NetworkAgentInfo nai,
- KeepalivePacketData packet, int interval) {
+ KeepaliveInfo(@NonNull Messenger messenger,
+ @NonNull IBinder binder,
+ @NonNull NetworkAgentInfo nai,
+ @NonNull KeepalivePacketData packet,
+ int interval,
+ int type,
+ @NonNull FileDescriptor fd) {
mMessenger = messenger;
mBinder = binder;
mPid = Binder.getCallingPid();
@@ -118,6 +139,8 @@
mNai = nai;
mPacket = packet;
mInterval = interval;
+ mType = type;
+ mFd = fd;
try {
mBinder.linkToDeath(this, 0);
@@ -130,32 +153,40 @@
return mNai;
}
+ private String startedStateString(final int state) {
+ switch (state) {
+ case NOT_STARTED : return "NOT_STARTED";
+ case STARTING : return "STARTING";
+ case STARTED : return "STARTED";
+ }
+ throw new IllegalArgumentException("Unknown state");
+ }
+
public String toString() {
- return new StringBuffer("KeepaliveInfo [")
- .append(" network=").append(mNai.network)
- .append(" isStarted=").append(isStarted)
- .append(" ")
- .append(IpUtils.addressAndPortToString(mPacket.srcAddress, mPacket.srcPort))
- .append("->")
- .append(IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort))
- .append(" interval=" + mInterval)
- .append(" packetData=" + HexDump.toHexString(mPacket.getPacket()))
- .append(" uid=").append(mUid).append(" pid=").append(mPid)
- .append(" ]")
- .toString();
+ return "KeepaliveInfo ["
+ + " network=" + mNai.network
+ + " startedState=" + startedStateString(mStartedState)
+ + " "
+ + IpUtils.addressAndPortToString(mPacket.srcAddress, mPacket.srcPort)
+ + "->"
+ + IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort)
+ + " interval=" + mInterval
+ + " uid=" + mUid + " pid=" + mPid
+ + " packetData=" + HexDump.toHexString(mPacket.getPacket())
+ + " ]";
}
/** Sends a message back to the application via its SocketKeepalive.Callback. */
void notifyMessenger(int slot, int err) {
+ if (DBG) {
+ Log.d(TAG, "notify keepalive " + mSlot + " on " + mNai.network + " for " + err);
+ }
KeepaliveTracker.this.notifyMessenger(mMessenger, slot, err);
}
/** Called when the application process is killed. */
public void binderDied() {
- // Not called from ConnectivityService handler thread, so send it a message.
- mConnectivityServiceHandler.obtainMessage(
- NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE,
- mSlot, BINDER_DIED, mNai.network).sendToTarget();
+ stop(BINDER_DIED);
}
void unlinkDeathRecipient() {
@@ -202,7 +233,26 @@
int error = isValid();
if (error == SUCCESS) {
Log.d(TAG, "Starting keepalive " + mSlot + " on " + mNai.name());
- mNai.asyncChannel.sendMessage(CMD_START_SOCKET_KEEPALIVE, slot, mInterval, mPacket);
+ switch (mType) {
+ case TYPE_NATT:
+ mNai.asyncChannel
+ .sendMessage(CMD_START_SOCKET_KEEPALIVE, slot, mInterval, mPacket);
+ break;
+ case TYPE_TCP:
+ mTcpController.startSocketMonitor(mFd, this, mSlot);
+ mNai.asyncChannel
+ .sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, slot, 0 /* Unused */,
+ mPacket);
+ // TODO: check result from apf and notify of failure as needed.
+ mNai.asyncChannel
+ .sendMessage(CMD_START_SOCKET_KEEPALIVE, slot, mInterval, mPacket);
+ break;
+ default:
+ Log.wtf(TAG, "Starting keepalive with unknown type: " + mType);
+ handleStopKeepalive(mNai, mSlot, error);
+ return;
+ }
+ mStartedState = STARTING;
} else {
handleStopKeepalive(mNai, mSlot, error);
return;
@@ -216,15 +266,27 @@
Log.e(TAG, "Cannot stop unowned keepalive " + mSlot + " on " + mNai.network);
}
}
- if (isStarted) {
+ if (NOT_STARTED != mStartedState) {
Log.d(TAG, "Stopping keepalive " + mSlot + " on " + mNai.name());
- mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
+ if (mType == TYPE_NATT) {
+ mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
+ } else if (mType == TYPE_TCP) {
+ mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
+ mNai.asyncChannel.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, mSlot);
+ mTcpController.stopSocketMonitor(mSlot);
+ } else {
+ Log.wtf(TAG, "Stopping keepalive with unknown type: " + mType);
+ }
}
// TODO: at the moment we unconditionally return failure here. In cases where the
// NetworkAgent is alive, should we ask it to reply, so it can return failure?
notifyMessenger(mSlot, reason);
unlinkDeathRecipient();
}
+
+ void onFileDescriptorInitiatedStop(final int socketKeepaliveReason) {
+ handleStopKeepalive(mNai, mSlot, socketKeepaliveReason);
+ }
}
void notifyMessenger(Messenger messenger, int slot, int err) {
@@ -328,20 +390,38 @@
return;
}
- if (reason == SUCCESS && !ki.isStarted) {
+ // This can be called in a number of situations :
+ // - startedState is STARTING.
+ // - reason is SUCCESS => go to STARTED.
+ // - reason isn't SUCCESS => it's an error starting. Go to NOT_STARTED and stop keepalive.
+ // - startedState is STARTED.
+ // - reason is SUCCESS => it's a success stopping. Go to NOT_STARTED and stop keepalive.
+ // - reason isn't SUCCESS => it's an error in exec. Go to NOT_STARTED and stop keepalive.
+ // The control is not supposed to ever come here if the state is NOT_STARTED. This is
+ // because in NOT_STARTED state, the code will switch to STARTING before sending messages
+ // to start, and the only way to NOT_STARTED is this function, through the edges outlined
+ // above : in all cases, keepalive gets stopped and can't restart without going into
+ // STARTING as messages are ordered. This also depends on the hardware processing the
+ // messages in order.
+ // TODO : clarify this code and get rid of mStartedState. Using a StateMachine is an
+ // option.
+ if (reason == SUCCESS && KeepaliveInfo.STARTING == ki.mStartedState) {
// Keepalive successfully started.
if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
- ki.isStarted = true;
+ ki.mStartedState = KeepaliveInfo.STARTED;
ki.notifyMessenger(slot, reason);
} else {
// Keepalive successfully stopped, or error.
- ki.isStarted = false;
+ ki.mStartedState = KeepaliveInfo.NOT_STARTED;
if (reason == SUCCESS) {
+ // The message indicated success stopping : don't call handleStopKeepalive.
if (DBG) Log.d(TAG, "Successfully stopped keepalive " + slot + " on " + nai.name());
} else {
+ // The message indicated some error trying to start or during the course of
+ // keepalive : do call handleStopKeepalive.
+ handleStopKeepalive(nai, slot, reason);
if (DBG) Log.d(TAG, "Keepalive " + slot + " on " + nai.name() + " error " + reason);
}
- handleStopKeepalive(nai, slot, reason);
}
}
@@ -379,10 +459,49 @@
notifyMessenger(messenger, NO_KEEPALIVE, e.error);
return;
}
- KeepaliveInfo ki = new KeepaliveInfo(messenger, binder, nai, packet, intervalSeconds);
- Log.d(TAG, "Created keepalive: " + ki.toString());
+ KeepaliveInfo ki = new KeepaliveInfo(messenger, binder, nai, packet, intervalSeconds,
+ KeepaliveInfo.TYPE_NATT, null);
mConnectivityServiceHandler.obtainMessage(
- CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget();
+ NetworkAgent.CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget();
+ }
+
+ /**
+ * Called by ConnectivityService to start TCP keepalive on a file descriptor.
+ *
+ * In order to offload keepalive for application correctly, sequence number, ack number and
+ * other fields are needed to form the keepalive packet. Thus, this function synchronously
+ * puts the socket into repair mode to get the necessary information. After the socket has been
+ * put into repair mode, the application cannot access the socket until reverted to normal.
+ *
+ * See {@link android.net.SocketKeepalive}.
+ **/
+ public void startTcpKeepalive(@Nullable NetworkAgentInfo nai,
+ @NonNull FileDescriptor fd,
+ int intervalSeconds,
+ @NonNull Messenger messenger,
+ @NonNull IBinder binder) {
+ if (nai == null) {
+ notifyMessenger(messenger, NO_KEEPALIVE, ERROR_INVALID_NETWORK);
+ return;
+ }
+
+ TcpKeepalivePacketData packet = null;
+ try {
+ TcpSocketInfo tsi = TcpKeepaliveController.switchToRepairMode(fd);
+ packet = TcpKeepalivePacketData.tcpKeepalivePacket(tsi);
+ } catch (InvalidPacketException | InvalidSocketException e) {
+ try {
+ TcpKeepaliveController.switchOutOfRepairMode(fd);
+ } catch (ErrnoException e1) {
+ Log.e(TAG, "Couldn't move fd out of repair mode after failure to start keepalive");
+ }
+ notifyMessenger(messenger, NO_KEEPALIVE, e.error);
+ return;
+ }
+ KeepaliveInfo ki = new KeepaliveInfo(messenger, binder, nai, packet, intervalSeconds,
+ KeepaliveInfo.TYPE_TCP, fd);
+ Log.d(TAG, "Created keepalive: " + ki.toString());
+ mConnectivityServiceHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, ki).sendToTarget();
}
/**
diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
new file mode 100644
index 0000000..8a9ac23
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.connectivity;
+
+import static android.net.SocketKeepalive.DATA_RECEIVED;
+import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET;
+import static android.net.SocketKeepalive.ERROR_SOCKET_NOT_IDLE;
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
+import static android.system.OsConstants.FIONREAD;
+import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.TIOCOUTQ;
+
+import android.annotation.NonNull;
+import android.net.NetworkUtils;
+import android.net.SocketKeepalive.InvalidSocketException;
+import android.net.TcpKeepalivePacketData.TcpSocketInfo;
+import android.net.TcpRepairWindow;
+import android.os.Handler;
+import android.os.MessageQueue;
+import android.os.Messenger;
+import android.system.ErrnoException;
+import android.system.Int32Ref;
+import android.system.Os;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo;
+
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+
+/**
+ * Manage tcp socket which offloads tcp keepalive.
+ *
+ * The input socket will be changed to repair mode and the application
+ * will not have permission to read/write data. If the application wants
+ * to write data, it must stop tcp keepalive offload to leave repair mode
+ * first. If a remote packet arrives, repair mode will be turned off and
+ * offload will be stopped. The application will receive a callback to know
+ * it can start reading data.
+ *
+ * {start,stop}SocketMonitor are thread-safe, but care must be taken in the
+ * order in which they are called. Please note that while calling
+ * {@link #startSocketMonitor(FileDescriptor, Messenger, int)} multiple times
+ * with either the same slot or the same FileDescriptor without stopping it in
+ * between will result in an exception, calling {@link #stopSocketMonitor(int)}
+ * multiple times with the same int is explicitly a no-op.
+ * Please also note that switching the socket to repair mode is not synchronized
+ * with either of these operations and has to be done in an orderly fashion
+ * with stopSocketMonitor. Take care in calling these in the right order.
+ * @hide
+ */
+public class TcpKeepaliveController {
+ private static final String TAG = "TcpKeepaliveController";
+ private static final boolean DBG = false;
+
+ private final MessageQueue mFdHandlerQueue;
+
+ private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
+
+ // Reference include/uapi/linux/tcp.h
+ private static final int TCP_REPAIR = 19;
+ private static final int TCP_REPAIR_QUEUE = 20;
+ private static final int TCP_QUEUE_SEQ = 21;
+ private static final int TCP_NO_QUEUE = 0;
+ private static final int TCP_RECV_QUEUE = 1;
+ private static final int TCP_SEND_QUEUE = 2;
+ private static final int TCP_REPAIR_OFF = 0;
+ private static final int TCP_REPAIR_ON = 1;
+ // Reference include/uapi/linux/sockios.h
+ private static final int SIOCINQ = FIONREAD;
+ private static final int SIOCOUTQ = TIOCOUTQ;
+
+ /**
+ * Keeps track of packet listeners.
+ * Key: slot number of keepalive offload.
+ * Value: {@link FileDescriptor} being listened to.
+ */
+ @GuardedBy("mListeners")
+ private final SparseArray<FileDescriptor> mListeners = new SparseArray<>();
+
+ public TcpKeepaliveController(final Handler connectivityServiceHandler) {
+ mFdHandlerQueue = connectivityServiceHandler.getLooper().getQueue();
+ }
+
+ /**
+ * Switch the tcp socket to repair mode and query tcp socket information.
+ *
+ * @param fd the fd of socket on which to use keepalive offload
+ * @return a {@link TcpKeepalivePacketData#TcpSocketInfo} object for current
+ * tcp/ip information.
+ */
+ // TODO : make this private. It's far too confusing that this gets called from outside
+ // at a time that nobody can understand.
+ public static TcpSocketInfo switchToRepairMode(FileDescriptor fd)
+ throws InvalidSocketException {
+ if (DBG) Log.i(TAG, "switchToRepairMode to start tcp keepalive : " + fd);
+ final SocketAddress srcSockAddr;
+ final SocketAddress dstSockAddr;
+ final InetAddress srcAddress;
+ final InetAddress dstAddress;
+ final int srcPort;
+ final int dstPort;
+ int seq;
+ final int ack;
+ final TcpRepairWindow trw;
+
+ // Query source address and port.
+ try {
+ srcSockAddr = Os.getsockname(fd);
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Get sockname fail: ", e);
+ throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
+ }
+ if (srcSockAddr instanceof InetSocketAddress) {
+ srcAddress = getAddress((InetSocketAddress) srcSockAddr);
+ srcPort = getPort((InetSocketAddress) srcSockAddr);
+ } else {
+ Log.e(TAG, "Invalid or mismatched SocketAddress");
+ throw new InvalidSocketException(ERROR_INVALID_SOCKET);
+ }
+ // Query destination address and port.
+ try {
+ dstSockAddr = Os.getpeername(fd);
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Get peername fail: ", e);
+ throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
+ }
+ if (dstSockAddr instanceof InetSocketAddress) {
+ dstAddress = getAddress((InetSocketAddress) dstSockAddr);
+ dstPort = getPort((InetSocketAddress) dstSockAddr);
+ } else {
+ Log.e(TAG, "Invalid or mismatched peer SocketAddress");
+ throw new InvalidSocketException(ERROR_INVALID_SOCKET);
+ }
+
+ // Query sequence and ack number
+ dropAllIncomingPackets(fd, true);
+ try {
+ // Enter tcp repair mode.
+ Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR, TCP_REPAIR_ON);
+ // Check if socket is idle.
+ if (!isSocketIdle(fd)) {
+ throw new InvalidSocketException(ERROR_SOCKET_NOT_IDLE);
+ }
+ // Query write sequence number from SEND_QUEUE.
+ Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_SEND_QUEUE);
+ seq = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
+ // Query read sequence number from RECV_QUEUE.
+ Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_RECV_QUEUE);
+ ack = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
+ // Switch to NO_QUEUE to prevent illegal socket read/write in repair mode.
+ Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_NO_QUEUE);
+ // Finally, check if socket is still idle. TODO : this check needs to move to
+ // after starting polling to prevent a race.
+ if (!isSocketIdle(fd)) {
+ throw new InvalidSocketException(ERROR_INVALID_SOCKET);
+ }
+
+ // Query tcp window size.
+ trw = NetworkUtils.getTcpRepairWindow(fd);
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Exception reading TCP state from socket", e);
+ try {
+ Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR, TCP_REPAIR_OFF);
+ } catch (ErrnoException ex) {
+ Log.e(TAG, "Exception while turning off repair mode due to exception", ex);
+ }
+ throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
+ } finally {
+ dropAllIncomingPackets(fd, false);
+ }
+
+ // Keepalive sequence number is last sequence number - 1. If it couldn't be retrieved,
+ // then it must be set to -1, so decrement in all cases.
+ seq = seq - 1;
+
+ return new TcpSocketInfo(srcAddress, srcPort, dstAddress, dstPort, seq, ack, trw.rcvWnd,
+ trw.rcvWndScale);
+ }
+
+ /**
+ * Switch the tcp socket out of repair mode.
+ *
+ * @param fd the fd of socket to switch back to normal.
+ */
+ // TODO : make this private.
+ public static void switchOutOfRepairMode(@NonNull final FileDescriptor fd)
+ throws ErrnoException {
+ Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR, TCP_REPAIR_OFF);
+ }
+
+ /**
+ * Start monitoring incoming packets.
+ *
+ * @param fd socket fd to monitor.
+ * @param messenger a callback to notify socket status.
+ * @param slot keepalive slot.
+ */
+ public void startSocketMonitor(@NonNull final FileDescriptor fd,
+ @NonNull final KeepaliveInfo ki, final int slot) {
+ synchronized (mListeners) {
+ if (null != mListeners.get(slot)) {
+ throw new IllegalArgumentException("This slot is already taken");
+ }
+ for (int i = 0; i < mListeners.size(); ++i) {
+ if (fd.equals(mListeners.valueAt(i))) {
+ throw new IllegalArgumentException("This fd is already registered");
+ }
+ }
+ mFdHandlerQueue.addOnFileDescriptorEventListener(fd, FD_EVENTS, (readyFd, events) -> {
+ // This can't be called twice because the queue guarantees that once the listener
+ // is unregistered it can't be called again, even for a message that arrived
+ // before it was unregistered.
+ final int reason;
+ if (0 != (events & EVENT_ERROR)) {
+ reason = ERROR_INVALID_SOCKET;
+ } else {
+ reason = DATA_RECEIVED;
+ }
+ ki.onFileDescriptorInitiatedStop(reason);
+ // The listener returns the new set of events to listen to. Because 0 means no
+ // event, the listener gets unregistered.
+ return 0;
+ });
+ mListeners.put(slot, fd);
+ }
+ }
+
+ /** Stop socket monitor */
+ // This slot may have been stopped automatically already because the socket received data,
+ // was closed on the other end or otherwise suffered some error. In this case, this function
+ // is a no-op.
+ public void stopSocketMonitor(final int slot) {
+ final FileDescriptor fd;
+ synchronized (mListeners) {
+ fd = mListeners.get(slot);
+ if (null == fd) return;
+ mListeners.remove(slot);
+ }
+ mFdHandlerQueue.removeOnFileDescriptorEventListener(fd);
+ try {
+ if (DBG) Log.d(TAG, "Moving socket out of repair mode for stop : " + fd);
+ switchOutOfRepairMode(fd);
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Cannot switch socket out of repair mode", e);
+ // Well, there is not much to do here to recover
+ }
+ }
+
+ private static InetAddress getAddress(InetSocketAddress inetAddr) {
+ return inetAddr.getAddress();
+ }
+
+ private static int getPort(InetSocketAddress inetAddr) {
+ return inetAddr.getPort();
+ }
+
+ private static boolean isSocketIdle(FileDescriptor fd) throws ErrnoException {
+ return isReceiveQueueEmpty(fd) && isSendQueueEmpty(fd);
+ }
+
+ private static boolean isReceiveQueueEmpty(FileDescriptor fd)
+ throws ErrnoException {
+ Int32Ref result = new Int32Ref(-1);
+ Os.ioctlInt(fd, SIOCINQ, result);
+ if (result.value != 0) {
+ Log.e(TAG, "Read queue has data");
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean isSendQueueEmpty(FileDescriptor fd)
+ throws ErrnoException {
+ Int32Ref result = new Int32Ref(-1);
+ Os.ioctlInt(fd, SIOCOUTQ, result);
+ if (result.value != 0) {
+ Log.e(TAG, "Write queue has data");
+ return false;
+ }
+ return true;
+ }
+
+ private static void dropAllIncomingPackets(FileDescriptor fd, boolean enable)
+ throws InvalidSocketException {
+ try {
+ if (enable) {
+ NetworkUtils.attachDropAllBPFFilter(fd);
+ } else {
+ NetworkUtils.detachBPFFilter(fd);
+ }
+ } catch (SocketException e) {
+ Log.e(TAG, "Socket Exception: ", e);
+ throw new InvalidSocketException(ERROR_INVALID_SOCKET, e);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index e268e44..bfa7f9d 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -899,9 +899,20 @@
@Override
public void setIsSyncable(Account account, String providerName, int syncable) {
+ setIsSyncableAsUser(account, providerName, syncable, UserHandle.getCallingUserId());
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void setIsSyncableAsUser(Account account, String providerName, int syncable,
+ int userId) {
if (TextUtils.isEmpty(providerName)) {
throw new IllegalArgumentException("Authority must not be empty");
}
+ enforceCrossUserPermission(userId,
+ "no permission to set the sync settings for user " + userId);
mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
"no permission to write the sync settings");
@@ -909,7 +920,6 @@
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
- int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
SyncManager syncManager = getSyncManager();
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 7096477..99e0707 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -3261,7 +3261,7 @@
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Account " + aau.account + " added, checking sync restore data");
}
- AccountSyncSettingsBackupHelper.accountAdded(mContext);
+ AccountSyncSettingsBackupHelper.accountAdded(mContext, syncTargets.userId);
break;
}
}
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index 3e16768..9cb6eee 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -114,6 +114,7 @@
private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 0;
private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 1;
private static final int MSG_APPLY_GLOBAL_SATURATION = 2;
+ private static final int MSG_APPLY_DISPLAY_WHITE_BALANCE = 3;
/**
* Return value if a setting has not been set.
@@ -322,8 +323,7 @@
}
private ColorSpace.Rgb getDisplayColorSpaceFromSurfaceControl() {
- IBinder displayToken = SurfaceControl.getBuiltInDisplay(
- SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
+ final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
if (displayToken == null) {
return null;
}
@@ -863,7 +863,7 @@
// If disabled, clear the tint. If enabled, do nothing more here and let the next
// temperature update set the correct tint.
if (!activated) {
- applyTint(mDisplayWhiteBalanceTintController, false);
+ mHandler.sendEmptyMessage(MSG_APPLY_DISPLAY_WHITE_BALANCE);
}
}
@@ -1534,7 +1534,7 @@
mDisplayWhiteBalanceTintController.setMatrix(cct);
if (mDisplayWhiteBalanceTintController.isActivated()) {
- applyTint(mDisplayWhiteBalanceTintController, false);
+ mHandler.sendEmptyMessage(MSG_APPLY_DISPLAY_WHITE_BALANCE);
return true;
}
return false;
@@ -1594,6 +1594,9 @@
case MSG_APPLY_NIGHT_DISPLAY_ANIMATED:
applyTint(mNightDisplayTintController, false);
break;
+ case MSG_APPLY_DISPLAY_WHITE_BALANCE:
+ applyTint(mDisplayWhiteBalanceTintController, false);
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index f2c539c..2f277e4 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -27,6 +27,7 @@
import android.opengl.EGLSurface;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
+import android.os.IBinder;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.Surface;
@@ -474,8 +475,14 @@
final SurfaceTexture st = new SurfaceTexture(mTexNames[0]);
final Surface s = new Surface(st);
try {
- SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
- SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), s);
+ final IBinder token = SurfaceControl.getInternalDisplayToken();
+ if (token == null) {
+ Slog.e(TAG,
+ "Failed to take screenshot because internal display is disconnected");
+ return false;
+ }
+
+ SurfaceControl.screenshot(token, s);
st.updateTexImage();
st.getTransformMatrix(mTexMatrix);
} finally {
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index b1b7d3c..ef92401 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -87,7 +87,7 @@
* Map of level -> color transformation matrix.
*/
@GuardedBy("mColorMatrix")
- private final SparseArray<float[]> mColorMatrix = new SparseArray<>(3);
+ private final SparseArray<float[]> mColorMatrix = new SparseArray<>(5);
/**
* Temporary matrix used internally by {@link #computeColorMatrixLocked()}.
*/
@@ -148,6 +148,21 @@
}
/**
+ * Sets the current Daltonization mode. This adjusts the color space to correct for or simulate
+ * various types of color blindness.
+ *
+ * @param mode the new Daltonization mode, or -1 to disable
+ */
+ public void setDaltonizerMode(int mode) {
+ synchronized (mDaltonizerModeLock) {
+ if (mDaltonizerMode != mode) {
+ mDaltonizerMode = mode;
+ applyDaltonizerMode(mode);
+ }
+ }
+ }
+
+ /**
* Returns the composition of all current color matrices, or {@code null} if there are none.
*/
@GuardedBy("mColorMatrix")
@@ -167,30 +182,6 @@
}
/**
- * Returns the current Daltonization mode.
- */
- public int getDaltonizerMode() {
- synchronized (mDaltonizerModeLock) {
- return mDaltonizerMode;
- }
- }
-
- /**
- * Sets the current Daltonization mode. This adjusts the color space to correct for or simulate
- * various types of color blindness.
- *
- * @param mode the new Daltonization mode, or -1 to disable
- */
- public void setDaltonizerMode(int mode) {
- synchronized (mDaltonizerModeLock) {
- if (mDaltonizerMode != mode) {
- mDaltonizerMode = mode;
- applyDaltonizerMode(mode);
- }
- }
- }
-
- /**
* Propagates the provided color transformation matrix to the SurfaceFlinger.
*/
private static void applyColorMatrix(float[] m) {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 16d82df..28f21f63 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -17,12 +17,8 @@
package com.android.server.display;
import android.app.ActivityThread;
-import android.content.res.Resources;
-import com.android.server.LocalServices;
-import com.android.server.lights.Light;
-import com.android.server.lights.LightsManager;
-
import android.content.Context;
+import android.content.res.Resources;
import android.hardware.sidekick.SidekickInternal;
import android.os.Build;
import android.os.Handler;
@@ -31,6 +27,7 @@
import android.os.PowerManager;
import android.os.SystemProperties;
import android.os.Trace;
+import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -38,6 +35,11 @@
import android.view.DisplayEventReceiver;
import android.view.Surface;
import android.view.SurfaceControl;
+
+import com.android.server.LocalServices;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -58,13 +60,9 @@
private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
- private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {
- SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,
- SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,
- };
+ private final LongSparseArray<LocalDisplayDevice> mDevices =
+ new LongSparseArray<LocalDisplayDevice>();
- private final SparseArray<LocalDisplayDevice> mDevices =
- new SparseArray<LocalDisplayDevice>();
@SuppressWarnings("unused") // Becomes active at instantiation time.
private HotplugDisplayEventReceiver mHotplugReceiver;
@@ -80,28 +78,26 @@
mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());
- for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
- tryConnectDisplayLocked(builtInDisplayId);
+ for (long physicalDisplayId : SurfaceControl.getPhysicalDisplayIds()) {
+ tryConnectDisplayLocked(physicalDisplayId);
}
}
- private void tryConnectDisplayLocked(int builtInDisplayId) {
- IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);
+ private void tryConnectDisplayLocked(long physicalDisplayId) {
+ final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
if (displayToken != null) {
SurfaceControl.PhysicalDisplayInfo[] configs =
SurfaceControl.getDisplayConfigs(displayToken);
if (configs == null) {
// There are no valid configs for this device, so we can't use it
- Slog.w(TAG, "No valid configs found for display device " +
- builtInDisplayId);
+ Slog.w(TAG, "No valid configs found for display device " + physicalDisplayId);
return;
}
int activeConfig = SurfaceControl.getActiveConfig(displayToken);
if (activeConfig < 0) {
// There is no active config, and for now we don't have the
// policy to set one.
- Slog.w(TAG, "No active config found for display device " +
- builtInDisplayId);
+ Slog.w(TAG, "No active config found for display device " + physicalDisplayId);
return;
}
int activeColorMode = SurfaceControl.getActiveColorMode(displayToken);
@@ -110,16 +106,17 @@
// configuration pass we'll go ahead and set it to whatever it was set to last (or
// COLOR_MODE_NATIVE if this is the first configuration).
Slog.w(TAG, "Unable to get active color mode for display device " +
- builtInDisplayId);
+ physicalDisplayId);
activeColorMode = Display.COLOR_MODE_INVALID;
}
int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
- LocalDisplayDevice device = mDevices.get(builtInDisplayId);
+ LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device == null) {
// Display was added.
- device = new LocalDisplayDevice(displayToken, builtInDisplayId,
- configs, activeConfig, colorModes, activeColorMode);
- mDevices.put(builtInDisplayId, device);
+ final boolean isInternal = mDevices.size() == 0;
+ device = new LocalDisplayDevice(displayToken, physicalDisplayId,
+ configs, activeConfig, colorModes, activeColorMode, isInternal);
+ mDevices.put(physicalDisplayId, device);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
} else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig,
colorModes, activeColorMode)) {
@@ -133,11 +130,11 @@
}
}
- private void tryDisconnectDisplayLocked(int builtInDisplayId) {
- LocalDisplayDevice device = mDevices.get(builtInDisplayId);
+ private void tryDisconnectDisplayLocked(long physicalDisplayId) {
+ LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device != null) {
// Display was removed.
- mDevices.remove(builtInDisplayId);
+ mDevices.remove(physicalDisplayId);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED);
}
}
@@ -158,10 +155,11 @@
}
private final class LocalDisplayDevice extends DisplayDevice {
- private final int mBuiltInDisplayId;
+ private final long mPhysicalDisplayId;
private final Light mBacklight;
private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>();
+ private final boolean mIsInternal;
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
@@ -179,16 +177,17 @@
private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
- public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
+ LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
- int[] colorModes, int activeColorMode) {
- super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
- mBuiltInDisplayId = builtInDisplayId;
+ int[] colorModes, int activeColorMode, boolean isInternal) {
+ super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId);
+ mPhysicalDisplayId = physicalDisplayId;
+ mIsInternal = isInternal;
updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo,
colorModes, activeColorMode);
updateColorModesLocked(colorModes, activeColorMode);
mSidekickInternal = LocalServices.getService(SidekickInternal.class);
- if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
+ if (mIsInternal) {
LightsManager lights = LocalServices.getService(LightsManager.class);
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
} else {
@@ -392,7 +391,7 @@
}
final Resources res = getOverlayContext().getResources();
- if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
+ if (mIsInternal) {
mInfo.name = res.getString(
com.android.internal.R.string.display_manager_built_in_display_name);
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
@@ -455,7 +454,7 @@
final boolean stateChanged = (mState != state);
final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;
if (stateChanged || brightnessChanged) {
- final int displayId = mBuiltInDisplayId;
+ final long physicalDisplayId = mPhysicalDisplayId;
final IBinder token = getDisplayTokenLocked();
final int oldState = mState;
@@ -519,7 +518,7 @@
private void setVrMode(boolean isVrEnabled) {
if (DEBUG) {
Slog.d(TAG, "setVrMode("
- + "id=" + displayId
+ + "id=" + physicalDisplayId
+ ", state=" + Display.stateToString(state) + ")");
}
mBacklight.setVrMode(isVrEnabled);
@@ -528,7 +527,7 @@
private void setDisplayState(int state) {
if (DEBUG) {
Slog.d(TAG, "setDisplayState("
- + "id=" + displayId
+ + "id=" + physicalDisplayId
+ ", state=" + Display.stateToString(state) + ")");
}
@@ -546,7 +545,7 @@
}
final int mode = getPowerModeForState(state);
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
- + "id=" + displayId
+ + "id=" + physicalDisplayId
+ ", state=" + Display.stateToString(state) + ")");
try {
SurfaceControl.setDisplayPowerMode(token, mode);
@@ -571,11 +570,12 @@
private void setDisplayBrightness(int brightness) {
if (DEBUG) {
Slog.d(TAG, "setDisplayBrightness("
- + "id=" + displayId + ", brightness=" + brightness + ")");
+ + "id=" + physicalDisplayId
+ + ", brightness=" + brightness + ")");
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
- + "id=" + displayId + ", brightness=" + brightness + ")");
+ + "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
try {
mBacklight.setBrightness(brightness);
Trace.traceCounter(Trace.TRACE_TAG_POWER,
@@ -646,7 +646,7 @@
@Override
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);
- pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
+ pw.println("mPhysicalDisplayId=" + mPhysicalDisplayId);
pw.println("mActivePhysIndex=" + mActivePhysIndex);
pw.println("mActiveModeId=" + mActiveModeId);
pw.println("mActiveColorMode=" + mActiveColorMode);
@@ -731,12 +731,12 @@
}
@Override
- public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
+ public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
synchronized (getSyncRoot()) {
if (connected) {
- tryConnectDisplayLocked(builtInDisplayId);
+ tryConnectDisplayLocked(physicalDisplayId);
} else {
- tryDisconnectDisplayLocked(builtInDisplayId);
+ tryDisconnectDisplayLocked(physicalDisplayId);
}
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java b/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
index adc1cd7..2c0cacd 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
@@ -450,6 +450,20 @@
}
/**
+ * Returns {@code true} if given Android keycode is volume control related,
+ * otherwise {@code false}.
+ */
+ static boolean isVolumeKeycode(int androidKeycode) {
+ int cecKeyCode = HdmiCecKeycode.androidKeyToCecKey(androidKeycode)[0];
+ return isSupportedKeycode(androidKeycode)
+ && (cecKeyCode == CEC_KEYCODE_VOLUME_UP
+ || cecKeyCode == CEC_KEYCODE_VOLUME_DOWN
+ || cecKeyCode == CEC_KEYCODE_MUTE
+ || cecKeyCode == CEC_KEYCODE_MUTE_FUNCTION
+ || cecKeyCode == CEC_KEYCODE_RESTORE_VOLUME_FUNCTION);
+ }
+
+ /**
* Returns CEC keycode to control audio mute status.
*
* @param muting {@code true} if audio is being muted
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 414f6bb..78b091e 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -1016,6 +1016,40 @@
}
/**
+ * Send a volume key event to other CEC device. The logical address of target device will be
+ * given by {@link #findAudioReceiverAddress()}.
+ *
+ * @param keyCode key code defined in {@link android.view.KeyEvent}
+ * @param isPressed {@code true} for key down event
+ * @see #findAudioReceiverAddress()
+ */
+ @ServiceThreadOnly
+ protected void sendVolumeKeyEvent(int keyCode, boolean isPressed) {
+ assertRunOnServiceThread();
+ if (!HdmiCecKeycode.isVolumeKeycode(keyCode)) {
+ Slog.w(TAG, "Not a volume key: " + keyCode);
+ return;
+ }
+ List<SendKeyAction> action = getActions(SendKeyAction.class);
+ int logicalAddress = findAudioReceiverAddress();
+ if (logicalAddress == Constants.ADDR_INVALID || logicalAddress == mAddress) {
+ // Don't send key event to invalid device or itself.
+ Slog.w(
+ TAG,
+ "Discard volume key event: "
+ + keyCode
+ + ", pressed:"
+ + isPressed
+ + ", receiverAddr="
+ + logicalAddress);
+ } else if (!action.isEmpty()) {
+ action.get(0).processKeyEvent(keyCode, isPressed);
+ } else if (isPressed) {
+ addAndStartAction(new SendKeyAction(this, logicalAddress, keyCode));
+ }
+ }
+
+ /**
* Returns the logical address of the device which will receive key events via {@link
* #sendKeyEvent}.
*
@@ -1026,6 +1060,17 @@
return Constants.ADDR_INVALID;
}
+ /**
+ * Returns the logical address of the audio receiver device which will receive volume key events
+ * via {@link#sendVolumeKeyEvent}.
+ *
+ * @see #sendVolumeKeyEvent(int, boolean)
+ */
+ protected int findAudioReceiverAddress() {
+ Slog.w(TAG, "findAudioReceiverAddress is not implemented");
+ return Constants.ADDR_INVALID;
+ }
+
@ServiceThreadOnly
void invokeCallback(IHdmiControlCallback callback, int result) {
assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 1ba0c52..6710986 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -68,11 +68,6 @@
private static final String TAG = "HdmiCecLocalDeviceAudioSystem";
- // Whether System audio mode is activated or not.
- // This becomes true only when all system audio sequences are finished.
- @GuardedBy("mLock")
- private boolean mSystemAudioActivated;
-
// Whether the System Audio Control feature is enabled or not. True by default.
@GuardedBy("mLock")
private boolean mSystemAudioControlFeatureEnabled;
@@ -271,7 +266,7 @@
synchronized (mLock) {
mService.writeStringSystemProperty(
Constants.PROPERTY_LAST_SYSTEM_AUDIO_CONTROL,
- mSystemAudioActivated ? "true" : "false");
+ isSystemAudioActivated() ? "true" : "false");
}
terminateSystemAudioMode();
}
@@ -786,7 +781,7 @@
int maxVolume = mService.getAudioManager().getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int minVolume = mService.getAudioManager().getStreamMinVolume(AudioManager.STREAM_MUSIC);
int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
- HdmiLogger.debug("Reporting volume %i (%i-%i) as CEC volume %i", volume,
+ HdmiLogger.debug("Reporting volume %d (%d-%d) as CEC volume %d", volume,
minVolume, maxVolume, scaledVolume);
mService.sendCecCommand(
@@ -814,7 +809,7 @@
}
HdmiLogger.debug(
"System Audio Mode change[old:%b new:%b]",
- mSystemAudioActivated, newSystemAudioMode);
+ isSystemAudioActivated(), newSystemAudioMode);
// Wake up device if System Audio Control is turned on
if (newSystemAudioMode) {
mService.wakeUp();
@@ -854,8 +849,8 @@
}
updateAudioManagerForSystemAudio(newSystemAudioMode);
synchronized (mLock) {
- if (mSystemAudioActivated != newSystemAudioMode) {
- mSystemAudioActivated = newSystemAudioMode;
+ if (isSystemAudioActivated() != newSystemAudioMode) {
+ mService.setSystemAudioActivated(newSystemAudioMode);
mService.announceSystemAudioModeChange(newSystemAudioMode);
}
}
@@ -946,9 +941,7 @@
}
protected boolean isSystemAudioActivated() {
- synchronized (mLock) {
- return mSystemAudioActivated;
- }
+ return mService.isSystemAudioActivated();
}
protected void terminateSystemAudioMode() {
@@ -1215,7 +1208,6 @@
protected void dump(IndentingPrintWriter pw) {
pw.println("HdmiCecLocalDeviceAudioSystem:");
pw.increaseIndent();
- pw.println("mSystemAudioActivated: " + mSystemAudioActivated);
pw.println("isRoutingFeatureEnabled " + isRoutingControlFeatureEnabled());
pw.println("mSystemAudioControlFeatureEnabled: " + mSystemAudioControlFeatureEnabled);
pw.println("mTvSystemAudioModeSupport: " + mTvSystemAudioModeSupport);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index ef7d241..20933db 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -19,6 +19,7 @@
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.IHdmiControlCallback;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemProperties;
@@ -30,6 +31,7 @@
import com.android.internal.app.LocalePicker.LocaleInfo;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
import java.io.UnsupportedEncodingException;
import java.util.List;
@@ -85,6 +87,22 @@
mAddress, mService.getPhysicalAddress(), mDeviceType));
mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
mAddress, mService.getVendorId()));
+ if (mService.audioSystem() == null) {
+ // If current device is not a functional audio system device,
+ // send message to potential audio system device in the system to get the system
+ // audio mode status. If no response, set to false.
+ mService.sendCecCommand(HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mAddress, Constants.ADDR_AUDIO_SYSTEM), new SendMessageCallback() {
+ @Override
+ public void onSendCompleted(int error) {
+ if (error != SendMessageResult.SUCCESS) {
+ HdmiLogger.debug(
+ "AVR did not respond to <Give System Audio Mode Status>");
+ mService.setSystemAudioActivated(false);
+ }
+ }
+ });
+ }
startQueuedActions();
}
@@ -275,11 +293,50 @@
}
@Override
+ protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
+ // System Audio Mode only turns on/off when Audio System broadcasts on/off message.
+ // For device with type 4 and 5, it can set system audio mode on/off
+ // when there is another audio system device connected into the system first.
+ if (message.getDestination() != Constants.ADDR_BROADCAST
+ || message.getSource() != Constants.ADDR_AUDIO_SYSTEM
+ || mService.audioSystem() != null) {
+ return true;
+ }
+ boolean setSystemAudioModeOn = HdmiUtils.parseCommandParamSystemAudioStatus(message);
+ if (mService.isSystemAudioActivated() != setSystemAudioModeOn) {
+ mService.setSystemAudioActivated(setSystemAudioModeOn);
+ }
+ return true;
+ }
+
+ @Override
+ protected boolean handleSystemAudioModeStatus(HdmiCecMessage message) {
+ // Only directly addressed System Audio Mode Status message can change internal
+ // system audio mode status.
+ if (message.getDestination() == mAddress
+ && message.getSource() == Constants.ADDR_AUDIO_SYSTEM) {
+ boolean setSystemAudioModeOn = HdmiUtils.parseCommandParamSystemAudioStatus(message);
+ if (mService.isSystemAudioActivated() != setSystemAudioModeOn) {
+ mService.setSystemAudioActivated(setSystemAudioModeOn);
+ }
+ }
+ return true;
+ }
+
+ @Override
protected int findKeyReceiverAddress() {
return Constants.ADDR_TV;
}
@Override
+ protected int findAudioReceiverAddress() {
+ if (mService.isSystemAudioActivated()) {
+ return Constants.ADDR_AUDIO_SYSTEM;
+ }
+ return Constants.ADDR_TV;
+ }
+
+ @Override
@ServiceThreadOnly
protected void disableDevice(boolean initiatedByCec, PendingActionClearedCallback callback) {
super.disableDevice(initiatedByCec, callback);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index a8c4350..8a7051f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -77,11 +77,6 @@
// True by default for all the ARC-enabled ports.
private final SparseBooleanArray mArcFeatureEnabled = new SparseBooleanArray();
- // Whether System audio mode is activated or not.
- // This becomes true only when all system audio sequences are finished.
- @GuardedBy("mLock")
- private boolean mSystemAudioActivated = false;
-
// Whether the System Audio Control feature is enabled or not. True by default.
@GuardedBy("mLock")
private boolean mSystemAudioControlFeatureEnabled;
@@ -829,11 +824,12 @@
+ "because the System Audio Control feature is disabled.");
return;
}
- HdmiLogger.debug("System Audio Mode change[old:%b new:%b]", mSystemAudioActivated, on);
+ HdmiLogger.debug("System Audio Mode change[old:%b new:%b]",
+ mService.isSystemAudioActivated(), on);
updateAudioManagerForSystemAudio(on);
synchronized (mLock) {
- if (mSystemAudioActivated != on) {
- mSystemAudioActivated = on;
+ if (mService.isSystemAudioActivated() != on) {
+ mService.setSystemAudioActivated(on);
mService.announceSystemAudioModeChange(on);
}
startArcAction(on);
@@ -849,9 +845,7 @@
if (!hasSystemAudioDevice()) {
return false;
}
- synchronized (mLock) {
- return mSystemAudioActivated;
- }
+ return mService.isSystemAudioActivated();
}
@ServiceThreadOnly
@@ -1904,7 +1898,6 @@
super.dump(pw);
pw.println("mArcEstablished: " + mArcEstablished);
pw.println("mArcFeatureEnabled: " + mArcFeatureEnabled);
- pw.println("mSystemAudioActivated: " + mSystemAudioActivated);
pw.println("mSystemAudioMute: " + mSystemAudioMute);
pw.println("mSystemAudioControlFeatureEnabled: " + mSystemAudioControlFeatureEnabled);
pw.println("mAutoDeviceOff: " + mAutoDeviceOff);
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index c5eccdf..072238e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -147,6 +147,10 @@
@GuardedBy("mLock")
protected final ActiveSource mActiveSource = new ActiveSource();
+ // Whether System Audio Mode is activated or not.
+ @GuardedBy("mLock")
+ private boolean mSystemAudioActivated = false;
+
private static final boolean isHdmiCecNeverClaimPlaybackLogicAddr =
SystemProperties.getBoolean(
Constants.PROPERTY_HDMI_CEC_NEVER_CLAIM_PLAYBACK_LOGICAL_ADDRESS, false);
@@ -1533,7 +1537,7 @@
if (mCecController != null) {
HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(deviceType);
if (localDevice == null) {
- Slog.w(TAG, "Local device not available");
+ Slog.w(TAG, "Local device not available to send key event.");
return;
}
localDevice.sendKeyEvent(keyCode, isPressed);
@@ -1543,6 +1547,28 @@
}
@Override
+ public void sendVolumeKeyEvent(
+ final int deviceType, final int keyCode, final boolean isPressed) {
+ enforceAccessPermission();
+ runOnServiceThread(new Runnable() {
+ @Override
+ public void run() {
+ if (mCecController == null) {
+ Slog.w(TAG, "CEC controller not available to send volume key event.");
+ return;
+ }
+ HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(deviceType);
+ if (localDevice == null) {
+ Slog.w(TAG, "Local device " + deviceType
+ + " not available to send volume key event.");
+ return;
+ }
+ localDevice.sendVolumeKeyEvent(keyCode, isPressed);
+ }
+ });
+ }
+
+ @Override
public void oneTouchPlay(final IHdmiControlCallback callback) {
enforceAccessPermission();
runOnServiceThread(new Runnable() {
@@ -2010,6 +2036,7 @@
pw.increaseIndent();
pw.println("mHdmiControlEnabled: " + mHdmiControlEnabled);
pw.println("mMhlInputChangeEnabled: " + mMhlInputChangeEnabled);
+ pw.println("mSystemAudioActivated: " + isSystemAudioActivated());
pw.decreaseIndent();
pw.println("mMhlController: ");
@@ -2385,7 +2412,8 @@
void wakeUp() {
assertRunOnServiceThread();
mWakeUpMessageReceived = true;
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.hdmi:WAKE");
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_HDMI,
+ "android.server.hdmi:WAKE");
// PowerManger will send the broadcast Intent.ACTION_SCREEN_ON and after this gets
// the intent, the sequence will continue at onWakeUp().
}
@@ -2610,7 +2638,8 @@
playback().sendStandby(0 /* unused */);
}
} else if (isPowerStandbyOrTransient() && !isStandbyModeOn) {
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.hdmi:WAKE");
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_HDMI,
+ "android.server.hdmi:WAKE");
if (playback() != null) {
oneTouchPlay(new IHdmiControlCallback.Stub() {
@Override
@@ -2636,6 +2665,18 @@
}
}
+ boolean isSystemAudioActivated() {
+ synchronized (mLock) {
+ return mSystemAudioActivated;
+ }
+ }
+
+ void setSystemAudioActivated(boolean on) {
+ synchronized (mLock) {
+ mSystemAudioActivated = on;
+ }
+ }
+
@ServiceThreadOnly
void setCecOption(int key, boolean value) {
assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/hdmi/SendKeyAction.java b/services/core/java/com/android/server/hdmi/SendKeyAction.java
index 40d2583..5ad7fab 100644
--- a/services/core/java/com/android/server/hdmi/SendKeyAction.java
+++ b/services/core/java/com/android/server/hdmi/SendKeyAction.java
@@ -17,8 +17,10 @@
import static com.android.server.hdmi.HdmiConfig.IRT_MS;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.util.Slog;
import android.view.KeyEvent;
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
/**
* Feature action that transmits remote control key command (User Control Press/
@@ -146,8 +148,26 @@
if (cecKeycodeAndParams == null) {
return;
}
- sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(),
- mTargetAddress, cecKeycodeAndParams));
+ // Devices that are not directly connected with audio system device can't detect if the
+ // audio system device is still plugged in. Framework checks if the volume key forwarding is
+ // successful or not every time to make sure the System Audio Mode status is still updated.
+ if (mTargetAddress == Constants.ADDR_AUDIO_SYSTEM
+ && localDevice().mAddress != Constants.ADDR_TV) {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(),
+ mTargetAddress, cecKeycodeAndParams), new SendMessageCallback() {
+ @Override
+ public void onSendCompleted(int error) {
+ if (error != SendMessageResult.SUCCESS) {
+ HdmiLogger.debug(
+ "AVR did not respond to <User Control Pressed>");
+ localDevice().mService.setSystemAudioActivated(false);
+ }
+ }
+ });
+ } else {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(),
+ mTargetAddress, cecKeycodeAndParams));
+ }
}
private void sendKeyUp() {
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 532aa01..2bfb31f 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -286,6 +286,46 @@
}
/**
+ * Sets whether the default service should be used.
+ *
+ * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
+ * with the test results.
+ *
+ * @throws SecurityException if caller is not allowed to manage this service's settings.
+ */
+ public final void setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) {
+ Slog.i(mTag, "setDefaultServiceEnabled() for userId " + userId + ": " + enabled);
+ enforceCallingPermissionForManagement();
+
+ synchronized (mLock) {
+ final S oldService = peekServiceForUserLocked(userId);
+ if (oldService != null) {
+ oldService.removeSelfFromCacheLocked();
+ }
+ mServiceNameResolver.setDefaultServiceEnabled(userId, enabled);
+
+ // Must update the service on cache so its initialization code is triggered
+ updateCachedServiceLocked(userId);
+ }
+ }
+
+ /**
+ * Checks whether the default service should be used.
+ *
+ * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
+ * with the test results.
+ *
+ * @throws SecurityException if caller is not allowed to manage this service's settings.
+ */
+ public final boolean isDefaultServiceEnabled(@UserIdInt int userId) {
+ enforceCallingPermissionForManagement();
+
+ synchronized (mLock) {
+ return mServiceNameResolver.isDefaultServiceEnabled(userId);
+ }
+ }
+
+ /**
* Gets the maximum time the service implementation can be changed.
*
* @throws UnsupportedOperationException if subclass doesn't override it.
diff --git a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
index 7f198ac..cf84e22 100644
--- a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
@@ -27,6 +27,7 @@
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
@@ -61,6 +62,15 @@
private final SparseArray<String> mTemporaryServiceNames = new SparseArray<>();
/**
+ * Map of default services that have been disabled by
+ * {@link #setDefaultServiceEnabled(int, boolean)},keyed by {@code userId}.
+ *
+ * <p>Typically used by Shell command and/or CTS tests.
+ */
+ @GuardedBy("mLock")
+ private final SparseBooleanArray mDefaultServicesDisabled = new SparseBooleanArray();
+
+ /**
* When the temporary service will expire (and reset back to the default).
*/
@GuardedBy("mLock")
@@ -99,12 +109,18 @@
final String temporaryName = mTemporaryServiceNames.get(userId);
if (temporaryName != null) {
// Always log it, as it should only be used on CTS or during development
- Slog.w(TAG, "getComponentName(): using temporary name " + temporaryName
+ Slog.w(TAG, "getServiceName(): using temporary name " + temporaryName
+ " for user " + userId);
return temporaryName;
- } else {
- return getDefaultServiceName(userId);
}
+ final boolean disabled = mDefaultServicesDisabled.get(userId);
+ if (disabled) {
+ // Always log it, as it should only be used on CTS or during development
+ Slog.w(TAG, "getServiceName(): temporary name not set and default disabled for "
+ + "user " + userId);
+ return null;
+ }
+ return getDefaultServiceName(userId);
}
}
@@ -158,6 +174,24 @@
}
@Override
+ public void setDefaultServiceEnabled(int userId, boolean enabled) {
+ synchronized (mLock) {
+ if (enabled) {
+ mDefaultServicesDisabled.removeAt(userId);
+ } else {
+ mDefaultServicesDisabled.put(userId, true);
+ }
+ }
+ }
+
+ @Override
+ public boolean isDefaultServiceEnabled(int userId) {
+ synchronized (mLock) {
+ return mDefaultServicesDisabled.get(userId);
+ }
+ }
+
+ @Override
public String toString() {
return "FrameworkResourcesServiceNamer[temps=" + mTemporaryServiceNames + "]";
}
@@ -168,6 +202,7 @@
synchronized (mLock) {
pw.print("FrameworkResourcesServiceNamer: resId="); pw.print(mResourceId);
pw.print(", numberTemps="); pw.print(mTemporaryServiceNames.size());
+ pw.print(", enabledDefaults="); pw.print(mDefaultServicesDisabled.size());
}
}
@@ -181,7 +216,9 @@
final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime();
pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.print("), ");
}
- pw.print("defaultName="); pw.println(getDefaultServiceName(userId));
+ pw.print("defaultName="); pw.print(getDefaultServiceName(userId));
+ final boolean disabled = mDefaultServicesDisabled.get(userId);
+ pw.println(disabled ? " (disabled)" : " (enabled)");
}
}
diff --git a/services/core/java/com/android/server/infra/ServiceNameResolver.java b/services/core/java/com/android/server/infra/ServiceNameResolver.java
index bc11ff3..5b60413 100644
--- a/services/core/java/com/android/server/infra/ServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/ServiceNameResolver.java
@@ -108,6 +108,36 @@
}
/**
+ * Sets whether the default service should be used when the temporary service is not set.
+ *
+ * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
+ * with the test results.
+ *
+ * @param userId user handle
+ * @param enabled whether the default service should be used when the temporary service is not
+ * set
+ *
+ * @throws UnsupportedOperationException if not implemented.
+ */
+ default void setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) {
+ throw new UnsupportedOperationException("changing default service not supported");
+ }
+
+ /**
+ * Checks whether the default service should be used when the temporary service is not set.
+ *
+ * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
+ * with the test results.
+ *
+ * @param userId user handle
+ *
+ * @throws UnsupportedOperationException if not implemented.
+ */
+ default boolean isDefaultServiceEnabled(@UserIdInt int userId) {
+ throw new UnsupportedOperationException("checking default service not supported");
+ }
+
+ /**
* Dumps the generic info in just one line (without calling {@code println}.
*/
// TODO(b/117779333): support proto
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index d20508a..144f2b6 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1627,10 +1627,12 @@
}
@Override
- public List<InputMethodInfo> getInputMethodList() {
- final int callingUserId = UserHandle.getCallingUserId();
+ public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
synchronized (mMethodMap) {
- final int[] resolvedUserIds = InputMethodUtils.resolveUserId(callingUserId,
+ final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId,
mSettings.getCurrentUserId(), null);
if (resolvedUserIds.length != 1) {
return Collections.emptyList();
@@ -1645,10 +1647,12 @@
}
@Override
- public List<InputMethodInfo> getEnabledInputMethodList() {
- final int callingUserId = UserHandle.getCallingUserId();
+ public List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ }
synchronized (mMethodMap) {
- final int[] resolvedUserIds = InputMethodUtils.resolveUserId(callingUserId,
+ final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId,
mSettings.getCurrentUserId(), null);
if (resolvedUserIds.length != 1) {
return Collections.emptyList();
@@ -4697,7 +4701,7 @@
mSettings.getCurrentUserId(),
mContext.getBasePackageName());
nextIme = mSettings.getSelectedInputMethod();
- nextEnabledImes = getEnabledInputMethodList();
+ nextEnabledImes = mSettings.getEnabledInputMethodListLocked();
final PrintWriter pr = shellCommand.getOutPrintWriter();
pr.println("Reset current and enabled IMEs");
pr.println("Newly selected IME:");
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 3222143..500c388 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.inputmethod;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -1195,6 +1196,7 @@
* Takes care of IPCs exposed to the IME client.
*/
private static final class ApiCallbacks extends IInputMethodManager.Stub {
+ private final Context mContext;
private final UserDataMap mUserDataMap;
private final UserToInputMethodInfoMap mInputMethodInfoMap;
private final AppOpsManager mAppOpsManager;
@@ -1202,6 +1204,7 @@
ApiCallbacks(Context context, UserDataMap userDataMap,
UserToInputMethodInfoMap inputMethodInfoMap) {
+ mContext = context;
mUserDataMap = userDataMap;
mInputMethodInfoMap = inputMethodInfoMap;
mAppOpsManager = context.getSystemService(AppOpsManager.class);
@@ -1233,14 +1236,20 @@
@BinderThread
@Override
- public List<InputMethodInfo> getInputMethodList() {
- return mInputMethodInfoMap.getAsList(UserHandle.getUserId(Binder.getCallingUid()));
+ public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, null);
+ }
+ return mInputMethodInfoMap.getAsList(userId);
}
@BinderThread
@Override
- public List<InputMethodInfo> getEnabledInputMethodList() {
- return mInputMethodInfoMap.getAsList(UserHandle.getUserId(Binder.getCallingUid()));
+ public List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) {
+ if (UserHandle.getCallingUserId() != userId) {
+ mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, null);
+ }
+ return mInputMethodInfoMap.getAsList(userId);
}
@BinderThread
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index cefe583..19d10ec 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -509,7 +509,7 @@
private static final float DEFAULT_CONN_CONGESTION_DELAY_FRAC = 0.5f;
private static final float DEFAULT_CONN_PREFETCH_RELAX_FRAC = 0.5f;
private static final boolean DEFAULT_USE_HEARTBEATS = false;
- private static final boolean DEFAULT_TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+ private static final boolean DEFAULT_TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
private static final long DEFAULT_QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS =
10 * 60 * 1000L; // 10 minutes
private static final long DEFAULT_QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS =
diff --git a/services/core/java/com/android/server/location/AbstractLocationProvider.java b/services/core/java/com/android/server/location/AbstractLocationProvider.java
index b3f1018..0edd17b 100644
--- a/services/core/java/com/android/server/location/AbstractLocationProvider.java
+++ b/services/core/java/com/android/server/location/AbstractLocationProvider.java
@@ -16,6 +16,7 @@
package com.android.server.location;
+import android.content.Context;
import android.location.Location;
import android.location.LocationProvider;
import android.os.Bundle;
@@ -26,6 +27,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Collections;
import java.util.List;
/**
@@ -65,9 +67,12 @@
void onReportLocation(List<Location> locations);
}
+ protected final Context mContext;
private final LocationProviderManager mLocationProviderManager;
- protected AbstractLocationProvider(LocationProviderManager locationProviderManager) {
+ protected AbstractLocationProvider(
+ Context context, LocationProviderManager locationProviderManager) {
+ mContext = context;
mLocationProviderManager = locationProviderManager;
}
@@ -101,6 +106,11 @@
mLocationProviderManager.onSetProperties(properties);
}
+ /** Returns list of packages currently associated with this provider. */
+ public List<String> getProviderPackages() {
+ return Collections.singletonList(mContext.getPackageName());
+ }
+
/**
* Called when the location service delivers a new request for fulfillment to the provider.
* Replaces any previous requests completely.
diff --git a/telephony/java/android/telephony/ims/RcsPart.java b/services/core/java/com/android/server/location/CallerIdentity.java
similarity index 62%
copy from telephony/java/android/telephony/ims/RcsPart.java
copy to services/core/java/com/android/server/location/CallerIdentity.java
index da50173..da31d0b 100644
--- a/telephony/java/android/telephony/ims/RcsPart.java
+++ b/services/core/java/com/android/server/location/CallerIdentity.java
@@ -13,13 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.telephony.ims;
-import android.os.Parcelable;
+package com.android.server.location;
/**
- * A part of a composite {@link RcsMessage}.
- * @hide - TODO(sahinc) make this public
+ * Represents the calling process's uid, pid, and package name.
*/
-public abstract class RcsPart implements Parcelable {
+public class CallerIdentity {
+ public final int mUid;
+ public final int mPid;
+ public final String mPackageName;
+
+ public CallerIdentity(int uid, int pid, String packageName) {
+ mUid = uid;
+ mPid = pid;
+ mPackageName = packageName;
+ }
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index ab9f711..f368e7b 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.ContentObserver;
import android.hardware.location.GeofenceHardware;
import android.hardware.location.GeofenceHardwareImpl;
import android.location.Criteria;
@@ -168,21 +169,13 @@
private static final int AGPS_SUPL_MODE_MSA = 0x02;
private static final int AGPS_SUPL_MODE_MSB = 0x01;
- // Handler messages
- private static final int CHECK_LOCATION = 1;
- private static final int ENABLE = 2;
private static final int SET_REQUEST = 3;
- private static final int UPDATE_NETWORK_STATE = 4;
private static final int INJECT_NTP_TIME = 5;
private static final int DOWNLOAD_XTRA_DATA = 6;
private static final int UPDATE_LOCATION = 7; // Handle external location from network listener
- private static final int ADD_LISTENER = 8;
- private static final int REMOVE_LISTENER = 9;
private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
private static final int SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED = 12;
private static final int INITIALIZE_HANDLER = 13;
- private static final int REQUEST_SUPL_CONNECTION = 14;
- private static final int RELEASE_SUPL_CONNECTION = 15;
private static final int REQUEST_LOCATION = 16;
private static final int REPORT_LOCATION = 17; // HAL reports location
private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
@@ -311,6 +304,8 @@
// true if we are enabled, protected by this
private boolean mEnabled = true;
+ private boolean mShutdown;
+
// states for injecting ntp and downloading xtra data
private static final int STATE_PENDING_NETWORK = 0;
private static final int STATE_DOWNLOADING = 1;
@@ -349,7 +344,7 @@
private GnssPositionMode mLastPositionMode;
// Current request from underlying location clients.
- private ProviderRequest mProviderRequest = null;
+ private ProviderRequest mProviderRequest;
// The WorkSource associated with the most recent client request (i.e, most recent call to
// setRequest).
private WorkSource mWorkSource = null;
@@ -368,11 +363,9 @@
private int mC2KServerPort;
private boolean mSuplEsEnabled = false;
- private final Context mContext;
private final Looper mLooper;
private final LocationExtras mLocationExtras = new LocationExtras();
private final GnssStatusListenerHelper mGnssStatusListenerHelper;
- private final GnssSatelliteBlacklistHelper mGnssSatelliteBlacklistHelper;
private final GnssMeasurementsProvider mGnssMeasurementsProvider;
private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
@@ -530,8 +523,8 @@
// Disable GPS if we are in device idle mode.
boolean disableGps = mPowerManager.isDeviceIdleMode();
final PowerSaveState result =
- mPowerManager.getPowerSaveState(ServiceType.GPS);
- switch (result.gpsMode) {
+ mPowerManager.getPowerSaveState(ServiceType.LOCATION);
+ switch (result.locationMode) {
case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
// If we are in battery saver mode and the screen is off, disable GPS.
disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
@@ -539,6 +532,7 @@
}
if (disableGps != mDisableGps) {
mDisableGps = disableGps;
+ updateEnabled();
updateRequirements();
}
}
@@ -562,9 +556,8 @@
public GnssLocationProvider(Context context, LocationProviderManager locationProviderManager,
Looper looper) {
- super(locationProviderManager);
+ super(context, locationProviderManager);
- mContext = context;
mLooper = looper;
// Create a wake lock
@@ -637,23 +630,32 @@
mGnssMetrics = new GnssMetrics(mBatteryStats);
mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
- mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
- looper, this);
- mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
+ GnssSatelliteBlacklistHelper gnssSatelliteBlacklistHelper =
+ new GnssSatelliteBlacklistHelper(mContext,
+ looper, this);
+ mHandler.post(gnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
mGnssBatchingProvider = new GnssBatchingProvider();
mGnssGeofenceProvider = new GnssGeofenceProvider();
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_SHUTDOWN);
mContext.registerReceiverAsUser(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (getSendingUserId() == UserHandle.USER_ALL) {
- mEnabled = false;
- handleDisable();
+ mShutdown = true;
+ updateEnabled();
}
}
- }, UserHandle.ALL, intentFilter, null, mHandler);
+ }, UserHandle.ALL, new IntentFilter(Intent.ACTION_SHUTDOWN), null, mHandler);
+
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE),
+ true,
+ new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateEnabled();
+ }
+ }, UserHandle.USER_ALL);
setProperties(PROPERTIES);
setEnabled(true);
@@ -867,12 +869,12 @@
return GPS_POSITION_MODE_STANDALONE;
}
- private void handleEnable() {
+ private boolean handleEnable() {
if (DEBUG) Log.d(TAG, "handleEnable");
- boolean enabled = native_init();
+ boolean inited = native_init();
- if (enabled) {
+ if (inited) {
mSupportsXtra = native_supports_xtra();
// TODO: remove the following native calls if we can make sure they are redundant.
@@ -889,11 +891,10 @@
mGnssNavigationMessageProvider.onGpsEnabledChanged();
mGnssBatchingProvider.enable();
} else {
- synchronized (mLock) {
- mEnabled = false;
- }
Log.w(TAG, "Failed to enable location provider");
}
+
+ return inited;
}
private void handleDisable() {
@@ -912,6 +913,26 @@
mGnssNavigationMessageProvider.onGpsEnabledChanged();
}
+ private void updateEnabled() {
+ synchronized (mLock) {
+ boolean enabled =
+ ((mProviderRequest != null && mProviderRequest.reportLocation
+ && mProviderRequest.forceLocation) || (
+ mContext.getSystemService(LocationManager.class).isLocationEnabled()
+ && !mDisableGps)) && !mShutdown;
+ if (enabled == mEnabled) {
+ return;
+ }
+
+ if (enabled) {
+ mEnabled = handleEnable();
+ } else {
+ mEnabled = false;
+ handleDisable();
+ }
+ }
+ }
+
public boolean isEnabled() {
synchronized (mLock) {
return mEnabled;
@@ -944,6 +965,7 @@
private void handleSetRequest(ProviderRequest request, WorkSource source) {
mProviderRequest = request;
mWorkSource = source;
+ updateEnabled();
updateRequirements();
}
@@ -1492,8 +1514,11 @@
class_init_native();
native_init_once();
if (isEnabled()) {
- // re-calls native_init() and other setup.
- handleEnable();
+ synchronized (mLock) {
+ mEnabled = false;
+ }
+ updateEnabled();
+
// resend configuration into the restarted HAL service.
reloadGpsProperties();
}
@@ -1692,7 +1717,7 @@
/* requestorIdEncoding= */ 0,
/* textEncoding= */ 0,
mSuplEsEnabled,
- mEnabled,
+ isEnabled(),
userResponse);
return true;
@@ -1758,7 +1783,7 @@
notification.requestorIdEncoding,
notification.textEncoding,
mSuplEsEnabled,
- mEnabled,
+ isEnabled(),
/* userResponse= */ 0);
}
@@ -1883,9 +1908,6 @@
public void handleMessage(Message msg) {
int message = msg.what;
switch (message) {
- case ENABLE:
- handleEnable();
- break;
case SET_REQUEST:
GpsRequest gpsRequest = (GpsRequest) msg.obj;
handleSetRequest(gpsRequest.request, gpsRequest.source);
@@ -2000,8 +2022,7 @@
new NetworkLocationListener(),
getLooper());
- // enable gps provider, it will never be disabled (legacy behavior)
- sendEmptyMessage(ENABLE);
+ updateEnabled();
}
}
@@ -2045,8 +2066,6 @@
*/
private String messageIdAsString(int message) {
switch (message) {
- case ENABLE:
- return "ENABLE";
case SET_REQUEST:
return "SET_REQUEST";
case INJECT_NTP_TIME:
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index 77dee82..1fc7192 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -95,15 +95,11 @@
*/
public void injectGnssMeasurementCorrections(
GnssMeasurementCorrections measurementCorrections) {
- mHandler.post(
- new Runnable() {
- @Override
- public void run() {
- if (!mNative.injectGnssMeasurementCorrections(measurementCorrections)) {
- Log.e(TAG, "Failure in injecting GNSS corrections.");
- }
- }
- });
+ mHandler.post(() -> {
+ if (!mNative.injectGnssMeasurementCorrections(measurementCorrections)) {
+ Log.e(TAG, "Failure in injecting GNSS corrections.");
+ }
+ });
}
@Override
@@ -115,15 +111,14 @@
}
public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
- foreach(
- (IGnssMeasurementsListener listener, int uid, String packageName) -> {
- if (!hasPermission(uid, packageName)) {
- logPermissionDisabledEventNotReported(
- TAG, packageName, "GNSS measurements");
- return;
- }
- listener.onGnssMeasurementsReceived(event);
- });
+ foreach((IGnssMeasurementsListener listener, CallerIdentity callerIdentity) -> {
+ if (!hasPermission(mContext, callerIdentity)) {
+ logPermissionDisabledEventNotReported(
+ TAG, callerIdentity.mPackageName, "GNSS measurements");
+ return;
+ }
+ listener.onGnssMeasurementsReceived(event);
+ });
}
/** Updates the framework about the capabilities of the GNSS chipset */
@@ -182,7 +177,7 @@
@Override
public void execute(IGnssMeasurementsListener listener,
- int uid, String packageName) throws RemoteException {
+ CallerIdentity callerIdentity) throws RemoteException {
listener.onStatusChanged(mStatus);
}
}
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index 679919f..80a3f9b 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -86,7 +86,7 @@
}
public void onNavigationMessageAvailable(final GnssNavigationMessage event) {
- foreach((IGnssNavigationMessageListener listener, int uid, String packageName) -> {
+ foreach((IGnssNavigationMessageListener listener, CallerIdentity callerIdentity) -> {
listener.onGnssNavigationMessageReceived(event);
}
);
@@ -136,7 +136,7 @@
@Override
public void execute(IGnssNavigationMessageListener listener,
- int uid, String packageName) throws RemoteException {
+ CallerIdentity callerIdentity) throws RemoteException {
listener.onStatusChanged(mStatus);
}
}
diff --git a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
index 454dbdd..d67d0c5 100644
--- a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
+++ b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
@@ -48,18 +48,18 @@
public void onStatusChanged(boolean isNavigating) {
if (isNavigating) {
- foreach((IGnssStatusListener listener, int uid, String packageName) -> {
+ foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> {
listener.onGnssStarted();
});
} else {
- foreach((IGnssStatusListener listener, int uid, String packageName) -> {
+ foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> {
listener.onGnssStopped();
});
}
}
public void onFirstFix(final int timeToFirstFix) {
- foreach((IGnssStatusListener listener, int uid, String packageName) -> {
+ foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> {
listener.onFirstFix(timeToFirstFix);
}
);
@@ -72,9 +72,10 @@
final float[] elevations,
final float[] azimuths,
final float[] carrierFreqs) {
- foreach((IGnssStatusListener listener, int uid, String packageName) -> {
- if (!hasPermission(uid, packageName)) {
- logPermissionDisabledEventNotReported(TAG, packageName, "GNSS status");
+ foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> {
+ if (!hasPermission(mContext, callerIdentity)) {
+ logPermissionDisabledEventNotReported(TAG, callerIdentity.mPackageName,
+ "GNSS status");
return;
}
listener.onSvStatusChanged(svCount, prnWithFlags, cn0s, elevations, azimuths,
@@ -83,9 +84,9 @@
}
public void onNmeaReceived(final long timestamp, final String nmea) {
- foreach((IGnssStatusListener listener, int uid, String packageName) -> {
- if (!hasPermission(uid, packageName)) {
- logPermissionDisabledEventNotReported(TAG, packageName, "NMEA");
+ foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> {
+ if (!hasPermission(mContext, callerIdentity)) {
+ logPermissionDisabledEventNotReported(TAG, callerIdentity.mPackageName, "NMEA");
return;
}
listener.onNmeaReceived(timestamp, nmea);
diff --git a/services/core/java/com/android/server/location/LocationPermissionUtil.java b/services/core/java/com/android/server/location/LocationPermissionUtil.java
new file mode 100644
index 0000000..4465f31
--- /dev/null
+++ b/services/core/java/com/android/server/location/LocationPermissionUtil.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+/**
+ * Encapsulates utility functions and classes related to location permission checking.
+ */
+public final class LocationPermissionUtil {
+ /**
+ * Returns true if the calling process identified by {@code callerIdentity} is enabled to
+ * report location to AppOps service before providing device location identifiable information
+ * to its clients. Packages with these permissions must report any reporting of location
+ * information to apps, via AppOps.
+ *
+ * <p>The calling package represented by {@code callerIdentity} is considered a part of the
+ * extended Location Manager Service if it has all of the permissions below.
+ * <ul>
+ * <li>{@link android.Manifest.permission#LOCATION_HARDWARE}
+ * <li>{@link android.Manifest.permission#UPDATE_APP_OPS_STATS}
+ * </ul>
+ *
+ * <p>Any package with these permissions, that passes along location information from Android
+ * framework to apps, must report to AppOps, similarly to Location Manager Service - i.e.
+ * whenever it reports device location or location identifiable information such as
+ * GNSS status, GNSS measurements, etc. to its clients.
+ */
+ public static boolean doesCallerReportToAppOps(Context context, CallerIdentity callerIdentity) {
+ return hasPermissionLocationHardware(context, callerIdentity)
+ && hasPermissionUpdateAppOpsStats(context, callerIdentity);
+ }
+
+ private static boolean hasPermissionLocationHardware(Context context,
+ CallerIdentity callerIdentity) {
+ return context.checkPermission(android.Manifest.permission.LOCATION_HARDWARE,
+ callerIdentity.mPid, callerIdentity.mUid) == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private static boolean hasPermissionUpdateAppOpsStats(Context context,
+ CallerIdentity callerIdentity) {
+ return context.checkPermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+ callerIdentity.mPid, callerIdentity.mUid) == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private LocationPermissionUtil() {}
+}
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index 776beb5..afe3473 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -16,8 +16,11 @@
package com.android.server.location;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+
import android.annotation.Nullable;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationProvider;
import android.os.Bundle;
@@ -39,6 +42,10 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* Proxy for ILocationProvider implementations.
@@ -48,14 +55,21 @@
private static final String TAG = "LocationProviderProxy";
private static final boolean D = LocationManagerService.D;
+ // used to ensure that updates to mProviderPackages are atomic
+ private final Object mProviderPackagesLock = new Object();
+
// used to ensure that updates to mRequest and mWorkSource are atomic
private final Object mRequestLock = new Object();
- private final ServiceWatcher mServiceWatcher;
-
private final ILocationProviderManager.Stub mManager = new ILocationProviderManager.Stub() {
// executed on binder thread
@Override
+ public void onSetAdditionalProviderPackages(List<String> packageNames) {
+ LocationProviderProxy.this.onSetAdditionalProviderPackages(packageNames);
+ }
+
+ // executed on binder thread
+ @Override
public void onSetEnabled(boolean enabled) {
LocationProviderProxy.this.setEnabled(enabled);
}
@@ -73,6 +87,11 @@
}
};
+ private final ServiceWatcher mServiceWatcher;
+
+ @GuardedBy("mProviderPackagesLock")
+ private final CopyOnWriteArrayList<String> mProviderPackages = new CopyOnWriteArrayList<>();
+
@GuardedBy("mRequestLock")
@Nullable
private ProviderRequest mRequest;
@@ -101,7 +120,7 @@
private LocationProviderProxy(Context context, LocationProviderManager locationProviderManager,
String action, int overlaySwitchResId, int defaultServicePackageNameResId,
int initialPackageNamesResId) {
- super(locationProviderManager);
+ super(context, locationProviderManager);
mServiceWatcher = new ServiceWatcher(context, TAG, action, overlaySwitchResId,
defaultServicePackageNameResId, initialPackageNamesResId,
@@ -114,6 +133,7 @@
@Override
protected void onUnbind() {
+ resetProviderPackages(Collections.emptyList());
setEnabled(false);
setProperties(null);
}
@@ -131,6 +151,8 @@
ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
if (D) Log.d(TAG, "applying state to connected service " + mServiceWatcher);
+ resetProviderPackages(Collections.emptyList());
+
service.setLocationProviderManager(mManager);
synchronized (mRequestLock) {
@@ -140,9 +162,11 @@
}
}
- @Nullable
- public String getConnectedPackageName() {
- return mServiceWatcher.getCurrentPackageName();
+ @Override
+ public List<String> getProviderPackages() {
+ synchronized (mProviderPackagesLock) {
+ return mProviderPackages;
+ }
}
@Override
@@ -159,12 +183,17 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(" service=" + mServiceWatcher);
+ pw.println(" service=" + mServiceWatcher);
+ synchronized (mProviderPackagesLock) {
+ if (mProviderPackages.size() > 1) {
+ pw.println(" additional packages=" + mProviderPackages);
+ }
+ }
mServiceWatcher.runOnBinderBlocking(binder -> {
try {
TransferPipe.dumpAsync(binder, fd, args);
} catch (IOException | RemoteException e) {
- pw.println(" failed to dump location provider");
+ pw.println(" <failed to dump location provider: " + e + ">");
}
return null;
}, null);
@@ -193,4 +222,30 @@
service.sendExtraCommand(command, extras);
});
}
+
+ private void onSetAdditionalProviderPackages(List<String> packageNames) {
+ resetProviderPackages(packageNames);
+ }
+
+ private void resetProviderPackages(List<String> additionalPackageNames) {
+ ArrayList<String> permittedPackages = new ArrayList<>(additionalPackageNames.size());
+ for (String packageName : additionalPackageNames) {
+ try {
+ mContext.getPackageManager().getPackageInfo(packageName, MATCH_SYSTEM_ONLY);
+ permittedPackages.add(packageName);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, mServiceWatcher + " specified unknown additional provider package: "
+ + packageName);
+ }
+ }
+
+ synchronized (mProviderPackagesLock) {
+ mProviderPackages.clear();
+ String myPackage = mServiceWatcher.getCurrentPackageName();
+ if (myPackage != null) {
+ mProviderPackages.add(myPackage);
+ mProviderPackages.addAll(permittedPackages);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/location/MockProvider.java b/services/core/java/com/android/server/location/MockProvider.java
index fe91c63..6accad8 100644
--- a/services/core/java/com/android/server/location/MockProvider.java
+++ b/services/core/java/com/android/server/location/MockProvider.java
@@ -17,6 +17,7 @@
package com.android.server.location;
import android.annotation.Nullable;
+import android.content.Context;
import android.location.Location;
import android.location.LocationProvider;
import android.os.Bundle;
@@ -41,9 +42,9 @@
private long mStatusUpdateTime;
private Bundle mExtras;
- public MockProvider(
+ public MockProvider(Context context,
LocationProviderManager locationProviderManager, ProviderProperties properties) {
- super(locationProviderManager);
+ super(context, locationProviderManager);
mEnabled = true;
mLocation = null;
diff --git a/services/core/java/com/android/server/location/PassiveProvider.java b/services/core/java/com/android/server/location/PassiveProvider.java
index 30260b2..3a841c9 100644
--- a/services/core/java/com/android/server/location/PassiveProvider.java
+++ b/services/core/java/com/android/server/location/PassiveProvider.java
@@ -16,6 +16,7 @@
package com.android.server.location;
+import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.os.Bundle;
@@ -42,8 +43,8 @@
private boolean mReportLocation;
- public PassiveProvider(LocationProviderManager locationProviderManager) {
- super(locationProviderManager);
+ public PassiveProvider(Context context, LocationProviderManager locationProviderManager) {
+ super(context, locationProviderManager);
mReportLocation = false;
diff --git a/services/core/java/com/android/server/location/RemoteListenerHelper.java b/services/core/java/com/android/server/location/RemoteListenerHelper.java
index e69b2ec..f03c99b 100644
--- a/services/core/java/com/android/server/location/RemoteListenerHelper.java
+++ b/services/core/java/com/android/server/location/RemoteListenerHelper.java
@@ -71,10 +71,10 @@
return mIsRegistered;
}
- public boolean addListener(@NonNull TListener listener, int uid, String packageName) {
+ public boolean addListener(@NonNull TListener listener, CallerIdentity callerIdentity) {
Preconditions.checkNotNull(listener, "Attempted to register a 'null' listener.");
IBinder binder = listener.asBinder();
- LinkedListener deathListener = new LinkedListener(listener, uid, packageName);
+ LinkedListener deathListener = new LinkedListener(listener, callerIdentity);
synchronized (mListenerMap) {
if (mListenerMap.containsKey(binder)) {
// listener already added
@@ -137,7 +137,7 @@
protected abstract ListenerOperation<TListener> getHandlerOperation(int result);
protected interface ListenerOperation<TListener extends IInterface> {
- void execute(TListener listener, int uid, String packageName) throws RemoteException;
+ void execute(TListener listener, CallerIdentity callerIdentity) throws RemoteException;
}
protected void foreach(ListenerOperation<TListener> operation) {
@@ -177,9 +177,16 @@
}
}
- protected boolean hasPermission(int uid, String packageName) {
- return mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, uid, packageName)
- == AppOpsManager.MODE_ALLOWED;
+ protected boolean hasPermission(Context context, CallerIdentity callerIdentity) {
+ if (LocationPermissionUtil.doesCallerReportToAppOps(context, callerIdentity)) {
+ // The caller is identified as a location provider that will report location
+ // access to AppOps. Skip noteOp but do checkOp to check for location permission.
+ return mAppOps.checkOpNoThrow(AppOpsManager.OP_FINE_LOCATION, callerIdentity.mUid,
+ callerIdentity.mPackageName) == AppOpsManager.MODE_ALLOWED;
+ }
+
+ return mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, callerIdentity.mUid,
+ callerIdentity.mPackageName) == AppOpsManager.MODE_ALLOWED;
}
protected void logPermissionDisabledEventNotReported(String tag, String packageName,
@@ -254,13 +261,11 @@
private class LinkedListener implements IBinder.DeathRecipient {
private final TListener mListener;
- private final int mUid;
- private final String mPackageName;
+ private final CallerIdentity mCallerIdentity;
- LinkedListener(@NonNull TListener listener, int uid, String packageName) {
+ LinkedListener(@NonNull TListener listener, CallerIdentity callerIdentity) {
mListener = listener;
- mUid = uid;
- mPackageName = packageName;
+ mCallerIdentity = callerIdentity;
}
@Override
@@ -282,8 +287,7 @@
@Override
public void run() {
try {
- mOperation.execute(mLinkedListener.mListener, mLinkedListener.mUid,
- mLinkedListener.mPackageName);
+ mOperation.execute(mLinkedListener.mListener, mLinkedListener.mCallerIdentity);
} catch (RemoteException e) {
Log.v(mTag, "Error in monitored listener.", e);
}
diff --git a/services/core/java/com/android/server/media/MediaUpdateService.java b/services/core/java/com/android/server/media/MediaUpdateService.java
deleted file mode 100644
index 7304f07..0000000
--- a/services/core/java/com/android/server/media/MediaUpdateService.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.media.IMediaUpdateService;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.Handler;
-import android.os.PatternMatcher;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Slog;
-import com.android.server.SystemService;
-import java.util.HashMap;
-
-/** This class provides a system service that manages media framework updates. */
-public class MediaUpdateService extends SystemService {
- private static final String TAG = "MediaUpdateService";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final String MEDIA_UPDATE_PACKAGE_NAME =
- SystemProperties.get("ro.mediacomponents.package");
- private static final String EXTRACTOR_UPDATE_SERVICE_NAME = "media.extractor.update";
- private static final String CODEC_UPDATE_SERVICE_NAME = "media.codec.update";
- private static final String[] UPDATE_SERVICE_NAME_ARRAY = {
- EXTRACTOR_UPDATE_SERVICE_NAME, CODEC_UPDATE_SERVICE_NAME,
- };
- private final HashMap<String, IMediaUpdateService> mUpdateServiceMap = new HashMap<>();
- private final Handler mHandler = new Handler();
-
- public MediaUpdateService(Context context) {
- super(context);
- }
-
- @Override
- public void onStart() {
- if (("userdebug".equals(android.os.Build.TYPE) || "eng".equals(android.os.Build.TYPE))
- && !TextUtils.isEmpty(MEDIA_UPDATE_PACKAGE_NAME)) {
- for (String serviceName : UPDATE_SERVICE_NAME_ARRAY) {
- connect(serviceName);
- }
- registerBroadcastReceiver();
- }
- }
-
- private void connect(final String serviceName) {
- IBinder binder = ServiceManager.getService(serviceName);
- if (binder != null) {
- try {
- binder.linkToDeath(new IBinder.DeathRecipient() {
- @Override
- public void binderDied() {
- Slog.w(TAG, "service " + serviceName + " died; reconnecting");
- synchronized (mUpdateServiceMap) {
- mUpdateServiceMap.remove(serviceName);
- }
- connect(serviceName);
- }
- }, 0);
- } catch (Exception e) {
- binder = null;
- }
- }
- if (binder != null) {
- synchronized (mUpdateServiceMap) {
- mUpdateServiceMap.put(serviceName,
- IMediaUpdateService.Stub.asInterface(binder));
- }
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- packageStateChanged(serviceName);
- }
- });
- } else {
- Slog.w(TAG, serviceName + " not found.");
- }
- }
-
- private void registerBroadcastReceiver() {
- BroadcastReceiver updateReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM)
- != UserHandle.USER_SYSTEM) {
- // Ignore broadcast for non system users. We don't want to update system
- // service multiple times.
- return;
- }
- switch (intent.getAction()) {
- case Intent.ACTION_PACKAGE_REMOVED:
- if (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) {
- // The existing package is updated. Will be handled with the
- // following ACTION_PACKAGE_ADDED case.
- return;
- }
- // fall-thru
- case Intent.ACTION_PACKAGE_CHANGED:
- case Intent.ACTION_PACKAGE_ADDED:
- for (String serviceName : UPDATE_SERVICE_NAME_ARRAY) {
- packageStateChanged(serviceName);
- }
- break;
- }
- }
- };
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_PACKAGE_ADDED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- filter.addDataScheme("package");
- filter.addDataSchemeSpecificPart(MEDIA_UPDATE_PACKAGE_NAME, PatternMatcher.PATTERN_LITERAL);
-
- getContext().registerReceiverAsUser(updateReceiver, UserHandle.ALL, filter,
- null /* broadcast permission */, null /* handler */);
- }
-
- private void packageStateChanged(String serviceName) {
- ApplicationInfo packageInfo = null;
- boolean pluginsAvailable = false;
- try {
- packageInfo = getContext().getPackageManager().getApplicationInfo(
- MEDIA_UPDATE_PACKAGE_NAME, PackageManager.MATCH_SYSTEM_ONLY);
- pluginsAvailable = packageInfo.enabled;
- } catch (Exception e) {
- Slog.v(TAG, "package '" + MEDIA_UPDATE_PACKAGE_NAME + "' not installed");
- }
- if (packageInfo != null && Build.VERSION.SDK_INT != packageInfo.targetSdkVersion) {
- Slog.w(TAG, "This update package is not for this platform version. Ignoring. "
- + "platform:" + Build.VERSION.SDK_INT
- + " targetSdk:" + packageInfo.targetSdkVersion);
- pluginsAvailable = false;
- }
- loadPlugins(serviceName,
- (packageInfo != null && pluginsAvailable) ? packageInfo.sourceDir : "");
- }
-
- private void loadPlugins(String serviceName, String apkPath) {
- try {
- IMediaUpdateService service = null;
- synchronized (serviceName) {
- service = mUpdateServiceMap.get(serviceName);
- }
- if (service != null) {
- service.loadPlugins(apkPath);
- } else {
- Slog.w(TAG, "service " + serviceName + " passed away");
- }
- } catch (Exception e) {
- Slog.w(TAG, "Error in loadPlugins for " + serviceName, e);
- }
- }
-}
diff --git a/services/core/java/com/android/server/notification/BubbleExtractor.java b/services/core/java/com/android/server/notification/BubbleExtractor.java
new file mode 100644
index 0000000..358bdb9
--- /dev/null
+++ b/services/core/java/com/android/server/notification/BubbleExtractor.java
@@ -0,0 +1,68 @@
+/**
+* Copyright (C) 2019 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package com.android.server.notification;
+
+import android.content.Context;
+import android.util.Slog;
+
+/**
+ * Determines whether a bubble can be shown for this notification
+ */
+public class BubbleExtractor implements NotificationSignalExtractor {
+ private static final String TAG = "BubbleExtractor";
+ private static final boolean DBG = false;
+
+ private RankingConfig mConfig;
+
+ public void initialize(Context ctx, NotificationUsageStats usageStats) {
+ if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + ".");
+ }
+
+ public RankingReconsideration process(NotificationRecord record) {
+ if (record == null || record.getNotification() == null) {
+ if (DBG) Slog.d(TAG, "skipping empty notification");
+ return null;
+ }
+
+ if (mConfig == null) {
+ if (DBG) Slog.d(TAG, "missing config");
+ return null;
+ }
+ boolean userWantsBubbles = mConfig.bubblesEnabled(record.sbn.getUser());
+ boolean appCanShowBubble =
+ mConfig.areBubblesAllowed(record.sbn.getPackageName(), record.sbn.getUid());
+ if (!userWantsBubbles || !appCanShowBubble) {
+ record.setAllowBubble(false);
+ } else {
+ if (record.getChannel() != null) {
+ record.setAllowBubble(record.getChannel().canBubble() && appCanShowBubble);
+ } else {
+ record.setAllowBubble(appCanShowBubble);
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void setConfig(RankingConfig config) {
+ mConfig = config;
+ }
+
+ @Override
+ public void setZenHelper(ZenModeHelper helper) {
+ }
+}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index c222e69..cf09b8f 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -306,18 +306,21 @@
}
}
- public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
+ public void writeXml(XmlSerializer out, boolean forBackup, int userId) throws IOException {
out.startTag(null, getConfig().xmlTag);
out.attribute(null, ATT_VERSION, String.valueOf(DB_VERSION));
if (forBackup) {
- trimApprovedListsAccordingToInstalledServices();
+ trimApprovedListsAccordingToInstalledServices(userId);
}
final int N = mApproved.size();
for (int i = 0 ; i < N; i++) {
- final int userId = mApproved.keyAt(i);
+ final int approvedUserId = mApproved.keyAt(i);
+ if (forBackup && approvedUserId != userId) {
+ continue;
+ }
final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
if (approvedByType != null) {
final int M = approvedByType.size();
@@ -328,14 +331,14 @@
String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved);
out.startTag(null, TAG_MANAGED_SERVICES);
out.attribute(null, ATT_APPROVED_LIST, allowedItems);
- out.attribute(null, ATT_USER_ID, Integer.toString(userId));
+ out.attribute(null, ATT_USER_ID, Integer.toString(approvedUserId));
out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary));
out.endTag(null, TAG_MANAGED_SERVICES);
if (!forBackup && isPrimary) {
// Also write values to settings, for observers who haven't migrated yet
Settings.Secure.putStringForUser(mContext.getContentResolver(),
- getConfig().secureSettingName, allowedItems, userId);
+ getConfig().secureSettingName, allowedItems, approvedUserId);
}
}
@@ -350,15 +353,12 @@
loadAllowedComponentsFromSettings();
}
- public void readXml(XmlPullParser parser, Predicate<String> allowedManagedServicePackages)
+ public void readXml(
+ XmlPullParser parser,
+ Predicate<String> allowedManagedServicePackages,
+ boolean forRestore,
+ int userId)
throws XmlPullParserException, IOException {
- // upgrade xml
- int xmlVersion = XmlUtils.readIntAttribute(parser, ATT_VERSION, 0);
- final List<UserInfo> activeUsers = mUm.getUsers(true);
- for (UserInfo userInfo : activeUsers) {
- upgradeXml(xmlVersion, userInfo.getUserHandle().getIdentifier());
- }
-
// read grants
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
@@ -372,14 +372,16 @@
Slog.i(TAG, "Read " + mConfig.caption + " permissions from xml");
final String approved = XmlUtils.readStringAttribute(parser, ATT_APPROVED_LIST);
- final int userId = XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0);
+ // Ignore parser's user id for restore.
+ final int resolvedUserId = forRestore
+ ? userId : XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0);
final boolean isPrimary =
XmlUtils.readBooleanAttribute(parser, ATT_IS_PRIMARY, true);
if (allowedManagedServicePackages == null ||
allowedManagedServicePackages.test(getPackageName(approved))) {
- if (mUm.getUserInfo(userId) != null) {
- addApprovedList(approved, userId, isPrimary);
+ if (mUm.getUserInfo(resolvedUserId) != null) {
+ addApprovedList(approved, resolvedUserId, isPrimary);
}
mUseXml = true;
}
@@ -389,8 +391,6 @@
rebindServices(false, USER_ALL);
}
- protected void upgradeXml(final int xmlVersion, final int userId) {}
-
private void loadAllowedComponentsFromSettings() {
for (UserInfo user : mUm.getUsers()) {
final ContentResolver cr = mContext.getContentResolver();
@@ -784,26 +784,23 @@
return allowedPackages;
}
- private void trimApprovedListsAccordingToInstalledServices() {
- int N = mApproved.size();
- for (int i = 0 ; i < N; i++) {
- final int userId = mApproved.keyAt(i);
- final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
- int M = approvedByType.size();
- for (int j = 0; j < M; j++) {
- final ArraySet<String> approved = approvedByType.valueAt(j);
- int P = approved.size();
- for (int k = P - 1; k >= 0; k--) {
- final String approvedPackageOrComponent = approved.valueAt(k);
- if (!isValidEntry(approvedPackageOrComponent, userId)){
- approved.removeAt(k);
- Slog.v(TAG, "Removing " + approvedPackageOrComponent
- + " from approved list; no matching services found");
- } else {
- if (DEBUG) {
- Slog.v(TAG, "Keeping " + approvedPackageOrComponent
- + " on approved list; matching services found");
- }
+ private void trimApprovedListsAccordingToInstalledServices(int userId) {
+ final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
+ if (approvedByType == null) {
+ return;
+ }
+ for (int i = 0; i < approvedByType.size(); i++) {
+ final ArraySet<String> approved = approvedByType.valueAt(i);
+ for (int j = approved.size() - 1; j >= 0; j--) {
+ final String approvedPackageOrComponent = approved.valueAt(j);
+ if (!isValidEntry(approvedPackageOrComponent, userId)){
+ approved.removeAt(j);
+ Slog.v(TAG, "Removing " + approvedPackageOrComponent
+ + " from approved list; no matching services found");
+ } else {
+ if (DEBUG) {
+ Slog.v(TAG, "Keeping " + approvedPackageOrComponent
+ + " on approved list; matching services found");
}
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index be15fda..b85abd9 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -51,7 +51,7 @@
* Notifies that smart replies and actions have been added to the UI.
*/
void onNotificationSmartSuggestionsAdded(String key, int smartReplyCount, int smartActionCount,
- boolean generatedByAssistant);
+ boolean generatedByAssistant, boolean editBeforeSending);
/**
* Notifies a smart reply is sent.
@@ -59,9 +59,9 @@
* @param key the notification key
* @param clickedIndex the index of clicked reply
* @param reply the reply that is sent
- * @param generatedByAssistant specifies is the reply generated by NAS
* @param notificationLocation the location of the notification containing the smart reply
+ * @param modifiedBeforeSending whether the user changed the smart reply before sending
*/
void onNotificationSmartReplySent(String key, int clickedIndex, CharSequence reply,
- boolean generatedByAssistant, int notificationLocation);
+ int notificationLocation, boolean modifiedBeforeSending);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ba187c0..3557fcf 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -213,6 +213,7 @@
import com.android.server.notification.ManagedServices.ManagedServiceInfo;
import com.android.server.notification.ManagedServices.UserProfiles;
import com.android.server.pm.PackageManagerService;
+import com.android.server.pm.UserManagerService;
import com.android.server.policy.PhoneWindowManager;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -538,30 +539,49 @@
}
}
- void readPolicyXml(InputStream stream, boolean forRestore)
+ UserManagerService getUserManagerService() {
+ return UserManagerService.getInstance();
+ }
+
+ void readPolicyXml(InputStream stream, boolean forRestore, int userId)
throws XmlPullParserException, NumberFormatException, IOException {
final XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, StandardCharsets.UTF_8.name());
XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY);
boolean migratedManagedServices = false;
+ boolean ineligibleForManagedServices = forRestore
+ && getUserManagerService().isManagedProfile(userId);
int outerDepth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) {
- mZenModeHelper.readXml(parser, forRestore);
+ mZenModeHelper.readXml(parser, forRestore, userId);
} else if (PreferencesHelper.TAG_RANKING.equals(parser.getName())){
- mPreferencesHelper.readXml(parser, forRestore);
+ mPreferencesHelper.readXml(parser, forRestore, userId);
}
if (mListeners.getConfig().xmlTag.equals(parser.getName())) {
- mListeners.readXml(parser, mAllowedManagedServicePackages);
+ if (ineligibleForManagedServices) {
+ continue;
+ }
+ mListeners.readXml(parser, mAllowedManagedServicePackages, forRestore, userId);
migratedManagedServices = true;
} else if (mAssistants.getConfig().xmlTag.equals(parser.getName())) {
- mAssistants.readXml(parser, mAllowedManagedServicePackages);
+ if (ineligibleForManagedServices) {
+ continue;
+ }
+ mAssistants.readXml(parser, mAllowedManagedServicePackages, forRestore, userId);
migratedManagedServices = true;
} else if (mConditionProviders.getConfig().xmlTag.equals(parser.getName())) {
- mConditionProviders.readXml(parser, mAllowedManagedServicePackages);
+ if (ineligibleForManagedServices) {
+ continue;
+ }
+ mConditionProviders.readXml(
+ parser, mAllowedManagedServicePackages, forRestore, userId);
migratedManagedServices = true;
}
if (LOCKSCREEN_ALLOW_SECURE_NOTIFICATIONS_TAG.equals(parser.getName())) {
+ if (forRestore && userId != UserHandle.USER_SYSTEM) {
+ continue;
+ }
mLockScreenAllowSecureNotifications =
safeBoolean(parser.getAttributeValue(null,
LOCKSCREEN_ALLOW_SECURE_NOTIFICATIONS_VALUE), true);
@@ -584,7 +604,7 @@
InputStream infile = null;
try {
infile = mPolicyFile.openRead();
- readPolicyXml(infile, false /*forRestore*/);
+ readPolicyXml(infile, false /*forRestore*/, UserHandle.USER_ALL);
} catch (FileNotFoundException e) {
// No data yet
// Load default managed services approvals
@@ -615,7 +635,7 @@
}
try {
- writePolicyXml(stream, false /*forBackup*/);
+ writePolicyXml(stream, false /*forBackup*/, UserHandle.USER_ALL);
mPolicyFile.finishWrite(stream);
} catch (IOException e) {
Slog.w(TAG, "Failed to save policy file, restoring backup", e);
@@ -626,18 +646,21 @@
});
}
- private void writePolicyXml(OutputStream stream, boolean forBackup) throws IOException {
+ private void writePolicyXml(OutputStream stream, boolean forBackup, int userId)
+ throws IOException {
final XmlSerializer out = new FastXmlSerializer();
out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_NOTIFICATION_POLICY);
out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
- mZenModeHelper.writeXml(out, forBackup, null);
- mPreferencesHelper.writeXml(out, forBackup);
- mListeners.writeXml(out, forBackup);
- mAssistants.writeXml(out, forBackup);
- mConditionProviders.writeXml(out, forBackup);
- writeSecureNotificationsPolicy(out);
+ mZenModeHelper.writeXml(out, forBackup, null, userId);
+ mPreferencesHelper.writeXml(out, forBackup, userId);
+ mListeners.writeXml(out, forBackup, userId);
+ mAssistants.writeXml(out, forBackup, userId);
+ mConditionProviders.writeXml(out, forBackup, userId);
+ if (!forBackup || userId == UserHandle.USER_SYSTEM) {
+ writeSecureNotificationsPolicy(out);
+ }
out.endTag(null, TAG_NOTIFICATION_POLICY);
out.endDocument();
}
@@ -917,20 +940,21 @@
@Override
public void onNotificationSmartSuggestionsAdded(String key, int smartReplyCount,
- int smartActionCount, boolean generatedByAssistant) {
+ int smartActionCount, boolean generatedByAssistant, boolean editBeforeSending) {
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r != null) {
r.setNumSmartRepliesAdded(smartReplyCount);
r.setNumSmartActionsAdded(smartActionCount);
r.setSuggestionsGeneratedByAssistant(generatedByAssistant);
+ r.setEditChoicesBeforeSending(editBeforeSending);
}
}
}
@Override
public void onNotificationSmartReplySent(String key, int replyIndex, CharSequence reply,
- boolean generatedByAssistant, int notificationLocation) {
+ int notificationLocation, boolean modifiedBeforeSending) {
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
@@ -940,14 +964,20 @@
.setSubtype(replyIndex)
.addTaggedData(
MetricsEvent.NOTIFICATION_SMART_SUGGESTION_ASSISTANT_GENERATED,
- generatedByAssistant ? 1 : 0)
+ r.getSuggestionsGeneratedByAssistant() ? 1 : 0)
.addTaggedData(MetricsEvent.NOTIFICATION_LOCATION,
- notificationLocation);
+ notificationLocation)
+ .addTaggedData(
+ MetricsEvent.NOTIFICATION_SMART_REPLY_EDIT_BEFORE_SENDING,
+ r.getEditChoicesBeforeSending() ? 1 : 0)
+ .addTaggedData(
+ MetricsEvent.NOTIFICATION_SMART_REPLY_MODIFIED_BEFORE_SENDING,
+ modifiedBeforeSending ? 1 : 0);
mMetricsLogger.write(logMaker);
// Treat clicking on a smart reply as a user interaction.
reportUserInteraction(r);
mAssistants.notifyAssistantSuggestedReplySent(
- r.sbn, reply, generatedByAssistant);
+ r.sbn, reply, r.getSuggestionsGeneratedByAssistant());
}
}
}
@@ -981,7 +1011,10 @@
r.getSuggestionsGeneratedByAssistant() ? 1 : 0)
// The fields in the NotificationVisibility.NotificationLocation enum map
// directly to the fields in the MetricsEvent.NotificationLocation enum.
- .addTaggedData(MetricsEvent.NOTIFICATION_LOCATION, notificationLocation);
+ .addTaggedData(MetricsEvent.NOTIFICATION_LOCATION, notificationLocation)
+ .addTaggedData(
+ MetricsEvent.NOTIFICATION_SMART_REPLY_EDIT_BEFORE_SENDING,
+ r.getEditChoicesBeforeSending() ? 1 : 0);
mMetricsLogger.write(logMaker);
}
}
@@ -1272,6 +1305,8 @@
private final class SettingsObserver extends ContentObserver {
private final Uri NOTIFICATION_BADGING_URI
= Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BADGING);
+ private final Uri NOTIFICATION_BUBBLES_URI
+ = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BUBBLES);
private final Uri NOTIFICATION_LIGHT_PULSE_URI
= Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
private final Uri NOTIFICATION_RATE_LIMIT_URI
@@ -1289,6 +1324,8 @@
false, this, UserHandle.USER_ALL);
resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI,
+ false, this, UserHandle.USER_ALL);
update(null);
}
@@ -1314,6 +1351,9 @@
if (uri == null || NOTIFICATION_BADGING_URI.equals(uri)) {
mPreferencesHelper.updateBadgingEnabled();
}
+ if (uri == null || NOTIFICATION_BUBBLES_URI.equals(uri)) {
+ mPreferencesHelper.updateBubblesEnabled();
+ }
}
}
@@ -3497,14 +3537,9 @@
public byte[] getBackupPayload(int user) {
checkCallerIsSystem();
if (DBG) Slog.d(TAG, "getBackupPayload u=" + user);
- //TODO: http://b/22388012
- if (user != USER_SYSTEM) {
- Slog.w(TAG, "getBackupPayload: cannot backup policy for user " + user);
- return null;
- }
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
- writePolicyXml(baos, true /*forBackup*/);
+ writePolicyXml(baos, true /*forBackup*/, user);
return baos.toByteArray();
} catch (IOException e) {
Slog.w(TAG, "getBackupPayload: error writing payload for user " + user, e);
@@ -3521,14 +3556,9 @@
Slog.w(TAG, "applyRestore: no payload to restore for user " + user);
return;
}
- //TODO: http://b/22388012
- if (user != USER_SYSTEM) {
- Slog.w(TAG, "applyRestore: cannot restore policy for user " + user);
- return;
- }
final ByteArrayInputStream bais = new ByteArrayInputStream(payload);
try {
- readPolicyXml(bais, true /*forRestore*/);
+ readPolicyXml(bais, true /*forRestore*/, user);
handleSavePolicyFile();
} catch (NumberFormatException | XmlPullParserException | IOException e) {
Slog.w(TAG, "applyRestore: error reading payload", e);
@@ -5839,6 +5869,7 @@
ArrayList<String> orderBefore = new ArrayList<>(N);
int[] visibilities = new int[N];
boolean[] showBadges = new boolean[N];
+ boolean[] allowBubbles = new boolean[N];
ArrayList<NotificationChannel> channelBefore = new ArrayList<>(N);
ArrayList<String> groupKeyBefore = new ArrayList<>(N);
ArrayList<ArrayList<String>> overridePeopleBefore = new ArrayList<>(N);
@@ -5853,6 +5884,7 @@
orderBefore.add(r.getKey());
visibilities[i] = r.getPackageVisibilityOverride();
showBadges[i] = r.canShowBadge();
+ allowBubbles[i] = r.canBubble();
channelBefore.add(r.getChannel());
groupKeyBefore.add(r.getGroupKey());
overridePeopleBefore.add(r.getPeopleOverride());
@@ -5870,6 +5902,7 @@
if (!orderBefore.get(i).equals(r.getKey())
|| visibilities[i] != r.getPackageVisibilityOverride()
|| showBadges[i] != r.canShowBadge()
+ || allowBubbles[i] != r.canBubble()
|| !Objects.equals(channelBefore.get(i), r.getChannel())
|| !Objects.equals(groupKeyBefore.get(i), r.getGroupKey())
|| !Objects.equals(overridePeopleBefore.get(i), r.getPeopleOverride())
@@ -6912,6 +6945,7 @@
Bundle smartReplies = new Bundle();
Bundle lastAudiblyAlerted = new Bundle();
Bundle noisy = new Bundle();
+ ArrayList<Boolean> canBubble = new ArrayList<>(N);
for (int i = 0; i < N; i++) {
NotificationRecord record = mNotificationList.get(i);
if (!isVisibleToListener(record.sbn, info)) {
@@ -6944,18 +6978,22 @@
smartReplies.putCharSequenceArrayList(key, record.getSmartReplies());
lastAudiblyAlerted.putLong(key, record.getLastAudiblyAlertedMs());
noisy.putBoolean(key, record.getSound() != null || record.getVibration() != null);
+ canBubble.add(record.canBubble());
}
final int M = keys.size();
String[] keysAr = keys.toArray(new String[M]);
String[] interceptedKeysAr = interceptedKeys.toArray(new String[interceptedKeys.size()]);
int[] importanceAr = new int[M];
+ boolean[] canBubbleAr = new boolean[M];
for (int i = 0; i < M; i++) {
importanceAr[i] = importance.get(i);
+ canBubbleAr[i] = canBubble.get(i);
}
return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys,
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden,
- systemGeneratedSmartActions, smartReplies, lastAudiblyAlerted, noisy);
+ systemGeneratedSmartActions, smartReplies, lastAudiblyAlerted, noisy,
+ canBubbleAr);
}
boolean hasCompanionDevice(ManagedServiceInfo info) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index ab49ebb..48818f5 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -161,6 +161,7 @@
private ArrayList<String> mPeopleOverride;
private ArrayList<SnoozeCriterion> mSnoozeCriteria;
private boolean mShowBadge;
+ private boolean mAllowBubble;
private Light mLight;
/**
* This list contains system generated smart actions from NAS, app-generated smart actions are
@@ -178,6 +179,7 @@
private int mNumberOfSmartRepliesAdded;
private int mNumberOfSmartActionsAdded;
private boolean mSuggestionsGeneratedByAssistant;
+ private boolean mEditChoicesBeforeSending;
private boolean mHasSeenSmartReplies;
/**
* Whether this notification (and its channels) should be considered user locked. Used in
@@ -993,6 +995,14 @@
mShowBadge = showBadge;
}
+ public boolean canBubble() {
+ return mAllowBubble;
+ }
+
+ public void setAllowBubble(boolean allow) {
+ mAllowBubble = allow;
+ }
+
public boolean canShowBadge() {
return mShowBadge;
}
@@ -1136,6 +1146,14 @@
return mSuggestionsGeneratedByAssistant;
}
+ public boolean getEditChoicesBeforeSending() {
+ return mEditChoicesBeforeSending;
+ }
+
+ public void setEditChoicesBeforeSending(boolean editChoicesBeforeSending) {
+ mEditChoicesBeforeSending = editChoicesBeforeSending;
+ }
+
public boolean hasSeenSmartReplies() {
return mHasSeenSmartReplies;
}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 6ed4f5c..2c47ec0 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -127,6 +127,7 @@
private final ZenModeHelper mZenModeHelper;
private SparseBooleanArray mBadgingEnabled;
+ private SparseBooleanArray mBubblesEnabled;
private boolean mAreChannelsBypassingDnd;
private boolean mHideSilentStatusBarIcons;
@@ -138,10 +139,11 @@
mPm = pm;
updateBadgingEnabled();
+ updateBubblesEnabled();
syncChannelsBypassingDnd(mContext.getUserId());
}
- public void readXml(XmlPullParser parser, boolean forRestore)
+ public void readXml(XmlPullParser parser, boolean forRestore, int userId)
throws XmlPullParserException, IOException {
int type = parser.getEventType();
if (type != XmlPullParser.START_TAG) return;
@@ -158,6 +160,9 @@
}
if (type == XmlPullParser.START_TAG) {
if (TAG_STATUS_ICONS.equals(tag)) {
+ if (forRestore && userId != UserHandle.USER_SYSTEM) {
+ continue;
+ }
mHideSilentStatusBarIcons = XmlUtils.readBooleanAttribute(
parser, ATT_HIDE_SILENT, DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
} else if (TAG_PACKAGE.equals(tag)) {
@@ -166,9 +171,7 @@
if (!TextUtils.isEmpty(name)) {
if (forRestore) {
try {
- //TODO: http://b/22388012
- uid = mPm.getPackageUidAsUser(name,
- UserHandle.USER_SYSTEM);
+ uid = mPm.getPackageUidAsUser(name, userId);
} catch (PackageManager.NameNotFoundException e) {
// noop
}
@@ -379,10 +382,11 @@
r.channels.put(channel.getId(), channel);
}
- public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
+ public void writeXml(XmlSerializer out, boolean forBackup, int userId) throws IOException {
out.startTag(null, TAG_RANKING);
out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
- if (mHideSilentStatusBarIcons != DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS) {
+ if (mHideSilentStatusBarIcons != DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS
+ && (!forBackup || userId == UserHandle.USER_SYSTEM)) {
out.startTag(null, TAG_STATUS_ICONS);
out.attribute(null, ATT_HIDE_SILENT, String.valueOf(mHideSilentStatusBarIcons));
out.endTag(null, TAG_STATUS_ICONS);
@@ -392,8 +396,7 @@
final int N = mPackagePreferences.size();
for (int i = 0; i < N; i++) {
final PackagePreferences r = mPackagePreferences.valueAt(i);
- //TODO: http://b/22388012
- if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_SYSTEM) {
+ if (forBackup && UserHandle.getUserId(r.uid) != userId) {
continue;
}
final boolean hasNonDefaultSettings =
@@ -485,6 +488,7 @@
* @param uid the uid to check if bubbles are allowed for.
* @return whether bubbles are allowed.
*/
+ @Override
public boolean areBubblesAllowed(String pkg, int uid) {
return getOrCreatePackagePreferences(pkg, uid).allowBubble;
}
@@ -1266,7 +1270,7 @@
if (original.canShowBadge() != update.canShowBadge()) {
update.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE);
}
- if (original.isBubbleAllowed() != update.isBubbleAllowed()) {
+ if (original.canBubble() != update.canBubble()) {
update.lockFields(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE);
}
}
@@ -1638,6 +1642,40 @@
.setPackageName(pkg);
}
+ public void updateBubblesEnabled() {
+ if (mBubblesEnabled == null) {
+ mBubblesEnabled = new SparseBooleanArray();
+ }
+ boolean changed = false;
+ // update the cached values
+ for (int index = 0; index < mBubblesEnabled.size(); index++) {
+ int userId = mBubblesEnabled.keyAt(index);
+ final boolean oldValue = mBubblesEnabled.get(userId);
+ final boolean newValue = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NOTIFICATION_BUBBLES,
+ DEFAULT_ALLOW_BUBBLE ? 1 : 0, userId) != 0;
+ mBubblesEnabled.put(userId, newValue);
+ changed |= oldValue != newValue;
+ }
+ if (changed) {
+ updateConfig();
+ }
+ }
+
+ public boolean bubblesEnabled(UserHandle userHandle) {
+ int userId = userHandle.getIdentifier();
+ if (userId == UserHandle.USER_ALL) {
+ return false;
+ }
+ if (mBubblesEnabled.indexOfKey(userId) < 0) {
+ mBubblesEnabled.put(userId,
+ Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NOTIFICATION_BUBBLES,
+ DEFAULT_ALLOW_BUBBLE ? 1 : 0, userId) != 0);
+ }
+ return mBubblesEnabled.get(userId, DEFAULT_ALLOW_BUBBLE);
+ }
+
public void updateBadgingEnabled() {
if (mBadgingEnabled == null) {
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 605348b..72502acd 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -29,6 +29,8 @@
void setShowBadge(String packageName, int uid, boolean showBadge);
boolean canShowBadge(String packageName, int uid);
boolean badgingEnabled(UserHandle userHandle);
+ boolean areBubblesAllowed(String packageName, int uid);
+ boolean bubblesEnabled(UserHandle userHandle);
boolean isGroupBlocked(String packageName, int uid, String groupId);
Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index afc0b72..ea7bf2d2 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -104,7 +104,7 @@
protected final RingerModeDelegate mRingerModeDelegate = new
RingerModeDelegate();
@VisibleForTesting protected final ZenModeConditions mConditions;
- private final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>();
+ @VisibleForTesting final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>();
private final Metrics mMetrics = new Metrics();
private final ConditionProviders.Config mServiceConfig;
@@ -662,17 +662,14 @@
}
}
- public void readXml(XmlPullParser parser, boolean forRestore)
+ public void readXml(XmlPullParser parser, boolean forRestore, int userId)
throws XmlPullParserException, IOException {
ZenModeConfig config = ZenModeConfig.readXml(parser);
String reason = "readXml";
if (config != null) {
if (forRestore) {
- //TODO: http://b/22388012
- if (config.user != UserHandle.USER_SYSTEM) {
- return;
- }
+ config.user = userId;
config.manualRule = null; // don't restore the manual rule
}
@@ -707,13 +704,15 @@
reason += ", reset to default rules";
}
+ // Resolve user id for settings.
+ userId = userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId;
if (config.version < ZenModeConfig.XML_VERSION) {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 1, userId);
} else {
// devices not restoring/upgrading already have updated zen settings
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ZEN_SETTINGS_UPDATED, 1);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_UPDATED, 1, userId);
}
if (DEBUG) Log.d(TAG, reason);
synchronized (mConfig) {
@@ -722,11 +721,11 @@
}
}
- public void writeXml(XmlSerializer out, boolean forBackup, Integer version) throws IOException {
+ public void writeXml(XmlSerializer out, boolean forBackup, Integer version, int userId)
+ throws IOException {
final int N = mConfigs.size();
for (int i = 0; i < N; i++) {
- //TODO: http://b/22388012
- if (forBackup && mConfigs.keyAt(i) != UserHandle.USER_SYSTEM) {
+ if (forBackup && mConfigs.keyAt(i) != userId) {
continue;
}
mConfigs.valueAt(i).writeXml(out, version);
diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
index f736056..1dada92 100644
--- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
+++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
@@ -17,8 +17,10 @@
package com.android.server.os;
import android.annotation.RequiresPermission;
+import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
+import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.BugreportParams;
import android.os.IDumpstate;
@@ -28,26 +30,29 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.UserManager;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
import java.io.FileDescriptor;
// TODO(b/111441001):
-// 1. Handle the case where another bugreport is in progress
-// 2. Make everything threadsafe
-// 3. Pass validation & other errors on listener
+// Intercept onFinished() & implement death recipient here and shutdown
+// bugreportd service.
/**
* Implementation of the service that provides a privileged API to capture and consume bugreports.
*
- * <p>Delegates the actualy generation to a native implementation of {@code Dumpstate}.
+ * <p>Delegates the actualy generation to a native implementation of {@code IDumpstate}.
*/
class BugreportManagerServiceImpl extends IDumpstate.Stub {
private static final String TAG = "BugreportManagerService";
private static final String BUGREPORT_SERVICE = "bugreportd";
private static final long DEFAULT_BUGREPORT_SERVICE_TIMEOUT_MILLIS = 30 * 1000;
- private IDumpstate mDs = null;
+ private final Object mLock = new Object();
private final Context mContext;
private final AppOpsManager mAppOps;
@@ -59,43 +64,44 @@
@Override
@RequiresPermission(android.Manifest.permission.DUMP)
public IDumpstateToken setListener(String name, IDumpstateListener listener,
- boolean getSectionDetails) throws RemoteException {
- // TODO(b/111441001): Figure out if lazy setting of listener should be allowed
- // and if so how to handle it.
+ boolean getSectionDetails) {
throw new UnsupportedOperationException("setListener is not allowed on this service");
}
- // TODO(b/111441001): Intercept onFinished here in system server and shutdown
- // the bugreportd service.
@Override
@RequiresPermission(android.Manifest.permission.DUMP)
public void startBugreport(int callingUidUnused, String callingPackage,
FileDescriptor bugreportFd, FileDescriptor screenshotFd,
- int bugreportMode, IDumpstateListener listener) throws RemoteException {
- int callingUid = Binder.getCallingUid();
- // TODO(b/111441001): validate all arguments & ensure primary user
- validate(bugreportMode);
+ int bugreportMode, IDumpstateListener listener) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, "startBugreport");
+ Preconditions.checkNotNull(callingPackage);
+ Preconditions.checkNotNull(bugreportFd);
+ Preconditions.checkNotNull(listener);
+ validateBugreportMode(bugreportMode);
+ ensureIsPrimaryUser();
+ int callingUid = Binder.getCallingUid();
mAppOps.checkPackage(callingUid, callingPackage);
- mDs = getDumpstateService();
- if (mDs == null) {
- Slog.w(TAG, "Unable to get bugreport service");
- // TODO(b/111441001): pass error on listener
- return;
+
+ synchronized (mLock) {
+ startBugreportLocked(callingUid, callingPackage, bugreportFd, screenshotFd,
+ bugreportMode, listener);
}
- mDs.startBugreport(callingUid, callingPackage,
- bugreportFd, screenshotFd, bugreportMode, listener);
}
@Override
@RequiresPermission(android.Manifest.permission.DUMP)
- public void cancelBugreport() throws RemoteException {
- // This tells init to cancel bugreportd service.
- SystemProperties.set("ctl.stop", BUGREPORT_SERVICE);
- mDs = null;
+ public void cancelBugreport() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, "startBugreport");
+ // This tells init to cancel bugreportd service. Note that this is achieved through setting
+ // a system property which is not thread-safe. So the lock here offers thread-safety only
+ // among callers of the API.
+ synchronized (mLock) {
+ SystemProperties.set("ctl.stop", BUGREPORT_SERVICE);
+ }
}
- private boolean validate(@BugreportParams.BugreportMode int mode) {
+ private void validateBugreportMode(@BugreportParams.BugreportMode int mode) {
if (mode != BugreportParams.BUGREPORT_MODE_FULL
&& mode != BugreportParams.BUGREPORT_MODE_INTERACTIVE
&& mode != BugreportParams.BUGREPORT_MODE_REMOTE
@@ -103,9 +109,66 @@
&& mode != BugreportParams.BUGREPORT_MODE_TELEPHONY
&& mode != BugreportParams.BUGREPORT_MODE_WIFI) {
Slog.w(TAG, "Unknown bugreport mode: " + mode);
- return false;
+ throw new IllegalArgumentException("Unknown bugreport mode: " + mode);
}
- return true;
+ }
+
+ /**
+ * Validates that the current user is the primary user.
+ *
+ * @throws IllegalArgumentException if the current user is not the primary user
+ */
+ private void ensureIsPrimaryUser() {
+ UserInfo currentUser = null;
+ try {
+ currentUser = ActivityManager.getService().getCurrentUser();
+ } catch (RemoteException e) {
+ // Impossible to get RemoteException for an in-process call.
+ }
+
+ UserInfo primaryUser = UserManager.get(mContext).getPrimaryUser();
+ if (currentUser == null) {
+ logAndThrow("No current user. Only primary user is allowed to take bugreports.");
+ }
+ if (primaryUser == null) {
+ logAndThrow("No primary user. Only primary user is allowed to take bugreports.");
+ }
+ if (primaryUser.id != currentUser.id) {
+ logAndThrow("Current user not primary user. Only primary user"
+ + " is allowed to take bugreports.");
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void startBugreportLocked(int callingUid, String callingPackage,
+ FileDescriptor bugreportFd, FileDescriptor screenshotFd,
+ int bugreportMode, IDumpstateListener listener) {
+ if (isDumpstateBinderServiceRunningLocked()) {
+ Slog.w(TAG, "'dumpstate' is already running. Cannot start a new bugreport"
+ + " while another one is currently in progress.");
+ // TODO(b/111441001): Use a new error code; add this to the documentation of the API.
+ reportError(listener, IDumpstateListener.BUGREPORT_ERROR_RUNTIME_ERROR);
+ return;
+ }
+
+ IDumpstate ds = startAndGetDumpstateBinderServiceLocked();
+ if (ds == null) {
+ Slog.w(TAG, "Unable to get bugreport service");
+ reportError(listener, IDumpstateListener.BUGREPORT_ERROR_RUNTIME_ERROR);
+ return;
+ }
+ try {
+ ds.startBugreport(callingUid, callingPackage,
+ bugreportFd, screenshotFd, bugreportMode, listener);
+ } catch (RemoteException e) {
+ reportError(listener, IDumpstateListener.BUGREPORT_ERROR_RUNTIME_ERROR);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private boolean isDumpstateBinderServiceRunningLocked() {
+ IDumpstate ds = IDumpstate.Stub.asInterface(ServiceManager.getService("dumpstate"));
+ return ds != null;
}
/*
@@ -115,8 +178,12 @@
* <p>Generating bugreports requires root privileges. To limit the footprint
* of the root access, the actual generation in Dumpstate binary is accessed as a
* oneshot service 'bugreport'.
+ *
+ * <p>Note that starting the service is achieved through setting a system property, which is
+ * not thread-safe. So the lock here offers thread-safety only among callers of the API.
*/
- private IDumpstate getDumpstateService() {
+ @GuardedBy("mLock")
+ private IDumpstate startAndGetDumpstateBinderServiceLocked() {
// Start bugreport service.
SystemProperties.set("ctl.start", BUGREPORT_SERVICE);
@@ -145,4 +212,18 @@
}
return ds;
}
+
+ private void reportError(IDumpstateListener listener, int errorCode) {
+ try {
+ listener.onError(errorCode);
+ } catch (RemoteException e) {
+ // Something went wrong in binder or app process. There's nothing to do here.
+ Slog.w(TAG, "onError() transaction threw RemoteException: " + e.getMessage());
+ }
+ }
+
+ private void logAndThrow(String message) {
+ Slog.w(TAG, message);
+ throw new IllegalArgumentException(message);
+ }
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index efafdfa..c2a75ab 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -611,18 +611,43 @@
}
}
- public boolean snapshotAppData(String pkg, @UserIdInt int userId, int storageFlags)
+ /**
+ * Snapshots user data of the given package.
+ *
+ * @param pkg name of the package to snapshot user data for.
+ * @param userId id of the user whose data to snapshot.
+ * @param storageFlags flags controlling which data (CE or DE) to snapshot.
+ *
+ * @return inode of the snapshot of users CE package data, or {@code 0} if a remote calls
+ * shouldn't be continued. See {@link #checkBeforeRemote}.
+ *
+ * @throws InstallerException if failed to snapshot user data.
+ */
+ public long snapshotAppData(String pkg, @UserIdInt int userId, int storageFlags)
throws InstallerException {
- if (!checkBeforeRemote()) return false;
+ if (!checkBeforeRemote()) return 0;
try {
- mInstalld.snapshotAppData(null, pkg, userId, storageFlags);
- return true;
+ return mInstalld.snapshotAppData(null, pkg, userId, storageFlags);
} catch (Exception e) {
throw InstallerException.from(e);
}
}
+ /**
+ * Restores user data snapshot of the given package.
+ *
+ * @param pkg name of the package to restore user data for.
+ * @param appId id of the package to restore user data for.
+ * @param ceDataInode inode of CE user data folder of this app.
+ * @param userId id of the user whose data to restore.
+ * @param storageFlags flags controlling which data (CE or DE) to restore.
+ *
+ * @return {@code true} if user data restore was successful, or {@code false} if a remote call
+ * shouldn't be continued. See {@link #checkBeforeRemote}.
+ *
+ * @throws InstallerException if failed to restore user data.
+ */
public boolean restoreAppDataSnapshot(String pkg, @AppIdInt int appId, long ceDataInode,
String seInfo, @UserIdInt int userId, int storageFlags) throws InstallerException {
if (!checkBeforeRemote()) return false;
@@ -636,6 +661,31 @@
}
}
+ /**
+ * Deletes user data snapshot of the given package.
+ *
+ * @param pkg name of the package to delete user data snapshot for.
+ * @param userId id of the user whose user data snapshot to delete.
+ * @param ceSnapshotInode inode of CE user data snapshot.
+ * @param storageFlags flags controlling which user data snapshot (CE or DE) to delete.
+ *
+ * @return {@code true} if user data snapshot was successfully deleted, or {@code false} if a
+ * remote call shouldn't be continued. See {@link #checkBeforeRemote}.
+ *
+ * @throws InstallerException if failed to delete user data snapshot.
+ */
+ public boolean destroyAppDataSnapshot(String pkg, @UserIdInt int userId, long ceSnapshotInode,
+ int storageFlags) throws InstallerException {
+ if (!checkBeforeRemote()) return false;
+
+ try {
+ mInstalld.destroyAppDataSnapshot(null, pkg, userId, ceSnapshotInode, storageFlags);
+ return true;
+ } catch (Exception e) {
+ throw InstallerException.from(e);
+ }
+ }
+
private static void assertValidInstructionSet(String instructionSet)
throws InstallerException {
for (String abi : Build.SUPPORTED_ABIS) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index d06fc51..1b71904 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -44,7 +44,6 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.apex.IApexService;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
import android.content.IIntentReceiver;
@@ -80,7 +79,6 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
-import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManager;
@@ -1084,6 +1082,11 @@
dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null);
return;
}
+ if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+ throw new PackageManagerException(
+ PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
+ "APEX packages can only be installed using staged sessions.");
+ }
final PackageManagerService.ActiveInstallSession committingSession =
makeSessionActiveLocked();
if (committingSession == null) {
@@ -1101,12 +1104,6 @@
final PackageManagerService.ActiveInstallSession activeSession =
session.makeSessionActiveLocked();
if (activeSession != null) {
- if ((activeSession.getSessionParams().installFlags
- & PackageManager.INSTALL_APEX) != 0) {
- throw new PackageManagerException(
- PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
- "Atomic install is not supported for APEX packages.");
- }
childSessions.add(activeSession);
}
} catch (PackageManagerException e) {
@@ -1124,27 +1121,7 @@
}
mPm.installStage(childSessions);
} else {
- if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
- commitApexLocked();
- } else {
- mPm.installStage(committingSession);
- }
- }
- }
-
- @GuardedBy("mLock")
- private void commitApexLocked() throws PackageManagerException {
- try {
- IApexService apex = IApexService.Stub.asInterface(
- ServiceManager.getService("apexservice"));
- apex.stagePackage(mResolvedBaseFile.toString());
- } catch (Throwable e) {
- // Convert all exceptions into package manager exceptions as only those are handled
- // in the code above
- throw new PackageManagerException(e);
- } finally {
- destroyInternal();
- dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "APEX installed", null);
+ mPm.installStage(committingSession);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e405f25..32dc988 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -984,6 +984,9 @@
@GuardedBy("mPackages")
private CheckPermissionDelegate mCheckPermissionDelegate;
+ @GuardedBy("mPackages")
+ private PackageManagerInternal.DefaultBrowserProvider mDefaultBrowserProvider;
+
private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
private Context mContext;
private ComponentName mIntentFilterVerifierComponent;
@@ -1927,7 +1930,7 @@
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting.getInstallReason(userId)
!= PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
- mSettings.setDefaultBrowserPackageNameLPw(null, userId);
+ setDefaultBrowserPackageName(null, userId);
}
}
@@ -2941,7 +2944,6 @@
if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : sUserManager.getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(user.id);
- applyFactoryDefaultBrowserLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
@@ -3014,8 +3016,6 @@
ver.fingerprint = Build.FINGERPRINT;
}
- checkDefaultBrowser();
-
// clear only after permissions and other defaults have been updated
mExistingSystemPackages.clear();
mPromoteSystemApps = false;
@@ -3670,58 +3670,6 @@
scheduleWriteSettingsLocked();
}
- @GuardedBy("mPackages")
- private void applyFactoryDefaultBrowserLPw(int userId) {
- // The default browser app's package name is stored in a string resource,
- // with a product-specific overlay used for vendor customization.
- String browserPkg = mContext.getResources().getString(
- com.android.internal.R.string.default_browser);
- if (!TextUtils.isEmpty(browserPkg)) {
- // non-empty string => required to be a known package
- PackageSetting ps = mSettings.mPackages.get(browserPkg);
- if (ps == null) {
- Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
- browserPkg = null;
- } else {
- mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
- }
- }
-
- // Nothing valid explicitly set? Make the factory-installed browser the explicit
- // default. If there's more than one, just leave everything alone.
- if (browserPkg == null) {
- calculateDefaultBrowserLPw(userId);
- }
- }
-
- @GuardedBy("mPackages")
- private void calculateDefaultBrowserLPw(int userId) {
- List<String> allBrowsers = resolveAllBrowserApps(userId);
- final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
- mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
- }
-
- private List<String> resolveAllBrowserApps(int userId) {
- // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
- List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
- PackageManager.MATCH_ALL, userId);
-
- final int count = list.size();
- List<String> result = new ArrayList<>(count);
- for (int i=0; i<count; i++) {
- ResolveInfo info = list.get(i);
- if (info.activityInfo == null
- || !info.handleAllWebDataURI
- || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
- || result.contains(info.activityInfo.packageName)) {
- continue;
- }
- result.add(info.activityInfo.packageName);
- }
-
- return result;
- }
-
private boolean packageIsBrowser(String packageName, int userId) {
List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
PackageManager.MATCH_ALL, userId);
@@ -3735,20 +3683,6 @@
return false;
}
- private void checkDefaultBrowser() {
- final int myUserId = UserHandle.myUserId();
- final String packageName = getDefaultBrowserPackageName(myUserId);
- if (packageName != null) {
- PackageInfo info = getPackageInfo(packageName, 0, myUserId);
- if (info == null) {
- Slog.w(TAG, "Default browser no longer installed: " + packageName);
- synchronized (mPackages) {
- applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1
- }
- }
- }
- }
-
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -4007,13 +3941,13 @@
if (apex != null) {
try {
final ApexInfo activePkg = apex.getActivePackage(packageName);
- if (activePkg != null) {
+ if (activePkg != null && !TextUtils.isEmpty(activePkg.packagePath)) {
try {
return PackageParser.generatePackageInfoFromApex(
new File(activePkg.packagePath), true /* collect certs */);
} catch (PackageParserException pe) {
- throw new IllegalStateException("Unable to parse: " + activePkg,
- pe);
+ Log.e(TAG, "Unable to parse package at "
+ + activePkg.packagePath, pe);
}
}
} catch (RemoteException e) {
@@ -13492,6 +13426,10 @@
return false;
}
+ if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
+ return false;
+ }
+
boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
// Check if installing from ADB
@@ -13645,15 +13583,28 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
-
- synchronized (mPackages) {
- boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
- if (packageName != null) {
- mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
- packageName, userId);
- }
- return result;
+ if (userId == UserHandle.USER_ALL) {
+ return false;
}
+ PackageManagerInternal.DefaultBrowserProvider provider;
+ synchronized (mPackages) {
+ provider = mDefaultBrowserProvider;
+ }
+ if (provider == null) {
+ Slog.e(TAG, "mDefaultBrowserProvider is null");
+ return false;
+ }
+ boolean successful = provider.setDefaultBrowser(packageName, userId);
+ if (!successful) {
+ return false;
+ }
+ if (packageName != null) {
+ synchronized (mPackages) {
+ mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
+ userId);
+ }
+ }
+ return true;
}
@Override
@@ -13665,9 +13616,15 @@
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return null;
}
+ PackageManagerInternal.DefaultBrowserProvider provider;
synchronized (mPackages) {
- return mSettings.getDefaultBrowserPackageNameLPw(userId);
+ provider = mDefaultBrowserProvider;
}
+ if (provider == null) {
+ Slog.e(TAG, "mDefaultBrowserProvider is null");
+ return null;
+ }
+ return provider.getDefaultBrowser(userId);
}
/**
@@ -14656,6 +14613,13 @@
PACKAGE_MIME_TYPE);
enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ // Allow the broadcast to be sent before boot complete.
+ // This is needed when committing the apk part of a staged
+ // session in early boot. The rollback manager registers
+ // its receiver early enough during the boot process that
+ // it will not miss the broadcast.
+ enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+
mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, getUser(),
android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
new BroadcastReceiver() {
@@ -19419,7 +19383,7 @@
// significant refactoring to keep all default apps in the package
// manager (cleaner but more work) or have the services provide
// callbacks to the package manager to request a default app reset.
- applyFactoryDefaultBrowserLPw(userId);
+ setDefaultBrowserPackageName(null, userId);
clearIntentFilterVerificationsLPw(userId);
primeDomainVerificationsLPw(userId);
resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
@@ -22761,7 +22725,6 @@
synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(userId);
scheduleWritePackageListLocked(userId);
- applyFactoryDefaultBrowserLPw(userId);
primeDomainVerificationsLPw(userId);
}
}
@@ -23959,6 +23922,21 @@
public void finishPackageInstall(int token, boolean didLaunch) {
PackageManagerService.this.finishPackageInstall(token, didLaunch);
}
+
+ @Nullable
+ @Override
+ public String removeLegacyDefaultBrowserPackageName(int userId) {
+ synchronized (mPackages) {
+ return mSettings.removeDefaultBrowserPackageNameLPw(userId);
+ }
+ }
+
+ @Override
+ public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
+ synchronized (mPackages) {
+ mDefaultBrowserProvider = provider;
+ }
+ }
}
@GuardedBy("mPackages")
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index b0f2326..975ffb2 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1327,21 +1327,8 @@
return result;
}
- boolean setDefaultBrowserPackageNameLPw(String packageName, int userId) {
- if (userId == UserHandle.USER_ALL) {
- return false;
- }
- if (packageName != null) {
- mDefaultBrowserApp.put(userId, packageName);
- } else {
- mDefaultBrowserApp.remove(userId);
- }
- writePackageRestrictionsLPr(userId);
- return true;
- }
-
- String getDefaultBrowserPackageNameLPw(int userId) {
- return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.get(userId);
+ String removeDefaultBrowserPackageNameLPw(int userId) {
+ return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.removeReturnOld(userId);
}
boolean setDefaultDialerPackageNameLPw(String packageName, int userId) {
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 0371663..89aea36 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -21,6 +21,7 @@
import android.apex.ApexInfoList;
import android.apex.ApexSessionInfo;
import android.apex.IApexService;
+import android.content.Context;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
@@ -33,6 +34,7 @@
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
import android.content.pm.ParceledListSlice;
import android.content.pm.Signature;
+import android.content.rollback.IRollbackManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -186,6 +188,7 @@
private void preRebootVerification(@NonNull PackageInstallerSession session) {
boolean success = true;
+ // STOPSHIP: TODO(b/123753157): Verify APKs through Package Verifier.
if (!sessionContainsApex(session)) {
// TODO: Decide whether we want to fail fast by detecting signature mismatches for APKs,
// right away.
@@ -238,6 +241,23 @@
}
}
+ if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
+ // If rollback is enabled for this session, we call through to the RollbackManager
+ // with the list of sessions it must enable rollback for. Note that notifyStagedSession
+ // is a synchronous operation.
+ final IRollbackManager rm = IRollbackManager.Stub.asInterface(
+ ServiceManager.getService(Context.ROLLBACK_SERVICE));
+ try {
+ // NOTE: To stay consistent with the non-staged install flow, we don't fail the
+ // entire install if rollbacks can't be enabled.
+ if (!rm.notifyStagedSession(session.sessionId)) {
+ Slog.e(TAG, "Unable to enable rollback for session: " + session.sessionId);
+ }
+ } catch (RemoteException re) {
+ // Cannot happen, the rollback manager is in the same process.
+ }
+ }
+
session.setStagedSessionReady();
if (!sendMarkStagedSessionReadyRequest(session.sessionId)) {
session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
@@ -336,6 +356,7 @@
PackageInstaller.SessionParams params = originalSession.params.copy();
params.isStaged = false;
+ params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
int apkSessionId = mPi.createSession(
params, originalSession.getInstallerPackageName(), originalSession.userId);
PackageInstallerSession apkSession = mPi.getSession(apkSessionId);
@@ -359,6 +380,19 @@
private boolean commitApkSession(@NonNull PackageInstallerSession apkSession,
int originalSessionId) {
+
+ if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
+ // If rollback is available for this session, notify the rollback
+ // manager of the apk session so it can properly enable rollback.
+ final IRollbackManager rm = IRollbackManager.Stub.asInterface(
+ ServiceManager.getService(Context.ROLLBACK_SERVICE));
+ try {
+ rm.notifyStagedApkSession(originalSessionId, apkSession.sessionId);
+ } catch (RemoteException re) {
+ // Cannot happen, the rollback manager is in the same process.
+ }
+ }
+
final LocalIntentReceiver receiver = new LocalIntentReceiver();
apkSession.commit(receiver.getIntentSender(), false);
final Intent result = receiver.getResult();
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 2213901..ee6995b 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -228,8 +228,11 @@
continue;
}
- mDexLogger.recordDex(loaderUserId, dexPath, searchResult.mOwningPackageName,
- loadingAppInfo.packageName);
+ if (!primaryOrSplit) {
+ // Record loading of a DEX file from an app data directory.
+ mDexLogger.recordDex(loaderUserId, dexPath, searchResult.mOwningPackageName,
+ loadingAppInfo.packageName);
+ }
if (classLoaderContexts != null) {
diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
index 09bacd6..0892b32 100644
--- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
@@ -18,6 +18,14 @@
"include-filter": "android.permission.cts.SplitPermissionTest"
}
]
+ },
+ {
+ "name": "CtsStatsdHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.cts.statsd.atom.UidAtomTests#testDangerousPermissionState"
+ }
+ ]
}
]
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0796a9c..b00193f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -148,6 +148,7 @@
import android.os.IDeviceIdleController;
import android.os.Message;
import android.os.PowerManager;
+import android.os.PowerManager.WakeReason;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
@@ -189,6 +190,7 @@
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
+import android.view.WindowManagerPolicyConstants;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
@@ -809,7 +811,7 @@
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false,
"Wake Up");
wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture,
- "android.policy:GESTURE");
+ PowerManager.WAKE_REASON_GESTURE, "android.policy:GESTURE");
}
}
}
@@ -3527,7 +3529,7 @@
if (lidOpen) {
wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch,
- "android.policy:LID");
+ PowerManager.WAKE_REASON_LID, "android.policy:LID");
} else if (!mLidControlsSleep) {
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
@@ -3550,7 +3552,7 @@
intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
}
wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens,
- "android.policy:CAMERA_COVER");
+ PowerManager.WAKE_REASON_CAMERA_LAUNCH, "android.policy:CAMERA_COVER");
startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
}
mCameraLensCoverState = lensCoverState;
@@ -3679,7 +3681,8 @@
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
if (isWakeKey) {
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
+ wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
+ PowerManager.WAKE_REASON_WAKE_KEY, "android.policy:KEY");
}
return result;
}
@@ -4025,7 +4028,8 @@
}
if (isWakeKey) {
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
+ wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
+ PowerManager.WAKE_REASON_WAKE_KEY, "android.policy:KEY");
}
return result;
@@ -4125,7 +4129,7 @@
public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
if ((policyFlags & FLAG_WAKE) != 0) {
if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion,
- "android.policy:MOTION")) {
+ PowerManager.WAKE_REASON_WAKE_MOTION, "android.policy:MOTION")) {
return 0;
}
}
@@ -4139,7 +4143,7 @@
// wake up in this case.
if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming,
- "android.policy:MOTION");
+ PowerManager.WAKE_REASON_WAKE_MOTION, "android.policy:MOTION");
}
return 0;
@@ -4371,7 +4375,10 @@
// Called on the PowerManager's Notifier thread.
@Override
public void startedGoingToSleep(int why) {
- if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
+ if (DEBUG_WAKEUP) {
+ Slog.i(TAG, "Started going to sleep... (why="
+ + WindowManagerPolicyConstants.offReasonToString(why) + ")");
+ }
mGoingToSleep = true;
mRequestedOrGoingToSleep = true;
@@ -4385,7 +4392,10 @@
@Override
public void finishedGoingToSleep(int why) {
EventLog.writeEvent(70000, 0);
- if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
+ if (DEBUG_WAKEUP) {
+ Slog.i(TAG, "Finished going to sleep... (why="
+ + WindowManagerPolicyConstants.offReasonToString(why) + ")");
+ }
MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
mGoingToSleep = false;
@@ -4409,9 +4419,12 @@
// Called on the PowerManager's Notifier thread.
@Override
- public void startedWakingUp() {
+ public void startedWakingUp(@OnReason int why) {
EventLog.writeEvent(70000, 1);
- if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");
+ if (DEBUG_WAKEUP) {
+ Slog.i(TAG, "Started waking up... (why="
+ + WindowManagerPolicyConstants.onReasonToString(why) + ")");
+ }
mDefaultDisplayPolicy.setAwake(true);
@@ -4432,8 +4445,11 @@
// Called on the PowerManager's Notifier thread.
@Override
- public void finishedWakingUp() {
- if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up...");
+ public void finishedWakingUp(@OnReason int why) {
+ if (DEBUG_WAKEUP) {
+ Slog.i(TAG, "Finished waking up... (why="
+ + WindowManagerPolicyConstants.onReasonToString(why) + ")");
+ }
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onFinishedWakingUp();
@@ -4441,10 +4457,12 @@
}
private void wakeUpFromPowerKey(long eventTime) {
- wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER");
+ wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey,
+ PowerManager.WAKE_REASON_POWER_BUTTON, "android.policy:POWER");
}
- private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) {
+ private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason,
+ String details) {
final boolean theaterModeEnabled = isTheaterModeEnabled();
if (!wakeInTheaterMode && theaterModeEnabled) {
return false;
@@ -4455,7 +4473,7 @@
Settings.Global.THEATER_MODE_ON, 0);
}
- mPowerManager.wakeUp(wakeTime, reason);
+ mPowerManager.wakeUp(wakeTime, reason, details);
return true;
}
@@ -4786,7 +4804,7 @@
mKeyguardDelegate.onBootCompleted();
}
}
- startedWakingUp();
+ startedWakingUp(ON_BECAUSE_OF_UNKNOWN);
screenTurningOn(null);
screenTurnedOn();
}
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index e18cd17..d1bd102 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -1070,12 +1070,12 @@
/**
* Called when the device has started waking up.
*/
- public void startedWakingUp();
+ void startedWakingUp(@OnReason int reason);
/**
* Called when the device has finished waking up.
*/
- public void finishedWakingUp();
+ void finishedWakingUp(@OnReason int reason);
/**
* Called when the device has started going to sleep.
diff --git a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
index bfe7725..e7de8dd 100644
--- a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
+++ b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
@@ -20,6 +20,7 @@
import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManagerInternal;
import android.os.Debug;
import android.provider.Settings;
import android.telecom.TelecomManager;
@@ -29,6 +30,7 @@
import com.android.internal.telephony.SmsApplication;
import com.android.internal.util.CollectionUtils;
+import com.android.server.LocalServices;
import com.android.server.role.RoleManagerService;
import java.util.Collection;
@@ -113,6 +115,13 @@
? setting
: mContext.getSystemService(TelecomManager.class).getSystemDialerPackage());
}
+ case RoleManager.ROLE_BROWSER: {
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ String packageName = packageManagerInternal.removeLegacyDefaultBrowserPackageName(
+ userId);
+ return CollectionUtils.singletonOrEmpty(packageName);
+ }
default: {
Slog.e(LOG_TAG, "Don't know how to find legacy role holders for " + roleName);
return Collections.emptyList();
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index c3f20aa..1a82858 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -36,6 +36,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
+import android.os.PowerManager.WakeReason;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
@@ -48,6 +49,7 @@
import android.util.EventLog;
import android.util.Slog;
import android.util.StatsLog;
+import android.view.WindowManagerPolicyConstants.OnReason;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
@@ -136,6 +138,7 @@
// broadcasted state over the course of reporting the transition asynchronously.
private boolean mInteractive = true;
private int mInteractiveChangeReason;
+ private long mInteractiveChangeStartTime; // In SystemClock.uptimeMillis()
private boolean mInteractiveChanging;
// The pending interactive state that we will eventually want to broadcast.
@@ -371,7 +374,7 @@
* which case it will assume that the state did not fully converge before the
* next transition began and will recover accordingly.
*/
- public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
+ public void onWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime) {
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
if (DEBUG) {
Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
@@ -410,6 +413,7 @@
// Handle early behaviors.
mInteractive = interactive;
mInteractiveChangeReason = reason;
+ mInteractiveChangeStartTime = eventTime;
mInteractiveChanging = true;
handleEarlyInteractiveChange();
}
@@ -440,8 +444,8 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- // Note a SCREEN tron event is logged in PowerManagerService.
- mPolicy.startedWakingUp();
+ final int why = translateOnReason(mInteractiveChangeReason);
+ mPolicy.startedWakingUp(why);
}
});
@@ -470,12 +474,21 @@
*/
private void handleLateInteractiveChange() {
synchronized (mLock) {
+ final int interactiveChangeLatency =
+ (int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
if (mInteractive) {
// Finished waking up...
+ final int why = translateOnReason(mInteractiveChangeReason);
mHandler.post(new Runnable() {
@Override
public void run() {
- mPolicy.finishedWakingUp();
+ LogMaker log = new LogMaker(MetricsEvent.SCREEN);
+ log.setType(MetricsEvent.TYPE_OPEN);
+ log.setSubtype(why);
+ log.setLatency(interactiveChangeLatency);
+ MetricsLogger.action(log);
+ EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency);
+ mPolicy.finishedWakingUp(why);
}
});
} else {
@@ -499,8 +512,9 @@
LogMaker log = new LogMaker(MetricsEvent.SCREEN);
log.setType(MetricsEvent.TYPE_CLOSE);
log.setSubtype(why);
+ log.setLatency(interactiveChangeLatency);
MetricsLogger.action(log);
- EventLogTags.writePowerScreenState(0, why, 0, 0, 0);
+ EventLogTags.writePowerScreenState(0, why, 0, 0, interactiveChangeLatency);
mPolicy.finishedGoingToSleep(why);
}
});
@@ -524,6 +538,23 @@
}
}
+ private static @OnReason int translateOnReason(@WakeReason int reason) {
+ switch (reason) {
+ case PowerManager.WAKE_REASON_POWER_BUTTON:
+ case PowerManager.WAKE_REASON_PLUGGED_IN:
+ case PowerManager.WAKE_REASON_GESTURE:
+ case PowerManager.WAKE_REASON_CAMERA_LAUNCH:
+ case PowerManager.WAKE_REASON_WAKE_KEY:
+ case PowerManager.WAKE_REASON_WAKE_MOTION:
+ case PowerManager.WAKE_REASON_LID:
+ return WindowManagerPolicy.ON_BECAUSE_OF_USER;
+ case PowerManager.WAKE_REASON_APPLICATION:
+ return WindowManagerPolicy.ON_BECAUSE_OF_APPLICATION;
+ default:
+ return WindowManagerPolicy.ON_BECAUSE_OF_UNKNOWN;
+ }
+ }
+
/**
* Called when screen brightness boost begins or ends.
*/
@@ -565,14 +596,16 @@
/**
* Called when the screen has turned on.
*/
- public void onWakeUp(String reason, int reasonUid, String opPackageName, int opUid) {
+ public void onWakeUp(int reason, String details, int reasonUid, String opPackageName,
+ int opUid) {
if (DEBUG) {
- Slog.d(TAG, "onWakeUp: event=" + reason + ", reasonUid=" + reasonUid
+ Slog.d(TAG, "onWakeUp: reason=" + PowerManager.wakeReasonToString(reason)
+ + ", details=" + details + ", reasonUid=" + reasonUid
+ " opPackageName=" + opPackageName + " opUid=" + opUid);
}
try {
- mBatteryStats.noteWakeUp(reason, reasonUid);
+ mBatteryStats.noteWakeUp(details, reasonUid);
if (opPackageName != null) {
mAppOps.noteOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 3ccd234..af3bff0 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -39,7 +39,6 @@
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.hardware.power.V1_0.PowerHint;
-import android.metrics.LogMaker;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
@@ -52,6 +51,7 @@
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
+import android.os.PowerManager.WakeReason;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.Process;
@@ -82,8 +82,6 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
import com.android.internal.hardware.AmbientDisplayConfiguration;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.server.EventLogTags;
@@ -295,6 +293,7 @@
private long mLastSleepTime;
// Last reason the device went to sleep.
+ private @WakeReason int mLastWakeReason;
private int mLastSleepReason;
// Timestamp of the last call to user activity.
@@ -1119,8 +1118,9 @@
opPackageName = wakeLock.mPackageName;
opUid = wakeLock.mOwnerUid;
}
- wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), wakeLock.mTag, opUid,
- opPackageName, opUid);
+ wakeUpNoUpdateLocked(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag,
+ opUid, opPackageName, opUid);
}
}
@@ -1410,17 +1410,17 @@
}
}
- private void wakeUpInternal(long eventTime, String reason, int uid, String opPackageName,
- int opUid) {
+ private void wakeUpInternal(long eventTime, @WakeReason int reason, String details, int uid,
+ String opPackageName, int opUid) {
synchronized (mLock) {
- if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {
+ if (wakeUpNoUpdateLocked(eventTime, reason, details, uid, opPackageName, opUid)) {
updatePowerStateLocked();
}
}
}
- private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,
- String opPackageName, int opUid) {
+ private boolean wakeUpNoUpdateLocked(long eventTime, @WakeReason int reason, String details,
+ int reasonUid, String opPackageName, int opUid) {
if (DEBUG_SPEW) {
Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
}
@@ -1434,25 +1434,18 @@
Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
try {
- switch (mWakefulness) {
- case WAKEFULNESS_ASLEEP:
- Slog.i(TAG, "Waking up from sleep (uid=" + reasonUid + " reason=" + reason
- + ")...");
- break;
- case WAKEFULNESS_DREAMING:
- Slog.i(TAG, "Waking up from dream (uid=" + reasonUid + " reason=" + reason
- + ")...");
- break;
- case WAKEFULNESS_DOZING:
- Slog.i(TAG, "Waking up from dozing (uid=" + reasonUid + " reason=" + reason
- + ")...");
- break;
- }
+ Slog.i(TAG, "Waking up from "
+ + PowerManagerInternal.wakefulnessToString(mWakefulness)
+ + " (uid=" + reasonUid
+ + ", reason=" + PowerManager.wakeReasonToString(reason)
+ + ", details=" + details
+ + ")...");
mLastWakeTime = eventTime;
- setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
+ mLastWakeReason = reason;
+ setWakefulnessLocked(WAKEFULNESS_AWAKE, reason, eventTime);
- mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);
+ mNotifier.onWakeUp(reason, details, reasonUid, opPackageName, opUid);
userActivityNoUpdateLocked(
eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
} finally {
@@ -1520,7 +1513,7 @@
mLastSleepTime = eventTime;
mLastSleepReason = reason;
mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
+ setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);
// Report the number of wake locks that will be cleared by going to sleep.
int numWakeLocksCleared = 0;
@@ -1570,7 +1563,7 @@
Slog.i(TAG, "Nap time (uid " + uid +")...");
mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DREAMING, 0);
+ setWakefulnessLocked(WAKEFULNESS_DREAMING, 0, eventTime);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -1593,7 +1586,8 @@
try {
Slog.i(TAG, "Sleeping (uid " + uid +")...");
- setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+ setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
+ eventTime);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -1601,13 +1595,13 @@
}
@VisibleForTesting
- void setWakefulnessLocked(int wakefulness, int reason) {
+ void setWakefulnessLocked(int wakefulness, int reason, long eventTime) {
if (mWakefulness != wakefulness) {
mWakefulness = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
if (mNotifier != null) {
- mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
+ mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
}
mAttentionDetector.onWakefulnessChangeStarted(wakefulness);
}
@@ -1631,23 +1625,6 @@
}
}
- private void logScreenOn() {
- Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
-
- final int latencyMs = (int) (SystemClock.uptimeMillis() - mLastWakeTime);
-
- LogMaker log = new LogMaker(MetricsEvent.SCREEN);
- log.setType(MetricsEvent.TYPE_OPEN);
- log.setSubtype(0); // not user initiated
- log.setLatency(latencyMs); // How long it took.
- MetricsLogger.action(log);
- EventLogTags.writePowerScreenState(1, 0, 0, 0, latencyMs);
-
- if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
- Slog.w(TAG, "Screen on took " + latencyMs+ " ms");
- }
- }
-
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
if (mWakefulness == WAKEFULNESS_DOZING
@@ -1658,7 +1635,11 @@
logSleepTimeoutRecapturedLocked();
}
if (mWakefulness == WAKEFULNESS_AWAKE) {
- logScreenOn();
+ Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
+ final int latencyMs = (int) (SystemClock.uptimeMillis() - mLastWakeTime);
+ if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
+ Slog.w(TAG, "Screen on took " + latencyMs + " ms");
+ }
}
mWakefulnessChanging = false;
mNotifier.onWakefulnessChangeFinished();
@@ -1786,7 +1767,8 @@
final long now = SystemClock.uptimeMillis();
if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
dockedOnWirelessCharger)) {
- wakeUpNoUpdateLocked(now, "android.server.power:POWER", Process.SYSTEM_UID,
+ wakeUpNoUpdateLocked(now, PowerManager.WAKE_REASON_PLUGGED_IN,
+ "android.server.power:PLUGGED:" + mIsPowered, Process.SYSTEM_UID,
mContext.getOpPackageName(), Process.SYSTEM_UID);
}
userActivityNoUpdateLocked(
@@ -2369,8 +2351,10 @@
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
updatePowerStateLocked();
} else {
- wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), "android.server.power:DREAM",
- Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID);
+ wakeUpNoUpdateLocked(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_UNKNOWN,
+ "android.server.power:DREAM_FINISHED", Process.SYSTEM_UID,
+ mContext.getOpPackageName(), Process.SYSTEM_UID);
updatePowerStateLocked();
}
} else if (wakefulness == WAKEFULNESS_DOZING) {
@@ -4375,7 +4359,8 @@
}
@Override // Binder call
- public void wakeUp(long eventTime, String reason, String opPackageName) {
+ public void wakeUp(long eventTime, @WakeReason int reason, String details,
+ String opPackageName) {
if (eventTime > SystemClock.uptimeMillis()) {
throw new IllegalArgumentException("event time must not be in the future");
}
@@ -4386,7 +4371,7 @@
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- wakeUpInternal(eventTime, reason, uid, opPackageName, uid);
+ wakeUpInternal(eventTime, reason, details, uid, opPackageName, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
index 1d74e1f..fac95f9 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
@@ -104,6 +104,7 @@
private static final String KEY_AOD_DISABLED = "aod_disabled";
// Go into deep Doze as soon as the screen turns off.
private static final String KEY_QUICK_DOZE_ENABLED = "quick_doze_enabled";
+ private static final String KEY_ENABLE_NIGHT_MODE = "enable_night_mode";
private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i";
private static final String KEY_CPU_FREQ_NONINTERACTIVE = "cpufreq-n";
@@ -123,12 +124,13 @@
false, /* enableAdjustBrightness */
false, /* enableDataSaver */
false, /* enableFireWall */
+ false, /* enableNightMode */
false, /* enableQuickDoze */
new ArrayMap<>(), /* filesForInteractive */
new ArrayMap<>(), /* filesForNoninteractive */
false, /* forceAllAppsStandby */
false, /* forceBackgroundCheck */
- PowerManager.LOCATION_MODE_NO_CHANGE /* gpsMode */
+ PowerManager.LOCATION_MODE_NO_CHANGE /* locationMode */
);
private static final Policy DEFAULT_ADAPTIVE_POLICY = OFF_POLICY;
@@ -147,12 +149,13 @@
false, /* enableAdjustBrightness */
false, /* enableDataSaver */
true, /* enableFirewall */
+ true, /* enableNightMode */
true, /* enableQuickDoze */
new ArrayMap<>(), /* filesForInteractive */
new ArrayMap<>(), /* filesForNoninteractive */
true, /* forceAllAppsStandby */
true, /* forceBackgroundCheck */
- PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF /* gpsMode */
+ PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF /* locationMode */
);
private final Object mLock;
@@ -416,7 +419,7 @@
if (currPolicy.disableAod) sb.append("o");
if (currPolicy.enableQuickDoze) sb.append("q");
- sb.append(currPolicy.gpsMode);
+ sb.append(currPolicy.locationMode);
mEventLogKeys = sb.toString();
}
@@ -523,6 +526,11 @@
public final boolean enableFirewall;
/**
+ * Whether to enable night mode or not.
+ */
+ public final boolean enableNightMode;
+
+ /**
* Whether Quick Doze is enabled or not.
*/
public final boolean enableQuickDoze;
@@ -554,12 +562,13 @@
public final boolean forceBackgroundCheck;
/**
- * This is the flag to decide the gps mode in battery saver mode.
+ * This is the flag to decide the location mode in battery saver mode. This was
+ * previously called gpsMode.
*
* @see Settings.Global#BATTERY_SAVER_CONSTANTS
* @see #KEY_GPS_MODE
*/
- public final int gpsMode;
+ public final int locationMode;
private final int mHashCode;
@@ -577,12 +586,13 @@
boolean enableAdjustBrightness,
boolean enableDataSaver,
boolean enableFirewall,
+ boolean enableNightMode,
boolean enableQuickDoze,
ArrayMap<String, String> filesForInteractive,
ArrayMap<String, String> filesForNoninteractive,
boolean forceAllAppsStandby,
boolean forceBackgroundCheck,
- int gpsMode) {
+ int locationMode) {
this.adjustBrightnessFactor = adjustBrightnessFactor;
this.advertiseIsEnabled = advertiseIsEnabled;
@@ -597,12 +607,13 @@
this.enableAdjustBrightness = enableAdjustBrightness;
this.enableDataSaver = enableDataSaver;
this.enableFirewall = enableFirewall;
+ this.enableNightMode = enableNightMode;
this.enableQuickDoze = enableQuickDoze;
this.filesForInteractive = filesForInteractive;
this.filesForNoninteractive = filesForNoninteractive;
this.forceAllAppsStandby = forceAllAppsStandby;
this.forceBackgroundCheck = forceBackgroundCheck;
- this.gpsMode = gpsMode;
+ this.locationMode = locationMode;
mHashCode = Objects.hash(
adjustBrightnessFactor,
@@ -618,12 +629,13 @@
enableAdjustBrightness,
enableDataSaver,
enableFirewall,
+ enableNightMode,
enableQuickDoze,
filesForInteractive,
filesForNoninteractive,
forceAllAppsStandby,
forceBackgroundCheck,
- gpsMode);
+ locationMode);
}
static Policy fromConfig(BatterySaverPolicyConfig config) {
@@ -653,6 +665,7 @@
config.getEnableAdjustBrightness(),
config.getEnableDataSaver(),
config.getEnableFirewall(),
+ config.getEnableNightMode(),
config.getEnableQuickDoze(),
/* filesForInteractive */
(new CpuFrequencies()).parseString(cpuFreqInteractive).toSysFileMap(),
@@ -660,7 +673,7 @@
(new CpuFrequencies()).parseString(cpuFreqNoninteractive).toSysFileMap(),
config.getForceAllAppsStandby(),
config.getForceBackgroundCheck(),
- config.getGpsMode()
+ config.getLocationMode()
);
}
@@ -715,13 +728,15 @@
!defaultPolicy.enableDataSaver);
boolean enableFirewall = !parser.getBoolean(KEY_ACTIVATE_FIREWALL_DISABLED,
!defaultPolicy.enableFirewall);
+ boolean enableNightMode = !parser.getBoolean(KEY_ENABLE_NIGHT_MODE,
+ !defaultPolicy.enableNightMode);
boolean enableQuickDoze = parser.getBoolean(KEY_QUICK_DOZE_ENABLED,
defaultPolicy.enableQuickDoze);
boolean forceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY,
defaultPolicy.forceAllAppsStandby);
boolean forceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK,
defaultPolicy.forceBackgroundCheck);
- int gpsMode = parser.getInt(KEY_GPS_MODE, defaultPolicy.gpsMode);
+ int locationMode = parser.getInt(KEY_GPS_MODE, defaultPolicy.locationMode);
return new Policy(
adjustBrightnessFactor,
@@ -738,6 +753,7 @@
enableAdjustBrightness,
enableDataSaver,
enableFirewall,
+ enableNightMode,
enableQuickDoze,
/* filesForInteractive */
(new CpuFrequencies()).parseString(cpuFreqInteractive).toSysFileMap(),
@@ -745,7 +761,7 @@
(new CpuFrequencies()).parseString(cpuFreqNoninteractive).toSysFileMap(),
forceAllAppsStandby,
forceBackgroundCheck,
- gpsMode
+ locationMode
);
}
@@ -767,10 +783,11 @@
&& enableAdjustBrightness == other.enableAdjustBrightness
&& enableDataSaver == other.enableDataSaver
&& enableFirewall == other.enableFirewall
+ && enableNightMode == other.enableNightMode
&& enableQuickDoze == other.enableQuickDoze
&& forceAllAppsStandby == other.forceAllAppsStandby
&& forceBackgroundCheck == other.forceBackgroundCheck
- && gpsMode == other.gpsMode
+ && locationMode == other.locationMode
&& filesForInteractive.equals(other.filesForInteractive)
&& filesForNoninteractive.equals(other.filesForNoninteractive);
}
@@ -795,11 +812,11 @@
final PowerSaveState.Builder builder = new PowerSaveState.Builder()
.setGlobalBatterySaverEnabled(currPolicy.advertiseIsEnabled);
switch (type) {
- case ServiceType.GPS:
+ case ServiceType.LOCATION:
boolean isEnabled = currPolicy.advertiseIsEnabled
- || currPolicy.gpsMode != PowerManager.LOCATION_MODE_NO_CHANGE;
+ || currPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE;
return builder.setBatterySaverEnabled(isEnabled)
- .setGpsMode(currPolicy.gpsMode)
+ .setLocationMode(currPolicy.locationMode)
.build();
case ServiceType.ANIMATION:
return builder.setBatterySaverEnabled(currPolicy.disableAnimation)
@@ -832,6 +849,9 @@
case ServiceType.FORCE_BACKGROUND_CHECK:
return builder.setBatterySaverEnabled(currPolicy.forceBackgroundCheck)
.build();
+ case ServiceType.NIGHT_MODE:
+ return builder.setBatterySaverEnabled(currPolicy.enableNightMode)
+ .build();
case ServiceType.OPTIONAL_SENSORS:
return builder.setBatterySaverEnabled(currPolicy.disableOptionalSensors)
.build();
@@ -910,7 +930,7 @@
public int getGpsMode() {
synchronized (mLock) {
- return getCurrentPolicyLocked().gpsMode;
+ return getCurrentPolicyLocked().locationMode;
}
}
@@ -995,7 +1015,7 @@
pw.print(indent);
pw.println(" " + KEY_ADJUST_BRIGHTNESS_FACTOR + "=" + p.adjustBrightnessFactor);
pw.print(indent);
- pw.println(" " + KEY_GPS_MODE + "=" + p.gpsMode);
+ pw.println(" " + KEY_GPS_MODE + "=" + p.locationMode);
pw.print(indent);
pw.println(" " + KEY_FORCE_ALL_APPS_STANDBY + "=" + p.forceAllAppsStandby);
pw.print(indent);
@@ -1008,6 +1028,8 @@
pw.println(" " + KEY_SOUNDTRIGGER_DISABLED + "=" + p.disableSoundTrigger);
pw.print(indent);
pw.println(" " + KEY_QUICK_DOZE_ENABLED + "=" + p.enableQuickDoze);
+ pw.print(indent);
+ pw.println(" " + KEY_ENABLE_NIGHT_MODE + "=" + p.enableNightMode);
pw.print(" Interactive File values:\n");
dumpMap(pw, " ", p.filesForInteractive);
diff --git a/services/core/java/com/android/server/role/RemoteRoleControllerService.java b/services/core/java/com/android/server/role/RemoteRoleControllerService.java
index be2544d..4fb40db 100644
--- a/services/core/java/com/android/server/role/RemoteRoleControllerService.java
+++ b/services/core/java/com/android/server/role/RemoteRoleControllerService.java
@@ -21,6 +21,7 @@
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.role.IRoleManagerCallback;
+import android.app.role.RoleManager;
import android.app.role.RoleManagerCallback;
import android.content.ComponentName;
import android.content.Context;
@@ -61,34 +62,35 @@
* Add a specific application to the holders of a role. If the role is exclusive, the previous
* holder will be replaced.
*
- * @see RoleControllerService#onAddRoleHolder(String, String, RoleManagerCallback)
+ * @see RoleControllerService#onAddRoleHolder(String, String, int, RoleManagerCallback)
*/
public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName,
- @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
mConnection.enqueueCall(new Connection.Call((service, callbackDelegate) ->
- service.onAddRoleHolder(roleName, packageName, callbackDelegate), callback));
+ service.onAddRoleHolder(roleName, packageName, flags, callbackDelegate), callback));
}
/**
* Remove a specific application from the holders of a role.
*
- * @see RoleControllerService#onRemoveRoleHolder(String, String, RoleManagerCallback)
+ * @see RoleControllerService#onRemoveRoleHolder(String, String, int, RoleManagerCallback)
*/
public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName,
- @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
mConnection.enqueueCall(new Connection.Call((service, callbackDelegate) ->
- service.onRemoveRoleHolder(roleName, packageName, callbackDelegate), callback));
+ service.onRemoveRoleHolder(roleName, packageName, flags, callbackDelegate),
+ callback));
}
/**
* Remove all holders of a role.
*
- * @see RoleControllerService#onClearRoleHolders(String, RoleManagerCallback)
+ * @see RoleControllerService#onClearRoleHolders(String, int, RoleManagerCallback)
*/
public void onClearRoleHolders(@NonNull String roleName,
- @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
mConnection.enqueueCall(new Connection.Call((service, callbackDelegate) ->
- service.onClearRoleHolders(roleName, callbackDelegate), callback));
+ service.onClearRoleHolders(roleName, flags, callbackDelegate), callback));
}
/**
@@ -101,6 +103,20 @@
callback));
}
+ /**
+ * @see RoleControllerService#onSmsKillSwitchToggled(boolean)
+ */
+ public void onSmsKillSwitchToggled(boolean smsRestrictionEnabled) {
+ mConnection.enqueueCall(new Connection.Call(
+ (s, cb) -> s.onSmsKillSwitchToggled(smsRestrictionEnabled),
+ new IRoleManagerCallback.Default() {
+ @Override
+ public void onFailure() {
+ Slog.e(LOG_TAG, "Failed onSmsKillSwitchToggled");
+ }
+ }));
+ }
+
private static final class Connection implements ServiceConnection {
private static final long UNBIND_DELAY_MILLIS = 15 * 1000;
diff --git a/services/core/java/com/android/server/role/RoleManagerServiceInternal.java b/services/core/java/com/android/server/role/RoleManagerInternal.java
similarity index 71%
rename from services/core/java/com/android/server/role/RoleManagerServiceInternal.java
rename to services/core/java/com/android/server/role/RoleManagerInternal.java
index 3afc3f7..7598bf7 100644
--- a/services/core/java/com/android/server/role/RoleManagerServiceInternal.java
+++ b/services/core/java/com/android/server/role/RoleManagerInternal.java
@@ -17,22 +17,23 @@
package com.android.server.role;
import android.annotation.NonNull;
-import android.os.UserHandle;
+import android.annotation.UserIdInt;
import android.util.ArrayMap;
import android.util.ArraySet;
/**
- * Internal calls into {@link RoleManagerService}
+ * Internal calls into {@link RoleManagerService}.
*/
-public abstract class RoleManagerServiceInternal {
+public abstract class RoleManagerInternal {
+
/**
- * Get all roles and packages hold them.
+ * Get all roles and their holders.
*
- * @param user The user to query to roles for
+ * @param userId The user to query to roles for
*
* @return The roles and their holders
*/
@NonNull
- public abstract ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(
- @NonNull UserHandle user);
+ public abstract ArrayMap<String, ArraySet<String>> getRolesAndHolders(
+ @UserIdInt int userId);
}
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index d72270e..21bf9de 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -38,7 +38,9 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.Signature;
+import android.database.ContentObserver;
import android.database.CursorWindow;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -49,6 +51,7 @@
import android.os.ShellCallback;
import android.os.UserHandle;
import android.os.UserManagerInternal;
+import android.provider.Settings;
import android.service.sms.FinancialSmsService;
import android.telephony.IFinancialSmsCallback;
import android.text.TextUtils;
@@ -146,8 +149,11 @@
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mAppOpsManager = context.getSystemService(AppOpsManager.class);
- LocalServices.addService(RoleManagerServiceInternal.class,
- new RoleManagerServiceInternalImpl());
+ LocalServices.addService(RoleManagerInternal.class, new Internal());
+
+ PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
+ packageManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
registerUserRemovedReceiver();
}
@@ -189,6 +195,23 @@
performInitialGrantsIfNecessary(userId);
}
}, UserHandle.SYSTEM, intentFilter, null /* broadcastPermission */, null /* handler */);
+
+ getContext().getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED), false,
+ new ContentObserver(getContext().getMainThreadHandler()) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ boolean killSwitchEnabled = Settings.Global.getInt(
+ getContext().getContentResolver(),
+ Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0) == 1;
+ for (int user : mUserManagerInternal.getUserIds()) {
+ if (mUserManagerInternal.isUserRunning(user)) {
+ getOrCreateControllerService(user)
+ .onSmsKillSwitchToggled(killSwitchEnabled);
+ }
+ }
+ }
+ }, UserHandle.USER_ALL);
}
@Override
@@ -360,10 +383,10 @@
notifyRoleHoldersChangedForListeners(listeners, roleName, userId);
}
- RemoteCallbackList<IOnRoleHoldersChangedListener> allUserListeners = getListeners(
+ RemoteCallbackList<IOnRoleHoldersChangedListener> allUsersListeners = getListeners(
UserHandle.USER_ALL);
- if (allUserListeners != null) {
- notifyRoleHoldersChangedForListeners(allUserListeners, roleName, userId);
+ if (allUsersListeners != null) {
+ notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId);
}
}
@@ -386,19 +409,6 @@
}
}
- /**
- * Get all roles and packages hold them.
- *
- * @param user The user to query to roles for
- *
- * @return The roles and their holders
- */
- @NonNull
- private ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(@NonNull UserHandle user) {
- RoleUserState userState = getOrCreateUserState(user.getIdentifier());
- return userState.getRoleHolders();
- }
-
private class Stub extends IRoleManager.Stub {
@Override
@@ -406,8 +416,7 @@
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
int userId = UserHandle.getUserId(getCallingUid());
- RoleUserState userState = getOrCreateUserState(userId);
- return userState.isRoleAvailable(roleName);
+ return getOrCreateUserState(userId).isRoleAvailable(roleName);
}
@Override
@@ -418,7 +427,7 @@
mAppOpsManager.checkPackage(callingUid, packageName);
int userId = UserHandle.getUserId(callingUid);
- ArraySet<String> roleHolders = getRoleHoldersInternal(roleName, userId);
+ ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName);
if (roleHolders == null) {
return false;
}
@@ -433,27 +442,21 @@
Slog.e(LOG_TAG, "user " + userId + " does not exist");
return Collections.emptyList();
}
- userId = handleIncomingUser(userId, "getRoleHoldersAsUser", false);
+ userId = handleIncomingUser(userId, false, "getRoleHoldersAsUser");
getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
"getRoleHoldersAsUser");
- ArraySet<String> roleHolders = getRoleHoldersInternal(roleName, userId);
+ ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName);
if (roleHolders == null) {
return Collections.emptyList();
}
return new ArrayList<>(roleHolders);
}
- @Nullable
- private ArraySet<String> getRoleHoldersInternal(@NonNull String roleName,
- @UserIdInt int userId) {
- RoleUserState userState = getOrCreateUserState(userId);
- return userState.getRoleHolders(roleName);
- }
-
@Override
public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
- @UserIdInt int userId, @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
+ @NonNull IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
@@ -461,33 +464,36 @@
Slog.e(LOG_TAG, "user " + userId + " does not exist");
return;
}
- userId = handleIncomingUser(userId, "addRoleHolderAsUser", false);
+ userId = handleIncomingUser(userId, false, "addRoleHolderAsUser");
getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
"addRoleHolderAsUser");
- getOrCreateControllerService(userId).onAddRoleHolder(roleName, packageName, callback);
- }
-
- @Override
- public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
- @UserIdInt int userId, @NonNull IRoleManagerCallback callback) {
- Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
- Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
- Preconditions.checkNotNull(callback, "callback cannot be null");
- if (!mUserManagerInternal.exists(userId)) {
- Slog.e(LOG_TAG, "user " + userId + " does not exist");
- return;
- }
- userId = handleIncomingUser(userId, "removeRoleHolderAsUser", false);
- getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
- "removeRoleHolderAsUser");
-
- getOrCreateControllerService(userId).onRemoveRoleHolder(roleName, packageName,
+ getOrCreateControllerService(userId).onAddRoleHolder(roleName, packageName, flags,
callback);
}
@Override
- public void clearRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId,
+ public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
+ @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
+ @NonNull IRoleManagerCallback callback) {
+ Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
+ Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
+ Preconditions.checkNotNull(callback, "callback cannot be null");
+ if (!mUserManagerInternal.exists(userId)) {
+ Slog.e(LOG_TAG, "user " + userId + " does not exist");
+ return;
+ }
+ userId = handleIncomingUser(userId, false, "removeRoleHolderAsUser");
+ getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
+ "removeRoleHolderAsUser");
+
+ getOrCreateControllerService(userId).onRemoveRoleHolder(roleName, packageName, flags,
+ callback);
+ }
+
+ @Override
+ public void clearRoleHoldersAsUser(@NonNull String roleName,
+ @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
@NonNull IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
@@ -495,11 +501,11 @@
Slog.e(LOG_TAG, "user " + userId + " does not exist");
return;
}
- userId = handleIncomingUser(userId, "clearRoleHoldersAsUser", false);
+ userId = handleIncomingUser(userId, false, "clearRoleHoldersAsUser");
getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
"clearRoleHoldersAsUser");
- getOrCreateControllerService(userId).onClearRoleHolders(roleName, callback);
+ getOrCreateControllerService(userId).onClearRoleHolders(roleName, flags, callback);
}
@Override
@@ -510,8 +516,7 @@
Slog.e(LOG_TAG, "user " + userId + " does not exist");
return;
}
- userId = handleIncomingUser(userId, "addOnRoleHoldersChangedListenerAsUser",
- true);
+ userId = handleIncomingUser(userId, true, "addOnRoleHoldersChangedListenerAsUser");
getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS,
"addOnRoleHoldersChangedListenerAsUser");
@@ -528,8 +533,7 @@
Slog.e(LOG_TAG, "user " + userId + " does not exist");
return;
}
- userId = handleIncomingUser(userId, "removeOnRoleHoldersChangedListenerAsUser",
- true);
+ userId = handleIncomingUser(userId, true, "removeOnRoleHoldersChangedListenerAsUser");
getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS,
"removeOnRoleHoldersChangedListenerAsUser");
@@ -548,8 +552,7 @@
"setRoleNamesFromController");
int userId = UserHandle.getCallingUserId();
- RoleUserState userState = getOrCreateUserState(userId);
- userState.setRoleNames(roleNames);
+ getOrCreateUserState(userId).setRoleNames(roleNames);
}
@Override
@@ -562,8 +565,7 @@
"addRoleHolderFromController");
int userId = UserHandle.getCallingUserId();
- RoleUserState userState = getOrCreateUserState(userId);
- return userState.addRoleHolder(roleName, packageName);
+ return getOrCreateUserState(userId).addRoleHolder(roleName, packageName);
}
@Override
@@ -576,8 +578,7 @@
"removeRoleHolderFromController");
int userId = UserHandle.getCallingUserId();
- RoleUserState userState = getOrCreateUserState(userId);
- return userState.removeRoleHolder(roleName, packageName);
+ return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName);
}
@Override
@@ -588,13 +589,12 @@
"getRolesHeldFromController");
int userId = UserHandle.getCallingUserId();
- RoleUserState userState = getOrCreateUserState(userId);
- return userState.getHeldRoles(packageName);
+ return getOrCreateUserState(userId).getHeldRoles(packageName);
}
@CheckResult
- private int handleIncomingUser(@UserIdInt int userId, @NonNull String name,
- boolean allowAll) {
+ private int handleIncomingUser(@UserIdInt int userId, boolean allowAll,
+ @NonNull String name) {
return ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
allowAll, true, name, null);
}
@@ -694,15 +694,51 @@
}
}
- /**
- * Entry point for internal calls into role manager
- */
- private final class RoleManagerServiceInternalImpl extends RoleManagerServiceInternal {
+ private class Internal extends RoleManagerInternal {
@NonNull
@Override
- public ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(@NonNull UserHandle user) {
- return RoleManagerService.this.getRoleHoldersAsUser(user);
+ public ArrayMap<String, ArraySet<String>> getRolesAndHolders(@UserIdInt int userId) {
+ return getOrCreateUserState(userId).getRolesAndHolders();
+ }
+ }
+
+ private class DefaultBrowserProvider implements PackageManagerInternal.DefaultBrowserProvider {
+
+ @Nullable
+ @Override
+ public String getDefaultBrowser(@UserIdInt int userId) {
+ return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
+ RoleManager.ROLE_BROWSER));
+ }
+
+ @Override
+ public boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) {
+ CompletableFuture<Void> future = new CompletableFuture<>();
+ IRoleManagerCallback callback = new IRoleManagerCallback.Stub() {
+ @Override
+ public void onSuccess() {
+ future.complete(null);
+ }
+ @Override
+ public void onFailure() {
+ future.completeExceptionally(new RuntimeException());
+ }
+ };
+ if (packageName != null) {
+ getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER,
+ packageName, 0, callback);
+ } else {
+ getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0,
+ callback);
+ }
+ try {
+ future.get(5, TimeUnit.SECONDS);
+ return true;
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e);
+ return false;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/role/RoleManagerShellCommand.java b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
index b245e98..00021d7 100644
--- a/services/core/java/com/android/server/role/RoleManagerShellCommand.java
+++ b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
@@ -98,13 +98,22 @@
return userId;
}
+ private int getFlagsMaybe() {
+ String flags = getNextArg();
+ if (flags == null) {
+ return 0;
+ }
+ return Integer.parseInt(flags);
+ }
+
private int runAddRoleHolder() throws RemoteException {
int userId = getUserIdMaybe();
String roleName = getNextArgRequired();
String packageName = getNextArgRequired();
+ int flags = getFlagsMaybe();
Callback callback = new Callback();
- mRoleManager.addRoleHolderAsUser(roleName, packageName, userId, callback);
+ mRoleManager.addRoleHolderAsUser(roleName, packageName, flags, userId, callback);
return callback.waitForResult();
}
@@ -112,18 +121,20 @@
int userId = getUserIdMaybe();
String roleName = getNextArgRequired();
String packageName = getNextArgRequired();
+ int flags = getFlagsMaybe();
Callback callback = new Callback();
- mRoleManager.removeRoleHolderAsUser(roleName, packageName, userId, callback);
+ mRoleManager.removeRoleHolderAsUser(roleName, packageName, flags, userId, callback);
return callback.waitForResult();
}
private int runClearRoleHolders() throws RemoteException {
int userId = getUserIdMaybe();
String roleName = getNextArgRequired();
+ int flags = getFlagsMaybe();
Callback callback = new Callback();
- mRoleManager.clearRoleHoldersAsUser(roleName, userId, callback);
+ mRoleManager.clearRoleHoldersAsUser(roleName, flags, userId, callback);
return callback.waitForResult();
}
@@ -134,9 +145,9 @@
pw.println(" help");
pw.println(" Print this help text.");
pw.println();
- pw.println(" add-role-holder [--user USER_ID] ROLE PACKAGE");
- pw.println(" remove-role-holder [--user USER_ID] ROLE PACKAGE");
- pw.println(" clear-role-holders [--user USER_ID] ROLE");
+ pw.println(" add-role-holder [--user USER_ID] ROLE PACKAGE [FLAGS]");
+ pw.println(" remove-role-holder [--user USER_ID] ROLE PACKAGE [FLAGS]");
+ pw.println(" clear-role-holders [--user USER_ID] ROLE [FLAGS]");
pw.println();
}
}
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index 5030e34..c7e3fa4 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -576,13 +576,14 @@
* @return A copy of the roles and their holders
*/
@NonNull
- public ArrayMap<String, ArraySet<String>> getRoleHolders() {
+ public ArrayMap<String, ArraySet<String>> getRolesAndHolders() {
synchronized (mLock) {
return snapshotRolesLocked();
}
}
@GuardedBy("mLock")
+ @NonNull
private ArrayMap<String, ArraySet<String>> snapshotRolesLocked() {
ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
@@ -615,7 +616,8 @@
}
}
- private static @NonNull File getFile(@UserIdInt int userId) {
+ @NonNull
+ private static File getFile(@UserIdInt int userId) {
return new File(Environment.getUserSystemDirectory(userId), ROLES_FILE_NAME);
}
diff --git a/services/core/java/com/android/server/role/TEST_MAPPING b/services/core/java/com/android/server/role/TEST_MAPPING
new file mode 100644
index 0000000..9efd292
--- /dev/null
+++ b/services/core/java/com/android/server/role/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsStatsdHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.cts.statsd.atom.UidAtomTests#testRoleHolder"
+ }
+ ]
+ },
+ {
+ "name": "CtsRoleTestCases"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index 8dd0760..f3b8385 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -22,6 +22,7 @@
import android.os.storage.StorageManager;
import android.util.IntArray;
import android.util.Log;
+import android.util.SparseLongArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.pm.Installer;
@@ -51,11 +52,13 @@
* Creates an app data snapshot for a specified {@code packageName} for {@code installedUsers},
* a specified set of users for whom the package is installed.
*
- * @return a list of users for which the snapshot is pending, usually because data for one or
- * more users is still credential locked.
+ * @return a {@link SnapshotAppDataResult}/
+ * @see SnapshotAppDataResult
*/
- public IntArray snapshotAppData(String packageName, int[] installedUsers) {
+ public SnapshotAppDataResult snapshotAppData(String packageName, int[] installedUsers) {
final IntArray pendingBackups = new IntArray();
+ final SparseLongArray ceSnapshotInodes = new SparseLongArray();
+
for (int user : installedUsers) {
final int storageFlags;
if (isUserCredentialLocked(user)) {
@@ -69,14 +72,17 @@
}
try {
- mInstaller.snapshotAppData(packageName, user, storageFlags);
+ long ceSnapshotInode = mInstaller.snapshotAppData(packageName, user, storageFlags);
+ if ((storageFlags & Installer.FLAG_STORAGE_CE) != 0) {
+ ceSnapshotInodes.put(user, ceSnapshotInode);
+ }
} catch (InstallerException ie) {
Log.e(TAG, "Unable to create app data snapshot for: " + packageName
+ ", userId: " + user, ie);
}
}
- return pendingBackups;
+ return new SnapshotAppDataResult(pendingBackups, ceSnapshotInodes);
}
/**
@@ -138,6 +144,22 @@
}
/**
+ * Deletes an app data data snapshot for a specified package {@code packageName} for a
+ * given {@code user}.
+ */
+ public void destroyAppDataSnapshot(String packageName, int user, long ceSnapshotInode) {
+ int storageFlags = Installer.FLAG_STORAGE_DE;
+ if (ceSnapshotInode > 0) {
+ storageFlags |= Installer.FLAG_STORAGE_CE;
+ }
+ try {
+ mInstaller.destroyAppDataSnapshot(packageName, user, ceSnapshotInode, storageFlags);
+ } catch (InstallerException ie) {
+ Log.e(TAG, "Unable to delete app data snapshot for " + packageName, ie);
+ }
+ }
+
+ /**
* Computes the list of pending backups and restores for {@code userId} given lists of
* available and recent rollbacks. Packages pending backup for the given user are added
* to {@code pendingBackups} and packages pending restore are added to {@code pendingRestores}
@@ -191,16 +213,28 @@
}
/**
- * Commits the list of pending backups and restores for a given {@code userId}.
+ * Commits the list of pending backups and restores for a given {@code userId}. For the pending
+ * backups updates corresponding {@code changedRollbackData} with a mapping from {@code userId}
+ * to a inode of theirs CE user data snapshot.
*/
public void commitPendingBackupAndRestoreForUser(int userId,
- ArrayList<String> pendingBackups, Map<String, RestoreInfo> pendingRestores) {
+ ArrayList<String> pendingBackups, Map<String, RestoreInfo> pendingRestores,
+ List<RollbackData> changedRollbackData) {
if (!pendingBackups.isEmpty()) {
for (String packageName : pendingBackups) {
try {
- mInstaller.snapshotAppData(packageName, userId, Installer.FLAG_STORAGE_CE);
+ long ceSnapshotInode = mInstaller.snapshotAppData(packageName, userId,
+ Installer.FLAG_STORAGE_CE);
+ for (RollbackData data : changedRollbackData) {
+ for (PackageRollbackInfo info : data.packages) {
+ if (info.getPackageName().equals(packageName)) {
+ info.putCeSnapshotInode(userId, ceSnapshotInode);
+ }
+ }
+ }
} catch (InstallerException ie) {
- Log.e(TAG, "Unable to create app data snapshot for: " + packageName, ie);
+ Log.e(TAG, "Unable to create app data snapshot for: " + packageName
+ + ", userId: " + userId, ie);
}
}
}
@@ -233,4 +267,26 @@
return StorageManager.isFileEncryptedNativeOrEmulated()
&& !StorageManager.isUserKeyUnlocked(userId);
}
+
+ /**
+ * Encapsulates a result of {@link #snapshotAppData} method.
+ */
+ public static final class SnapshotAppDataResult {
+
+ /**
+ * A list of users for which the snapshot is pending, usually because data for one or more
+ * users is still credential locked.
+ */
+ public final IntArray pendingBackups;
+
+ /**
+ * A mapping between user and an inode of theirs CE data snapshot.
+ */
+ public final SparseLongArray ceSnapshotInodes;
+
+ public SnapshotAppDataResult(IntArray pendingBackups, SparseLongArray ceSnapshotInodes) {
+ this.pendingBackups = pendingBackups;
+ this.ceSnapshotInodes = ceSnapshotInodes;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/rollback/RollbackData.java b/services/core/java/com/android/server/rollback/RollbackData.java
index a4f3064..fcd5297 100644
--- a/services/core/java/com/android/server/rollback/RollbackData.java
+++ b/services/core/java/com/android/server/rollback/RollbackData.java
@@ -50,6 +50,25 @@
public Instant timestamp;
/**
+ * The session ID for the staged session if this rollback data represents a staged session,
+ * {@code -1} otherwise.
+ */
+ public int stagedSessionId;
+
+ /**
+ * A flag to indicate whether the rollback should be considered available
+ * for use. This will always be true for rollbacks of non-staged sessions.
+ * For rollbacks of staged sessions, this is not set to true until after
+ * the staged session has been applied.
+ */
+ public boolean isAvailable;
+
+ /**
+ * The id of the post-reboot apk session for a staged install, if any.
+ */
+ public int apkSessionId = -1;
+
+ /**
* Whether this Rollback is currently in progress. This field is true from the point
* we commit a {@code PackageInstaller} session containing these packages to the point the
* {@code PackageInstaller} calls into the {@code onFinished} callback.
@@ -57,8 +76,17 @@
// NOTE: All accesses to this field are from the RollbackManager handler thread.
public boolean inProgress = false;
- RollbackData(int rollbackId, File backupDir) {
+ RollbackData(int rollbackId, File backupDir, int stagedSessionId, boolean isAvailable) {
this.rollbackId = rollbackId;
this.backupDir = backupDir;
+ this.stagedSessionId = stagedSessionId;
+ this.isAvailable = isAvailable;
+ }
+
+ /**
+ * Whether the rollback is for rollback of a staged install.
+ */
+ public boolean isStaged() {
+ return stagedSessionId != -1;
}
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerService.java b/services/core/java/com/android/server/rollback/RollbackManagerService.java
index ba6cddd..f7ba9bb 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerService.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerService.java
@@ -44,4 +44,11 @@
public void onUnlockUser(int user) {
mService.onUnlockUser(user);
}
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+ mService.onBootCompleted();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index f5b37b4..95c3f4c 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -43,6 +43,7 @@
import android.util.IntArray;
import android.util.Log;
import android.util.SparseBooleanArray;
+import android.util.SparseLongArray;
import com.android.internal.annotations.GuardedBy;
import com.android.server.LocalServices;
@@ -59,6 +60,7 @@
import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.concurrent.LinkedBlockingQueue;
/**
* Implementation of service that manages APK level rollbacks.
@@ -109,7 +111,7 @@
private final HandlerThread mHandlerThread;
private final Installer mInstaller;
private final RollbackPackageHealthObserver mPackageHealthObserver;
- private final AppDataRollbackHelper mUserdataHelper;
+ private final AppDataRollbackHelper mAppDataRollbackHelper;
RollbackManagerServiceImpl(Context context) {
mContext = context;
@@ -123,7 +125,7 @@
mRollbackStore = new RollbackStore(new File(Environment.getDataDirectory(), "rollback"));
mPackageHealthObserver = new RollbackPackageHealthObserver(mContext);
- mUserdataHelper = new AppDataRollbackHelper(mInstaller);
+ mAppDataRollbackHelper = new AppDataRollbackHelper(mInstaller);
// Kick off loading of the rollback data from strorage in a background
// thread.
@@ -156,6 +158,17 @@
}
}, filter, null, getHandler());
+ // NOTE: A new intent filter is being created here because this broadcast
+ // doesn't use a data scheme ("package") like above.
+ IntentFilter sessionUpdatedFilter = new IntentFilter();
+ sessionUpdatedFilter.addAction(PackageInstaller.ACTION_SESSION_UPDATED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onStagedSessionUpdated(intent);
+ }
+ }, sessionUpdatedFilter, null, getHandler());
+
IntentFilter enableRollbackFilter = new IntentFilter();
enableRollbackFilter.addAction(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
try {
@@ -209,9 +222,10 @@
List<RollbackInfo> rollbacks = new ArrayList<>();
for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
RollbackData data = mAvailableRollbacks.get(i);
- // TODO: Pass the correct value for isStaged instead of
- // assuming always false.
- rollbacks.add(new RollbackInfo(data.rollbackId, data.packages, false));
+ if (data.isAvailable) {
+ rollbacks.add(new RollbackInfo(data.rollbackId,
+ data.packages, data.isStaged()));
+ }
}
return new ParceledListSlice<>(rollbacks);
}
@@ -311,20 +325,32 @@
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
parentParams.setAllowDowngrade(true);
parentParams.setMultiPackage();
+ if (data.isStaged()) {
+ parentParams.setStaged();
+ }
+
int parentSessionId = packageInstaller.createSession(parentParams);
PackageInstaller.Session parentSession = packageInstaller.openSession(parentSessionId);
for (PackageRollbackInfo info : data.packages) {
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- String installerPackageName = pm.getInstallerPackageName(info.getPackageName());
- if (installerPackageName == null) {
- sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE,
- "Cannot find installer package");
- return;
+ // TODO: We can't get the installerPackageName for apex
+ // (b/123920130). Is it okay to ignore the installer package
+ // for apex?
+ if (!info.isApex()) {
+ String installerPackageName = pm.getInstallerPackageName(info.getPackageName());
+ if (installerPackageName != null) {
+ params.setInstallerPackageName(installerPackageName);
+ }
}
- params.setInstallerPackageName(installerPackageName);
params.setAllowDowngrade(true);
+ if (data.isStaged()) {
+ params.setStaged();
+ }
+ if (info.isApex()) {
+ params.setInstallAsApex();
+ }
int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
@@ -364,11 +390,9 @@
return;
}
- // TODO: Set the correct values for isStaged and
- // committedSessionId.
addRecentlyExecutedRollback(new RollbackInfo(
- data.rollbackId, data.packages, false, causePackages,
- PackageInstaller.SessionInfo.INVALID_ID));
+ data.rollbackId, data.packages, data.isStaged(),
+ causePackages, parentSessionId));
sendSuccess(statusReceiver);
Intent broadcast = new Intent(Intent.ACTION_ROLLBACK_COMMITTED);
@@ -423,7 +447,7 @@
for (PackageRollbackInfo info : data.packages) {
if (info.getPackageName().equals(packageName)) {
iter.remove();
- mRollbackStore.deleteAvailableRollback(data);
+ deleteRollback(data);
break;
}
}
@@ -438,13 +462,13 @@
final List<RollbackData> changed;
synchronized (mLock) {
ensureRollbackDataLoadedLocked();
- changed = mUserdataHelper.computePendingBackupsAndRestores(userId,
+ changed = mAppDataRollbackHelper.computePendingBackupsAndRestores(userId,
pendingBackupPackages, pendingRestorePackages, mAvailableRollbacks,
mRecentlyExecutedRollbacks);
}
- mUserdataHelper.commitPendingBackupAndRestoreForUser(userId,
- pendingBackupPackages, pendingRestorePackages);
+ mAppDataRollbackHelper.commitPendingBackupAndRestoreForUser(userId,
+ pendingBackupPackages, pendingRestorePackages, changed);
for (RollbackData rd : changed) {
try {
@@ -460,6 +484,47 @@
});
}
+ void onBootCompleted() {
+ getHandler().post(() -> {
+ // Check to see if any staged sessions with rollback enabled have
+ // been applied.
+ List<RollbackData> staged = new ArrayList<>();
+ synchronized (mLock) {
+ ensureRollbackDataLoadedLocked();
+ for (RollbackData data : mAvailableRollbacks) {
+ if (data.stagedSessionId != -1) {
+ staged.add(data);
+ }
+ }
+ }
+
+ for (RollbackData data : staged) {
+ PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
+ PackageInstaller.SessionInfo session = installer.getSessionInfo(
+ data.stagedSessionId);
+ if (session != null) {
+ if (session.isSessionApplied()) {
+ synchronized (mLock) {
+ data.isAvailable = true;
+ }
+ try {
+ mRollbackStore.saveAvailableRollback(data);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Unable to save rollback info for : "
+ + data.rollbackId, ioe);
+ }
+ } else if (session.isSessionFailed()) {
+ // TODO: Do we need to remove this from
+ // mAvailableRollbacks, or is it okay to leave as
+ // unavailable until the next reboot when it will go
+ // away on its own?
+ deleteRollback(data);
+ }
+ }
+ }
+ });
+ }
+
/**
* Load rollback data from storage if it has not already been loaded.
* After calling this funciton, mAvailableRollbacks and
@@ -525,7 +590,7 @@
info.getVersionRolledBackFrom(),
installedVersion)) {
iter.remove();
- mRollbackStore.deleteAvailableRollback(data);
+ deleteRollback(data);
break;
}
}
@@ -632,9 +697,13 @@
Iterator<RollbackData> iter = mAvailableRollbacks.iterator();
while (iter.hasNext()) {
RollbackData data = iter.next();
+ if (!data.isAvailable) {
+ continue;
+ }
+
if (!now.isBefore(data.timestamp.plusMillis(ROLLBACK_LIFETIME_DURATION_MILLIS))) {
iter.remove();
- mRollbackStore.deleteAvailableRollback(data);
+ deleteRollback(data);
} else if (oldest == null || oldest.isAfter(data.timestamp)) {
oldest = data.timestamp;
}
@@ -695,6 +764,7 @@
// ourselves.
PackageInstaller.SessionInfo session = null;
+ int parentSessionId = -1;
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
for (PackageInstaller.SessionInfo info : installer.getAllSessions()) {
if (info.isMultiPackage()) {
@@ -702,12 +772,14 @@
PackageInstaller.SessionInfo child = installer.getSessionInfo(childId);
if (sessionMatchesForEnableRollback(child, installFlags, newPackageCodePath)) {
// TODO: Check we only have one matching session?
+ parentSessionId = info.getSessionId();
session = child;
break;
}
}
} else if (sessionMatchesForEnableRollback(info, installFlags, newPackageCodePath)) {
// TODO: Check we only have one matching session?
+ parentSessionId = info.getSessionId();
session = info;
break;
}
@@ -718,7 +790,59 @@
return false;
}
- return enableRollbackForSession(session, installedUsers);
+ // Check to see if this is the apk session for a staged session with
+ // rollback enabled.
+ // TODO: This check could be made more efficient.
+ RollbackData rd = null;
+ synchronized (mLock) {
+ ensureRollbackDataLoadedLocked();
+ for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
+ RollbackData data = mAvailableRollbacks.get(i);
+ if (data.apkSessionId == parentSessionId) {
+ rd = data;
+ break;
+ }
+ }
+ }
+
+ if (rd != null) {
+ // This is the apk session for a staged session. We have already
+ // backed up the apks, we just need to do user data backup.
+ PackageParser.PackageLite newPackage = null;
+ try {
+ newPackage = PackageParser.parsePackageLite(
+ new File(session.resolvedBaseCodePath), 0);
+ } catch (PackageParser.PackageParserException e) {
+ Log.e(TAG, "Unable to parse new package", e);
+ return false;
+ }
+ String packageName = newPackage.packageName;
+ for (PackageRollbackInfo info : rd.packages) {
+ if (info.getPackageName().equals(packageName)) {
+ AppDataRollbackHelper.SnapshotAppDataResult rs =
+ mAppDataRollbackHelper.snapshotAppData(packageName, installedUsers);
+ info.getPendingBackups().addAll(rs.pendingBackups);
+ for (int i = 0; i < rs.ceSnapshotInodes.size(); i++) {
+ info.putCeSnapshotInode(rs.ceSnapshotInodes.keyAt(i),
+ rs.ceSnapshotInodes.valueAt(i));
+ }
+ try {
+ mRollbackStore.saveAvailableRollback(rd);
+ } catch (IOException ioe) {
+ // TODO: Hopefully this is okay because we will try
+ // again to save the rollback when the staged session
+ // is applied. Just so long as the device doesn't
+ // reboot before then.
+ Log.e(TAG, "Unable to save rollback info for : " + rd.rollbackId, ioe);
+ }
+ return true;
+ }
+ }
+ Log.e(TAG, "Unable to find package in apk session");
+ return false;
+ }
+
+ return enableRollbackForSession(session, installedUsers, true);
}
/**
@@ -727,7 +851,7 @@
* the child sessions, not the parent session.
*/
private boolean enableRollbackForSession(PackageInstaller.SessionInfo session,
- int[] installedUsers) {
+ int[] installedUsers, boolean snapshotUserData) {
// TODO: Don't attempt to enable rollback for split installs.
final int installFlags = session.installFlags;
if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
@@ -749,15 +873,17 @@
}
String packageName = newPackage.packageName;
- Log.i(TAG, "Enabling rollback for install of " + packageName);
+ Log.i(TAG, "Enabling rollback for install of " + packageName
+ + ", session:" + session.sessionId);
VersionedPackage newVersion = new VersionedPackage(packageName, newPackage.versionCode);
+ final boolean isApex = ((installFlags & PackageManager.INSTALL_APEX) != 0);
// Get information about the currently installed package.
PackageManager pm = mContext.getPackageManager();
PackageInfo pkgInfo = null;
try {
- pkgInfo = pm.getPackageInfo(packageName, 0);
+ pkgInfo = pm.getPackageInfo(packageName, isApex ? PackageManager.MATCH_APEX : 0);
} catch (PackageManager.NameNotFoundException e) {
// TODO: Support rolling back fresh package installs rather than
// fail here. Test this case.
@@ -768,17 +894,18 @@
VersionedPackage installedVersion = new VersionedPackage(packageName,
pkgInfo.getLongVersionCode());
- final boolean isApex = ((installFlags & PackageManager.INSTALL_APEX) != 0);
- final IntArray pendingBackups;
- if (isApex) {
- pendingBackups = IntArray.wrap(new int[0]);
+ final AppDataRollbackHelper.SnapshotAppDataResult result;
+ if (snapshotUserData && !isApex) {
+ result = mAppDataRollbackHelper.snapshotAppData(packageName, installedUsers);
} else {
- pendingBackups = mUserdataHelper.snapshotAppData(packageName, installedUsers);
+ result = new AppDataRollbackHelper.SnapshotAppDataResult(IntArray.wrap(new int[0]),
+ new SparseLongArray());
}
- // TODO: Record if this is an apex or not.
PackageRollbackInfo info = new PackageRollbackInfo(newVersion, installedVersion,
- pendingBackups, new ArrayList<>());
+ result.pendingBackups, new ArrayList<>(), isApex, IntArray.wrap(installedUsers),
+ result.ceSnapshotInodes);
+
RollbackData data;
try {
int childSessionId = session.getSessionId();
@@ -786,6 +913,7 @@
if (parentSessionId == PackageInstaller.SessionInfo.INVALID_ID) {
parentSessionId = childSessionId;
}
+
synchronized (mLock) {
// TODO: no need to add to mChildSessions if childSessionId is
// the same as parentSessionId.
@@ -793,7 +921,12 @@
data = mPendingRollbacks.get(parentSessionId);
if (data == null) {
int rollbackId = allocateRollbackIdLocked();
- data = mRollbackStore.createAvailableRollback(rollbackId);
+ if (session.isStaged()) {
+ data = mRollbackStore.createPendingStagedRollback(rollbackId,
+ parentSessionId);
+ } else {
+ data = mRollbackStore.createAvailableRollback(rollbackId);
+ }
mPendingRollbacks.put(parentSessionId, data);
}
data.packages.add(info);
@@ -822,9 +955,8 @@
getHandler().post(() -> {
final RollbackData rollbackData = getRollbackForPackage(packageName);
for (int userId : userIds) {
- final boolean changedRollbackData = mUserdataHelper.restoreAppData(packageName,
- rollbackData, userId, appId, ceDataInode, seInfo);
-
+ final boolean changedRollbackData = mAppDataRollbackHelper.restoreAppData(
+ packageName, rollbackData, userId, appId, ceDataInode, seInfo);
// We've updated metadata about this rollback, so save it to flash.
if (changedRollbackData) {
try {
@@ -844,6 +976,82 @@
});
}
+ @Override
+ public boolean notifyStagedSession(int sessionId) {
+ final LinkedBlockingQueue<Boolean> result = new LinkedBlockingQueue<>();
+
+ // NOTE: We post this runnable on the RollbackManager's binder thread because we'd prefer
+ // to preserve the invariant that all operations that modify state happen there.
+ getHandler().post(() -> {
+ PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
+
+ final PackageInstaller.SessionInfo session = installer.getSessionInfo(sessionId);
+ if (session == null) {
+ Log.e(TAG, "No matching install session for: " + sessionId);
+ result.offer(false);
+ return;
+ }
+
+ if (!session.isMultiPackage()) {
+ if (!enableRollbackForSession(session, null, false)) {
+ Log.e(TAG, "Unable to enable rollback for session: " + sessionId);
+ result.offer(false);
+ return;
+ }
+ } else {
+ for (int childSessionId : session.getChildSessionIds()) {
+ final PackageInstaller.SessionInfo childSession =
+ installer.getSessionInfo(childSessionId);
+ if (childSession == null) {
+ Log.e(TAG, "No matching child install session for: " + childSessionId);
+ result.offer(false);
+ return;
+ }
+ if (!enableRollbackForSession(childSession, null, false)) {
+ Log.e(TAG, "Unable to enable rollback for session: " + sessionId);
+ result.offer(false);
+ return;
+ }
+ }
+ }
+
+ result.offer(true);
+ });
+
+ try {
+ return result.take();
+ } catch (InterruptedException ie) {
+ Log.e(TAG, "Interrupted while waiting for notifyStagedSession response");
+ return false;
+ }
+ }
+
+ @Override
+ public void notifyStagedApkSession(int originalSessionId, int apkSessionId) {
+ getHandler().post(() -> {
+ RollbackData rd = null;
+ synchronized (mLock) {
+ ensureRollbackDataLoadedLocked();
+ for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
+ RollbackData data = mAvailableRollbacks.get(i);
+ if (data.stagedSessionId == originalSessionId) {
+ data.apkSessionId = apkSessionId;
+ rd = data;
+ break;
+ }
+ }
+ }
+
+ if (rd != null) {
+ try {
+ mRollbackStore.saveAvailableRollback(rd);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Unable to save rollback info for : " + rd.rollbackId, ioe);
+ }
+ }
+ });
+ }
+
/**
* Gets the version of the package currently installed.
* Returns null if the package is not currently installed.
@@ -852,7 +1060,7 @@
PackageManager pm = mContext.getPackageManager();
PackageInfo pkgInfo = null;
try {
- pkgInfo = pm.getPackageInfo(packageName, 0);
+ pkgInfo = pm.getPackageInfo(packageName, PackageManager.MATCH_APEX);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
@@ -881,60 +1089,100 @@
@Override
public void onFinished(int sessionId, boolean success) {
- RollbackData data = null;
- synchronized (mLock) {
- Integer parentSessionId = mChildSessions.remove(sessionId);
- if (parentSessionId != null) {
- sessionId = parentSessionId;
- }
- data = mPendingRollbacks.remove(sessionId);
+ // If sessionId refers to a staged session, we can't deal with it here since the
+ // session might take an unbounded amount of time to become "ready" after the package
+ // installer session is committed. In those cases, we respond to it in response to
+ // a session ready broadcast.
+ PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
+ PackageInstaller.SessionInfo si = packageInstaller.getSessionInfo(sessionId);
+ if (si != null && si.isStaged()) {
+ return;
}
- if (data != null) {
- if (success) {
- try {
- data.timestamp = Instant.now();
+ completeEnableRollback(sessionId, success);
+ }
+ }
- mRollbackStore.saveAvailableRollback(data);
- synchronized (mLock) {
- // Note: There is a small window of time between when
- // the session has been committed by the package
- // manager and when we make the rollback available
- // here. Presumably the window is small enough that
- // nobody will want to roll back the newly installed
- // package before we make the rollback available.
- // TODO: We'll lose the rollback data if the
- // device reboots between when the session is
- // committed and this point. Revisit this after
- // adding support for rollback of staged installs.
- ensureRollbackDataLoadedLocked();
- mAvailableRollbacks.add(data);
- }
- // TODO(zezeozue): Provide API to explicitly start observing instead
- // of doing this for all rollbacks. If we do this for all rollbacks,
- // should document in PackageInstaller.SessionParams#setEnableRollback
- // After enabling and commiting any rollback, observe packages and
- // prepare to rollback if packages crashes too frequently.
- List<String> packages = new ArrayList<>();
- for (int i = 0; i < data.packages.size(); i++) {
- packages.add(data.packages.get(i).getPackageName());
- }
- mPackageHealthObserver.startObservingHealth(packages,
- ROLLBACK_LIFETIME_DURATION_MILLIS);
- scheduleExpiration(ROLLBACK_LIFETIME_DURATION_MILLIS);
- } catch (IOException e) {
- Log.e(TAG, "Unable to enable rollback", e);
- mRollbackStore.deleteAvailableRollback(data);
+ private void completeEnableRollback(int sessionId, boolean success) {
+ RollbackData data = null;
+ synchronized (mLock) {
+ Integer parentSessionId = mChildSessions.remove(sessionId);
+ if (parentSessionId != null) {
+ sessionId = parentSessionId;
+ }
+
+ data = mPendingRollbacks.remove(sessionId);
+ }
+
+ if (data != null) {
+ if (success) {
+ try {
+ data.timestamp = Instant.now();
+
+ mRollbackStore.saveAvailableRollback(data);
+ synchronized (mLock) {
+ // Note: There is a small window of time between when
+ // the session has been committed by the package
+ // manager and when we make the rollback available
+ // here. Presumably the window is small enough that
+ // nobody will want to roll back the newly installed
+ // package before we make the rollback available.
+ // TODO: We'll lose the rollback data if the
+ // device reboots between when the session is
+ // committed and this point. Revisit this after
+ // adding support for rollback of staged installs.
+ ensureRollbackDataLoadedLocked();
+ mAvailableRollbacks.add(data);
}
- } else {
- // The install session was aborted, clean up the pending
- // install.
- mRollbackStore.deleteAvailableRollback(data);
+ // TODO(zezeozue): Provide API to explicitly start observing instead
+ // of doing this for all rollbacks. If we do this for all rollbacks,
+ // should document in PackageInstaller.SessionParams#setEnableRollback
+ // After enabling and commiting any rollback, observe packages and
+ // prepare to rollback if packages crashes too frequently.
+ List<String> packages = new ArrayList<>();
+ for (int i = 0; i < data.packages.size(); i++) {
+ packages.add(data.packages.get(i).getPackageName());
+ }
+ mPackageHealthObserver.startObservingHealth(packages,
+ ROLLBACK_LIFETIME_DURATION_MILLIS);
+ scheduleExpiration(ROLLBACK_LIFETIME_DURATION_MILLIS);
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to enable rollback", e);
+ deleteRollback(data);
}
+ } else {
+ // The install session was aborted, clean up the pending
+ // install.
+ deleteRollback(data);
}
}
}
+ private void onStagedSessionUpdated(Intent intent) {
+ PackageInstaller.SessionInfo pi = intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
+ if (pi == null) {
+ Log.e(TAG, "Missing intent extra: " + PackageInstaller.EXTRA_SESSION);
+ return;
+ }
+
+ if (pi.isStaged()) {
+ if (!pi.isSessionFailed()) {
+ // TODO: The session really isn't "enabled" at this point, since more work might
+ // be required post reboot.
+ // TODO: We need to make this case consistent with the call from onFinished.
+ // Ideally, we'd call completeEnableRollback excatly once per multi-package session
+ // with the parentSessionId only.
+ completeEnableRollback(pi.sessionId, pi.isSessionReady());
+ } else {
+ // TODO: Clean up the saved rollback when the session fails. This may need to be
+ // unified with the case where things fail post reboot.
+ }
+ } else {
+ Log.e(TAG, "Received onStagedSessionUpdated for: " + pi.sessionId
+ + ", which isn't staged");
+ }
+ }
+
/*
* Returns the RollbackData, if any, for an available rollback that would
* roll back the given package. Note: This assumes we have at most one
@@ -947,7 +1195,7 @@
ensureRollbackDataLoadedLocked();
for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
RollbackData data = mAvailableRollbacks.get(i);
- if (getPackageRollbackInfo(data, packageName) != null) {
+ if (data.isAvailable && getPackageRollbackInfo(data, packageName) != null) {
return data;
}
}
@@ -966,7 +1214,7 @@
ensureRollbackDataLoadedLocked();
for (int i = 0; i < mAvailableRollbacks.size(); ++i) {
RollbackData data = mAvailableRollbacks.get(i);
- if (data.rollbackId == rollbackId) {
+ if (data.isAvailable && data.rollbackId == rollbackId) {
return data;
}
}
@@ -1004,4 +1252,17 @@
throw new IOException("Failed to allocate rollback ID");
}
+
+ private void deleteRollback(RollbackData rollbackData) {
+ for (PackageRollbackInfo info : rollbackData.packages) {
+ IntArray installedUsers = info.getInstalledUsers();
+ SparseLongArray ceSnapshotInodes = info.getCeSnapshotInodes();
+ for (int i = 0; i < installedUsers.size(); i++) {
+ int userId = installedUsers.get(i);
+ mAppDataRollbackHelper.destroyAppDataSnapshot(info.getPackageName(), userId,
+ ceSnapshotInodes.get(userId, 0));
+ }
+ }
+ mRollbackStore.deleteAvailableRollback(rollbackData);
+ }
}
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 8e04160..3c6a54a 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -26,6 +26,7 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.text.TextUtils;
+import android.util.Pair;
import android.util.Slog;
import android.util.StatsLog;
@@ -64,10 +65,8 @@
return PackageHealthObserverImpact.USER_IMPACT_NONE;
}
- RollbackInfo rollback =
- getAvailableMainlineRollback(mContext.getSystemService(RollbackManager.class),
- failedPackage, moduleMetadataPackage);
- if (rollback == null) {
+ if (getAvailableRollback(mContext.getSystemService(RollbackManager.class),
+ failedPackage, moduleMetadataPackage) == null) {
// Don't handle the notification, no rollbacks available for the package
return PackageHealthObserverImpact.USER_IMPACT_NONE;
}
@@ -84,38 +83,46 @@
}
RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
- RollbackInfo rollback = getAvailableMainlineRollback(rollbackManager,
+ Pair<RollbackInfo, Boolean> rollbackPair = getAvailableRollback(rollbackManager,
failedPackage, moduleMetadataPackage);
- if (rollback == null) {
- Slog.w(TAG, "Expected rollback but no mainline rollback found for package: [ "
+ if (rollbackPair == null) {
+ Slog.w(TAG, "Expected rollback but no valid rollback found for package: [ "
+ failedPackage.getPackageName() + "] with versionCode: ["
+ failedPackage.getVersionCode() + "]");
return false;
}
+ RollbackInfo rollback = rollbackPair.first;
+ // We only log mainline package rollbacks, so check if rollback contains the
+ // module metadata provider, if it does, the rollback is a mainline rollback
+ boolean hasModuleMetadataPackage = rollbackPair.second;
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
+ if (hasModuleMetadataPackage) {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
+ }
LocalIntentReceiver rollbackReceiver = new LocalIntentReceiver((Intent result) -> {
- int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
- RollbackManager.STATUS_FAILURE);
- if (status == RollbackManager.STATUS_SUCCESS) {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
- } else {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
+ if (hasModuleMetadataPackage) {
+ int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
+ RollbackManager.STATUS_FAILURE);
+ if (status == RollbackManager.STATUS_SUCCESS) {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
+ } else {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
+ }
}
});
mHandler.post(() ->
rollbackManager.commitRollback(rollback.getRollbackId(),
- Collections.singletonList(moduleMetadataPackage),
+ Collections.singletonList(failedPackage),
rollbackReceiver.getIntentSender()));
// Assume rollback executed successfully
return true;
@@ -134,7 +141,7 @@
PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs);
}
- private RollbackInfo getAvailableMainlineRollback(RollbackManager rollbackManager,
+ private Pair<RollbackInfo, Boolean> getAvailableRollback(RollbackManager rollbackManager,
VersionedPackage failedPackage, VersionedPackage moduleMetadataPackage) {
for (RollbackInfo rollback : rollbackManager.getAvailableRollbacks()) {
// We only rollback mainline packages, so check if rollback contains the
@@ -149,8 +156,8 @@
&& packageRollback.getVersionRolledBackFrom().getVersionCode()
== failedPackage.getVersionCode();
}
- if (hasModuleMetadataPackage && hasFailedPackage) {
- return rollback;
+ if (hasFailedPackage) {
+ return new Pair<RollbackInfo, Boolean>(rollback, hasModuleMetadataPackage);
}
}
return null;
@@ -159,7 +166,7 @@
private VersionedPackage getModuleMetadataPackage() {
String packageName = mContext.getResources().getString(
R.string.config_defaultModuleMetadataProvider);
- if (!TextUtils.isEmpty(packageName)) {
+ if (TextUtils.isEmpty(packageName)) {
return null;
}
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 1069530..be904ea 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -23,6 +23,7 @@
import android.content.rollback.RollbackInfo;
import android.util.IntArray;
import android.util.Log;
+import android.util.SparseLongArray;
import libcore.io.IoUtils;
@@ -160,6 +161,28 @@
return restoreInfos;
}
+ private static @NonNull JSONArray ceSnapshotInodesToJson(
+ @NonNull SparseLongArray ceSnapshotInodes) throws JSONException {
+ JSONArray array = new JSONArray();
+ for (int i = 0; i < ceSnapshotInodes.size(); i++) {
+ JSONObject entryJson = new JSONObject();
+ entryJson.put("userId", ceSnapshotInodes.keyAt(i));
+ entryJson.put("ceSnapshotInode", ceSnapshotInodes.valueAt(i));
+ array.put(entryJson);
+ }
+ return array;
+ }
+
+ private static @NonNull SparseLongArray ceSnapshotInodesFromJson(JSONArray json)
+ throws JSONException {
+ SparseLongArray ceSnapshotInodes = new SparseLongArray(json.length());
+ for (int i = 0; i < json.length(); i++) {
+ JSONObject entry = json.getJSONObject(i);
+ ceSnapshotInodes.append(entry.getInt("userId"), entry.getLong("ceSnapshotInode"));
+ }
+ return ceSnapshotInodes;
+ }
+
/**
* Reads the list of recently executed rollbacks from persistent storage.
*/
@@ -201,7 +224,13 @@
*/
RollbackData createAvailableRollback(int rollbackId) throws IOException {
File backupDir = new File(mAvailableRollbacksDir, Integer.toString(rollbackId));
- return new RollbackData(rollbackId, backupDir);
+ return new RollbackData(rollbackId, backupDir, -1, true);
+ }
+
+ RollbackData createPendingStagedRollback(int rollbackId, int stagedSessionId)
+ throws IOException {
+ File backupDir = new File(mAvailableRollbacksDir, Integer.toString(rollbackId));
+ return new RollbackData(rollbackId, backupDir, stagedSessionId, false);
}
/**
@@ -240,6 +269,9 @@
dataJson.put("rollbackId", data.rollbackId);
dataJson.put("packages", toJson(data.packages));
dataJson.put("timestamp", data.timestamp.toString());
+ dataJson.put("stagedSessionId", data.stagedSessionId);
+ dataJson.put("isAvailable", data.isAvailable);
+ dataJson.put("apkSessionId", data.apkSessionId);
PrintWriter pw = new PrintWriter(new File(data.backupDir, "rollback.json"));
pw.println(dataJson.toString());
@@ -254,8 +286,6 @@
* rollback.
*/
void deleteAvailableRollback(RollbackData data) {
- // TODO(narayan): Make sure we delete the userdata snapshot along with the backup of the
- // actual app.
removeFile(data.backupDir);
}
@@ -299,9 +329,13 @@
IoUtils.readFileAsString(rollbackJsonFile.getAbsolutePath()));
int rollbackId = dataJson.getInt("rollbackId");
- RollbackData data = new RollbackData(rollbackId, backupDir);
+ int stagedSessionId = dataJson.getInt("stagedSessionId");
+ boolean isAvailable = dataJson.getBoolean("isAvailable");
+ RollbackData data = new RollbackData(rollbackId, backupDir,
+ stagedSessionId, isAvailable);
data.packages.addAll(packageRollbackInfosFromJson(dataJson.getJSONArray("packages")));
data.timestamp = Instant.parse(dataJson.getString("timestamp"));
+ data.apkSessionId = dataJson.getInt("apkSessionId");
return data;
} catch (JSONException | DateTimeParseException e) {
throw new IOException(e);
@@ -328,9 +362,15 @@
IntArray pendingBackups = info.getPendingBackups();
List<RestoreInfo> pendingRestores = info.getPendingRestores();
+ IntArray installedUsers = info.getInstalledUsers();
json.put("pendingBackups", convertToJsonArray(pendingBackups));
json.put("pendingRestores", convertToJsonArray(pendingRestores));
+ json.put("isApex", info.isApex());
+
+ json.put("installedUsers", convertToJsonArray(installedUsers));
+ json.put("ceSnapshotInodes", ceSnapshotInodesToJson(info.getCeSnapshotInodes()));
+
return json;
}
@@ -345,8 +385,14 @@
final ArrayList<RestoreInfo> pendingRestores = convertToRestoreInfoArray(
json.getJSONArray("pendingRestores"));
+ final boolean isApex = json.getBoolean("isApex");
+
+ final IntArray installedUsers = convertToIntArray(json.getJSONArray("installedUsers"));
+ final SparseLongArray ceSnapshotInodes = ceSnapshotInodesFromJson(
+ json.getJSONArray("ceSnapshotInodes"));
+
return new PackageRollbackInfo(versionRolledBackFrom, versionRolledBackTo,
- pendingBackups, pendingRestores);
+ pendingBackups, pendingRestores, isApex, installedUsers, ceSnapshotInodes);
}
private JSONArray versionedPackagesToJson(List<VersionedPackage> packages)
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 48e64338..3586772 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -118,7 +118,7 @@
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.am.MemoryStatUtil.MemoryStat;
-import com.android.server.role.RoleManagerServiceInternal;
+import com.android.server.role.RoleManagerInternal;
import com.android.server.storage.DiskStatsFileLogger;
import com.android.server.storage.DiskStatsLoggingService;
@@ -1780,8 +1780,8 @@
long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
final long elapsedMillis = SystemClock.elapsedRealtime();
- // Fails every 10 buckets.
- if (mDebugFailingElapsedClockPullCount++ % 10 == 0) {
+ // Fails every 5 buckets.
+ if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
mDebugFailingElapsedClockPreviousValue = elapsedMillis;
throw new RuntimeException("Failing debug elapsed clock");
}
@@ -1867,16 +1867,16 @@
long callingToken = Binder.clearCallingIdentity();
try {
PackageManager pm = mContext.getPackageManager();
- RoleManagerServiceInternal rm =
- LocalServices.getService(RoleManagerServiceInternal.class);
+ RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
int numUsers = users.size();
for (int userNum = 0; userNum < numUsers; userNum++) {
- UserHandle user = users.get(userNum).getUserHandle();
+ int userId = users.get(userNum).getUserHandle().getIdentifier();
- ArrayMap<String, ArraySet<String>> roles = rm.getRoleHoldersAsUser(user);
+ ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(
+ userId);
int numRoles = roles.size();
for (int roleNum = 0; roleNum < numRoles; roleNum++) {
@@ -1889,7 +1889,7 @@
PackageInfo pkg;
try {
- pkg = pm.getPackageInfoAsUser(holderName, 0, user.getIdentifier());
+ pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Role holder " + holderName + " not found");
return;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index d932a40..0493ae90 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -1280,12 +1280,12 @@
@Override
public void onNotificationSmartSuggestionsAdded(String key, int smartReplyCount,
- int smartActionCount, boolean generatedByAssistant) {
+ int smartActionCount, boolean generatedByAssistant, boolean editBeforeSending) {
enforceStatusBarService();
long identity = Binder.clearCallingIdentity();
try {
mNotificationDelegate.onNotificationSmartSuggestionsAdded(key, smartReplyCount,
- smartActionCount, generatedByAssistant);
+ smartActionCount, generatedByAssistant, editBeforeSending);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1293,13 +1293,13 @@
@Override
public void onNotificationSmartReplySent(
- String key, int replyIndex, CharSequence reply, boolean generatedByAssistant,
- int notificationLocation) throws RemoteException {
+ String key, int replyIndex, CharSequence reply, int notificationLocation,
+ boolean modifiedBeforeSending) throws RemoteException {
enforceStatusBarService();
long identity = Binder.clearCallingIdentity();
try {
mNotificationDelegate.onNotificationSmartReplySent(key, replyIndex, reply,
- generatedByAssistant, notificationLocation);
+ notificationLocation, modifiedBeforeSending);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 1163d39..057b53e 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -128,6 +128,8 @@
private final WatchLogHandler mWatchLogHandler;
+ private IBinder.DeathRecipient mDeathRecipient;
+
public TvInputManagerService(Context context) {
super(context);
@@ -674,6 +676,7 @@
if (sessionToken == userState.mainSessionToken) {
setMainLocked(sessionToken, false, callingUid, userId);
}
+ sessionState.session.asBinder().unlinkToDeath(sessionState, 0);
sessionState.session.release();
}
} catch (RemoteException | SessionNotFoundException e) {
@@ -709,6 +712,7 @@
clientState.sessionTokens.remove(sessionToken);
if (clientState.isEmpty()) {
userState.clientStateMap.remove(sessionState.client.asBinder());
+ sessionState.client.asBinder().unlinkToDeath(clientState, 0);
}
}
@@ -1002,17 +1006,19 @@
synchronized (mLock) {
final UserState userState = getOrCreateUserStateLocked(resolvedUserId);
userState.callbackSet.add(callback);
- try {
- callback.asBinder().linkToDeath(new IBinder.DeathRecipient() {
- @Override
- public void binderDied() {
- synchronized (mLock) {
- if (userState.callbackSet != null) {
- userState.callbackSet.remove(callback);
- }
+ mDeathRecipient = new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ synchronized (mLock) {
+ if (userState.callbackSet != null) {
+ userState.callbackSet.remove(callback);
}
}
- }, 0);
+ }
+ };
+
+ try {
+ callback.asBinder().linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
Slog.e(TAG, "client process has already died", e);
}
@@ -1031,6 +1037,7 @@
synchronized (mLock) {
UserState userState = getOrCreateUserStateLocked(resolvedUserId);
userState.callbackSet.remove(callback);
+ callback.asBinder().unlinkToDeath(mDeathRecipient, 0);
}
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 744efab..332df95 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -1067,8 +1067,9 @@
// Figure out the value returned when access is allowed
final int allowedResult;
- if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
- // If we're extending a persistable grant, then we need to return
+ if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0
+ || pi.forceUriPermissions) {
+ // If we're extending a persistable grant or need to force, then we need to return
// "targetUid" so that we always create a grant data structure to
// support take/release APIs
allowedResult = targetUid;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 071dde7..b0ef8a0 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2243,9 +2243,12 @@
synchronized (mLock) {
mInAmbientMode = inAmbientMode;
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
+ final boolean hasConnection = data != null && data.connection != null;
+ final WallpaperInfo info = hasConnection ? data.connection.mInfo : null;
+
// The wallpaper info is null for image wallpaper, also use the engine in this case.
- if (data != null && data.connection != null && (data.connection.mInfo == null
- || data.connection.mInfo.supportsAmbientMode())) {
+ if (hasConnection && (info == null && isAodImageWallpaperEnabled()
+ || info != null && info.supportsAmbientMode())) {
// TODO(multi-display) Extends this method with specific display.
engine = data.connection.getDisplayConnectorOrCreate(DEFAULT_DISPLAY).mEngine;
} else {
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index 5b3a2fe..62421ac 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -1436,9 +1436,10 @@
}
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
+ super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
proto.write(ID, mDisplayId);
proto.write(SINGLE_TASK_INSTANCE, mSingleTaskInstance);
final ActivityStack focusedStack = getFocusedStack();
@@ -1453,7 +1454,7 @@
}
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
- stack.writeToProto(proto, STACKS);
+ stack.writeToProto(proto, STACKS, logLevel);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index ad76af6..ef40648 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3467,7 +3467,7 @@
* {@code ActivityRecordProto} is the outer-most proto data.
*/
void writeToProto(ProtoOutputStream proto) {
- super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
+ super.writeToProto(proto, CONFIGURATION_CONTAINER, WindowTraceLogLevel.ALL);
writeIdentifierToProto(proto, IDENTIFIER);
proto.write(STATE, mState.toString());
proto.write(VISIBLE, visible);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 6fc2014..6f07be8 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -5655,13 +5655,14 @@
return shouldSleepActivities() || mService.mShuttingDown;
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
+ super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
proto.write(ID, mStackId);
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
- task.writeToProto(proto, TASKS);
+ task.writeToProto(proto, TASKS, logLevel);
}
if (mResumedActivity != null) {
mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index c0fe6e9..0a3c2fb 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -97,7 +97,6 @@
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.ResumeActivityItem;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -467,7 +466,7 @@
* initialized. So we initialize our wakelocks afterwards.
*/
void initPowerManagement() {
- mPowerManager = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
+ mPowerManager = mService.mContext.getSystemService(PowerManager.class);
mGoingToSleep = mPowerManager
.newWakeLock(PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
mLaunchingActivity = mPowerManager.newWakeLock(PARTIAL_WAKE_LOCK, "*launch*");
@@ -2456,7 +2455,8 @@
}
void wakeUp(String reason) {
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.am:TURN_ON:" + reason);
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_APPLICATION,
+ "android.server.am:TURN_ON:" + reason);
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 1d71d876..678a896 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -753,8 +753,8 @@
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"shouldAbortBackgroundActivityStart");
abortBackgroundStart = shouldAbortBackgroundActivityStart(callingUid, callingPid,
- callingPackage, realCallingUid, callerApp, originatingPendingIntent,
- allowBackgroundActivityStart, intent);
+ callingPackage, realCallingUid, realCallingPid, callerApp,
+ originatingPendingIntent, allowBackgroundActivityStart, intent);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -914,22 +914,14 @@
}
private boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
- final String callingPackage, int realCallingUid, WindowProcessController callerApp,
- PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart,
- Intent intent) {
+ final String callingPackage, int realCallingUid, int realCallingPid,
+ WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
+ boolean allowBackgroundActivityStart, Intent intent) {
// don't abort for the most important UIDs
if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID
|| callingUid == Process.NFC_UID) {
return false;
}
- // don't abort if the callerApp has any visible activity
- if (callerApp != null && callerApp.hasForegroundActivities()) {
- return false;
- }
- // don't abort if the callerApp is instrumenting with background activity starts privileges
- if (callerApp != null && callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) {
- return false;
- }
// don't abort if the callingUid is in the foreground or is a persistent system process
final int callingUidProcState = mService.getUidStateLocked(callingUid);
final boolean callingUidHasAnyVisibleWindow =
@@ -967,9 +959,26 @@
return false;
}
}
- // don't abort if the caller is currently temporarily whitelisted
- if (callerApp != null && callerApp.areBackgroundActivityStartsAllowed()) {
- return false;
+ // If we don't have callerApp at this point, no caller was provided to startActivity().
+ // That's the case for PendingIntent-based starts, since the creator's process might not be
+ // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
+ // caller, so that we can make the decision based on its foreground/whitelisted state.
+ if (callerApp == null) {
+ callerApp = mService.getProcessController(realCallingPid, realCallingUid);
+ }
+ if (callerApp != null) {
+ // don't abort if the callerApp has any visible activity
+ if (callerApp.hasForegroundActivities()) {
+ return false;
+ }
+ // don't abort if the callerApp is instrumenting with background activity starts privs
+ if (callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) {
+ return false;
+ }
+ // don't abort if the caller is currently temporarily whitelisted
+ if (callerApp.areBackgroundActivityStartsAllowed()) {
+ return false;
+ }
}
// don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
@@ -996,6 +1005,7 @@
+ "; originatingPendingIntent: " + originatingPendingIntent
+ "; isBgStartWhitelisted: " + allowBackgroundActivityStart
+ "; intent: " + intent
+ + "; callerApp: " + callerApp
+ "]");
// log aborted activity start to TRON
if (mService.isActivityStartsLoggingEnabled()) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 14c4814..7aa3481 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -5666,6 +5666,20 @@
return null;
}
+ WindowProcessController getProcessController(int pid, int uid) {
+ final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
+ for (int i = pmap.size()-1; i >= 0; i--) {
+ final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
+ for (int j = procs.size() - 1; j >= 0; j--) {
+ final WindowProcessController proc = procs.valueAt(j);
+ if (UserHandle.isApp(uid) && proc.getPid() == pid && proc.mUid == uid) {
+ return proc;
+ }
+ }
+ }
+ return null;
+ }
+
int getUidStateLocked(int uid) {
return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
}
@@ -6587,7 +6601,8 @@
// The output proto of "activity --proto activities"
// is ActivityManagerServiceDumpActivitiesProto
mRootActivityContainer.writeToProto(proto,
- ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
+ ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR,
+ WindowTraceLogLevel.ALL);
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
index ed029cd..6fcc331 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -158,7 +158,9 @@
final long token = proto.start(fieldId);
proto.write(WIDTH, mWidth);
proto.write(HEIGHT, mHeight);
- mSurfaceAnimator.writeToProto(proto, SURFACE_ANIMATOR);
+ if (mSurfaceAnimator.isAnimating()) {
+ mSurfaceAnimator.writeToProto(proto, SURFACE_ANIMATOR);
+ }
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 29ba166..3246a87 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2885,10 +2885,16 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ // Critical log level logs only visible elements to mitigate performance overheard
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
+ return;
+ }
+
final long token = proto.start(fieldId);
writeNameToProto(proto, NAME);
- super.writeToProto(proto, WINDOW_TOKEN, trim);
+ super.writeToProto(proto, WINDOW_TOKEN, logLevel);
proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
@@ -2907,7 +2913,7 @@
proto.write(ALL_DRAWN, allDrawn);
proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
proto.write(REMOVED, removed);
- if (startingWindow != null){
+ if (startingWindow != null) {
startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
}
proto.write(STARTING_DISPLAYED, startingDisplayed);
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index d86cf0f..97062a6 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -331,6 +331,10 @@
return boundsChange;
}
+ boolean hasOverrideConfiguration() {
+ return mHasOverrideConfiguration;
+ }
+
public WindowConfiguration getWindowConfiguration() {
return mFullConfiguration.windowConfiguration;
}
@@ -551,18 +555,24 @@
* @param proto Stream to write the ConfigurationContainer object to.
* @param fieldId Field Id of the ConfigurationContainer as defined in the parent
* message.
- * @param trim If true, reduce amount of data written.
+ * @param logLevel Determines the amount of data to be written to the Protobuf.
* @hide
*/
@CallSuper
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
- final long token = proto.start(fieldId);
- if (!trim || mHasOverrideConfiguration) {
- mRequestedOverrideConfiguration.writeToProto(proto, OVERRIDE_CONFIGURATION);
+ protected void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ // Critical log level logs only visible elements to mitigate performance overheard
+ if (logLevel != WindowTraceLogLevel.ALL && !mHasOverrideConfiguration) {
+ return;
}
- if (!trim) {
- mFullConfiguration.writeToProto(proto, FULL_CONFIGURATION);
- mMergedOverrideConfiguration.writeToProto(proto, MERGED_OVERRIDE_CONFIGURATION);
+
+ final long token = proto.start(fieldId);
+ mRequestedOverrideConfiguration.writeToProto(proto, OVERRIDE_CONFIGURATION,
+ logLevel != WindowTraceLogLevel.CRITICAL);
+ if (logLevel == WindowTraceLogLevel.ALL) {
+ mFullConfiguration.writeToProto(proto, FULL_CONFIGURATION, false /* critical */);
+ mMergedOverrideConfiguration.writeToProto(proto, MERGED_OVERRIDE_CONFIGURATION,
+ false /* critical */);
}
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 9fb922f..7a8fd49 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -20,8 +20,10 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -31,14 +33,11 @@
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.InsetsState.TYPE_IME;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.View.GONE;
-import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowManager.DOCKED_BOTTOM;
import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.DOCKED_TOP;
@@ -173,7 +172,6 @@
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
import android.view.View;
-import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
@@ -1160,14 +1158,12 @@
@Override
boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
ConfigurationContainer requestingContainer) {
- final int previousRotation = mRotation;
final Configuration config = updateOrientationFromAppTokens(
getRequestedOverrideConfiguration(), freezeDisplayToken, false);
- // This event is considered handled iff a configuration propagation is triggered, because
- // that's the only place lower level containers check if they need to do something to this
- // request. The only guaranteed signal is that the display is rotated to a different
- // orientation (i.e. rotating 180 degrees doesn't count).
- final boolean handled = (mRotation - previousRotation) % 2 != 0;
+ // If display rotation class tells us that it doesn't consider app requested orientation,
+ // this display won't rotate just because of an app changes its requested orientation. Thus
+ // it indicates that this display chooses not to handle this request.
+ final boolean handled = getDisplayRotation().respectAppRequestedOrientation();
if (config == null) {
return handled;
}
@@ -1189,6 +1185,11 @@
return handled;
}
+ @Override
+ boolean handlesOrientationChangeFromDescendant() {
+ return getDisplayRotation().respectAppRequestedOrientation();
+ }
+
/**
* Determine the new desired orientation of this display.
*
@@ -1369,8 +1370,7 @@
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
+ " selected orientation " + lastOrientation
- + ", got rotation " + rotation + " which has "
- + " metrics");
+ + ", got rotation " + rotation);
if (oldRotation == rotation) {
// No change.
@@ -2679,27 +2679,33 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ // Critical log level logs only visible elements to mitigate performance overheard
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
+ return;
+ }
+
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, trim);
+ super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
proto.write(ID, mDisplayId);
for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
- stack.writeToProto(proto, STACKS, trim);
+ stack.writeToProto(proto, STACKS, logLevel);
}
mDividerControllerLocked.writeToProto(proto, DOCKED_STACK_DIVIDER_CONTROLLER);
mPinnedStackControllerLocked.writeToProto(proto, PINNED_STACK_CONTROLLER);
for (int i = mAboveAppWindowsContainers.getChildCount() - 1; i >= 0; --i) {
final WindowToken windowToken = mAboveAppWindowsContainers.getChildAt(i);
- windowToken.writeToProto(proto, ABOVE_APP_WINDOWS, trim);
+ windowToken.writeToProto(proto, ABOVE_APP_WINDOWS, logLevel);
}
for (int i = mBelowAppWindowsContainers.getChildCount() - 1; i >= 0; --i) {
final WindowToken windowToken = mBelowAppWindowsContainers.getChildAt(i);
- windowToken.writeToProto(proto, BELOW_APP_WINDOWS, trim);
+ windowToken.writeToProto(proto, BELOW_APP_WINDOWS, logLevel);
}
for (int i = mImeWindowsContainers.getChildCount() - 1; i >= 0; --i) {
final WindowToken windowToken = mImeWindowsContainers.getChildAt(i);
- windowToken.writeToProto(proto, IME_WINDOWS, trim);
+ windowToken.writeToProto(proto, IME_WINDOWS, logLevel);
}
proto.write(DPI, mBaseDisplayDensity);
mDisplayInfo.writeToProto(proto, DISPLAY_INFO);
@@ -3244,6 +3250,7 @@
mInputMethodTarget = target;
mInputMethodTargetWaitingAnim = targetWaitingAnim;
assignWindowLayers(false /* setLayoutNeeded */);
+ mInsetsStateController.onImeTargetChanged(target);
}
boolean getNeedsMenu(WindowState top, WindowManagerPolicy.WindowState bottom) {
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index bc165dc..5f341ee 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -329,6 +329,15 @@
return mFixedToUserRotation;
}
+ /**
+ * Returns {@code true} if this display rotation takes app requested orientation into
+ * consideration; {@code false} otherwise. For the time being the only case where this is {@code
+ * false} is when {@link #isFixedToUserRotation()} is {@code true}.
+ */
+ boolean respectAppRequestedOrientation() {
+ return !mFixedToUserRotation;
+ }
+
public int getLandscapeRotation() {
return mLandscapeRotation;
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 66666e6..f67b11b 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -26,6 +26,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Point;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsState;
@@ -135,6 +136,12 @@
mTmpRect.inset(mWin.mGivenContentInsets);
}
mSource.setFrame(mTmpRect);
+ if (mControl != null) {
+ final Rect frame = mWin.getWindowFrames().mFrame;
+ if (mControl.setSurfacePosition(frame.left, frame.top)) {
+ mStateController.notifyControlChanged(mControllingWin);
+ }
+ }
setServerVisible(mWin.wouldBeVisibleIfPolicyIgnored() && mWin.mPolicyVisibility
&& !mWin.mGivenInsetsPending);
}
@@ -157,7 +164,8 @@
mWin.startAnimation(mDisplayContent.getPendingTransaction(), mAdapter,
!mClientVisible /* hidden */);
mControllingWin = target;
- mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash);
+ mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash,
+ new Point(mWin.getWindowFrames().mFrame.left, mWin.getWindowFrames().mFrame.top));
}
boolean onInsetsModified(WindowState caller, InsetsSource modifiedSource) {
@@ -213,7 +221,8 @@
public void startAnimation(SurfaceControl animationLeash, Transaction t,
OnAnimationFinishedCallback finishCallback) {
mCapturedLeash = animationLeash;
- t.setPosition(mCapturedLeash, mSource.getFrame().left, mSource.getFrame().top);
+ final Rect frame = mWin.getWindowFrames().mFrame;
+ t.setPosition(mCapturedLeash, frame.left, frame.top);
}
@Override
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index bb0cbb1..afae9c4 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -204,6 +204,11 @@
mTypeWinControlMap.put(type, win);
}
+ void notifyControlChanged(WindowState target) {
+ mPendingControlChanged.add(target);
+ notifyPendingInsetsControlChanged();
+ }
+
private void notifyPendingInsetsControlChanged() {
if (mPendingControlChanged.isEmpty()) {
return;
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index ecab1f1..fb5b1d8 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -2369,12 +2369,13 @@
return printed;
}
- void writeToProto(ProtoOutputStream proto, long fieldId) {
+ protected void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
+ super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx);
- activityDisplay.writeToProto(proto, DISPLAYS);
+ activityDisplay.writeToProto(proto, DISPLAYS, logLevel);
}
mStackSupervisor.getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER);
// TODO(b/111541062): Update tests to look for resumed activities on all displays
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 8fb7947..300cd17 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -999,17 +999,22 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
+ return;
+ }
+
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, trim);
+ super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
if (mWmService.mDisplayReady) {
final int count = mChildren.size();
for (int i = 0; i < count; ++i) {
final DisplayContent displayContent = mChildren.get(i);
- displayContent.writeToProto(proto, DISPLAYS, trim);
+ displayContent.writeToProto(proto, DISPLAYS, logLevel);
}
}
- if (!trim) {
+ if (logLevel == WindowTraceLogLevel.ALL) {
forAllWindows((w) -> {
w.writeIdentifierToProto(proto, WINDOWS);
}, true);
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 1a8a911..c600e0f 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -325,7 +325,7 @@
if (mAnimation != null) {
mAnimation.writeToProto(proto, ANIMATION_ADAPTER);
}
- if (mLeash != null){
+ if (mLeash != null) {
mLeash.writeToProto(proto, LEASH);
}
proto.write(ANIMATION_START_DELAYED, mAnimationStartDelayed);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7a86c96..888d741 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -316,6 +316,7 @@
mRotation = rotation;
+ updateSurfacePosition();
return boundsChange;
}
@@ -358,6 +359,7 @@
} else {
mOverrideDisplayedBounds.setEmpty();
}
+ updateSurfacePosition();
}
/**
@@ -795,13 +797,18 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
+ return;
+ }
+
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, trim);
+ super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
proto.write(ID, mTaskId);
for (int i = mChildren.size() - 1; i >= 0; i--) {
final AppWindowToken appWindowToken = mChildren.get(i);
- appWindowToken.writeToProto(proto, APP_WINDOW_TOKENS, trim);
+ appWindowToken.writeToProto(proto, APP_WINDOW_TOKENS, logLevel);
}
proto.write(FILLS_PARENT, matchParentBounds());
getBounds().writeToProto(proto, BOUNDS);
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 0529ed1..69f0012 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -2197,11 +2197,15 @@
// In FULLSCREEN mode, always start with empty bounds to indicate "fill parent"
outOverrideBounds.setEmpty();
+ final boolean parentHandlesOrientationChange = mTask != null
+ && mTask.getParent() != null
+ && mTask.getParent().handlesOrientationChangeFromDescendant();
// If the task or its top activity requires a different orientation, make it fit the
// available bounds by scaling down its bounds.
int forcedOrientation = getTopActivityRequestedOrientation();
if (forcedOrientation != ORIENTATION_UNDEFINED
- && forcedOrientation != newParentConfig.orientation) {
+ && forcedOrientation != newParentConfig.orientation
+ && !parentHandlesOrientationChange) {
final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
final int parentWidth = parentBounds.width();
final int parentHeight = parentBounds.height();
@@ -2476,9 +2480,14 @@
return toString();
}
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
+ return;
+ }
+
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
+ super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
proto.write(ID, taskId);
for (int i = mActivities.size() - 1; i >= 0; i--) {
ActivityRecord activity = mActivities.get(i);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 6d4bcdc..53cd5ea 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1340,12 +1340,17 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
+ return;
+ }
+
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, trim);
+ super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
proto.write(ID, mStackId);
for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
- mChildren.get(taskNdx).writeToProto(proto, TASKS, trim);
+ mChildren.get(taskNdx).writeToProto(proto, TASKS, logLevel);
}
proto.write(FILLS_PARENT, matchParentBounds());
getRawBounds().writeToProto(proto, BOUNDS);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index f330569..a054148 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -45,6 +45,7 @@
import android.view.SurfaceControl.Builder;
import android.view.SurfaceSession;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.wm.SurfaceAnimator.Animatable;
@@ -714,6 +715,21 @@
}
/**
+ * Check if this container or its parent will handle orientation changes from descendants. It's
+ * different from the return value of {@link #onDescendantOrientationChanged(IBinder,
+ * ConfigurationContainer)} in the sense that the return value of this method tells if this
+ * container or its parent will handle the request eventually, while the return value of the
+ * other method is if it handled the request synchronously.
+ *
+ * @return {@code true} if it handles or will handle orientation change in the future; {@code
+ * false} if it won't handle the change at anytime.
+ */
+ boolean handlesOrientationChangeFromDescendant() {
+ final WindowContainer parent = getParent();
+ return parent != null && parent.handlesOrientationChangeFromDescendant();
+ }
+
+ /**
* Calls {@link #setOrientation(int, IBinder, ActivityRecord)} with {@code null} to the last 2
* parameters.
*
@@ -1096,17 +1112,25 @@
*
* @param proto Stream to write the WindowContainer object to.
* @param fieldId Field Id of the WindowContainer as defined in the parent message.
- * @param trim If true, reduce the amount of data written.
+ * @param logLevel Determines the amount of data to be written to the Protobuf.
* @hide
*/
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ boolean isVisible = isVisible();
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible) {
+ return;
+ }
+
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, trim);
+ super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
proto.write(ORIENTATION, mOrientation);
- proto.write(VISIBLE, isVisible());
- mSurfaceAnimator.writeToProto(proto, SURFACE_ANIMATOR);
+ proto.write(VISIBLE, isVisible);
+ if (mSurfaceAnimator.isAnimating()) {
+ mSurfaceAnimator.writeToProto(proto, SURFACE_ANIMATOR);
+ }
proto.end(token);
}
@@ -1323,6 +1347,11 @@
mLastSurfacePosition.set(mTmpPos.x, mTmpPos.y);
}
+ @VisibleForTesting
+ Point getLastSurfacePosition() {
+ return mLastSurfacePosition;
+ }
+
/**
* Displayed bounds specify where to display this container at. It differs from bounds during
* certain operations (like animation or interactive dragging).
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 975e62a..3bb6608 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -841,11 +841,8 @@
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
synchronized (mGlobalLock) {
- try {
- traceStateLocked(where);
- } finally {
- SurfaceControl.closeTransaction();
- }
+ SurfaceControl.closeTransaction();
+ traceStateLocked(where);
}
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -4436,7 +4433,8 @@
if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing focus: " + lastFocus);
lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
}
- } break;
+ break;
+ }
case REPORT_LOSING_FOCUS: {
final DisplayContent displayContent = (DisplayContent) msg.obj;
@@ -4453,7 +4451,8 @@
losers.get(i));
losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
}
- } break;
+ break;
+ }
case WINDOW_FREEZE_TIMEOUT: {
final DisplayContent displayContent = (DisplayContent) msg.obj;
@@ -4617,12 +4616,13 @@
break;
}
- case NOTIFY_ACTIVITY_DRAWN:
+ case NOTIFY_ACTIVITY_DRAWN: {
try {
mActivityTaskManager.notifyActivityDrawn((IBinder) msg.obj);
} catch (RemoteException e) {
}
break;
+ }
case ALL_WINDOWS_DRAWN: {
Runnable callback;
synchronized (mGlobalLock) {
@@ -4659,8 +4659,8 @@
}
}
}
+ break;
}
- break;
case CHECK_IF_BOOT_ANIMATION_FINISHED: {
final boolean bootAnimationComplete;
synchronized (mGlobalLock) {
@@ -4670,15 +4670,15 @@
if (bootAnimationComplete) {
performEnableScreen();
}
+ break;
}
- break;
case RESET_ANR_MESSAGE: {
synchronized (mGlobalLock) {
mLastANRState = null;
}
mAtmInternal.clearSavedANRState();
+ break;
}
- break;
case WALLPAPER_DRAW_PENDING_TIMEOUT: {
synchronized (mGlobalLock) {
final WallpaperController wallpaperController =
@@ -4688,16 +4688,16 @@
mWindowPlacerLocked.performSurfacePlacement();
}
}
+ break;
}
- break;
case UPDATE_DOCKED_STACK_DIVIDER: {
synchronized (mGlobalLock) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
displayContent.getDockedDividerController().reevaluateVisibility(false);
displayContent.adjustForImeIfNeeded();
}
+ break;
}
- break;
case WINDOW_REPLACEMENT_TIMEOUT: {
synchronized (mGlobalLock) {
for (int i = mWindowReplacementTimeouts.size() - 1; i >= 0; i--) {
@@ -4706,8 +4706,8 @@
}
mWindowReplacementTimeouts.clear();
}
+ break;
}
- break;
case WINDOW_HIDE_TIMEOUT: {
final WindowState window = (WindowState) msg.obj;
synchronized (mGlobalLock) {
@@ -4727,44 +4727,44 @@
window.setDisplayLayoutNeeded();
mWindowPlacerLocked.performSurfacePlacement();
}
+ break;
}
- break;
case RESTORE_POINTER_ICON: {
synchronized (mGlobalLock) {
restorePointerIconLocked((DisplayContent)msg.obj, msg.arg1, msg.arg2);
}
+ break;
}
- break;
case SEAMLESS_ROTATION_TIMEOUT: {
final DisplayContent displayContent = (DisplayContent) msg.obj;
synchronized (mGlobalLock) {
displayContent.onSeamlessRotationTimeout();
}
+ break;
}
- break;
case SET_HAS_OVERLAY_UI: {
mAmInternal.setHasOverlayUi(msg.arg1, msg.arg2 == 1);
+ break;
}
- break;
case SET_RUNNING_REMOTE_ANIMATION: {
mAmInternal.setRunningRemoteAnimation(msg.arg1, msg.arg2 == 1);
+ break;
}
- break;
case ANIMATION_FAILSAFE: {
synchronized (mGlobalLock) {
if (mRecentsAnimationController != null) {
mRecentsAnimationController.scheduleFailsafe();
}
}
+ break;
}
- break;
case RECOMPUTE_FOCUS: {
synchronized (mGlobalLock) {
updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
true /* updateInputWindows */);
}
+ break;
}
- break;
}
if (DEBUG_WINDOW_TRACE) {
Slog.v(TAG_WM, "handleMessage: exit");
@@ -5742,11 +5742,11 @@
* {@link com.android.server.wm.WindowManagerServiceDumpProto}.
*
* @param proto Stream to write the WindowContainer object to.
- * @param trim If true, reduce the amount of data written.
+ * @param logLevel Determines the amount of data to be written to the Protobuf.
*/
- void writeToProtoLocked(ProtoOutputStream proto, boolean trim) {
+ void writeToProtoLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {
mPolicy.writeToProto(proto, POLICY);
- mRoot.writeToProto(proto, ROOT_WINDOW_CONTAINER, trim);
+ mRoot.writeToProto(proto, ROOT_WINDOW_CONTAINER, logLevel);
final DisplayContent topFocusedDisplayContent = mRoot.getTopFocusedDisplayContent();
if (topFocusedDisplayContent.mCurrentFocus != null) {
topFocusedDisplayContent.mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW);
@@ -5765,13 +5765,13 @@
}
void traceStateLocked(String where) {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "traceStateLocked");
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "traceStateLocked");
try {
mWindowTracing.traceStateLocked(where, this);
} catch (Exception e) {
Log.wtf(TAG, "Exception while tracing state", e);
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
@@ -6074,7 +6074,7 @@
if (useProto) {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
synchronized (mGlobalLock) {
- writeToProtoLocked(proto, false /* trim */);
+ writeToProtoLocked(proto, WindowTraceLogLevel.ALL);
}
proto.flush();
return;
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 0fb900a..465f413 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -986,7 +986,7 @@
@Override
public String toString() {
- return mOwner.toString();
+ return mOwner != null ? mOwner.toString() : null;
}
public void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 05c19b5..85b251a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -156,6 +156,7 @@
import android.os.Debug;
import android.os.IBinder;
import android.os.PowerManager;
+import android.os.PowerManager.WakeReason;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -611,7 +612,7 @@
}
interface PowerManagerWrapper {
- void wakeUp(long time, String reason);
+ void wakeUp(long time, @WakeReason int reason, String details);
boolean isInteractive();
@@ -623,8 +624,8 @@
this(service, s, c, token, parentWindow, appOp, seq, a, viewVisibility, ownerId,
ownerCanAddInternalSystemWindow, new PowerManagerWrapper() {
@Override
- public void wakeUp(long time, String reason) {
- service.mPowerManager.wakeUp(time, reason);
+ public void wakeUp(long time, @WakeReason int reason, String details) {
+ service.mPowerManager.wakeUp(time, reason, details);
}
@Override
@@ -2253,7 +2254,7 @@
Slog.v(TAG, "Relayout window turning screen on: " + this);
}
mPowerManagerWrapper.wakeUp(SystemClock.uptimeMillis(),
- "android.server.wm:TURN_ON");
+ PowerManager.WAKE_REASON_APPLICATION, "android.server.wm:SCREEN_ON_FLAG");
}
if (mAppToken != null) {
@@ -3221,9 +3222,15 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ boolean isVisible = isVisible();
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible) {
+ return;
+ }
+
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, trim);
+ super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
writeIdentifierToProto(proto, IDENTIFIER);
proto.write(DISPLAY_ID, getDisplayId());
proto.write(STACK_ID, getStackId());
@@ -3235,7 +3242,7 @@
mWinAnimator.writeToProto(proto, ANIMATOR);
proto.write(ANIMATING_EXIT, mAnimatingExit);
for (int i = 0; i < mChildren.size(); i++) {
- mChildren.get(i).writeToProto(proto, CHILD_WINDOWS, trim);
+ mChildren.get(i).writeToProto(proto, CHILD_WINDOWS, logLevel);
}
proto.write(REQUESTED_WIDTH, mRequestedWidth);
proto.write(REQUESTED_HEIGHT, mRequestedHeight);
@@ -3247,7 +3254,7 @@
proto.write(DESTROYING, mDestroying);
proto.write(REMOVED, mRemoved);
proto.write(IS_ON_SCREEN, isOnScreen());
- proto.write(IS_VISIBLE, isVisible());
+ proto.write(IS_VISIBLE, isVisible);
proto.write(PENDING_SEAMLESS_ROTATION, mPendingSeamlessRotate != null);
proto.write(FINISHED_SEAMLESS_ROTATION_FRAME, mFinishSeamlessRotateFrameNumber);
proto.write(FORCE_SEAMLESS_ROTATION, mForceSeamlesslyRotate);
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 9c13782..3b9b8ba 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -270,13 +270,18 @@
@CallSuper
@Override
- public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId,
+ @WindowTraceLogLevel int logLevel) {
+ if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
+ return;
+ }
+
final long token = proto.start(fieldId);
- super.writeToProto(proto, WINDOW_CONTAINER, trim);
+ super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
proto.write(HASH_CODE, System.identityHashCode(this));
for (int i = 0; i < mChildren.size(); i++) {
final WindowState w = mChildren.get(i);
- w.writeToProto(proto, WINDOWS, trim);
+ w.writeToProto(proto, WINDOWS, logLevel);
}
proto.write(HIDDEN, mHidden);
proto.write(WAITING_TO_SHOW, waitingToShow);
diff --git a/services/core/java/com/android/server/wm/WindowTraceBuffer.java b/services/core/java/com/android/server/wm/WindowTraceBuffer.java
index 2f672f2..e4461ea 100644
--- a/services/core/java/com/android/server/wm/WindowTraceBuffer.java
+++ b/services/core/java/com/android/server/wm/WindowTraceBuffer.java
@@ -40,7 +40,7 @@
private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
final Object mBufferLock = new Object();
- final Queue<byte[]> mBuffer = new ArrayDeque<>();
+ final Queue<ProtoOutputStream> mBuffer = new ArrayDeque<>();
final File mTraceFile;
int mBufferSize;
private final int mBufferCapacity;
@@ -64,8 +64,7 @@
* than the buffer size.
*/
void add(ProtoOutputStream proto) {
- byte[] protoBytes = proto.getBytes();
- int protoLength = protoBytes.length;
+ int protoLength = proto.getRawSize();
if (protoLength > mBufferCapacity) {
throw new IllegalStateException("Trace object too large for the buffer. Buffer size:"
+ mBufferCapacity + " Object size: " + protoLength);
@@ -73,7 +72,7 @@
synchronized (mBufferLock) {
boolean canAdd = canAdd(protoLength);
if (canAdd) {
- mBuffer.offer(protoBytes);
+ mBuffer.add(proto);
mBufferSize += protoLength;
}
mBufferLock.notify();
@@ -97,7 +96,7 @@
@VisibleForTesting
boolean contains(byte[] other) {
return mBuffer.stream()
- .anyMatch(p -> Arrays.equals(p, other));
+ .anyMatch(p -> Arrays.equals(p.getBytes(), other));
}
private void initTraceFile() throws IOException {
diff --git a/services/core/java/com/android/server/wm/WindowTraceLogLevel.java b/services/core/java/com/android/server/wm/WindowTraceLogLevel.java
new file mode 100644
index 0000000..2165c66
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowTraceLogLevel.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@IntDef({
+ WindowTraceLogLevel.ALL,
+ WindowTraceLogLevel.TRIM,
+ WindowTraceLogLevel.CRITICAL,
+})
+@Retention(RetentionPolicy.SOURCE)
+@interface WindowTraceLogLevel{
+ /**
+ * Logs all elements with maximum amount of information.
+ *
+ * Used to store the current window manager state when generating a bug report
+ */
+ int ALL = 0;
+ /**
+ * Logs all elements but doesn't write all configuration data
+ *
+ * Default log level for manually activated Winscope traces
+ */
+ int TRIM = 1;
+ /**
+ * Logs only visible elements, with the minimum amount of performance overhead
+ *
+ * Default log level for continuous traces
+ */
+ int CRITICAL = 2;
+}
diff --git a/services/core/java/com/android/server/wm/WindowTraceQueueBuffer.java b/services/core/java/com/android/server/wm/WindowTraceQueueBuffer.java
index eaedde9..5888b7a 100644
--- a/services/core/java/com/android/server/wm/WindowTraceQueueBuffer.java
+++ b/services/core/java/com/android/server/wm/WindowTraceQueueBuffer.java
@@ -19,6 +19,7 @@
import static android.os.Build.IS_USER;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
@@ -67,19 +68,18 @@
private void loop() throws IOException, InterruptedException {
while (!mCancel) {
- byte[] proto;
+ ProtoOutputStream proto;
synchronized (mBufferLock) {
mBufferLock.wait();
-
proto = mBuffer.poll();
if (proto != null) {
- mBufferSize -= proto.length;
+ mBufferSize -= proto.getRawSize();
}
}
-
if (proto != null) {
try (OutputStream os = new FileOutputStream(mTraceFile, true)) {
- os.write(proto);
+ byte[] protoBytes = proto.getBytes();
+ os.write(protoBytes);
}
}
}
@@ -97,7 +97,6 @@
mCancel = true;
mBufferLock.notify();
}
-
if (mConsumerThread != null) {
mConsumerThread.join();
mConsumerThread = null;
diff --git a/services/core/java/com/android/server/wm/WindowTraceRingBuffer.java b/services/core/java/com/android/server/wm/WindowTraceRingBuffer.java
index 7c69f23..77d30be 100644
--- a/services/core/java/com/android/server/wm/WindowTraceRingBuffer.java
+++ b/services/core/java/com/android/server/wm/WindowTraceRingBuffer.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import android.util.proto.ProtoOutputStream;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -49,20 +51,20 @@
synchronized (mBufferLock) {
try (OutputStream os = new FileOutputStream(mTraceFile, true)) {
while (!mBuffer.isEmpty()) {
- byte[] proto;
- proto = mBuffer.poll();
- mBufferSize -= proto.length;
- os.write(proto);
+ ProtoOutputStream proto = mBuffer.poll();
+ mBufferSize -= proto.getRawSize();
+ byte[] protoBytes = proto.getBytes();
+ os.write(protoBytes);
}
}
}
}
private void discardOldest() {
- byte[] item = mBuffer.poll();
+ ProtoOutputStream item = mBuffer.poll();
if (item == null) {
throw new IllegalStateException("No element to discard from buffer");
}
- mBufferSize -= item.length;
+ mBufferSize -= item.getRawSize();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index 4c9a917..8b1ffa8 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -53,6 +53,7 @@
private WindowTraceBuffer mTraceBuffer;
+ private @WindowTraceLogLevel int mWindowTraceLogLevel = WindowTraceLogLevel.TRIM;
private boolean mContinuousMode;
private boolean mEnabled;
private volatile boolean mEnabledLockFree;
@@ -118,6 +119,8 @@
+ "trace is restarted.");
}
mContinuousMode = continuous;
+ mWindowTraceLogLevel = (continuous) ? WindowTraceLogLevel.CRITICAL :
+ WindowTraceLogLevel.TRIM;
}
private void appendTraceEntry(ProtoOutputStream proto) {
@@ -166,22 +169,26 @@
return;
}
- ProtoOutputStream os = new ProtoOutputStream();
- long tokenOuter = os.start(ENTRY);
- os.write(ELAPSED_REALTIME_NANOS, SystemClock.elapsedRealtimeNanos());
- os.write(WHERE, where);
-
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "writeToProtoLocked");
+ Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "writeToBufferLocked");
try {
- long tokenInner = os.start(WINDOW_MANAGER_SERVICE);
- service.writeToProtoLocked(os, true /* trim */);
- os.end(tokenInner);
+ ProtoOutputStream os = new ProtoOutputStream();
+ long tokenOuter = os.start(ENTRY);
+ os.write(ELAPSED_REALTIME_NANOS, SystemClock.elapsedRealtimeNanos());
+ os.write(WHERE, where);
+
+ Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "writeToProtoLocked");
+ try {
+ long tokenInner = os.start(WINDOW_MANAGER_SERVICE);
+ service.writeToProtoLocked(os, mWindowTraceLogLevel);
+ os.end(tokenInner);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ }
+ os.end(tokenOuter);
+ appendTraceEntry(os);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
- os.end(tokenOuter);
- appendTraceEntry(os);
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
/**
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 3729eaf..5c7b287 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -127,6 +127,7 @@
"android.frameworks.schedulerservice@1.0",
"android.frameworks.sensorservice@1.0",
"android.system.suspend@1.0",
+ "suspend_control_aidl_interface-cpp",
],
static_libs: [
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 024760d..5c19ad3 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -32,8 +32,8 @@
#include <android/hardware/power/1.0/IPower.h>
#include <android/hardware/power/1.1/IPower.h>
#include <android/hardware/power/stats/1.0/IPowerStats.h>
-#include <android/system/suspend/1.0/ISystemSuspend.h>
-#include <android/system/suspend/1.0/ISystemSuspendCallback.h>
+#include <android/system/suspend/BnSuspendCallback.h>
+#include <android/system/suspend/ISuspendControlService.h>
#include <android_runtime/AndroidRuntime.h>
#include <jni.h>
@@ -46,14 +46,14 @@
using android::hardware::Return;
using android::hardware::Void;
+using android::system::suspend::BnSuspendCallback;
using android::hardware::power::V1_0::PowerStatePlatformSleepState;
using android::hardware::power::V1_0::PowerStateVoter;
using android::hardware::power::V1_0::Status;
using android::hardware::power::V1_1::PowerStateSubsystem;
using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
using android::hardware::hidl_vec;
-using android::system::suspend::V1_0::ISystemSuspend;
-using android::system::suspend::V1_0::ISystemSuspendCallback;
+using android::system::suspend::ISuspendControlService;
using IPowerV1_1 = android::hardware::power::V1_1::IPower;
using IPowerV1_0 = android::hardware::power::V1_0::IPower;
@@ -68,7 +68,7 @@
extern sp<IPowerV1_0> getPowerHalV1_0();
extern sp<IPowerV1_1> getPowerHalV1_1();
extern bool processPowerHalReturn(const Return<void> &ret, const char* functionName);
-extern sp<ISystemSuspend> getSuspendHal();
+extern sp<ISuspendControlService> getSuspendControl();
// Java methods used in getLowPowerStats
static jmethodID jgetAndUpdatePlatformState = NULL;
@@ -103,17 +103,17 @@
sp<PowerHalDeathRecipient> gDeathRecipient = new PowerHalDeathRecipient();
-class WakeupCallback : public ISystemSuspendCallback {
-public:
- Return<void> notifyWakeup(bool success) override {
- ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
+class WakeupCallback : public BnSuspendCallback {
+ public:
+ binder::Status notifyWakeup(bool success) override {
+ ALOGI("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
int ret = sem_post(&wakeup_sem);
if (ret < 0) {
char buf[80];
strerror_r(errno, buf, sizeof(buf));
ALOGE("Error posting wakeup sem: %s\n", buf);
}
- return Void();
+ return binder::Status::ok();
}
};
@@ -136,9 +136,12 @@
jniThrowException(env, "java/lang/IllegalStateException", buf);
return -1;
}
- ALOGV("Registering callback...");
- sp<ISystemSuspend> suspendHal = getSuspendHal();
- suspendHal->registerCallback(new WakeupCallback());
+ sp<ISuspendControlService> suspendControl = getSuspendControl();
+ bool isRegistered = false;
+ suspendControl->registerCallback(new WakeupCallback(), &isRegistered);
+ if (!isRegistered) {
+ ALOGE("Failed to register wakeup callback");
+ }
}
// Wait for wakeup.
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 0c9b5f4..9be728b 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/power/1.1/IPower.h>
#include <android/system/suspend/1.0/ISystemSuspend.h>
+#include <android/system/suspend/ISuspendControlService.h>
#include <nativehelper/JNIHelp.h>
#include "jni.h"
@@ -30,13 +31,14 @@
#include <android-base/chrono_utils.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
+#include <binder/IServiceManager.h>
+#include <hardware/power.h>
+#include <hardware_legacy/power.h>
+#include <hidl/ServiceManagement.h>
#include <utils/Timers.h>
#include <utils/misc.h>
#include <utils/String8.h>
#include <utils/Log.h>
-#include <hardware/power.h>
-#include <hardware_legacy/power.h>
-#include <hidl/ServiceManagement.h>
#include "com_android_server_power_PowerManagerService.h"
@@ -48,6 +50,7 @@
using android::system::suspend::V1_0::ISystemSuspend;
using android::system::suspend::V1_0::IWakeLock;
using android::system::suspend::V1_0::WakeLockType;
+using android::system::suspend::ISuspendControlService;
using IPowerV1_1 = android::hardware::power::V1_1::IPower;
using IPowerV1_0 = android::hardware::power::V1_0::IPower;
@@ -176,6 +179,7 @@
}
static sp<ISystemSuspend> gSuspendHal = nullptr;
+static sp<ISuspendControlService> gSuspendControl = nullptr;
static sp<IWakeLock> gSuspendBlocker = nullptr;
static std::mutex gSuspendMutex;
@@ -191,18 +195,33 @@
return gSuspendHal;
}
+sp<ISuspendControlService> getSuspendControl() {
+ static std::once_flag suspendControlFlag;
+ std::call_once(suspendControlFlag, [](){
+ while(gSuspendControl == nullptr) {
+ sp<IBinder> control =
+ defaultServiceManager()->getService(String16("suspend_control"));
+ if (control != nullptr) {
+ gSuspendControl = interface_cast<ISuspendControlService>(control);
+ }
+ }
+ });
+ return gSuspendControl;
+}
+
void enableAutoSuspend() {
static bool enabled = false;
-
- std::lock_guard<std::mutex> lock(gSuspendMutex);
if (!enabled) {
- sp<ISystemSuspend> suspendHal = getSuspendHal();
- suspendHal->enableAutosuspend();
- enabled = true;
+ sp<ISuspendControlService> suspendControl = getSuspendControl();
+ suspendControl->enableAutosuspend(&enabled);
}
- if (gSuspendBlocker) {
- gSuspendBlocker->release();
- gSuspendBlocker.clear();
+
+ {
+ std::lock_guard<std::mutex> lock(gSuspendMutex);
+ if (gSuspendBlocker) {
+ gSuspendBlocker->release();
+ gSuspendBlocker.clear();
+ }
}
}
diff --git a/services/core/jni/com_android_server_security_VerityUtils.cpp b/services/core/jni/com_android_server_security_VerityUtils.cpp
index 988d75c..bf96f9a 100644
--- a/services/core/jni/com_android_server_security_VerityUtils.cpp
+++ b/services/core/jni/com_android_server_security_VerityUtils.cpp
@@ -27,6 +27,8 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <type_traits>
+
#include <android-base/unique_fd.h>
// TODO(112037636): Always include once fsverity.h is upstreamed.
@@ -99,8 +101,14 @@
class JavaByteArrayHolder {
public:
- static JavaByteArrayHolder* newArray(JNIEnv* env, jsize size) {
- return new JavaByteArrayHolder(env, size);
+ JavaByteArrayHolder(const JavaByteArrayHolder &other) = delete;
+ JavaByteArrayHolder(JavaByteArrayHolder &&other)
+ : mEnv(other.mEnv), mBytes(other.mBytes), mElements(other.mElements) {
+ other.mElements = nullptr;
+ }
+
+ static JavaByteArrayHolder newArray(JNIEnv* env, jsize size) {
+ return JavaByteArrayHolder(env, size);
}
jbyte* getRaw() {
@@ -113,6 +121,10 @@
return mBytes;
}
+ ~JavaByteArrayHolder() {
+ LOG_ALWAYS_FATAL_IF(mElements == nullptr, "Elements are not released");
+ }
+
private:
JavaByteArrayHolder(JNIEnv* env, jsize size) {
mEnv = env;
@@ -121,10 +133,6 @@
memset(mElements, 0, size);
}
- virtual ~JavaByteArrayHolder() {
- LOG_ALWAYS_FATAL_IF(mElements == nullptr, "Elements are not released");
- }
-
JNIEnv* mEnv;
jbyteArray mBytes;
jbyte* mElements;
@@ -143,8 +151,10 @@
}
int measureFsverity(JNIEnv* env, jobject /* clazz */, jstring filePath) {
- auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_digest) + kSha256Bytes);
- fsverity_digest* data = reinterpret_cast<fsverity_digest*>(raii->getRaw());
+ using Storage = std::aligned_storage_t<sizeof(fsverity_digest) + kSha256Bytes>;
+
+ Storage bytes;
+ fsverity_digest *data = reinterpret_cast<fsverity_digest *>(&bytes);
data->digest_size = kSha256Bytes; // the only input/output parameter
const char* path = env->GetStringUTFChars(filePath, nullptr);
@@ -160,7 +170,7 @@
jbyteArray constructFsveritySignedData(JNIEnv* env, jobject /* clazz */, jbyteArray digest) {
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_digest_disk) + kSha256Bytes);
- fsverity_digest_disk* data = reinterpret_cast<fsverity_digest_disk*>(raii->getRaw());
+ fsverity_digest_disk* data = reinterpret_cast<fsverity_digest_disk*>(raii.getRaw());
data->digest_algorithm = FS_VERITY_ALG_SHA256;
data->digest_size = kSha256Bytes;
@@ -172,13 +182,13 @@
const jbyte* src = env->GetByteArrayElements(digest, nullptr);
memcpy(data->digest, src, kSha256Bytes);
- return raii->release();
+ return raii.release();
}
jbyteArray constructFsverityDescriptor(JNIEnv* env, jobject /* clazz */, jlong fileSize) {
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_descriptor));
- fsverity_descriptor* desc = reinterpret_cast<fsverity_descriptor*>(raii->getRaw());
+ fsverity_descriptor* desc = reinterpret_cast<fsverity_descriptor*>(raii.getRaw());
memcpy(desc->magic, FS_VERITY_MAGIC, sizeof(desc->magic));
desc->major_version = 1;
@@ -191,29 +201,29 @@
desc->orig_file_size = fileSize;
desc->auth_ext_count = 1;
- return raii->release();
+ return raii.release();
}
jbyteArray constructFsverityExtension(JNIEnv* env, jobject /* clazz */, jshort extensionId,
jint extensionDataSize) {
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_extension));
- fsverity_extension* ext = reinterpret_cast<fsverity_extension*>(raii->getRaw());
+ fsverity_extension* ext = reinterpret_cast<fsverity_extension*>(raii.getRaw());
ext->length = sizeof(fsverity_extension) + extensionDataSize;
ext->type = extensionId;
- return raii->release();
+ return raii.release();
}
jbyteArray constructFsverityFooter(JNIEnv* env, jobject /* clazz */,
jint offsetToDescriptorHead) {
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_footer));
- fsverity_footer* footer = reinterpret_cast<fsverity_footer*>(raii->getRaw());
+ fsverity_footer* footer = reinterpret_cast<fsverity_footer*>(raii.getRaw());
footer->desc_reverse_offset = offsetToDescriptorHead + sizeof(fsverity_footer);
memcpy(footer->magic, FS_VERITY_MAGIC, sizeof(footer->magic));
- return raii->release();
+ return raii.release();
}
const JNINativeMethod sMethods[] = {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 71ed5ae..ab30cda 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -102,7 +102,6 @@
import com.android.server.media.MediaResourceMonitorService;
import com.android.server.media.MediaRouterService;
import com.android.server.media.MediaSessionService;
-import com.android.server.media.MediaUpdateService;
import com.android.server.media.projection.MediaProjectionManagerService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
@@ -1286,47 +1285,45 @@
}
traceEnd();
- if (!mOnlyCore) {
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI)) {
- // Wifi Service must be started first for wifi-related services.
- traceBeginAndSlog("StartWifi");
- mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
- traceEnd();
- traceBeginAndSlog("StartWifiScanning");
- mSystemServiceManager.startService(
- "com.android.server.wifi.scanner.WifiScanningService");
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WIFI)) {
+ // Wifi Service must be started first for wifi-related services.
+ traceBeginAndSlog("StartWifi");
+ mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
+ traceEnd();
+ traceBeginAndSlog("StartWifiScanning");
+ mSystemServiceManager.startService(
+ "com.android.server.wifi.scanner.WifiScanningService");
+ traceEnd();
+ }
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_RTT)) {
- traceBeginAndSlog("StartRttService");
- mSystemServiceManager.startService(
- "com.android.server.wifi.rtt.RttService");
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WIFI_RTT)) {
+ traceBeginAndSlog("StartRttService");
+ mSystemServiceManager.startService(
+ "com.android.server.wifi.rtt.RttService");
+ traceEnd();
+ }
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_AWARE)) {
- traceBeginAndSlog("StartWifiAware");
- mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WIFI_AWARE)) {
+ traceBeginAndSlog("StartWifiAware");
+ mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
+ traceEnd();
+ }
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_DIRECT)) {
- traceBeginAndSlog("StartWifiP2P");
- mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WIFI_DIRECT)) {
+ traceBeginAndSlog("StartWifiP2P");
+ mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
+ traceEnd();
+ }
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_LOWPAN)) {
- traceBeginAndSlog("StartLowpan");
- mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LOWPAN)) {
+ traceBeginAndSlog("StartLowpan");
+ mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
+ traceEnd();
}
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
@@ -1688,10 +1685,6 @@
mSystemServiceManager.startService(MediaSessionService.class);
traceEnd();
- traceBeginAndSlog("StartMediaUpdateService");
- mSystemServiceManager.startService(MediaUpdateService.class);
- traceEnd();
-
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
traceBeginAndSlog("StartHdmiControlService");
mSystemServiceManager.startService(HdmiControlService.class);
diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
index b8db3f3..37909c3 100644
--- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -62,6 +62,7 @@
import java.io.File;
import java.io.FileDescriptor;
+import java.io.IOException;
import java.io.PrintWriter;
/** Tests for the user-aware backup/restore system service {@link BackupManagerService}. */
@@ -1516,8 +1517,7 @@
public void testDump_onRegisteredUser_callsMethodForUser() throws Exception {
BackupManagerService backupManagerService =
createServiceAndRegisterUser(UserHandle.USER_SYSTEM, mUserOneService);
- File testFile = new File(mContext.getFilesDir(), "test");
- testFile.createNewFile();
+ File testFile = createTestFile();
FileDescriptor fileDescriptor = new FileDescriptor();
PrintWriter printWriter = new PrintWriter(testFile);
String[] args = {"1", "2"};
@@ -1531,8 +1531,7 @@
@Test
public void testDump_onUnknownUser_doesNotPropagateCall() throws Exception {
BackupManagerService backupManagerService = createService();
- File testFile = new File(mContext.getFilesDir(), "test");
- testFile.createNewFile();
+ File testFile = createTestFile();
FileDescriptor fileDescriptor = new FileDescriptor();
PrintWriter printWriter = new PrintWriter(testFile);
String[] args = {"1", "2"};
@@ -1542,6 +1541,12 @@
verify(mUserOneService, never()).dump(fileDescriptor, printWriter, args);
}
+ private File createTestFile() throws IOException {
+ File testFile = new File(mContext.getFilesDir(), "test");
+ testFile.createNewFile();
+ return testFile;
+ }
+
private BackupManagerService createService() {
mShadowContext.grantPermissions(BACKUP);
return new BackupManagerService(
diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
index 427aed7..c8d1eb4 100644
--- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
@@ -76,6 +76,7 @@
import org.robolectric.shadows.ShadowPackageManager;
import java.io.File;
+import java.io.IOException;
import java.util.List;
/**
@@ -1158,6 +1159,58 @@
}
/**
+ * Test that {@link UserBackupManagerService#getAncestralSerialNumber()} returns {@code -1}
+ * when value not set.
+ */
+ @Test
+ public void testGetAncestralSerialNumber_notSet_returnsMinusOne() {
+ UserBackupManagerService service = createUserBackupManagerServiceAndRunTasks();
+
+ assertThat(service.getAncestralSerialNumber()).isEqualTo(-1L);
+ }
+
+ /**
+ * Test that {@link UserBackupManagerService#getAncestralSerialNumber()} returns correct value
+ * when value set.
+ */
+ @Test
+ public void testGetAncestralSerialNumber_set_returnsCorrectValue() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ UserBackupManagerService service = createUserBackupManagerServiceAndRunTasks();
+ service.setAncestralSerialNumberFile(createTestFile());
+
+ long testSerialNumber = 20L;
+ service.setAncestralSerialNumber(testSerialNumber);
+
+ assertThat(service.getAncestralSerialNumber()).isEqualTo(testSerialNumber);
+ }
+
+ /**
+ * Test that {@link UserBackupManagerService#getAncestralSerialNumber()} returns correct value
+ * when value set.
+ */
+ @Test
+ public void testGetAncestralSerialNumber_setTwice_returnsCorrectValue() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ UserBackupManagerService service = createUserBackupManagerServiceAndRunTasks();
+ service.setAncestralSerialNumberFile(createTestFile());
+
+ long testSerialNumber = 20L;
+ long testSerialNumber2 = 21L;
+ service.setAncestralSerialNumber(testSerialNumber);
+ service.setAncestralSerialNumber(testSerialNumber2);
+
+ assertThat(service.getAncestralSerialNumber()).isEqualTo(testSerialNumber2);
+ }
+
+ private File createTestFile() throws IOException {
+ File testFile = new File(mContext.getFilesDir(), "test");
+ testFile.createNewFile();
+ return testFile;
+ }
+
+
+ /**
* We can't mock the void method {@link #schedule(Context, long, BackupManagerConstants)} so we
* extend {@link ShadowKeyValueBackupJob} and throw an exception at the end of the method.
*/
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
new file mode 100644
index 0000000..8df0826
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import static org.junit.Assert.assertEquals;
+import static org.testng.Assert.assertThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link ByteRange}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class ByteRangeTest {
+ @Test
+ public void getLength_includesEnd() throws Exception {
+ ByteRange byteRange = new ByteRange(5, 10);
+
+ int length = byteRange.getLength();
+
+ assertEquals(6, length);
+ }
+
+ @Test
+ public void constructor_rejectsNegativeStart() {
+ assertThrows(IllegalArgumentException.class, () -> new ByteRange(-1, 10));
+ }
+
+ @Test
+ public void constructor_rejectsEndBeforeStart() {
+ assertThrows(IllegalArgumentException.class, () -> new ByteRange(10, 9));
+ }
+
+ @Test
+ public void extend_withZeroLength_throwsException() {
+ ByteRange byteRange = new ByteRange(5, 10);
+
+ assertThrows(IllegalArgumentException.class, () -> byteRange.extend(0));
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
new file mode 100644
index 0000000..2af6f2b
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.google.common.primitives.Bytes;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.robolectric.RobolectricTestRunner;
+
+import java.io.IOException;
+
+/** Tests for {@link DiffScriptBackupWriter}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class DiffScriptBackupWriterTest {
+ private static final byte[] TEST_BYTES = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+ @Captor private ArgumentCaptor<Byte> mBytesCaptor;
+ @Mock private SingleStreamDiffScriptWriter mDiffScriptWriter;
+ private BackupWriter mBackupWriter;
+
+ @Before
+ public void setUp() {
+ mDiffScriptWriter = mock(SingleStreamDiffScriptWriter.class);
+ mBackupWriter = new DiffScriptBackupWriter(mDiffScriptWriter);
+ mBytesCaptor = ArgumentCaptor.forClass(Byte.class);
+ }
+
+ @Test
+ public void writeBytes_writesBytesToWriter() throws Exception {
+ mBackupWriter.writeBytes(TEST_BYTES);
+
+ verify(mDiffScriptWriter, atLeastOnce()).writeByte(mBytesCaptor.capture());
+ assertThat(mBytesCaptor.getAllValues())
+ .containsExactlyElementsIn(Bytes.asList(TEST_BYTES))
+ .inOrder();
+ }
+
+ @Test
+ public void writeChunk_writesChunkToWriter() throws Exception {
+ mBackupWriter.writeChunk(0, 10);
+
+ verify(mDiffScriptWriter).writeChunk(0, 10);
+ }
+
+ @Test
+ public void getBytesWritten_returnsTotalSum() throws Exception {
+ mBackupWriter.writeBytes(TEST_BYTES);
+ mBackupWriter.writeBytes(TEST_BYTES);
+ mBackupWriter.writeChunk(/*start=*/ 0, /*length=*/ 10);
+
+ long bytesWritten = mBackupWriter.getBytesWritten();
+
+ assertThat(bytesWritten).isEqualTo(2 * TEST_BYTES.length + 10);
+ }
+
+ @Test
+ public void flush_flushesWriter() throws IOException {
+ mBackupWriter.flush();
+
+ verify(mDiffScriptWriter).flush();
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
new file mode 100644
index 0000000..73baf80
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.testng.Assert.assertThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Locale;
+
+/** Tests for {@link SingleStreamDiffScriptWriter}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class SingleStreamDiffScriptWriterTest {
+ private static final int MAX_CHUNK_SIZE_IN_BYTES = 256;
+ /** By default this Locale does not use Arabic numbers for %d formatting. */
+ private static final Locale HINDI = new Locale("hi", "IN");
+
+ private Locale mDefaultLocale;
+ private ByteArrayOutputStream mOutputStream;
+ private SingleStreamDiffScriptWriter mDiffScriptWriter;
+
+ @Before
+ public void setUp() {
+ mDefaultLocale = Locale.getDefault();
+ mOutputStream = new ByteArrayOutputStream();
+ mDiffScriptWriter =
+ new SingleStreamDiffScriptWriter(mOutputStream, MAX_CHUNK_SIZE_IN_BYTES);
+ }
+
+ @After
+ public void tearDown() {
+ Locale.setDefault(mDefaultLocale);
+ }
+
+ @Test
+ public void writeChunk_withNegativeStart_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> mDiffScriptWriter.writeChunk(-1, 50));
+ }
+
+ @Test
+ public void writeChunk_withZeroLength_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> mDiffScriptWriter.writeChunk(0, 0));
+ }
+
+ @Test
+ public void writeChunk_withExistingBytesInBuffer_writesBufferFirst()
+ throws IOException {
+ String testString = "abcd";
+ writeStringAsBytesToWriter(testString, mDiffScriptWriter);
+
+ mDiffScriptWriter.writeChunk(0, 20);
+ mDiffScriptWriter.flush();
+
+ // Expected format: length of abcd, newline, abcd, newline, chunk start - chunk end
+ assertThat(mOutputStream.toString("UTF-8")).isEqualTo(
+ String.format("%d\n%s\n%d-%d\n", testString.length(), testString, 0, 19));
+ }
+
+ @Test
+ public void writeChunk_overlappingPreviousChunk_combinesChunks() throws IOException {
+ mDiffScriptWriter.writeChunk(3, 4);
+
+ mDiffScriptWriter.writeChunk(7, 5);
+ mDiffScriptWriter.flush();
+
+ assertThat(mOutputStream.toString("UTF-8")).isEqualTo(String.format("3-11\n"));
+ }
+
+ @Test
+ public void writeChunk_formatsByteIndexesUsingArabicNumbers() throws Exception {
+ Locale.setDefault(HINDI);
+
+ mDiffScriptWriter.writeChunk(0, 12345);
+ mDiffScriptWriter.flush();
+
+ assertThat(mOutputStream.toString("UTF-8")).isEqualTo("0-12344\n");
+ }
+
+ @Test
+ public void flush_flushesOutputStream() throws IOException {
+ ByteArrayOutputStream mockOutputStream = mock(ByteArrayOutputStream.class);
+ SingleStreamDiffScriptWriter diffScriptWriter =
+ new SingleStreamDiffScriptWriter(mockOutputStream, MAX_CHUNK_SIZE_IN_BYTES);
+
+ diffScriptWriter.flush();
+
+ verify(mockOutputStream).flush();
+ }
+
+ private void writeStringAsBytesToWriter(String string, SingleStreamDiffScriptWriter writer)
+ throws IOException {
+ byte[] bytes = string.getBytes("UTF-8");
+ for (int i = 0; i < bytes.length; i++) {
+ writer.writeByte(bytes[i]);
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index 48c8902..11bd29d 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -23,8 +23,10 @@
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.os.Looper;
import android.os.test.TestLooper;
+
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -42,9 +44,8 @@
private TestLooper mTestLooper = new TestLooper();
private boolean mSendCecCommandSuccess;
private boolean mShouldDispatchReportArcTerminated;
- private boolean mArcEnabled;
- private boolean mSetArcStatusCalled;
private Instrumentation mInstrumentation;
+ @Nullable private Boolean mArcEnabled = null;
@Before
public void setUp() {
@@ -102,7 +103,6 @@
@Override
void setArcStatus(boolean enabled) {
- mSetArcStatusCalled = true;
mArcEnabled = enabled;
}
};
@@ -110,45 +110,38 @@
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
- mArcEnabled = true;
mAction = new ArcTerminationActionFromAvr(mHdmiCecLocalDeviceAudioSystem);
}
@Test
- public void testSendMessage_NotSuccess() {
+ public void testSendMessage_notSuccess() {
mSendCecCommandSuccess = false;
mShouldDispatchReportArcTerminated = false;
- mSetArcStatusCalled = false;
mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
mTestLooper.dispatchAll();
- assertThat(mSetArcStatusCalled).isFalse();
- assertThat(mArcEnabled).isTrue();
+ assertThat(mArcEnabled).isNull();
}
@Test
- public void testReportArcTerminated_NotReceived() {
+ public void testReportArcTerminated_notReceived() {
mSendCecCommandSuccess = true;
mShouldDispatchReportArcTerminated = false;
- mSetArcStatusCalled = false;
mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
mTestLooper.moveTimeForward(1000);
mTestLooper.dispatchAll();
- assertThat(mSetArcStatusCalled).isFalse();
- assertThat(mArcEnabled).isTrue();
+ assertThat(mArcEnabled).isNull();
}
@Test
- public void testReportArcTerminated_Received() {
+ public void testReportArcTerminated_received() {
mSendCecCommandSuccess = true;
mShouldDispatchReportArcTerminated = true;
- mSetArcStatusCalled = false;
mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
mTestLooper.moveTimeForward(1000);
mTestLooper.dispatchAll();
- assertThat(mSetArcStatusCalled).isTrue();
assertThat(mArcEnabled).isFalse();
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index feae4ee..b8799c3 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -60,6 +60,11 @@
boolean isControlEnabled() {
return true;
}
+
+ @Override
+ void writeStringSystemProperty(String key, String value) {
+ // do nothing
+ }
};
mMyLooper = mTestLooper.getLooper();
@@ -92,4 +97,39 @@
// TODO(amyjojo): Move set and get LocalActivePath to Control Service.
assertThat(mHdmiCecLocalDevicePlayback.getLocalActivePath()).isEqualTo(1);
}
+
+ @Test
+ public void handleSetSystemAudioModeOn_audioSystemBroadcast() {
+ mHdmiControlService.setSystemAudioActivated(false);
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_BROADCAST, true);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
+ }
+
+ @Test
+ public void handleSetSystemAudioModeOff_audioSystemToPlayback() {
+ mHdmiCecLocalDevicePlayback.mService.setSystemAudioActivated(true);
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
+ // This direct message to Playback device is invalid.
+ // Test should ignore it and still keep the system audio mode on.
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ Constants.ADDR_AUDIO_SYSTEM, mHdmiCecLocalDevicePlayback.mAddress, false);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
+ }
+
+ @Test
+ public void handleSystemAudioModeStatusOn_DirectltToLocalDeviceFromAudioSystem() {
+ mHdmiControlService.setSystemAudioActivated(false);
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ Constants.ADDR_AUDIO_SYSTEM, mHdmiCecLocalDevicePlayback.mAddress, true);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSystemAudioModeStatus(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
index 910af78..039b904 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -30,9 +30,10 @@
import android.hardware.hdmi.HdmiControlManager;
import android.os.test.TestLooper;
+
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import java.util.Arrays;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 2ddc71f..48ab8d6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -141,7 +141,8 @@
assertIsUsedByOtherApps(mBarUser0, pui, true);
assertTrue(pui.getDexUseInfoMap().isEmpty());
- assertHasDclInfo(mBarUser0, mFooUser0, mBarUser0.getBaseAndSplitDexPaths());
+ // A package loading another package's APK is not DCL (it's not app data).
+ assertNoDclInfo(mBarUser0);
}
@Test
@@ -334,7 +335,9 @@
notifyDexLoad(mFooUser0, newSplits, mUser0);
PackageUseInfo pui = getPackageUseInfo(mBarUser0);
assertIsUsedByOtherApps(newSplits, pui, true);
- assertHasDclInfo(mBarUser0, mFooUser0, newSplits);
+
+ // Primary and split APKs are not recorded as DCL.
+ assertNoDclInfo(mBarUser0);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index bfa0b74..63341b6 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -150,7 +150,7 @@
@SmallTest
public void testGetDesiredScreenPolicy_WithVR() throws Exception {
// Brighten up the screen
- mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
+ mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
DisplayPowerRequest.POLICY_BRIGHT);
@@ -160,12 +160,13 @@
DisplayPowerRequest.POLICY_VR);
// Then take a nap
- mService.setWakefulnessLocked(WAKEFULNESS_ASLEEP, 0);
+ mService.setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
+ 0);
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
DisplayPowerRequest.POLICY_OFF);
// Wake up to VR
- mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
+ mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
DisplayPowerRequest.POLICY_VR);
diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
index e32a789..5c0a1c8 100644
--- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
@@ -40,7 +40,7 @@
* Tests for {@link com.android.server.power.batterysaver.BatterySaverPolicy}
*/
public class BatterySaverPolicyTest extends AndroidTestCase {
- private static final int MAX_SERVICE_TYPE = 15;
+ private static final int MAX_SERVICE_TYPE = 16;
private static final float BRIGHTNESS_FACTOR = 0.7f;
private static final float DEFAULT_BRIGHTNESS_FACTOR = 0.5f;
private static final float PRECISION = 0.001f;
@@ -146,6 +146,11 @@
}
@SmallTest
+ public void testGetBatterySaverPolicy_PolicyNightMode_DefaultValueCorrect() {
+ testServiceDefaultValue_On(ServiceType.NIGHT_MODE);
+ }
+
+ @SmallTest
public void testGetBatterySaverPolicy_PolicyDataSaver_DefaultValueCorrect() {
mBatterySaverPolicy.updateConstantsLocked("", "");
mBatterySaverPolicy.setPolicyLevel(POLICY_LEVEL_FULL);
@@ -166,12 +171,12 @@
@SmallTest
public void testGetBatterySaverPolicy_PolicyGps_DefaultValueCorrect() {
- testServiceDefaultValue_On(ServiceType.GPS);
+ testServiceDefaultValue_On(ServiceType.LOCATION);
mBatterySaverPolicy.setPolicyLevel(POLICY_LEVEL_FULL);
PowerSaveState stateOn =
- mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.GPS);
- assertThat(stateOn.gpsMode).isEqualTo(DEFAULT_GPS_MODE);
+ mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION);
+ assertThat(stateOn.locationMode).isEqualTo(DEFAULT_GPS_MODE);
}
@SmallTest
@@ -222,9 +227,9 @@
assertThat(dataSaverState.batterySaverEnabled).isTrue();
final PowerSaveState gpsState =
- mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.GPS);
+ mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION);
assertThat(gpsState.batterySaverEnabled).isTrue();
- assertThat(gpsState.gpsMode).isEqualTo(GPS_MODE);
+ assertThat(gpsState.locationMode).isEqualTo(GPS_MODE);
final PowerSaveState quickDozeState = mBatterySaverPolicy.getBatterySaverPolicy(
ServiceType.QUICK_DOZE);
diff --git a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
index 33cbf7a..50dbaf5 100644
--- a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
@@ -18,15 +18,19 @@
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.PackageRollbackInfo.RestoreInfo;
import android.util.IntArray;
+import android.util.SparseLongArray;
import com.android.server.pm.Installer;
@@ -38,6 +42,7 @@
import java.io.File;
import java.util.ArrayList;
+import java.util.HashMap;
@RunWith(JUnit4.class)
public class AppDataRollbackHelperTest {
@@ -50,10 +55,14 @@
// All users are unlocked so we should snapshot data for them.
doReturn(true).when(helper).isUserCredentialLocked(eq(10));
doReturn(true).when(helper).isUserCredentialLocked(eq(11));
- IntArray pending = helper.snapshotAppData("com.foo.bar", new int[]{10, 11});
- assertEquals(2, pending.size());
- assertEquals(10, pending.get(0));
- assertEquals(11, pending.get(1));
+ AppDataRollbackHelper.SnapshotAppDataResult result = helper.snapshotAppData("com.foo.bar",
+ new int[]{10, 11});
+
+ assertEquals(2, result.pendingBackups.size());
+ assertEquals(10, result.pendingBackups.get(0));
+ assertEquals(11, result.pendingBackups.get(1));
+
+ assertEquals(0, result.ceSnapshotInodes.size());
InOrder inOrder = Mockito.inOrder(installer);
inOrder.verify(installer).snapshotAppData(
@@ -65,10 +74,14 @@
// One of the users is unlocked but the other isn't
doReturn(false).when(helper).isUserCredentialLocked(eq(10));
doReturn(true).when(helper).isUserCredentialLocked(eq(11));
+ when(installer.snapshotAppData(anyString(), anyInt(), anyInt())).thenReturn(239L);
- pending = helper.snapshotAppData("com.foo.bar", new int[]{10, 11});
- assertEquals(1, pending.size());
- assertEquals(11, pending.get(0));
+ result = helper.snapshotAppData("com.foo.bar", new int[]{10, 11});
+ assertEquals(1, result.pendingBackups.size());
+ assertEquals(11, result.pendingBackups.get(0));
+
+ assertEquals(1, result.ceSnapshotInodes.size());
+ assertEquals(239L, result.ceSnapshotInodes.get(10));
inOrder = Mockito.inOrder(installer);
inOrder.verify(installer).snapshotAppData(
@@ -80,10 +93,10 @@
}
private static RollbackData createInProgressRollbackData(String packageName) {
- RollbackData data = new RollbackData(1, new File("/does/not/exist"));
+ RollbackData data = new RollbackData(1, new File("/does/not/exist"), -1, true);
data.packages.add(new PackageRollbackInfo(
new VersionedPackage(packageName, 1), new VersionedPackage(packageName, 1),
- new IntArray(), new ArrayList<>()));
+ new IntArray(), new ArrayList<>(), false, new IntArray(), new SparseLongArray()));
data.inProgress = true;
return data;
@@ -173,4 +186,53 @@
ArrayList<RestoreInfo> pendingRestores = rd.packages.get(0).getPendingRestores();
assertEquals(0, pendingRestores.size());
}
+
+ @Test
+ public void destroyAppData() throws Exception {
+ Installer installer = mock(Installer.class);
+ AppDataRollbackHelper helper = new AppDataRollbackHelper(installer);
+ SparseLongArray ceSnapshotInodes = new SparseLongArray();
+ ceSnapshotInodes.put(11, 239L);
+
+ helper.destroyAppDataSnapshot("com.foo.bar", 10, 0L);
+ helper.destroyAppDataSnapshot("com.foo.bar", 11, 239L);
+
+ InOrder inOrder = Mockito.inOrder(installer);
+ inOrder.verify(installer).destroyAppDataSnapshot(
+ eq("com.foo.bar"), eq(10), eq(0L),
+ eq(Installer.FLAG_STORAGE_DE));
+ inOrder.verify(installer).destroyAppDataSnapshot(
+ eq("com.foo.bar"), eq(11), eq(239L),
+ eq(Installer.FLAG_STORAGE_DE | Installer.FLAG_STORAGE_CE));
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ public void commitPendingBackupAndRestoreForUser_updatesRollbackData() throws Exception {
+ Installer installer = mock(Installer.class);
+ AppDataRollbackHelper helper = new AppDataRollbackHelper(installer);
+
+ ArrayList<RollbackData> changedRollbackData = new ArrayList<>();
+ changedRollbackData.add(createInProgressRollbackData("com.foo.bar"));
+
+ when(installer.snapshotAppData(anyString(), anyInt(), anyInt())).thenReturn(239L);
+
+ ArrayList<String> pendingBackups = new ArrayList<>();
+ pendingBackups.add("com.foo.bar");
+
+ helper.commitPendingBackupAndRestoreForUser(11, pendingBackups,
+ new HashMap<>() /* pendingRestores */, changedRollbackData);
+
+ assertEquals(1, changedRollbackData.size());
+ assertEquals(1, changedRollbackData.get(0).packages.size());
+ PackageRollbackInfo info = changedRollbackData.get(0).packages.get(0);
+
+ assertEquals(1, info.getCeSnapshotInodes().size());
+ assertEquals(239L, info.getCeSnapshotInodes().get(11));
+
+ InOrder inOrder = Mockito.inOrder(installer);
+ inOrder.verify(installer).snapshotAppData("com.foo.bar", 11 /* userId */,
+ Installer.FLAG_STORAGE_CE);
+ inOrder.verifyNoMoreInteractions();
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java
new file mode 100644
index 0000000..3e01fb5
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.app.Notification.Builder;
+import android.app.NotificationChannel;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BubbleExtractorTest extends UiServiceTestCase {
+
+ @Mock RankingConfig mConfig;
+
+ private String mPkg = "com.android.server.notification";
+ private int mId = 1001;
+ private String mTag = null;
+ private int mUid = 1000;
+ private int mPid = 2000;
+ private UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ private NotificationRecord getNotificationRecord(boolean allow, int importanceHigh) {
+ NotificationChannel channel = new NotificationChannel("a", "a", importanceHigh);
+ channel.setAllowBubbles(allow);
+ when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel);
+
+ final Builder builder = new Builder(getContext())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setDefaults(Notification.DEFAULT_SOUND);
+
+ Notification n = builder.build();
+ StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid,
+ mPid, n, mUser, null, System.currentTimeMillis());
+ NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+ return r;
+ }
+
+ //
+ // Tests
+ //
+
+ @Test
+ public void testAppYesChannelNo() {
+ BubbleExtractor extractor = new BubbleExtractor();
+ extractor.setConfig(mConfig);
+
+ when(mConfig.bubblesEnabled(mUser)).thenReturn(true);
+ when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true);
+ NotificationRecord r = getNotificationRecord(false, IMPORTANCE_UNSPECIFIED);
+
+ extractor.process(r);
+
+ assertFalse(r.canBubble());
+ }
+
+ @Test
+ public void testAppNoChannelYes() throws Exception {
+ BubbleExtractor extractor = new BubbleExtractor();
+ extractor.setConfig(mConfig);
+
+ when(mConfig.bubblesEnabled(mUser)).thenReturn(true);
+ when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(false);
+ NotificationRecord r = getNotificationRecord(true, IMPORTANCE_HIGH);
+
+ extractor.process(r);
+
+ assertFalse(r.canBubble());
+ }
+
+ @Test
+ public void testAppYesChannelYes() {
+ BubbleExtractor extractor = new BubbleExtractor();
+ extractor.setConfig(mConfig);
+
+ when(mConfig.bubblesEnabled(mUser)).thenReturn(true);
+ when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true);
+ NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED);
+
+ extractor.process(r);
+
+ assertTrue(r.canBubble());
+ }
+
+ @Test
+ public void testAppNoChannelNo() {
+ BubbleExtractor extractor = new BubbleExtractor();
+ extractor.setConfig(mConfig);
+
+ when(mConfig.bubblesEnabled(mUser)).thenReturn(true);
+ when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(false);
+ NotificationRecord r = getNotificationRecord(false, IMPORTANCE_UNSPECIFIED);
+
+ extractor.process(r);
+
+ assertFalse(r.canBubble());
+ }
+
+ @Test
+ public void testAppYesChannelYesUserNo() {
+ BubbleExtractor extractor = new BubbleExtractor();
+ extractor.setConfig(mConfig);
+
+ when(mConfig.bubblesEnabled(mUser)).thenReturn(false);
+ when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true);
+ NotificationRecord r = getNotificationRecord(true, IMPORTANCE_HIGH);
+
+ extractor.process(r);
+
+ assertFalse(r.canBubble());
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 20f72bf..7a530df 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -74,6 +74,7 @@
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -305,6 +306,82 @@
}
}
+ /** Test that restore ignores the user id attribute and applies the data to the target user. */
+ @Test
+ public void testReadXml_onlyRestoresForTargetUser() throws Exception {
+ for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
+ ManagedServices service =
+ new TestManagedServices(
+ getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
+ String testPackage = "user.test.package";
+ String testComponent = "user.test.component/C1";
+ String resolvedValue =
+ (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent : testPackage;
+ XmlPullParser parser =
+ getParserWithEntries(service, getXmlEntry(resolvedValue, 0, true));
+
+ service.readXml(parser, null, true, 10);
+
+ assertFalse(service.isPackageOrComponentAllowed(resolvedValue, 0));
+ assertTrue(service.isPackageOrComponentAllowed(resolvedValue, 10));
+ }
+ }
+
+ /** Test that backup only writes packages/components that belong to the target user. */
+ @Test
+ public void testWriteXml_onlyBackupsForTargetUser() throws Exception {
+ for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
+ ManagedServices service =
+ new TestManagedServices(
+ getContext(), mLock, mUserProfiles, mIpm, approvalLevel);
+ // Set up components.
+ String testPackage0 = "user0.test.package";
+ String testComponent0 = "user0.test.component/C1";
+ String testPackage10 = "user10.test.package";
+ String testComponent10 = "user10.test.component/C1";
+ String resolvedValue0 =
+ (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent0 : testPackage0;
+ String resolvedValue10 =
+ (approvalLevel == APPROVAL_BY_COMPONENT) ? testComponent10 : testPackage10;
+ addExpectedServices(
+ service, Collections.singletonList(service.getPackageName(resolvedValue0)), 0);
+ addExpectedServices(
+ service,
+ Collections.singletonList(service.getPackageName(resolvedValue10)),
+ 10);
+ XmlPullParser parser =
+ getParserWithEntries(
+ service,
+ getXmlEntry(resolvedValue0, 0, true),
+ getXmlEntry(resolvedValue10, 10, true));
+ service.readXml(parser, null, false, UserHandle.USER_ALL);
+
+ // Write backup.
+ XmlSerializer serializer = new FastXmlSerializer();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+ serializer.startDocument(null, true);
+ service.writeXml(serializer, true, 10);
+ serializer.endDocument();
+ serializer.flush();
+
+ // Reset values.
+ service.setPackageOrComponentEnabled(resolvedValue0, 0, true, false);
+ service.setPackageOrComponentEnabled(resolvedValue10, 10, true, false);
+
+ // Parse backup via restore.
+ XmlPullParser restoreParser = Xml.newPullParser();
+ restoreParser.setInput(
+ new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null);
+ restoreParser.nextTag();
+ service.readXml(restoreParser, null, true, 10);
+
+ assertFalse(service.isPackageOrComponentAllowed(resolvedValue0, 0));
+ assertFalse(service.isPackageOrComponentAllowed(resolvedValue0, 10));
+ assertTrue(service.isPackageOrComponentAllowed(resolvedValue10, 10));
+ }
+ }
+
@Test
public void testWriteXml_trimsMissingServices() throws Exception {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
@@ -348,7 +425,9 @@
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
serializer.startDocument(null, true);
- service.writeXml(serializer, true);
+ for (UserInfo userInfo : mUm.getUsers()) {
+ service.writeXml(serializer, true, userInfo.id);
+ }
serializer.endDocument();
serializer.flush();
@@ -356,7 +435,9 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- service.readXml(parser, null);
+ for (UserInfo userInfo : mUm.getUsers()) {
+ service.readXml(parser, null, true, userInfo.id);
+ }
verifyExpectedApprovedEntries(service);
assertFalse(service.isPackageOrComponentAllowed("this.is.a.package.name", 0));
@@ -376,7 +457,7 @@
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
serializer.startDocument(null, true);
- service.writeXml(serializer, false);
+ service.writeXml(serializer, false, UserHandle.USER_ALL);
serializer.endDocument();
serializer.flush();
@@ -921,7 +1002,23 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.toString().getBytes())), null);
parser.nextTag();
- service.readXml(parser, null);
+ service.readXml(parser, null, false, UserHandle.USER_ALL);
+ }
+
+ private XmlPullParser getParserWithEntries(ManagedServices service, String... xmlEntries)
+ throws Exception {
+ final StringBuffer xml = new StringBuffer();
+ xml.append("<" + service.getConfig().xmlTag + ">\n");
+ for (String xmlEntry : xmlEntries) {
+ xml.append(xmlEntry);
+ }
+ xml.append("</" + service.getConfig().xmlTag + ">");
+
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(
+ new ByteArrayInputStream(xml.toString().getBytes())), null);
+ parser.nextTag();
+ return parser;
}
private void addExpectedServices(final ManagedServices service, final List<String> packages,
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 0b488c0..19b567f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -33,6 +33,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
+import android.os.UserHandle;
import android.os.UserManager;
import android.util.IntArray;
import android.util.Xml;
@@ -129,7 +130,7 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.toString().getBytes())), null);
parser.nextTag();
- mAssistants.readXml(parser, null);
+ mAssistants.readXml(parser, null, false, UserHandle.USER_ALL);
verify(mNm, never()).readDefaultAssistant(anyInt());
verify(mAssistants, times(1)).addApprovedList(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index daca9cb..2162f28 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -54,7 +54,7 @@
@RunWith(AndroidJUnit4.class)
public class NotificationListenerServiceTest extends UiServiceTestCase {
- private String[] mKeys = new String[] { "key", "key1", "key2", "key3"};
+ private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
@Test
public void testGetActiveNotifications_notNull() throws Exception {
@@ -70,7 +70,7 @@
}
@Test
- public void testRanking() throws Exception {
+ public void testRanking() {
TestListenerService service = new TestListenerService();
service.applyUpdateLocked(generateUpdate());
for (int i = 0; i < mKeys.length; i++) {
@@ -92,6 +92,7 @@
assertEquals(lastAudiblyAlerted(i), ranking.getLastAudiblyAlertedMillis());
assertActionsEqual(getSmartActions(key, i), ranking.getSmartActions());
assertEquals(getSmartReplies(key, i), ranking.getSmartReplies());
+ assertEquals(canBubble(i), ranking.canBubble());
}
}
@@ -112,6 +113,7 @@
Bundle smartReplies = new Bundle();
Bundle lastAudiblyAlerted = new Bundle();
Bundle noisy = new Bundle();
+ boolean[] canBubble = new boolean[mKeys.length];
for (int i = 0; i < mKeys.length; i++) {
String key = mKeys[i];
@@ -133,12 +135,13 @@
smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i));
lastAudiblyAlerted.putLong(key, lastAudiblyAlerted(i));
noisy.putBoolean(key, getNoisy(i));
+ canBubble[i] = canBubble(i);
}
NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
interceptedKeys.toArray(new String[0]), visibilityOverrides,
suppressedVisualEffects, importance, explanation, overrideGroupKeys,
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden,
- smartActions, smartReplies, lastAudiblyAlerted, noisy);
+ smartActions, smartReplies, lastAudiblyAlerted, noisy, canBubble);
return update;
}
@@ -235,6 +238,10 @@
return choices;
}
+ private boolean canBubble(int index) {
+ return index % 4 == 0;
+ }
+
private void assertActionsEqual(
List<Notification.Action> expecteds, List<Notification.Action> actuals) {
assertEquals(expecteds.size(), actuals.size());
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 4cae3b3..cc62138 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -123,6 +123,7 @@
import com.android.server.lights.LightsManager;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
+import com.android.server.pm.UserManagerService;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.wm.WindowManagerInternal;
@@ -206,15 +207,19 @@
UriGrantsManagerInternal mUgmInternal;
@Mock
AppOpsManager mAppOpsManager;
+ @Mock
+ private UserManagerService mUserMangerService;
// Use a Testable subclass so we can simulate calls from the system without failing.
private static class TestableNotificationManagerService extends NotificationManagerService {
int countSystemChecks = 0;
boolean isSystemUid = true;
int countLogSmartSuggestionsVisible = 0;
+ UserManagerService mUserManagerService;
- public TestableNotificationManagerService(Context context) {
+ TestableNotificationManagerService(Context context, UserManagerService userManagerService) {
super(context);
+ mUserManagerService = userManagerService;
}
@Override
@@ -250,7 +255,10 @@
countLogSmartSuggestionsVisible++;
}
-
+ @Override
+ UserManagerService getUserManagerService() {
+ return mUserManagerService;
+ }
}
private class TestableToastCallback extends ITransientNotification.Stub {
@@ -267,17 +275,12 @@
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- // most tests assume badging is enabled
- Secure.putIntForUser(getContext().getContentResolver(),
- Secure.NOTIFICATION_BADGING, 1,
- UserHandle.getUserHandleForUid(mUid).getIdentifier());
-
LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal);
LocalServices.removeServiceForTest(WindowManagerInternal.class);
LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
- mService = new TestableNotificationManagerService(mContext);
+ mService = new TestableNotificationManagerService(mContext, mUserMangerService);
// Use this testable looper.
mTestableLooper = TestableLooper.get(this);
@@ -426,6 +429,11 @@
r.setShowBadge(!r.canShowBadge());
return null;
});
+ answers.put("bubbles", invocationOnMock -> {
+ NotificationRecord r = (NotificationRecord) invocationOnMock.getArguments()[0];
+ r.setAllowBubble(!r.canBubble());
+ return null;
+ });
answers.put("package visibility", invocationOnMock -> {
((NotificationRecord) invocationOnMock.getArguments()[0]).setPackageVisibilityOverride(
Notification.VISIBILITY_SECRET);
@@ -1847,7 +1855,7 @@
@Test
public void testHasCompanionDevice_noService() throws Exception {
- mService = new TestableNotificationManagerService(mContext);
+ mService = new TestableNotificationManagerService(mContext, mUserMangerService);
assertFalse(mService.hasCompanionDevice(mListener));
}
@@ -2500,10 +2508,12 @@
+ "</dnd_apps>"
+ "</notification-policy>";
mService.readPolicyXml(
- new BufferedInputStream(new ByteArrayInputStream(upgradeXml.getBytes())), false);
- verify(mListeners, times(1)).readXml(any(), any());
- verify(mConditionProviders, times(1)).readXml(any(), any());
- verify(mAssistants, times(1)).readXml(any(), any());
+ new BufferedInputStream(new ByteArrayInputStream(upgradeXml.getBytes())),
+ false,
+ UserHandle.USER_ALL);
+ verify(mListeners, times(1)).readXml(any(), any(), anyBoolean(), anyInt());
+ verify(mConditionProviders, times(1)).readXml(any(), any(), anyBoolean(), anyInt());
+ verify(mAssistants, times(1)).readXml(any(), any(), anyBoolean(), anyInt());
// numbers are inflated for setup
verify(mListeners, times(1)).migrateToXml();
@@ -2518,10 +2528,12 @@
+ "<ranking></ranking>"
+ "</notification-policy>";
mService.readPolicyXml(
- new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
- verify(mListeners, never()).readXml(any(), any());
- verify(mConditionProviders, never()).readXml(any(), any());
- verify(mAssistants, never()).readXml(any(), any());
+ new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
+ false,
+ UserHandle.USER_ALL);
+ verify(mListeners, never()).readXml(any(), any(), anyBoolean(), anyInt());
+ verify(mConditionProviders, never()).readXml(any(), any(), anyBoolean(), anyInt());
+ verify(mAssistants, never()).readXml(any(), any(), anyBoolean(), anyInt());
// numbers are inflated for setup
verify(mListeners, times(2)).migrateToXml();
@@ -2530,6 +2542,53 @@
verify(mAssistants, times(2)).ensureAssistant();
}
+ @Test
+ public void testReadPolicyXml_doesNotRestoreManagedServicesForManagedUser() throws Exception {
+ final String policyXml = "<notification-policy version=\"1\">"
+ + "<ranking></ranking>"
+ + "<enabled_listeners>"
+ + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
+ + "</enabled_listeners>"
+ + "<enabled_assistants>"
+ + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
+ + "</enabled_assistants>"
+ + "<dnd_apps>"
+ + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
+ + "</dnd_apps>"
+ + "</notification-policy>";
+ when(mUserMangerService.isManagedProfile(10)).thenReturn(true);
+ mService.readPolicyXml(
+ new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
+ true,
+ 10);
+ verify(mListeners, never()).readXml(any(), any(), eq(true), eq(10));
+ verify(mConditionProviders, never()).readXml(any(), any(), eq(true), eq(10));
+ verify(mAssistants, never()).readXml(any(), any(), eq(true), eq(10));
+ }
+
+ @Test
+ public void testReadPolicyXml_restoresManagedServicesForNonManagedUser() throws Exception {
+ final String policyXml = "<notification-policy version=\"1\">"
+ + "<ranking></ranking>"
+ + "<enabled_listeners>"
+ + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
+ + "</enabled_listeners>"
+ + "<enabled_assistants>"
+ + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
+ + "</enabled_assistants>"
+ + "<dnd_apps>"
+ + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
+ + "</dnd_apps>"
+ + "</notification-policy>";
+ when(mUserMangerService.isManagedProfile(10)).thenReturn(false);
+ mService.readPolicyXml(
+ new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
+ true,
+ 10);
+ verify(mListeners, times(1)).readXml(any(), any(), eq(true), eq(10));
+ verify(mConditionProviders, times(1)).readXml(any(), any(), eq(true), eq(10));
+ verify(mAssistants, times(1)).readXml(any(), any(), eq(true), eq(10));
+ }
@Test
public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception {
@@ -3925,13 +3984,16 @@
public void testOnNotificationSmartReplySent() {
final int replyIndex = 2;
final String reply = "Hello";
+ final boolean modifiedBeforeSending = true;
final boolean generatedByAssistant = true;
NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ r.setSuggestionsGeneratedByAssistant(generatedByAssistant);
mService.addNotification(r);
mService.mNotificationDelegate.onNotificationSmartReplySent(
- r.getKey(), replyIndex, reply, generatedByAssistant, NOTIFICATION_LOCATION_UNKNOWN);
+ r.getKey(), replyIndex, reply, NOTIFICATION_LOCATION_UNKNOWN,
+ modifiedBeforeSending);
verify(mAssistants).notifyAssistantSuggestedReplySent(
eq(r.sbn), eq(reply), eq(generatedByAssistant));
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 47ec390..05bb307 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -149,6 +149,8 @@
contentResolver.setFallbackToExisting(false);
Secure.putIntForUser(contentResolver,
Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID_N_MR1));
+ Secure.putIntForUser(contentResolver,
+ Secure.NOTIFICATION_BUBBLES, 1, UserHandle.getUserId(UID_N_MR1));
ContentProvider testContentProvider = mock(ContentProvider.class);
when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
@@ -174,14 +176,14 @@
.build();
}
- private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, boolean forBackup,
- String... channelIds)
+ private ByteArrayOutputStream writeXmlAndPurge(
+ String pkg, int uid, boolean forBackup, int userId, String... channelIds)
throws Exception {
XmlSerializer serializer = new FastXmlSerializer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
serializer.startDocument(null, true);
- mHelper.writeXml(serializer, forBackup);
+ mHelper.writeXml(serializer, forBackup, userId);
serializer.endDocument();
serializer.flush();
for (String channelId : channelIds) {
@@ -190,15 +192,17 @@
return baos;
}
- private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore) throws Exception {
- loadByteArrayXml(stream.toByteArray(), forRestore);
+ private void loadStreamXml(ByteArrayOutputStream stream, boolean forRestore, int userId)
+ throws Exception {
+ loadByteArrayXml(stream.toByteArray(), forRestore, userId);
}
- private void loadByteArrayXml(byte[] byteArray, boolean forRestore) throws Exception {
+ private void loadByteArrayXml(byte[] byteArray, boolean forRestore, int userId)
+ throws Exception {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(byteArray)), null);
parser.nextTag();
- mHelper.readXml(parser, forRestore);
+ mHelper.readXml(parser, forRestore, userId);
}
private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
@@ -242,6 +246,69 @@
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
}
+ private void setUpPackageWithUid(String packageName, int uid) throws Exception {
+ when(mPm.getApplicationInfoAsUser(eq(packageName), anyInt(), anyInt()))
+ .thenReturn(new ApplicationInfo());
+ when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
+ }
+
+ @Test
+ public void testWriteXml_onlyBackupsTargetUser() throws Exception {
+ // Setup package notifications.
+ String package0 = "test.package.user0";
+ int uid0 = 1001;
+ setUpPackageWithUid(package0, uid0);
+ NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
+ mHelper.createNotificationChannel(package0, uid0, channel0, true, false);
+
+ String package10 = "test.package.user10";
+ int uid10 = 1001001;
+ setUpPackageWithUid(package10, uid10);
+ NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
+ mHelper.createNotificationChannel(package10, uid10, channel10, true, false);
+
+ ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
+
+ // Reset state.
+ mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
+ mHelper.onPackagesChanged(true, 10, new String[] {package10}, new int[] {uid10});
+
+ // Parse backup data.
+ loadStreamXml(baos, true, 0);
+ loadStreamXml(baos, true, 10);
+
+ assertEquals(
+ channel10,
+ mHelper.getNotificationChannel(package10, uid10, channel10.getId(), false));
+ assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
+ }
+
+ @Test
+ public void testReadXml_onlyRestoresTargetUser() throws Exception {
+ // Setup package in user 0.
+ String package0 = "test.package.user0";
+ int uid0 = 1001;
+ setUpPackageWithUid(package0, uid0);
+ NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
+ mHelper.createNotificationChannel(package0, uid0, channel0, true, false);
+
+ ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
+
+ // Reset state.
+ mHelper.onPackagesChanged(true, 0, new String[] {package0}, new int[] {uid0});
+
+ // Restore should convert the uid according to the target user.
+ int expectedUid = 1001001;
+ setUpPackageWithUid(package0, expectedUid);
+ // Parse backup data.
+ loadStreamXml(baos, true, 10);
+
+ assertEquals(
+ channel0,
+ mHelper.getNotificationChannel(package0, expectedUid, channel0.getId(), false));
+ assertNull(mHelper.getNotificationChannel(package0, uid0, channel0.getId(), false));
+ }
+
@Test
public void testChannelXml() throws Exception {
NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye");
@@ -270,12 +337,13 @@
mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false, channel1.getId(),
- channel2.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
+ UserHandle.USER_ALL, channel1.getId(), channel2.getId(),
+ NotificationChannel.DEFAULT_CHANNEL_ID);
mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
UID_N_MR1});
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
@@ -337,14 +405,15 @@
mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, channel1.getId(),
- channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+ UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
+ NotificationChannel.DEFAULT_CHANNEL_ID);
mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1, PKG_O},
new int[]{UID_N_MR1, UID_O});
mHelper.setShowBadge(PKG_O, UID_O, true);
- loadStreamXml(baos, true);
+ loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O));
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
@@ -385,10 +454,11 @@
channel.setSound(SOUND_URI, mAudioAttributes);
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, channel.getId());
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+ UserHandle.USER_SYSTEM, channel.getId());
// Testing that in restore we are given the canonical version
- loadStreamXml(baos, true);
+ loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
verify(mTestIContentProvider).uncanonicalize(any(), eq(CANONICAL_SOUND_URI));
}
@@ -410,9 +480,10 @@
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(SOUND_URI, mAudioAttributes);
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, channel.getId());
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+ UserHandle.USER_SYSTEM, channel.getId());
- loadStreamXml(baos, true);
+ loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
NotificationChannel actualChannel = mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -431,9 +502,10 @@
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(SOUND_URI, mAudioAttributes);
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, channel.getId());
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+ UserHandle.USER_SYSTEM, channel.getId());
- loadStreamXml(baos, true);
+ loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
NotificationChannel actualChannel = mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -460,7 +532,8 @@
+ "</package>\n"
+ "</ranking>\n";
- loadByteArrayXml(backupWithUncanonicalizedSoundUri.getBytes(), true);
+ loadByteArrayXml(
+ backupWithUncanonicalizedSoundUri.getBytes(), true, UserHandle.USER_SYSTEM);
NotificationChannel actualChannel = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, id, false);
assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, actualChannel.getSound());
@@ -472,9 +545,10 @@
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(null, mAudioAttributes);
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, channel.getId());
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+ UserHandle.USER_SYSTEM, channel.getId());
- loadStreamXml(baos, true);
+ loadStreamXml(baos, true, UserHandle.USER_SYSTEM);
NotificationChannel actualChannel = mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -504,8 +578,9 @@
assertEquals(channel2,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, channel1.getId(),
- channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
+ UserHandle.USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
+ NotificationChannel.DEFAULT_CHANNEL_ID);
mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_N_MR1}, new int[]{
UID_N_MR1});
@@ -513,7 +588,7 @@
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
null);
parser.nextTag();
- mHelper.readXml(parser, true);
+ mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
assertNull(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
@@ -525,9 +600,9 @@
@Test
public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
- NotificationChannel.DEFAULT_CHANNEL_ID);
+ UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
final NotificationChannel updated = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
NotificationChannel.DEFAULT_CHANNEL_ID, false);
@@ -546,9 +621,9 @@
mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
- NotificationChannel.DEFAULT_CHANNEL_ID);
+ UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
@@ -568,7 +643,7 @@
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
null);
parser.nextTag();
- mHelper.readXml(parser, false);
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
final NotificationChannel updated1 =
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
@@ -590,13 +665,13 @@
final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
assertTrue(defaultChannel != null);
- ByteArrayOutputStream baos =
- writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false, NotificationChannel.DEFAULT_CHANNEL_ID);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
+ UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
// Load package at higher sdk.
final ApplicationInfo upgraded = new ApplicationInfo();
upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
// Default Channel should be gone.
assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
@@ -608,13 +683,13 @@
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
- NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
+ UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
// Load package at higher sdk.
final ApplicationInfo upgraded = new ApplicationInfo();
upgraded.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(upgraded);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
// Default Channel should be gone.
assertEquals(null, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1,
@@ -624,11 +699,11 @@
@Test
public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
- NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
+ UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
// Should still have the newly created channel that wasn't in the xml.
assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "bananas", false) != null);
@@ -1828,6 +1903,46 @@
}
@Test
+ public void testBubblesOverrideTrue() {
+ Secure.putIntForUser(getContext().getContentResolver(),
+ Secure.NOTIFICATION_BUBBLES, 1,
+ USER.getIdentifier());
+ mHelper.updateBubblesEnabled(); // would be called by settings observer
+ assertTrue(mHelper.bubblesEnabled(USER));
+ }
+
+ @Test
+ public void testBubblesOverrideFalse() {
+ Secure.putIntForUser(getContext().getContentResolver(),
+ Secure.NOTIFICATION_BUBBLES, 0,
+ USER.getIdentifier());
+ mHelper.updateBubblesEnabled(); // would be called by settings observer
+ assertFalse(mHelper.bubblesEnabled(USER));
+ }
+
+ @Test
+ public void testBubblesForUserAll() {
+ try {
+ mHelper.bubblesEnabled(UserHandle.ALL);
+ } catch (Exception e) {
+ fail("just don't throw");
+ }
+ }
+
+ @Test
+ public void testBubblesOverrideUserIsolation() {
+ Secure.putIntForUser(getContext().getContentResolver(),
+ Secure.NOTIFICATION_BUBBLES, 0,
+ USER.getIdentifier());
+ Secure.putIntForUser(getContext().getContentResolver(),
+ Secure.NOTIFICATION_BUBBLES, 1,
+ USER2.getIdentifier());
+ mHelper.updateBubblesEnabled(); // would be called by settings observer
+ assertFalse(mHelper.bubblesEnabled(USER));
+ assertTrue(mHelper.bubblesEnabled(USER2));
+ }
+
+ @Test
public void testOnLocaleChanged_updatesDefaultChannels() throws Exception {
String newLabel = "bananas!";
final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
@@ -2007,9 +2122,9 @@
@Test
public void testXml_statusBarIcons_default() throws Exception {
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
mHelper.shouldHideSilentStatusIcons());
@@ -2019,9 +2134,9 @@
public void testXml_statusBarIcons() throws Exception {
mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
mHelper.shouldHideSilentStatusIcons());
@@ -2115,9 +2230,9 @@
public void testDelegateXml_noDelegate() throws Exception {
mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
}
@@ -2126,9 +2241,9 @@
public void testDelegateXml_delegate() throws Exception {
mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
}
@@ -2138,9 +2253,9 @@
mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
mHelper.revokeNotificationDelegate(PKG_O, UID_O);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
}
@@ -2150,9 +2265,9 @@
mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
// appears disabled
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2168,9 +2283,9 @@
mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
mHelper.revokeNotificationDelegate(PKG_O, UID_O);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
// appears disabled
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2186,9 +2301,9 @@
public void testAllowBubbles_defaults() throws Exception {
assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O));
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O));
assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
@@ -2201,9 +2316,9 @@
assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
mHelper.getAppLockedFields(PKG_O, UID_O));
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper);
- loadStreamXml(baos, false);
+ loadStreamXml(baos, false, UserHandle.USER_ALL);
assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O));
assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index c79e1db0..b322887 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -125,11 +125,8 @@
InstrumentationRegistry.getContext().getContentResolver());
when(mContext.getPackageManager()).thenReturn(mPm);
when(mContext.getApplicationInfo()).thenReturn(legacy);
- // most tests assume badging is enabled
TestableContentResolver contentResolver = getContext().getContentResolver();
contentResolver.setFallbackToExisting(false);
- Secure.putIntForUser(contentResolver,
- Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID));
ContentProvider testContentProvider = mock(ContentProvider.class);
when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index a459b0a..08d8333 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -25,6 +25,7 @@
import static junit.framework.Assert.assertFalse;
import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertNotEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -56,6 +57,7 @@
import android.media.AudioSystem;
import android.media.VolumePolicy;
import android.net.Uri;
+import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.notification.Condition;
@@ -158,19 +160,58 @@
return new XmlResourceParserImpl(parser);
}
- private ByteArrayOutputStream writeXmlAndPurge(boolean forBackup, Integer version)
+ private ByteArrayOutputStream writeXmlAndPurge(Integer version) throws Exception {
+ XmlSerializer serializer = new FastXmlSerializer();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+ serializer.startDocument(null, true);
+ mZenModeHelperSpy.writeXml(serializer, false, version, UserHandle.USER_ALL);
+ serializer.endDocument();
+ serializer.flush();
+ mZenModeHelperSpy.setConfig(new ZenModeConfig(), null, "writing xml");
+ return baos;
+ }
+
+ private ByteArrayOutputStream writeXmlAndPurgeForUser(Integer version, int userId)
throws Exception {
XmlSerializer serializer = new FastXmlSerializer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
serializer.startDocument(null, true);
- mZenModeHelperSpy.writeXml(serializer, forBackup, version);
+ mZenModeHelperSpy.writeXml(serializer, true, version, userId);
serializer.endDocument();
serializer.flush();
- mZenModeHelperSpy.setConfig(new ZenModeConfig(), null, "writing xml");
+ ZenModeConfig newConfig = new ZenModeConfig();
+ newConfig.user = userId;
+ mZenModeHelperSpy.setConfig(newConfig, null, "writing xml");
return baos;
}
+ private XmlPullParser getParserForByteStream(ByteArrayOutputStream baos) throws Exception {
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(
+ new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null);
+ parser.nextTag();
+ return parser;
+ }
+
+ private ArrayMap<String, ZenModeConfig.ZenRule> getCustomAutomaticRules() {
+ ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
+ ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
+ final ScheduleInfo customRuleInfo = new ScheduleInfo();
+ customRule.enabled = true;
+ customRule.creationTime = 0;
+ customRule.id = "customRule";
+ customRule.name = "Custom Rule";
+ customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
+ customRule.configurationActivity =
+ new ComponentName("android", "ScheduleConditionProvider");
+ customRule.pkg = customRule.configurationActivity.getPackageName();
+ automaticRules.put("customRule", customRule);
+ return automaticRules;
+ }
+
@Test
public void testZenOff_NoMuteApplied() {
mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_OFF;
@@ -639,50 +680,86 @@
ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
- ByteArrayOutputStream baos = writeXmlAndPurge(false, null);
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(
- new ByteArrayInputStream(baos.toByteArray())), null);
- parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ ByteArrayOutputStream baos = writeXmlAndPurge(null);
+ XmlPullParser parser = getParserForByteStream(baos);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
assertEquals("Config mismatch: current vs expected: "
+ mZenModeHelperSpy.mConfig.diff(expected), expected, mZenModeHelperSpy.mConfig);
}
@Test
- public void testReadXmlRestore() throws Exception {
+ public void testWriteXml_onlyBackupsTargetUser() throws Exception {
+ // Setup configs for user 10 and 11.
setupZenConfig();
+ ZenModeConfig config10 = mZenModeHelperSpy.mConfig.copy();
+ config10.user = 10;
+ config10.allowAlarms = true;
+ config10.allowMedia = true;
+ mZenModeHelperSpy.setConfig(config10, null, "writeXml");
+ ZenModeConfig config11 = mZenModeHelperSpy.mConfig.copy();
+ config11.user = 11;
+ config11.allowAlarms = false;
+ config11.allowMedia = false;
+ mZenModeHelperSpy.setConfig(config11, null, "writeXml");
+ // Backup user 10 and reset values.
+ ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10);
+ ZenModeConfig newConfig11 = new ZenModeConfig();
+ newConfig11.user = 11;
+ mZenModeHelperSpy.mConfigs.put(11, newConfig11);
+
+ // Parse backup data.
+ XmlPullParser parser = getParserForByteStream(baos);
+ mZenModeHelperSpy.readXml(parser, true, 10);
+ mZenModeHelperSpy.readXml(parser, true, 11);
+
+ ZenModeConfig actual = mZenModeHelperSpy.mConfigs.get(10);
+ assertEquals(
+ "Config mismatch: current vs expected: " + actual.diff(config10), config10, actual);
+ assertNotEquals("Expected config mismatch", config11, mZenModeHelperSpy.mConfigs.get(11));
+ }
+
+ @Test
+ public void testReadXmlRestore_forSystemUser() throws Exception {
+ setupZenConfig();
// one enabled automatic rule
- ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
- ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
- final ScheduleInfo customRuleInfo = new ScheduleInfo();
- customRule.enabled = true;
- customRule.creationTime = 0;
- customRule.id = "customRule";
- customRule.name = "Custom Rule";
- customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
- customRule.configurationActivity
- = new ComponentName("android", "ScheduleConditionProvider");
- customRule.pkg = customRule.configurationActivity.getPackageName();
- automaticRules.put("customRule", customRule);
- mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
-
+ mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
ZenModeConfig original = mZenModeHelperSpy.mConfig.copy();
- ByteArrayOutputStream baos = writeXmlAndPurge(false, null);
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(
- new ByteArrayInputStream(baos.toByteArray())), null);
- parser.nextTag();
- mZenModeHelperSpy.readXml(parser, true);
+ ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
+ XmlPullParser parser = getParserForByteStream(baos);
+ mZenModeHelperSpy.readXml(parser, true, UserHandle.USER_SYSTEM);
+
assertEquals("Config mismatch: current vs original: "
+ mZenModeHelperSpy.mConfig.diff(original), original, mZenModeHelperSpy.mConfig);
assertEquals(original.hashCode(), mZenModeHelperSpy.mConfig.hashCode());
}
+ /** Restore should ignore the data's user id and restore for the target user. */
+ @Test
+ public void testReadXmlRestore_forNonSystemUser() throws Exception {
+ // Setup config.
+ setupZenConfig();
+ mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
+ ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+
+ // Backup data for user 0.
+ ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
+
+ // Restore data for user 10.
+ XmlPullParser parser = getParserForByteStream(baos);
+ mZenModeHelperSpy.readXml(parser, true, 10);
+
+ ZenModeConfig actual = mZenModeHelperSpy.mConfigs.get(10);
+ expected.user = 10;
+ assertEquals(
+ "Config mismatch: current vs original: " + actual.diff(expected), expected, actual);
+ assertEquals(expected.hashCode(), actual.hashCode());
+ expected.user = 0;
+ assertNotEquals(expected, mZenModeHelperSpy.mConfig);
+ }
+
@Test
public void testWriteXmlWithZenPolicy() throws Exception {
final String ruleId = "customRule";
@@ -715,12 +792,12 @@
ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
- ByteArrayOutputStream baos = writeXmlAndPurge(false, null);
+ ByteArrayOutputStream baos = writeXmlAndPurge(null);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
ZenModeConfig.ZenRule current = mZenModeHelperSpy.mConfig.automaticRules.get(ruleId);
@@ -729,7 +806,7 @@
}
@Test
- public void testReadXmlRestoreWithZenPolicy() throws Exception {
+ public void testReadXmlRestoreWithZenPolicy_forSystemUser() throws Exception {
final String ruleId = "customRule";
setupZenConfig();
@@ -756,12 +833,9 @@
ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
- ByteArrayOutputStream baos = writeXmlAndPurge(false, null);
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(
- new ByteArrayInputStream(baos.toByteArray())), null);
- parser.nextTag();
- mZenModeHelperSpy.readXml(parser, true);
+ ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
+ XmlPullParser parser = getParserForByteStream(baos);
+ mZenModeHelperSpy.readXml(parser, true, UserHandle.USER_SYSTEM);
ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
ZenModeConfig.ZenRule current = mZenModeHelperSpy.mConfig.automaticRules.get(ruleId);
@@ -786,12 +860,12 @@
mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule;
// set previous version
- ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
+ ByteArrayOutputStream baos = writeXmlAndPurge(5);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
assertTrue(mZenModeHelperSpy.mConfig.automaticRules.containsKey("customRule"));
setupZenConfigMaintained();
@@ -811,7 +885,7 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
@@ -827,7 +901,7 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
}
@@ -846,7 +920,7 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
}
@@ -865,7 +939,7 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
| SUPPRESSED_EFFECT_LIGHTS
@@ -884,7 +958,7 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
@@ -900,7 +974,7 @@
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT | SUPPRESSED_EFFECT_LIGHTS,
mZenModeHelperSpy.mConfig.suppressedVisualEffects);
@@ -915,12 +989,12 @@
mZenModeHelperSpy.mConfig.automaticRules = new ArrayMap<>();
// set previous version
- ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
+ ByteArrayOutputStream baos = writeXmlAndPurge(5);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
// check default rules
ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
@@ -951,12 +1025,12 @@
mZenModeHelperSpy.mConfig.automaticRules = disabledAutoRule;
// set previous version
- ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
+ ByteArrayOutputStream baos = writeXmlAndPurge(5);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
// check default rules
ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
@@ -1003,12 +1077,12 @@
mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
// set previous version
- ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
+ ByteArrayOutputStream baos = writeXmlAndPurge(5);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
// check default rules
ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
@@ -1072,12 +1146,12 @@
mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
// set previous version
- ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
+ ByteArrayOutputStream baos = writeXmlAndPurge(5);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false);
+ mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
// check default rules
ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 3f3b996..bfda2ea 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -37,8 +37,10 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
+ <!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
<application android:debuggable="true"
- android:testOnly="true">
+ android:testOnly="true"
+ android:largeHeap="true">
<uses-library android:name="android.test.mock" android:required="true" />
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityA" />
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index ee22861..2de4ae0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -57,7 +57,6 @@
*/
@SmallTest
@Presubmit
-@FlakyTest(detail="promote once confirmed non-flaky")
public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
private ActivityMetricsLogger mActivityMetricsLogger;
private ActivityMetricsLaunchObserver mLaunchObserver;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index f1506a0..192915f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -379,4 +379,39 @@
mSupervisor.endDeferResume();
assertEquals(true, mActivity.shouldMakeActive(null /* activeActivity */));
}
+
+ @Test
+ public void testPushConfigurationWhenLaunchTaskBehind() throws Exception {
+ mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
+
+ final TestActivityStack stack = (TestActivityStack) new StackBuilder(mRootActivityContainer)
+ .build();
+ try {
+ stack.setIsTranslucent(false);
+ assertFalse(mStack.shouldBeVisible(null /* starting */));
+
+ mTask.onRequestedOverrideConfigurationChanged(mTask.getConfiguration());
+ mActivity.setLastReportedConfiguration(new MergedConfiguration(new Configuration(),
+ mActivity.getConfiguration()));
+
+ mActivity.mLaunchTaskBehind = true;
+ mActivity.info.configChanges |= ActivityInfo.CONFIG_ORIENTATION;
+ final Configuration newConfig = new Configuration(mActivity.getConfiguration());
+ newConfig.orientation = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT
+ ? Configuration.ORIENTATION_LANDSCAPE
+ : Configuration.ORIENTATION_PORTRAIT;
+
+ mTask.onConfigurationChanged(newConfig);
+
+ mActivity.ensureActivityConfiguration(0 /* globalChanges */,
+ false /* preserveWindow */, true /* ignoreStopState */);
+
+ final ActivityConfigurationChangeItem expected =
+ ActivityConfigurationChangeItem.obtain(newConfig);
+ verify(mService.getLifecycleManager()).scheduleTransaction(
+ eq(mActivity.app.getThread()), eq(mActivity.appToken), eq(expected));
+ } finally {
+ stack.getDisplay().removeChild(stack);
+ }
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 3bf884f..defe981 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -42,7 +42,6 @@
* Build/Install/Run:
* atest WmTests:AppChangeTransitionTests
*/
-@FlakyTest(detail = "Promote when shown to be stable.")
@SmallTest
public class AppChangeTransitionTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index f399463..3826fac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -59,7 +59,6 @@
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
import android.view.DisplayCutout;
-import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
@@ -585,17 +584,15 @@
@Test
public void testOnDescendantOrientationRequestChanged() {
- final DisplayInfo info = new DisplayInfo();
- info.logicalWidth = 1080;
- info.logicalHeight = 1920;
- info.logicalDensityDpi = 240;
- final DisplayContent dc = createNewDisplay(info);
- dc.configureDisplayPolicy();
+ final DisplayContent dc = createNewDisplay();
mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
+ final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
+ ? SCREEN_ORIENTATION_PORTRAIT
+ : SCREEN_ORIENTATION_LANDSCAPE;
final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
- window.mAppToken.mOrientation = SCREEN_ORIENTATION_LANDSCAPE;
+ window.mAppToken.setOrientation(newOrientation);
ActivityRecord activityRecord = mock(ActivityRecord.class);
@@ -606,22 +603,21 @@
verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(),
same(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
final Configuration newDisplayConfig = captor.getValue();
- assertEquals(Configuration.ORIENTATION_LANDSCAPE, newDisplayConfig.orientation);
+ assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation);
}
@Test
public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() {
- final DisplayInfo info = new DisplayInfo();
- info.logicalWidth = 1080;
- info.logicalHeight = 1920;
- info.logicalDensityDpi = 240;
- final DisplayContent dc = createNewDisplay(info);
+ final DisplayContent dc = createNewDisplay();
dc.getDisplayRotation().setFixedToUserRotation(true);
mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
+ final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
+ ? SCREEN_ORIENTATION_PORTRAIT
+ : SCREEN_ORIENTATION_LANDSCAPE;
final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
- window.mAppToken.mOrientation = SCREEN_ORIENTATION_LANDSCAPE;
+ window.mAppToken.setOrientation(newOrientation);
ActivityRecord activityRecord = mock(ActivityRecord.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index d05711e..198e7ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -33,6 +33,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.content.ContentResolver;
@@ -611,6 +612,23 @@
// ========================
// Non-rotation API Tests
// ========================
+ @Test
+ public void testRespectsAppRequestedOrientationByDefault() throws Exception {
+ mBuilder.build();
+
+ assertTrue("Display rotation should respect app requested orientation by"
+ + " default.", mTarget.respectAppRequestedOrientation());
+ }
+
+ @Test
+ public void testNotRespectAppRequestedOrientation_FixedToUserRotation() throws Exception {
+ mBuilder.build();
+ mTarget.setFixedToUserRotation(true);
+
+ assertFalse("Display rotation shouldn't respect app requested orientation if"
+ + " fixed to user rotation.", mTarget.respectAppRequestedOrientation());
+ }
+
/**
* Call {@link DisplayRotation#configure(int, int, int, int)} to configure {@link #mTarget}
* according to given parameters.
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index a498a1a..0c363de 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -39,7 +39,6 @@
import org.junit.Test;
@SmallTest
-@FlakyTest(detail = "Promote once confirmed non-flaky")
@Presubmit
public class InsetsSourceProviderTest extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
index beaac8e..86bf3db 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
@@ -40,7 +40,6 @@
* atest WmTests:PendingRemoteAnimationRegistryTest
*/
@SmallTest
-@FlakyTest
@Presubmit
public class PendingRemoteAnimationRegistryTest extends ActivityTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index 434ba93..c3d2f33 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -47,7 +47,6 @@
* atest WmTests:PersisterQueueTests
*/
@MediumTest
-@FlakyTest(detail = "Confirm stable in post-submit before removing")
@Presubmit
public class PersisterQueueTests implements PersisterQueue.Listener {
private static final long INTER_WRITE_DELAY_MS = 50;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
index 530fd6d..dad6c95 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
@@ -31,7 +31,6 @@
* atest WmTests:SafeActivityOptionsTest
*/
@MediumTest
-@FlakyTest
@Presubmit
public class SafeActivityOptionsTest {
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 9b84215..edb395a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -179,7 +179,6 @@
}
@Test
- @FlakyTest(detail = "Promote once confirmed non-flaky")
public void testDeferFinish() {
// Start animation
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
index df7bc11..12ed3c2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
@@ -41,7 +41,6 @@
* Build/Install/Run:
* atest WmTests:TaskPersisterTest
*/
-@FlakyTest(detail = "Promote to presubmit if stable")
@Presubmit
public class TaskPersisterTest {
private static final String TEST_USER_NAME = "AM-Test-User";
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index e182c45..bcf9dd2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -25,13 +25,6 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static org.hamcrest.Matchers.not;
@@ -41,6 +34,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
import android.app.ActivityManager;
import android.content.ComponentName;
@@ -53,7 +47,6 @@
import android.service.voice.IVoiceInteractionSession;
import android.util.Xml;
import android.view.DisplayInfo;
-import android.view.Surface;
import androidx.test.filters.MediumTest;
@@ -62,6 +55,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -284,48 +278,33 @@
}
@Test
- public void testUpdatesForcedOrientationInBackground() {
- final DisplayInfo info = new DisplayInfo();
- info.logicalWidth = 1920;
- info.logicalHeight = 1080;
- final ActivityDisplay display = addNewActivityDisplayAt(info, POSITION_TOP);
- doCallRealMethod().when(display.mDisplayContent).setDisplayRotation(any());
- display.mDisplayContent.setDisplayRotation(mock(DisplayRotation.class));
- doCallRealMethod().when(display.mDisplayContent).onDescendantOrientationChanged(any(),
- any());
- doCallRealMethod().when(display.mDisplayContent).setRotation(anyInt());
- doAnswer(invocation -> {
- display.mDisplayContent.setRotation(Surface.ROTATION_0);
- return null;
- }).when(display.mDisplayContent).updateOrientationFromAppTokens(any(), any(), anyBoolean());
+ public void testIgnoresForcedOrientationWhenParentHandles() {
+ final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
+ DisplayInfo info = new DisplayInfo();
+ info.logicalWidth = fullScreenBounds.width();
+ info.logicalHeight = fullScreenBounds.height();
+ ActivityDisplay display = addNewActivityDisplayAt(info, POSITION_TOP);
- final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+ display.getRequestedOverrideConfiguration().orientation =
+ Configuration.ORIENTATION_LANDSCAPE;
+ display.onRequestedOverrideConfigurationChanged(
+ display.getRequestedOverrideConfiguration());
+ ActivityStack stack = new StackBuilder(mRootActivityContainer)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
- final TaskRecord task = stack.getChildAt(0);
- final ActivityRecord activity = task.getRootActivity();
+ TaskRecord task = stack.getChildAt(0);
+ ActivityRecord root = task.getTopActivity();
- // Wire up app window token and task.
- doCallRealMethod().when(activity.mAppWindowToken).setOrientation(anyInt(), any(), any());
- doCallRealMethod().when(activity.mAppWindowToken).onDescendantOrientationChanged(any(),
- any());
- doReturn(task.mTask).when(activity.mAppWindowToken).getParent();
+ final WindowContainer parentWindowContainer = mock(WindowContainer.class);
+ Mockito.doReturn(parentWindowContainer).when(task.mTask).getParent();
+ Mockito.doReturn(true).when(parentWindowContainer)
+ .handlesOrientationChangeFromDescendant();
- // Wire up task and stack.
- task.mTask.mTaskRecord = task;
- doCallRealMethod().when(task.mTask).onDescendantOrientationChanged(any(), any());
- doReturn(stack.getTaskStack()).when(task.mTask).getParent();
-
- // Wire up stack and display content.
- doCallRealMethod().when(stack.mTaskStack).onDescendantOrientationChanged(any(), any());
- doReturn(display.mDisplayContent).when(stack.mTaskStack).getParent();
-
- activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
- assertTrue("Bounds of the task should be pillarboxed.",
- task.getBounds().width() < task.getBounds().height());
-
- activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- assertTrue("Bounds of the task should be fullscreen.",
- task.getBounds().equals(new Rect(0, 0, 1920, 1080)));
+ // Setting app to fixed portrait fits within parent, but TaskRecord shouldn't adjust the
+ // bounds because its parent says it will handle it at a later time.
+ setActivityRequestedOrientation(root, SCREEN_ORIENTATION_PORTRAIT);
+ assertEquals(root, task.getRootActivity());
+ assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getRootActivity().getOrientation());
+ assertEquals(fullScreenBounds, task.getBounds());
}
/** Ensures that the alias intent won't have target component resolved. */
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index ae211d3..4184201 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -22,6 +22,8 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import android.graphics.Point;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -123,4 +125,19 @@
assertEquals(1, task2.positionInParent());
assertTrue(task.mOnDisplayChangedCalled);
}
+
+ @Test
+ public void testBounds() {
+ final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+ final WindowTestUtils.TestTask task = WindowTestUtils.createTestTask(stack1);
+
+ // Check that setting bounds also updates surface position
+ Rect bounds = new Rect(10, 10, 100, 200);
+ task.setBounds(bounds);
+ assertEquals(new Point(bounds.left, bounds.top), task.getLastSurfacePosition());
+
+ Rect dispBounds = new Rect(20, 30, 110, 220);
+ task.setOverrideDisplayedBounds(dispBounds);
+ assertEquals(new Point(dispBounds.left, dispBounds.top), task.getLastSurfacePosition());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index d1fe48a..bfb9193 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -28,6 +28,7 @@
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.PowerManager.WakeReason;
import android.os.RemoteException;
import android.util.proto.ProtoOutputStream;
import android.view.IWindow;
@@ -182,11 +183,11 @@
}
@Override
- public void startedWakingUp() {
+ public void startedWakingUp(@WakeReason int reason) {
}
@Override
- public void finishedWakingUp() {
+ public void finishedWakingUp(@WakeReason int reason) {
}
@Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
index de3567e..af8ccc9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -37,7 +37,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowContainerControllerTests
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowContainerControllerTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 8628575..a9a76c2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -51,6 +51,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.mockito.Mockito;
import java.util.Comparator;
@@ -739,6 +740,18 @@
verify(root).onDescendantOrientationChanged(binder, activityRecord);
}
+ @Test
+ public void testHandlesOrientationChangeFromDescendantProgation() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
+ final TestWindowContainer root = spy(builder.build());
+
+ final TestWindowContainer child = root.addChildWindow();
+ assertFalse(child.handlesOrientationChangeFromDescendant());
+
+ Mockito.doReturn(true).when(root).handlesOrientationChangeFromDescendant();
+ assertTrue(child.handlesOrientationChangeFromDescendant());
+ }
+
/* Used so we can gain access to some protected members of the {@link WindowContainer} class */
private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
private final int mLayer;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index c09cd46..be47153 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -48,6 +48,7 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -263,12 +264,12 @@
reset(sPowerManagerWrapper);
first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
assertTrue(appWindowToken.canTurnScreenOn());
reset(sPowerManagerWrapper);
second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
// Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
@@ -279,12 +280,12 @@
reset(sPowerManagerWrapper);
first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
reset(sPowerManagerWrapper);
second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
// Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
@@ -300,11 +301,11 @@
reset(sPowerManagerWrapper);
firstWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
reset(sPowerManagerWrapper);
secondWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
}
@Test
@@ -435,6 +436,6 @@
root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 3048f1a..d556886 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -39,7 +39,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowTokenTests
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowTokenTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTraceBufferTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTraceBufferTest.java
index df3ef55..2b8e307 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTraceBufferTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTraceBufferTest.java
@@ -67,27 +67,25 @@
ProtoOutputStream toWrite1 = getDummy(1);
ProtoOutputStream toWrite2 = getDummy(2);
ProtoOutputStream toWrite3 = getDummy(3);
- byte[] toWrite1Bytes = toWrite1.getBytes();
- byte[] toWrite2Bytes = toWrite2.getBytes();
- byte[] toWrite3Bytes = toWrite3.getBytes();
-
- final int objectSize = toWrite1.getBytes().length;
+ final int objectSize = toWrite1.getRawSize();
final int bufferCapacity = objectSize * 2;
final WindowTraceBuffer buffer = buildQueueBuffer(bufferCapacity);
buffer.add(toWrite1);
+ byte[] toWrite1Bytes = toWrite1.getBytes();
assertTrue("First element should be in the list",
buffer.contains(toWrite1Bytes));
buffer.add(toWrite2);
+ byte[] toWrite2Bytes = toWrite2.getBytes();
assertTrue("First element should be in the list",
buffer.contains(toWrite1Bytes));
assertTrue("Second element should be in the list",
buffer.contains(toWrite2Bytes));
buffer.add(toWrite3);
-
+ byte[] toWrite3Bytes = toWrite3.getBytes();
assertTrue("First element should be in the list",
buffer.contains(toWrite1Bytes));
assertTrue("Second element should be in the list",
@@ -105,7 +103,7 @@
@Test
public void testTraceRingBuffer_addItem() throws Exception {
ProtoOutputStream toWrite = getDummy(1);
- final int objectSize = toWrite.getBytes().length;
+ final int objectSize = toWrite.getRawSize();
final WindowTraceBuffer buffer = buildRingBuffer(objectSize);
@@ -125,25 +123,25 @@
ProtoOutputStream toWrite1 = getDummy(1);
ProtoOutputStream toWrite2 = getDummy(2);
ProtoOutputStream toWrite3 = getDummy(3);
- byte[] toWrite1Bytes = toWrite1.getBytes();
- byte[] toWrite2Bytes = toWrite2.getBytes();
- byte[] toWrite3Bytes = toWrite3.getBytes();
- final int objectSize = toWrite1.getBytes().length;
+ final int objectSize = toWrite1.getRawSize();
final int bufferCapacity = objectSize * 2 + 1;
final WindowTraceBuffer buffer = buildRingBuffer(bufferCapacity);
buffer.add(toWrite1);
+ byte[] toWrite1Bytes = toWrite1.getBytes();
assertTrue("First element should be in the list",
buffer.contains(toWrite1Bytes));
buffer.add(toWrite2);
+ byte[] toWrite2Bytes = toWrite2.getBytes();
assertTrue("First element should be in the list",
buffer.contains(toWrite1Bytes));
assertTrue("Second element should be in the list",
buffer.contains(toWrite2Bytes));
buffer.add(toWrite3);
+ byte[] toWrite3Bytes = toWrite3.getBytes();
assertTrue("First element should not be in the list",
!buffer.contains(toWrite1Bytes));
assertTrue("Second element should be in the list",
@@ -161,9 +159,7 @@
public void testTraceRingBuffer_addItemMustOverwriteMultiple() throws Exception {
ProtoOutputStream toWriteSmall1 = getDummy(1);
ProtoOutputStream toWriteSmall2 = getDummy(2);
- byte[] toWriteSmall1Bytes = toWriteSmall1.getBytes();
- byte[] toWriteSmall2Bytes = toWriteSmall2.getBytes();
- final int objectSize = toWriteSmall1.getBytes().length;
+ final int objectSize = toWriteSmall1.getRawSize();
final int bufferCapacity = objectSize * 2;
final WindowTraceBuffer buffer = buildRingBuffer(bufferCapacity);
@@ -171,20 +167,21 @@
ProtoOutputStream toWriteBig = new ProtoOutputStream();
toWriteBig.write(MAGIC_NUMBER, 1);
toWriteBig.write(MAGIC_NUMBER, 2);
- byte[] toWriteBigBytes = toWriteBig.getBytes();
- toWriteBig.flush();
buffer.add(toWriteSmall1);
+ byte[] toWriteSmall1Bytes = toWriteSmall1.getBytes();
assertTrue("First element should be in the list",
buffer.contains(toWriteSmall1Bytes));
buffer.add(toWriteSmall2);
+ byte[] toWriteSmall2Bytes = toWriteSmall2.getBytes();
assertTrue("First element should be in the list",
buffer.contains(toWriteSmall1Bytes));
assertTrue("Second element should be in the list",
buffer.contains(toWriteSmall2Bytes));
buffer.add(toWriteBig);
+ byte[] toWriteBigBytes = toWriteBig.getBytes();
assertTrue("Third element should overwrite all others",
!buffer.contains(toWriteSmall1Bytes));
assertTrue("Third element should overwrite all others",
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
index 46d6835..b6b9a86 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
@@ -60,7 +60,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowTracingTest
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowTracingTest {
@@ -123,7 +122,7 @@
mWindowTracing.startTrace(mock(PrintWriter.class));
mWindowTracing.traceStateLocked("where", mWmMock);
- verify(mWmMock).writeToProtoLocked(any(), eq(true));
+ verify(mWmMock).writeToProtoLocked(any(), eq(WindowTraceLogLevel.TRIM));
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
index 33f34b4..05d8237 100644
--- a/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
@@ -37,7 +37,6 @@
* atest WmTests:RotationCacheTest
*/
@SmallTest
-@FlakyTest(bugId = 74078662)
@Presubmit
public class RotationCacheTest {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 85939d4..df2f455 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -432,6 +432,7 @@
synchronized (mLock) {
mHandler.removeMessages(MSG_REPORT_EVENT);
Event event = new Event(DEVICE_SHUTDOWN, SystemClock.elapsedRealtime());
+ event.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME;
// orderly shutdown, the last event is DEVICE_SHUTDOWN.
reportEventToAllUserId(event);
flushToDiskLocked();
@@ -449,6 +450,7 @@
*/
void prepareForPossibleShutdown() {
Event event = new Event(DEVICE_SHUTDOWN, SystemClock.elapsedRealtime());
+ event.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME;
mHandler.obtainMessage(MSG_REPORT_EVENT_TO_ALL_USERID, event).sendToTarget();
mHandler.sendEmptyMessage(MSG_FLUSH_TO_DISK);
}
@@ -491,6 +493,8 @@
switch (event.mEventType) {
case Event.ACTIVITY_RESUMED:
synchronized (mVisibleActivities) {
+ // check if this activity has already been resumed
+ if (mVisibleActivities.get(event.mInstanceId) != null) break;
mVisibleActivities.put(event.mInstanceId, event.getClassName());
try {
mAppTimeLimit.noteUsageStart(packageName, userId);
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index d52d32f..3cb2216 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -143,6 +143,7 @@
if (size == 0 || currentDailyStats.events.get(size - 1).mEventType != DEVICE_SHUTDOWN) {
// The last event in event list is not DEVICE_SHUTDOWN, then we insert one.
final Event event = new Event(DEVICE_SHUTDOWN, currentDailyStats.lastTimeSaved);
+ event.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME;
currentDailyStats.addEvent(event);
}
}
diff --git a/startop/view_compiler/OWNERS b/startop/view_compiler/OWNERS
new file mode 100644
index 0000000..e5aead9
--- /dev/null
+++ b/startop/view_compiler/OWNERS
@@ -0,0 +1,2 @@
+eholk@google.com
+mathieuc@google.com
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 4c1a0dc7..6047e8c 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -426,7 +426,7 @@
// Some of the registers don't fit in the four bit short form of the invoke
// instruction, so we need to do an invoke/range. To do this, we need to
// first move all the arguments into contiguous temporary registers.
- std::array<Value, kMaxArgs> scratch{GetScratchRegisters<kMaxArgs>()};
+ std::array<Value, kMaxArgs> scratch = GetScratchRegisters<kMaxArgs>();
const auto& prototype = dex_->GetPrototypeByMethodId(instruction.method_id());
CHECK(prototype.has_value());
diff --git a/telecomm/java/android/telecom/ConferenceParticipant.java b/telecomm/java/android/telecom/ConferenceParticipant.java
index 20b04eb..6317770 100644
--- a/telecomm/java/android/telecom/ConferenceParticipant.java
+++ b/telecomm/java/android/telecom/ConferenceParticipant.java
@@ -19,6 +19,10 @@
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.PhoneConstants;
/**
* Parcelable representation of a participant's state in a conference call.
@@ -27,6 +31,11 @@
public class ConferenceParticipant implements Parcelable {
/**
+ * RFC5767 states that a SIP URI with an unknown number should use an address of
+ * {@code anonymous@anonymous.invalid}. E.g. the host name is anonymous.invalid.
+ */
+ private static final String ANONYMOUS_INVALID_HOST = "anonymous.invalid";
+ /**
* The conference participant's handle (e.g., phone number).
*/
private final Uri mHandle;
@@ -50,6 +59,16 @@
private final int mState;
/**
+ * The connect time of the participant.
+ */
+ private long mConnectTime;
+
+ /**
+ * The connect elapsed time of the participant.
+ */
+ private long mConnectElapsedTime;
+
+ /**
* Creates an instance of {@code ConferenceParticipant}.
*
* @param handle The conference participant's handle (e.g., phone number).
@@ -92,6 +111,54 @@
}
/**
+ * Determines the number presentation for a conference participant. Per RFC5767, if the host
+ * name contains {@code anonymous.invalid} we can assume that there is no valid caller ID
+ * information for the caller, otherwise we'll assume that the URI can be shown.
+ *
+ * @return The number presentation.
+ */
+ @VisibleForTesting
+ public int getParticipantPresentation() {
+ Uri address = getHandle();
+ if (address == null) {
+ return PhoneConstants.PRESENTATION_RESTRICTED;
+ }
+
+ String number = address.getSchemeSpecificPart();
+ // If no number, bail early and set restricted presentation.
+ if (TextUtils.isEmpty(number)) {
+ return PhoneConstants.PRESENTATION_RESTRICTED;
+ }
+ // Per RFC3261, the host name portion can also potentially include extra information:
+ // E.g. sip:anonymous1@anonymous.invalid;legid=1
+ // In this case, hostName will be anonymous.invalid and there is an extra parameter for
+ // legid=1.
+ // Parameters are optional, and the address (e.g. test@test.com) will always be the first
+ // part, with any parameters coming afterwards.
+ String [] hostParts = number.split("[;]");
+ String addressPart = hostParts[0];
+
+ // Get the number portion from the address part.
+ // This will typically be formatted similar to: 6505551212@test.com
+ String [] numberParts = addressPart.split("[@]");
+
+ // If we can't parse the host name out of the URI, then there is probably other data
+ // present, and is likely a valid SIP URI.
+ if (numberParts.length != 2) {
+ return PhoneConstants.PRESENTATION_ALLOWED;
+ }
+ String hostName = numberParts[1];
+
+ // If the hostname portion of the SIP URI is the invalid host string, presentation is
+ // restricted.
+ if (hostName.equals(ANONYMOUS_INVALID_HOST)) {
+ return PhoneConstants.PRESENTATION_RESTRICTED;
+ }
+
+ return PhoneConstants.PRESENTATION_ALLOWED;
+ }
+
+ /**
* Writes the {@code ConferenceParticipant} to a parcel.
*
* @param dest The Parcel in which the object should be written.
@@ -121,6 +188,10 @@
sb.append(Log.pii(mEndpoint));
sb.append(" State: ");
sb.append(Connection.stateToString(mState));
+ sb.append(" ConnectTime: ");
+ sb.append(getConnectTime());
+ sb.append(" ConnectElapsedTime: ");
+ sb.append(getConnectElapsedTime());
sb.append("]");
return sb.toString();
}
@@ -155,4 +226,26 @@
public int getState() {
return mState;
}
+
+ /**
+ * The connect time of the participant to the conference.
+ */
+ public long getConnectTime() {
+ return mConnectTime;
+ }
+
+ public void setConnectTime(long connectTime) {
+ this.mConnectTime = connectTime;
+ }
+
+ /**
+ * The connect elpased time of the participant to the conference.
+ */
+ public long getConnectElapsedTime() {
+ return mConnectElapsedTime;
+ }
+
+ public void setConnectElapsedTime(long connectElapsedTime) {
+ mConnectElapsedTime = connectElapsedTime;
+ }
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 05d5a13..bd0d4ae 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -16,10 +16,6 @@
package android.telecom;
-import com.android.internal.os.SomeArgs;
-import com.android.internal.telecom.IVideoCallback;
-import com.android.internal.telecom.IVideoProvider;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -43,6 +39,10 @@
import android.util.ArraySet;
import android.view.Surface;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecom.IVideoCallback;
+import com.android.internal.telecom.IVideoProvider;
+
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index 57ae5d3..aac0956d 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -78,7 +78,7 @@
try {
RoleManagerCallback.Future cb = new RoleManagerCallback.Future();
context.getSystemService(RoleManager.class).addRoleHolderAsUser(
- RoleManager.ROLE_DIALER, packageName, UserHandle.of(user),
+ RoleManager.ROLE_DIALER, packageName, 0, UserHandle.of(user),
AsyncTask.THREAD_POOL_EXECUTOR, cb);
cb.get(5, TimeUnit.SECONDS);
return true;
diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java
index 1de67a5..5a97c94 100644
--- a/telecomm/java/android/telecom/DisconnectCause.java
+++ b/telecomm/java/android/telecom/DisconnectCause.java
@@ -16,9 +16,9 @@
package android.telecom;
+import android.media.ToneGenerator;
import android.os.Parcel;
import android.os.Parcelable;
-import android.media.ToneGenerator;
import android.text.TextUtils;
import java.util.Objects;
@@ -91,6 +91,12 @@
*/
public static final String REASON_IMS_ACCESS_BLOCKED = "REASON_IMS_ACCESS_BLOCKED";
+ /**
+ * Reason code, which indicates that the conference call is simulating single party conference.
+ * @hide
+ */
+ public static final String REASON_EMULATING_SINGLE_CALL = "EMULATING_SINGLE_CALL";
+
private int mDisconnectCode;
private CharSequence mDisconnectLabel;
private CharSequence mDisconnectDescription;
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 5482270..4539ab3 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -2118,6 +2118,608 @@
}
/**
+ * Columns for the "rcs_*" tables used by {@link android.telephony.ims.RcsMessageStore} classes.
+ *
+ * @hide - not meant for public use
+ */
+ public interface RcsColumns {
+ /**
+ * The authority for the content provider
+ */
+ String AUTHORITY = "rcs";
+
+ /**
+ * The URI to start building upon to use {@link com.android.providers.telephony.RcsProvider}
+ */
+ Uri CONTENT_AND_AUTHORITY = Uri.parse("content://" + AUTHORITY);
+
+ /**
+ * The value to be used whenever a transaction that expects an integer to be returned
+ * failed.
+ */
+ int TRANSACTION_FAILED = Integer.MIN_VALUE;
+
+ /**
+ * The value that denotes a timestamp was not set before (e.g. a message that is not
+ * delivered yet will not have a DELIVERED_TIMESTAMP)
+ */
+ long TIMESTAMP_NOT_SET = 0;
+
+ /**
+ * The table that {@link android.telephony.ims.RcsThread} gets persisted to
+ */
+ interface RcsThreadColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.RcsThread}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String RCS_THREAD_URI_PART = "thread";
+
+ /**
+ * The URI to query or modify {@link android.telephony.ims.RcsThread} via the content
+ * provider.
+ */
+ Uri RCS_THREAD_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY, RCS_THREAD_URI_PART);
+
+ /**
+ * The unique identifier of an {@link android.telephony.ims.RcsThread}
+ */
+ String RCS_THREAD_ID_COLUMN = "rcs_thread_id";
+ }
+
+ /**
+ * The table that {@link android.telephony.ims.Rcs1To1Thread} gets persisted to
+ */
+ interface Rcs1To1ThreadColumns extends RcsThreadColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.Rcs1To1Thread}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String RCS_1_TO_1_THREAD_URI_PART = "p2p_thread";
+
+ /**
+ * The URI to query or modify {@link android.telephony.ims.Rcs1To1Thread}s via the
+ * content provider
+ */
+ Uri RCS_1_TO_1_THREAD_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY,
+ RCS_1_TO_1_THREAD_URI_PART);
+
+ /**
+ * The SMS/MMS thread to fallback to in case of an RCS outage
+ */
+ String FALLBACK_THREAD_ID_COLUMN = "rcs_fallback_thread_id";
+ }
+
+ /**
+ * The table that {@link android.telephony.ims.RcsGroupThread} gets persisted to
+ */
+ interface RcsGroupThreadColumns extends RcsThreadColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.RcsGroupThread}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String RCS_GROUP_THREAD_URI_PART = "group_thread";
+
+ /**
+ * The URI to query or modify {@link android.telephony.ims.RcsGroupThread}s via the
+ * content provider
+ */
+ Uri RCS_GROUP_THREAD_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY,
+ RCS_GROUP_THREAD_URI_PART);
+
+ /**
+ * The owner/admin of the {@link android.telephony.ims.RcsGroupThread}
+ */
+ String OWNER_PARTICIPANT_COLUMN = "owner_participant";
+
+ /**
+ * The user visible name of the group
+ */
+ String GROUP_NAME_COLUMN = "group_name";
+
+ /**
+ * The user visible icon of the group
+ */
+ String GROUP_ICON_COLUMN = "group_icon";
+
+ /**
+ * The RCS conference URI for this group
+ */
+ String CONFERENCE_URI_COLUMN = "conference_uri";
+ }
+
+ /**
+ * The view that enables polling from all types of RCS threads at once
+ */
+ interface RcsUnifiedThreadColumns extends RcsThreadColumns, Rcs1To1ThreadColumns,
+ RcsGroupThreadColumns {
+ /**
+ * The type of this {@link android.telephony.ims.RcsThread}
+ */
+ String THREAD_TYPE_COLUMN = "thread_type";
+
+ /**
+ * Integer returned as a result from a database query that denotes the thread is 1 to 1
+ */
+ int THREAD_TYPE_1_TO_1 = 0;
+
+ /**
+ * Integer returned as a result from a database query that denotes the thread is 1 to 1
+ */
+ int THREAD_TYPE_GROUP = 1;
+ }
+
+ /**
+ * The table that {@link android.telephony.ims.RcsParticipant} gets persisted to
+ */
+ interface RcsParticipantColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.RcsParticipant}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String RCS_PARTICIPANT_URI_PART = "participant";
+
+ /**
+ * The URI to query or modify {@link android.telephony.ims.RcsParticipant}s via the
+ * content provider
+ */
+ Uri RCS_PARTICIPANT_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY,
+ RCS_PARTICIPANT_URI_PART);
+
+ /**
+ * The unique identifier of the entry in the database
+ */
+ String RCS_PARTICIPANT_ID_COLUMN = "rcs_participant_id";
+
+ /**
+ * A foreign key on canonical_address table, also used by SMS/MMS
+ */
+ String CANONICAL_ADDRESS_ID_COLUMN = "canonical_address_id";
+
+ /**
+ * The user visible RCS alias for this participant.
+ */
+ String RCS_ALIAS_COLUMN = "rcs_alias";
+ }
+
+ /**
+ * Additional constants to enable access to {@link android.telephony.ims.RcsParticipant}
+ * related data
+ */
+ interface RcsParticipantHelpers extends RcsParticipantColumns {
+ /**
+ * The view that unifies "rcs_participant" and "canonical_addresses" tables for easy
+ * access to participant address.
+ */
+ String RCS_PARTICIPANT_WITH_ADDRESS_VIEW = "rcs_participant_with_address_view";
+
+ /**
+ * The view that unifies "rcs_participant", "canonical_addresses" and
+ * "rcs_thread_participant" junction table to get full information on participants that
+ * contribute to threads.
+ */
+ String RCS_PARTICIPANT_WITH_THREAD_VIEW = "rcs_participant_with_thread_view";
+ }
+
+ /**
+ * The table that {@link android.telephony.ims.RcsMessage} gets persisted to
+ */
+ interface RcsMessageColumns {
+ /**
+ * Denotes the type of this message (i.e.
+ * {@link android.telephony.ims.RcsIncomingMessage} or
+ * {@link android.telephony.ims.RcsOutgoingMessage}
+ */
+ String MESSAGE_TYPE_COLUMN = "rcs_message_type";
+
+ /**
+ * The unique identifier for the message in the database - i.e. the primary key.
+ */
+ String MESSAGE_ID_COLUMN = "rcs_message_row_id";
+
+ /**
+ * The globally unique RCS identifier for the message. Please see 4.4.5.2 - GSMA
+ * RCC.53 (RCS Device API 1.6 Specification)
+ */
+ String GLOBAL_ID_COLUMN = "rcs_message_global_id";
+
+ /**
+ * The subscription where this message was sent from/to.
+ */
+ String SUB_ID_COLUMN = "sub_id";
+
+ /**
+ * The sending status of the message.
+ * @see android.telephony.ims.RcsMessage.RcsMessageStatus
+ */
+ String STATUS_COLUMN = "status";
+
+ /**
+ * The creation timestamp of the message.
+ */
+ String ORIGINATION_TIMESTAMP_COLUMN = "origination_timestamp";
+
+ /**
+ * The text content of the message.
+ */
+ String MESSAGE_TEXT_COLUMN = "rcs_text";
+
+ /**
+ * The latitude content of the message, if it contains a location.
+ */
+ String LATITUDE_COLUMN = "latitude";
+
+ /**
+ * The longitude content of the message, if it contains a location.
+ */
+ String LONGITUDE_COLUMN = "longitude";
+ }
+
+ /**
+ * The table that additional information of {@link android.telephony.ims.RcsIncomingMessage}
+ * gets persisted to.
+ */
+ interface RcsIncomingMessageColumns extends RcsMessageColumns {
+ /**
+ The path that should be used for referring to
+ * {@link android.telephony.ims.RcsIncomingMessage}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String INCOMING_MESSAGE_URI_PART = "incoming_message";
+
+ /**
+ * The URI to query incoming messages through
+ * {@link com.android.providers.telephony.RcsProvider}
+ */
+ Uri INCOMING_MESSAGE_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY,
+ INCOMING_MESSAGE_URI_PART);
+
+ /**
+ * The ID of the {@link android.telephony.ims.RcsParticipant} that sent this message
+ */
+ String SENDER_PARTICIPANT_ID_COLUMN = "sender_participant";
+
+ /**
+ * The timestamp of arrival for this message.
+ */
+ String ARRIVAL_TIMESTAMP_COLUMN = "arrival_timestamp";
+
+ /**
+ * The time when the recipient has read this message.
+ */
+ String SEEN_TIMESTAMP_COLUMN = "seen_timestamp";
+ }
+
+ /**
+ * The table that additional information of {@link android.telephony.ims.RcsOutgoingMessage}
+ * gets persisted to.
+ */
+ interface RcsOutgoingMessageColumns extends RcsMessageColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.RcsOutgoingMessage}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String OUTGOING_MESSAGE_URI_PART = "outgoing_message";
+
+ /**
+ * The URI to query or modify {@link android.telephony.ims.RcsOutgoingMessage}s via the
+ * content provider
+ */
+ Uri OUTGOING_MESSAGE_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY,
+ OUTGOING_MESSAGE_URI_PART);
+ }
+
+ /**
+ * The delivery information of an {@link android.telephony.ims.RcsOutgoingMessage}
+ */
+ interface RcsMessageDeliveryColumns extends RcsOutgoingMessageColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.RcsOutgoingMessageDelivery}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String DELIVERY_URI_PART = "delivery";
+
+ /**
+ * The timestamp of delivery of this message.
+ */
+ String DELIVERED_TIMESTAMP_COLUMN = "delivered_timestamp";
+
+ /**
+ * The time when the recipient has read this message.
+ */
+ String SEEN_TIMESTAMP_COLUMN = "seen_timestamp";
+ }
+
+ /**
+ * The views that allow querying {@link android.telephony.ims.RcsIncomingMessage} and
+ * {@link android.telephony.ims.RcsOutgoingMessage} at the same time.
+ */
+ interface RcsUnifiedMessageColumns extends RcsIncomingMessageColumns,
+ RcsOutgoingMessageColumns {
+ /**
+ * The path that is used to query all {@link android.telephony.ims.RcsMessage} in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String UNIFIED_MESSAGE_URI_PART = "message";
+
+ /**
+ * The URI to query all types of {@link android.telephony.ims.RcsMessage}s
+ */
+ Uri UNIFIED_MESSAGE_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY,
+ UNIFIED_MESSAGE_URI_PART);
+
+ /**
+ * The name of the view that unites rcs_message and rcs_incoming_message tables.
+ */
+ String UNIFIED_INCOMING_MESSAGE_VIEW = "unified_incoming_message_view";
+
+ /**
+ * The name of the view that unites rcs_message and rcs_outgoing_message tables.
+ */
+ String UNIFIED_OUTGOING_MESSAGE_VIEW = "unified_outgoing_message_view";
+
+ /**
+ * The column that shows from which table the message entry came from.
+ */
+ String MESSAGE_TYPE_COLUMN = "message_type";
+
+ /**
+ * Integer returned as a result from a database query that denotes that the message is
+ * an incoming message
+ */
+ int MESSAGE_TYPE_INCOMING = 1;
+
+ /**
+ * Integer returned as a result from a database query that denotes that the message is
+ * an outgoing message
+ */
+ int MESSAGE_TYPE_OUTGOING = 0;
+ }
+
+ /**
+ * The table that {@link android.telephony.ims.RcsFileTransferPart} gets persisted to.
+ */
+ interface RcsFileTransferColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.RcsFileTransferPart}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String FILE_TRANSFER_URI_PART = "file_transfer";
+
+ /**
+ * The URI to query or modify {@link android.telephony.ims.RcsFileTransferPart}s via the
+ * content provider
+ */
+ Uri FILE_TRANSFER_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY,
+ FILE_TRANSFER_URI_PART);
+
+ /**
+ * The globally unique file transfer ID for this RCS file transfer.
+ */
+ String FILE_TRANSFER_ID_COLUMN = "rcs_file_transfer_id";
+
+ /**
+ * The RCS session ID for this file transfer. The ID is implementation dependent but
+ * should be unique.
+ */
+ String SESSION_ID_COLUMN = "session_id";
+
+ /**
+ * The URI that points to the content of this file transfer
+ */
+ String CONTENT_URI_COLUMN = "content_uri";
+
+ /**
+ * The file type of this file transfer in bytes. The validity of types is not enforced
+ * in {@link android.telephony.ims.RcsMessageStore} APIs.
+ */
+ String CONTENT_TYPE_COLUMN = "content_type";
+
+ /**
+ * The size of the file transfer in bytes.
+ */
+ String FILE_SIZE_COLUMN = "file_size";
+
+ /**
+ * Number of bytes that was successfully transmitted for this file transfer
+ */
+ String SUCCESSFULLY_TRANSFERRED_BYTES = "transfer_offset";
+
+ /**
+ * The status of this file transfer
+ * @see android.telephony.ims.RcsFileTransferPart.RcsFileTransferStatus
+ */
+ String TRANSFER_STATUS_COLUMN = "transfer_status";
+
+ /**
+ * The on-screen width of the file transfer, if it contains multi-media
+ */
+ String WIDTH_COLUMN = "width";
+
+ /**
+ * The on-screen height of the file transfer, if it contains multi-media
+ */
+ String HEIGHT_COLUMN = "height";
+
+ /**
+ * The duration of the content in milliseconds if this file transfer contains
+ * multi-media
+ */
+ String DURATION_MILLIS_COLUMN = "duration";
+
+ /**
+ * The URI to the preview of the content of this file transfer
+ */
+ String PREVIEW_URI_COLUMN = "preview_uri";
+
+ /**
+ * The type of the preview of the content of this file transfer. The validity of types
+ * is not enforced in {@link android.telephony.ims.RcsMessageStore} APIs.
+ */
+ String PREVIEW_TYPE_COLUMN = "preview_type";
+ }
+
+ /**
+ * The table that holds the information for
+ * {@link android.telephony.ims.RcsGroupThreadEvent} and its subclasses.
+ */
+ interface RcsThreadEventColumns {
+ /**
+ * The string used in the {@link com.android.providers.telephony.RcsProvider} URI to
+ * refer to participant joined events (example URI:
+ * {@code content://rcs/group_thread/3/participant_joined_event})
+ */
+ String PARTICIPANT_JOINED_URI_PART = "participant_joined_event";
+
+ /**
+ * The string used in the {@link com.android.providers.telephony.RcsProvider} URI to
+ * refer to participant left events. (example URI:
+ * {@code content://rcs/group_thread/3/participant_left_event/4})
+ */
+ String PARTICIPANT_LEFT_URI_PART = "participant_left_event";
+
+ /**
+ * The string used in the {@link com.android.providers.telephony.RcsProvider} URI to
+ * refer to name changed events. (example URI:
+ * {@code content://rcs/group_thread/3/name_changed_event})
+ */
+ String NAME_CHANGED_URI_PART = "name_changed_event";
+
+ /**
+ * The string used in the {@link com.android.providers.telephony.RcsProvider} URI to
+ * refer to icon changed events. (example URI:
+ * {@code content://rcs/group_thread/3/icon_changed_event})
+ */
+ String ICON_CHANGED_URI_PART = "icon_changed_event";
+
+ /**
+ * The unique ID of this event in the database, i.e. the primary key
+ */
+ String EVENT_ID_COLUMN = "event_id";
+
+ /**
+ * The type of this event
+ *
+ * @see RcsEventTypes
+ */
+ String EVENT_TYPE_COLUMN = "event_type";
+
+ /**
+ * The timestamp in milliseconds of when this event happened
+ */
+ String TIMESTAMP_COLUMN = "origination_timestamp";
+
+ /**
+ * The participant that generated this event
+ */
+ String SOURCE_PARTICIPANT_ID_COLUMN = "source_participant";
+
+ /**
+ * The receiving participant of this event if this was an
+ * {@link android.telephony.ims.RcsGroupThreadParticipantJoinedEvent} or
+ * {@link android.telephony.ims.RcsGroupThreadParticipantLeftEvent}
+ */
+ String DESTINATION_PARTICIPANT_ID_COLUMN = "destination_participant";
+
+ /**
+ * The URI for the new icon of the group thread if this was an
+ * {@link android.telephony.ims.RcsGroupThreadIconChangedEvent}
+ */
+ String NEW_ICON_URI_COLUMN = "new_icon_uri";
+
+ /**
+ * The URI for the new name of the group thread if this was an
+ * {@link android.telephony.ims.RcsGroupThreadNameChangedEvent}
+ */
+ String NEW_NAME_COLUMN = "new_name";
+ }
+
+ /**
+ * The table that {@link android.telephony.ims.RcsParticipantAliasChangedEvent} gets
+ * persisted to
+ */
+ interface RcsParticipantEventColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.RcsParticipantAliasChangedEvent}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String ALIAS_CHANGE_EVENT_URI_PART = "alias_change_event";
+
+ /**
+ * The new alias of the participant
+ */
+ String NEW_ALIAS_COLUMN = "new_alias";
+ }
+
+ /**
+ * These values are used in {@link com.android.providers.telephony.RcsProvider} to determine
+ * what kind of event is present in the storage.
+ */
+ interface RcsEventTypes {
+ /**
+ * Integer constant that is stored in the
+ * {@link com.android.providers.telephony.RcsProvider} database that denotes the event
+ * is of type {@link android.telephony.ims.RcsParticipantAliasChangedEvent}
+ */
+ int PARTICIPANT_ALIAS_CHANGED_EVENT_TYPE = 1;
+
+ /**
+ * Integer constant that is stored in the
+ * {@link com.android.providers.telephony.RcsProvider} database that denotes the event
+ * is of type {@link android.telephony.ims.RcsGroupThreadParticipantJoinedEvent}
+ */
+ int PARTICIPANT_JOINED_EVENT_TYPE = 2;
+
+ /**
+ * Integer constant that is stored in the
+ * {@link com.android.providers.telephony.RcsProvider} database that denotes the event
+ * is of type {@link android.telephony.ims.RcsGroupThreadParticipantLeftEvent}
+ */
+ int PARTICIPANT_LEFT_EVENT_TYPE = 4;
+
+ /**
+ * Integer constant that is stored in the
+ * {@link com.android.providers.telephony.RcsProvider} database that denotes the event
+ * is of type {@link android.telephony.ims.RcsGroupThreadIconChangedEvent}
+ */
+ int ICON_CHANGED_EVENT_TYPE = 8;
+
+ /**
+ * Integer constant that is stored in the
+ * {@link com.android.providers.telephony.RcsProvider} database that denotes the event
+ * is of type {@link android.telephony.ims.RcsGroupThreadNameChangedEvent}
+ */
+ int NAME_CHANGED_EVENT_TYPE = 16;
+ }
+
+ /**
+ * The view that allows unified querying across all events
+ */
+ interface RcsUnifiedEventHelper extends RcsParticipantEventColumns, RcsThreadEventColumns {
+ /**
+ * The path that should be used for referring to
+ * {@link android.telephony.ims.RcsEvent}s in
+ * {@link com.android.providers.telephony.RcsProvider} URIs.
+ */
+ String RCS_EVENT_QUERY_URI_PATH = "event";
+
+ /**
+ * The URI to query {@link android.telephony.ims.RcsEvent}s via the content provider.
+ */
+ Uri RCS_EVENT_QUERY_URI = Uri.withAppendedPath(CONTENT_AND_AUTHORITY,
+ RCS_EVENT_QUERY_URI_PATH);
+ }
+ }
+
+ /**
* Contains all MMS messages.
*/
public static final class Mms implements BaseMmsColumns {
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java
index 4da79b3..b407b2a 100644
--- a/telephony/java/android/telephony/AvailableNetworkInfo.java
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.java
@@ -114,7 +114,7 @@
in.readStringList(mMccMncs);
}
- public AvailableNetworkInfo(int subId, int priority, ArrayList<String> mccMncs) {
+ public AvailableNetworkInfo(int subId, int priority, List<String> mccMncs) {
mSubId = subId;
mPriority = priority;
mMccMncs = new ArrayList<String>(mccMncs);
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
index a4cce9c..0d4f09f 100644
--- a/telephony/java/android/telephony/CallAttributes.java
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -117,9 +117,9 @@
CallAttributes s = (CallAttributes) o;
- return (mPreciseCallState == s.mPreciseCallState
+ return (Objects.equals(mPreciseCallState, s.mPreciseCallState)
&& mNetworkType == s.mNetworkType
- && mCallQuality == s.mCallQuality);
+ && Objects.equals(mCallQuality, s.mCallQuality));
}
/**
diff --git a/telephony/java/android/telephony/DebugEventReporter.java b/telephony/java/android/telephony/DebugEventReporter.java
new file mode 100644
index 0000000..14b7dd6
--- /dev/null
+++ b/telephony/java/android/telephony/DebugEventReporter.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.ParcelUuid;
+
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A Simple Surface for Telephony to notify a loosely-coupled debugger of particular issues.
+ *
+ * DebugEventReporter allows an optional external logging component to receive events detected by
+ * the framework and take action. This log surface is designed to provide maximium flexibility
+ * to the receiver of these events. Envisioned use cases of this include notifying a vendor
+ * component of: an event that necessitates (timely) log collection on non-AOSP components;
+ * notifying a vendor component of a rare event that should prompt further action such as a
+ * bug report or user intervention for debug purposes.
+ *
+ * <p>This surface is not intended to enable a diagnostic monitor, nor is it intended to support
+ * streaming logs.
+ *
+ * @hide
+ */
+public final class DebugEventReporter {
+ private static final String TAG = "DebugEventReporter";
+
+ private static Context sContext = null;
+
+ private static Map<UUID, Integer> sEvents = new ConcurrentHashMap<>();
+
+ /*
+ * Because this is only supporting system packages, once we find a package, it will be the
+ * same package until the next system upgrade. Thus, to save time in processing debug events
+ * we can cache this info and skip the resolution process after it's done the first time.
+ */
+ private static String sDebugPackageName = null;
+
+ private DebugEventReporter() {};
+
+ /**
+ * If enabled, build and send an intent to a Debug Service for logging.
+ *
+ * This method sends the {@link TelephonyManager#DEBUG_EVENT DEBUG_EVENT} broadcast, which is
+ * system protected. Invoking this method unless you are the system will result in an error.
+ *
+ * @param eventId a fixed event ID that will be sent for each instance of the same event. This
+ * ID should be generated randomly.
+ * @param description an optional description, that if included will be used as the subject for
+ * identification and discussion of this event. This description should ideally be
+ * static and must not contain any sensitive information (especially PII).
+ */
+ public static void sendEvent(@NonNull UUID eventId, String description) {
+ if (sContext == null) {
+ Rlog.w(TAG, "DebugEventReporter not yet initialized, dropping event=" + eventId);
+ return;
+ }
+
+ // If this event has already occurred, skip sending intents for it; regardless log its
+ // invocation here.
+ Integer count = sEvents.containsKey(eventId) ? sEvents.get(eventId) + 1 : 1;
+ sEvents.put(eventId, count);
+ if (count > 1) return;
+
+ // Even if we are initialized, that doesn't mean that a package name has been found.
+ // This is normal in many cases, such as when no debug package is installed on the system,
+ // so drop these events silently.
+ if (sDebugPackageName == null) return;
+
+ Intent dbgIntent = new Intent(TelephonyManager.ACTION_DEBUG_EVENT);
+ dbgIntent.putExtra(TelephonyManager.EXTRA_DEBUG_EVENT_ID, new ParcelUuid(eventId));
+ if (description != null) {
+ dbgIntent.putExtra(TelephonyManager.EXTRA_DEBUG_EVENT_DESCRIPTION, description);
+ }
+ dbgIntent.setPackage(sDebugPackageName);
+ sContext.sendBroadcast(dbgIntent, android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+ }
+
+ /**
+ * Initialize the DebugEventReporter with the current context.
+ *
+ * This method must be invoked before any calls to sendEvent() will succeed. This method should
+ * only be invoked at most once.
+ *
+ * @param context a Context object used to initialize this singleton DebugEventReporter in
+ * the current process.
+ */
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public static void initialize(@NonNull Context context) {
+ if (context == null) {
+ throw new IllegalArgumentException("DebugEventReporter needs a non-null context.");
+ }
+
+ // Ensure that this context has sufficient permissions to send debug events.
+ context.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE,
+ "This app does not have privileges to send debug events");
+
+ sContext = context;
+
+ // Check to see if there is a valid debug package; if there are multiple, that's a config
+ // error, so just take the first one.
+ PackageManager pm = sContext.getPackageManager();
+ if (pm == null) return;
+ List<ResolveInfo> packages = pm.queryBroadcastReceivers(
+ new Intent(TelephonyManager.ACTION_DEBUG_EVENT),
+ PackageManager.MATCH_SYSTEM_ONLY
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+ if (packages == null || packages.isEmpty()) return;
+ if (packages.size() > 1) {
+ Rlog.e(TAG, "Multiple DebugEvent Receivers installed.");
+ }
+
+ for (ResolveInfo r : packages) {
+ if (r.activityInfo == null
+ || pm.checkPermission(
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+ r.activityInfo.packageName)
+ != PackageManager.PERMISSION_GRANTED) {
+ Rlog.w(TAG,
+ "Found package without proper permissions or no activity"
+ + r.activityInfo.packageName);
+ continue;
+ }
+ Rlog.d(TAG, "Found a valid package " + r.activityInfo.packageName);
+ sDebugPackageName = r.activityInfo.packageName;
+ break;
+ }
+ // Initialization may only be performed once.
+ }
+
+ /** Dump the contents of the DebugEventReporter */
+ public static void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+ if (sContext == null) return;
+ IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
+ sContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, "Requires DUMP");
+ pw.println("Initialized=" + (sContext != null ? "Yes" : "No"));
+ pw.println("Debug Package=" + sDebugPackageName);
+ pw.println("Event Counts:");
+ pw.increaseIndent();
+ for (UUID event : sEvents.keySet()) {
+ pw.println(event + ": " + sEvents.get(event));
+ }
+ pw.decreaseIndent();
+ pw.flush();
+ }
+}
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index 59f3e1f..19e1931 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -287,11 +287,11 @@
return false;
}
PreciseCallState other = (PreciseCallState) obj;
- return (mRingingCallState != other.mRingingCallState &&
- mForegroundCallState != other.mForegroundCallState &&
- mBackgroundCallState != other.mBackgroundCallState &&
- mDisconnectCause != other.mDisconnectCause &&
- mPreciseDisconnectCause != other.mPreciseDisconnectCause);
+ return (mRingingCallState == other.mRingingCallState
+ && mForegroundCallState == other.mForegroundCallState
+ && mBackgroundCallState == other.mBackgroundCallState
+ && mDisconnectCause == other.mDisconnectCause
+ && mPreciseDisconnectCause == other.mPreciseDisconnectCause);
}
@Override
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7c3bde4..eab536f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1326,13 +1326,15 @@
"android.intent.action.DATA_STALL_DETECTED";
/**
- * A service action that identifies a {@link android.app.SmsAppService} subclass in the
+ * A service action that identifies
+ * a {@link android.service.carrier.CarrierMessagingClientService} subclass in the
* AndroidManifest.xml.
*
- * <p>See {@link android.app.SmsAppService} for the details.
+ * <p>See {@link android.service.carrier.CarrierMessagingClientService} for the details.
*/
@SdkConstant(SdkConstantType.SERVICE_ACTION)
- public static final String ACTION_SMS_APP_SERVICE = "android.telephony.action.SMS_APP_SERVICE";
+ public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE =
+ "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE";
/**
* An int extra used with {@link #ACTION_DATA_STALL_DETECTED} to indicate the
@@ -1351,6 +1353,38 @@
@SystemApi
public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000;
+ /**
+ * Intent sent when an error occurs that debug tools should log and possibly take further
+ * action such as capturing vendor-specific logs.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public static final String ACTION_DEBUG_EVENT = "android.telephony.action.DEBUG_EVENT";
+
+ /**
+ * An arbitrary ParcelUuid which should be consistent for each occurrence of the same event.
+ *
+ * This field must be included in all events.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_DEBUG_EVENT_ID = "android.telephony.extra.DEBUG_EVENT_ID";
+
+ /**
+ * A freeform string description of the event.
+ *
+ * This field is optional for all events and as a guideline should not exceed 80 characters
+ * and should be as short as possible to convey the essence of the event.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_DEBUG_EVENT_DESCRIPTION =
+ "android.telephony.extra.DEBUG_EVENT_DESCRIPTION";
+
//
//
// Device Info
@@ -7974,9 +8008,7 @@
* support for the feature and device firmware support.
*
* @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
- * @hide
*/
- @TestApi
public boolean isRttSupported() {
try {
ITelephony telephony = getITelephony();
@@ -9702,10 +9734,10 @@
*
* <p>
* Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
* @hide
*/
- @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isOpportunisticNetworkEnabled() {
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
boolean isEnabled = false;
@@ -10093,12 +10125,17 @@
* Get preferred opportunistic data subscription Id
*
* <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}),
- * or has permission {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}.
+ * or has either READ_PRIVILEGED_PHONE_STATE
+ * or {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} permission.
* @return subId preferred opportunistic subscription id or
* {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} if there are no preferred
* subscription id
*
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+ android.Manifest.permission.READ_PHONE_STATE
+ })
public int getPreferredOpportunisticDataSubscription() {
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 4d95e55..d8d2d9e 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -465,7 +465,7 @@
public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511;
/**
- * Upgrade Downgrade request cacncelled by the user who initiated it
+ * Upgrade Downgrade request cancelled by the user who initiated it
*/
public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512;
@@ -887,6 +887,185 @@
public static final int CODE_OEM_CAUSE_15 = 0xf00f;
/**
+ * @hide
+ */
+ @IntDef(value = {
+ CODE_UNSPECIFIED,
+ CODE_LOCAL_ILLEGAL_ARGUMENT,
+ CODE_LOCAL_ILLEGAL_STATE,
+ CODE_LOCAL_INTERNAL_ERROR,
+ CODE_LOCAL_IMS_SERVICE_DOWN,
+ CODE_LOCAL_NO_PENDING_CALL,
+ CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE,
+ CODE_LOCAL_POWER_OFF,
+ CODE_LOCAL_LOW_BATTERY,
+ CODE_LOCAL_NETWORK_NO_SERVICE,
+ CODE_LOCAL_NETWORK_NO_LTE_COVERAGE,
+ CODE_LOCAL_NETWORK_ROAMING,
+ CODE_LOCAL_NETWORK_IP_CHANGED,
+ CODE_LOCAL_SERVICE_UNAVAILABLE,
+ CODE_LOCAL_NOT_REGISTERED,
+ CODE_LOCAL_CALL_EXCEEDED,
+ CODE_LOCAL_CALL_BUSY,
+ CODE_LOCAL_CALL_DECLINE,
+ CODE_LOCAL_CALL_VCC_ON_PROGRESSING,
+ CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED,
+ CODE_LOCAL_CALL_CS_RETRY_REQUIRED,
+ CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED,
+ CODE_LOCAL_CALL_TERMINATED,
+ CODE_LOCAL_HO_NOT_FEASIBLE,
+ CODE_TIMEOUT_1XX_WAITING,
+ CODE_TIMEOUT_NO_ANSWER,
+ CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE,
+ CODE_CALL_BARRED,
+ CODE_FDN_BLOCKED,
+ CODE_IMEI_NOT_ACCEPTED,
+ CODE_DIAL_MODIFIED_TO_USSD,
+ CODE_DIAL_MODIFIED_TO_SS,
+ CODE_DIAL_MODIFIED_TO_DIAL,
+ CODE_DIAL_MODIFIED_TO_DIAL_VIDEO,
+ CODE_DIAL_VIDEO_MODIFIED_TO_DIAL,
+ CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO,
+ CODE_DIAL_VIDEO_MODIFIED_TO_SS,
+ CODE_DIAL_VIDEO_MODIFIED_TO_USSD,
+ CODE_SIP_REDIRECTED,
+ CODE_SIP_BAD_REQUEST,
+ CODE_SIP_FORBIDDEN,
+ CODE_SIP_NOT_FOUND,
+ CODE_SIP_NOT_SUPPORTED,
+ CODE_SIP_REQUEST_TIMEOUT,
+ CODE_SIP_TEMPRARILY_UNAVAILABLE,
+ CODE_SIP_BAD_ADDRESS,
+ CODE_SIP_BUSY,
+ CODE_SIP_REQUEST_CANCELLED,
+ CODE_SIP_NOT_ACCEPTABLE,
+ CODE_SIP_NOT_REACHABLE,
+ CODE_SIP_CLIENT_ERROR,
+ CODE_SIP_TRANSACTION_DOES_NOT_EXIST,
+ CODE_SIP_SERVER_INTERNAL_ERROR,
+ CODE_SIP_SERVICE_UNAVAILABLE,
+ CODE_SIP_SERVER_TIMEOUT,
+ CODE_SIP_SERVER_ERROR,
+ CODE_SIP_USER_REJECTED,
+ CODE_SIP_GLOBAL_ERROR,
+ CODE_EMERGENCY_TEMP_FAILURE,
+ CODE_EMERGENCY_PERM_FAILURE,
+ CODE_SIP_USER_MARKED_UNWANTED,
+ CODE_SIP_METHOD_NOT_ALLOWED,
+ CODE_SIP_PROXY_AUTHENTICATION_REQUIRED,
+ CODE_SIP_REQUEST_ENTITY_TOO_LARGE,
+ CODE_SIP_REQUEST_URI_TOO_LARGE,
+ CODE_SIP_EXTENSION_REQUIRED,
+ CODE_SIP_INTERVAL_TOO_BRIEF,
+ CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST,
+ CODE_SIP_LOOP_DETECTED,
+ CODE_SIP_TOO_MANY_HOPS,
+ CODE_SIP_AMBIGUOUS,
+ CODE_SIP_REQUEST_PENDING,
+ CODE_SIP_UNDECIPHERABLE,
+ CODE_MEDIA_INIT_FAILED,
+ CODE_MEDIA_NO_DATA,
+ CODE_MEDIA_NOT_ACCEPTABLE,
+ CODE_MEDIA_UNSPECIFIED,
+ CODE_USER_TERMINATED,
+ CODE_USER_NOANSWER,
+ CODE_USER_IGNORE,
+ CODE_USER_DECLINE,
+ CODE_LOW_BATTERY,
+ CODE_BLACKLISTED_CALL_ID,
+ CODE_USER_TERMINATED_BY_REMOTE,
+ CODE_USER_REJECTED_SESSION_MODIFICATION,
+ CODE_USER_CANCELLED_SESSION_MODIFICATION,
+ CODE_SESSION_MODIFICATION_FAILED,
+ CODE_UT_NOT_SUPPORTED,
+ CODE_UT_SERVICE_UNAVAILABLE,
+ CODE_UT_OPERATION_NOT_ALLOWED,
+ CODE_UT_NETWORK_ERROR,
+ CODE_UT_CB_PASSWORD_MISMATCH,
+ CODE_UT_SS_MODIFIED_TO_DIAL,
+ CODE_UT_SS_MODIFIED_TO_USSD,
+ CODE_UT_SS_MODIFIED_TO_SS,
+ CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO,
+ CODE_ECBM_NOT_SUPPORTED,
+ CODE_MULTIENDPOINT_NOT_SUPPORTED,
+ CODE_REGISTRATION_ERROR,
+ CODE_ANSWERED_ELSEWHERE,
+ CODE_CALL_PULL_OUT_OF_SYNC,
+ CODE_CALL_END_CAUSE_CALL_PULL,
+ CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE,
+ CODE_REJECTED_ELSEWHERE,
+ CODE_SUPP_SVC_FAILED,
+ CODE_SUPP_SVC_CANCELLED,
+ CODE_SUPP_SVC_REINVITE_COLLISION,
+ CODE_IWLAN_DPD_FAILURE,
+ CODE_EPDG_TUNNEL_ESTABLISH_FAILURE,
+ CODE_EPDG_TUNNEL_REKEY_FAILURE,
+ CODE_EPDG_TUNNEL_LOST_CONNECTION,
+ CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED,
+ CODE_REMOTE_CALL_DECLINE,
+ CODE_DATA_LIMIT_REACHED,
+ CODE_DATA_DISABLED,
+ CODE_WIFI_LOST,
+ CODE_IKEV2_AUTH_FAILURE,
+ CODE_RADIO_OFF,
+ CODE_NO_VALID_SIM,
+ CODE_RADIO_INTERNAL_ERROR,
+ CODE_NETWORK_RESP_TIMEOUT,
+ CODE_NETWORK_REJECT,
+ CODE_RADIO_ACCESS_FAILURE,
+ CODE_RADIO_LINK_FAILURE,
+ CODE_RADIO_LINK_LOST,
+ CODE_RADIO_UPLINK_FAILURE,
+ CODE_RADIO_SETUP_FAILURE,
+ CODE_RADIO_RELEASE_NORMAL,
+ CODE_RADIO_RELEASE_ABNORMAL,
+ CODE_ACCESS_CLASS_BLOCKED,
+ CODE_NETWORK_DETACH,
+ CODE_SIP_ALTERNATE_EMERGENCY_CALL,
+ CODE_UNOBTAINABLE_NUMBER,
+ CODE_NO_CSFB_IN_CS_ROAM,
+ CODE_REJECT_UNKNOWN,
+ CODE_REJECT_ONGOING_CALL_WAITING_DISABLED,
+ CODE_REJECT_CALL_ON_OTHER_SUB,
+ CODE_REJECT_1X_COLLISION,
+ CODE_REJECT_SERVICE_NOT_REGISTERED,
+ CODE_REJECT_CALL_TYPE_NOT_ALLOWED,
+ CODE_REJECT_ONGOING_E911_CALL,
+ CODE_REJECT_ONGOING_CALL_SETUP,
+ CODE_REJECT_MAX_CALL_LIMIT_REACHED,
+ CODE_REJECT_UNSUPPORTED_SIP_HEADERS,
+ CODE_REJECT_UNSUPPORTED_SDP_HEADERS,
+ CODE_REJECT_ONGOING_CALL_TRANSFER,
+ CODE_REJECT_INTERNAL_ERROR,
+ CODE_REJECT_QOS_FAILURE,
+ CODE_REJECT_ONGOING_HANDOVER,
+ CODE_REJECT_VT_TTY_NOT_ALLOWED,
+ CODE_REJECT_ONGOING_CALL_UPGRADE,
+ CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED,
+ CODE_REJECT_ONGOING_CONFERENCE_CALL,
+ CODE_REJECT_VT_AVPF_NOT_ALLOWED,
+ CODE_REJECT_ONGOING_ENCRYPTED_CALL,
+ CODE_REJECT_ONGOING_CS_CALL,
+ CODE_OEM_CAUSE_1,
+ CODE_OEM_CAUSE_2,
+ CODE_OEM_CAUSE_3,
+ CODE_OEM_CAUSE_4,
+ CODE_OEM_CAUSE_5,
+ CODE_OEM_CAUSE_6,
+ CODE_OEM_CAUSE_7,
+ CODE_OEM_CAUSE_8,
+ CODE_OEM_CAUSE_9,
+ CODE_OEM_CAUSE_10,
+ CODE_OEM_CAUSE_11,
+ CODE_OEM_CAUSE_12,
+ CODE_OEM_CAUSE_13,
+ CODE_OEM_CAUSE_14,
+ CODE_OEM_CAUSE_15
+ }, prefix = "CODE_")
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ImsCode {}
+
+ /**
* Network string error messages.
* mExtraMessage may have these values.
*/
@@ -964,7 +1143,7 @@
/**
* @return an integer representing more information about the completion of an operation.
*/
- public int getCode() {
+ public @ImsCode int getCode() {
return mCode;
}
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index b171f79..6e98a0a 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -372,14 +372,6 @@
}
}
- private static SubscriptionManager getSubscriptionManager(Context context) {
- SubscriptionManager manager = context.getSystemService(SubscriptionManager.class);
- if (manager == null) {
- throw new RuntimeException("Could not find SubscriptionManager.");
- }
- return manager;
- }
-
private static ITelephony getITelephony() {
ITelephony binder = ITelephony.Stub.asInterface(
ServiceManager.getService(Context.TELEPHONY_SERVICE));
diff --git a/telephony/java/android/telephony/ims/Rcs1To1Thread.java b/telephony/java/android/telephony/ims/Rcs1To1Thread.java
index 709b3aa..cc28ee0 100644
--- a/telephony/java/android/telephony/ims/Rcs1To1Thread.java
+++ b/telephony/java/android/telephony/ims/Rcs1To1Thread.java
@@ -15,42 +15,72 @@
*/
package android.telephony.ims;
-import android.os.Parcel;
+import android.annotation.NonNull;
+import android.annotation.WorkerThread;
/**
* Rcs1To1Thread represents a single RCS conversation thread with a total of two
- * {@link RcsParticipant}s.
- * @hide - TODO(sahinc) make this public
+ * {@link RcsParticipant}s. Please see Section 5 (1-to-1 Messaging) - GSMA RCC.71 (RCS Universal
+ * Profile Service Definition Document)
+ *
+ * @hide - TODO(109759350) make this public
*/
public class Rcs1To1Thread extends RcsThread {
+ private int mThreadId;
+
+ /**
+ * Public constructor only for RcsMessageStoreController to initialize new threads.
+ *
+ * @hide
+ */
public Rcs1To1Thread(int threadId) {
super(threadId);
+ mThreadId = threadId;
}
- public static final Creator<Rcs1To1Thread> CREATOR = new Creator<Rcs1To1Thread>() {
- @Override
- public Rcs1To1Thread createFromParcel(Parcel in) {
- return new Rcs1To1Thread(in);
- }
-
- @Override
- public Rcs1To1Thread[] newArray(int size) {
- return new Rcs1To1Thread[size];
- }
- };
-
- protected Rcs1To1Thread(Parcel in) {
- super(in);
- }
-
+ /**
+ * @return Returns {@code false} as this is always a 1 to 1 thread.
+ */
@Override
- public int describeContents() {
- return 0;
+ public boolean isGroup() {
+ return false;
}
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(RCS_1_TO_1_TYPE);
- super.writeToParcel(dest, flags);
+ /**
+ * {@link Rcs1To1Thread}s can fall back to SMS as a back-up protocol. This function returns the
+ * thread id to be used to query {@code content://mms-sms/conversation/#} to get the fallback
+ * thread.
+ *
+ * @return The thread id to be used to query the mms-sms authority
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getFallbackThreadId() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.get1To1ThreadFallbackThreadId(mThreadId));
+ }
+
+ /**
+ * If the RCS client allows falling back to SMS, it needs to create an MMS-SMS thread in the
+ * SMS/MMS Provider( see {@link android.provider.Telephony.MmsSms#CONTENT_CONVERSATIONS_URI}.
+ * Use this function to link the {@link Rcs1To1Thread} to the MMS-SMS thread. This function
+ * also updates the storage.
+ *
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setFallbackThreadId(long fallbackThreadId) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.set1To1ThreadFallbackThreadId(mThreadId, fallbackThreadId));
+ }
+
+ /**
+ * @return Returns the {@link RcsParticipant} that receives the messages sent in this thread.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @NonNull
+ @WorkerThread
+ public RcsParticipant getRecipient() throws RcsMessageStoreException {
+ return new RcsParticipant(
+ RcsControllerCall.call(iRcs -> iRcs.get1To1ThreadOtherParticipantId(mThreadId)));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsControllerCall.java b/telephony/java/android/telephony/ims/RcsControllerCall.java
new file mode 100644
index 0000000..5512c4c
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsControllerCall.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.ims.aidl.IRcs;
+
+/**
+ * A wrapper class around RPC calls that {@link RcsMessageStore} APIs to minimize boilerplate code.
+ *
+ * @hide - not meant for public use
+ */
+class RcsControllerCall {
+ static <R> R call(RcsServiceCall<R> serviceCall) throws RcsMessageStoreException {
+ IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_RCS_SERVICE));
+ if (iRcs == null) {
+ throw new RcsMessageStoreException("Could not connect to RCS storage service");
+ }
+
+ try {
+ return serviceCall.methodOnIRcs(iRcs);
+ } catch (RemoteException exception) {
+ throw new RcsMessageStoreException(exception.getMessage());
+ }
+ }
+
+ static void callWithNoReturn(RcsServiceCallWithNoReturn serviceCall)
+ throws RcsMessageStoreException {
+ IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_RCS_SERVICE));
+ if (iRcs == null) {
+ throw new RcsMessageStoreException("Could not connect to RCS storage service");
+ }
+
+ try {
+ serviceCall.methodOnIRcs(iRcs);
+ } catch (RemoteException exception) {
+ throw new RcsMessageStoreException(exception.getMessage());
+ }
+ }
+
+ interface RcsServiceCall<R> {
+ R methodOnIRcs(IRcs iRcs) throws RemoteException;
+ }
+
+ interface RcsServiceCallWithNoReturn {
+ void methodOnIRcs(IRcs iRcs) throws RemoteException;
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsPart.aidl b/telephony/java/android/telephony/ims/RcsEvent.aidl
similarity index 96%
rename from telephony/java/android/telephony/ims/RcsPart.aidl
rename to telephony/java/android/telephony/ims/RcsEvent.aidl
index 8b8077d..08974e0 100644
--- a/telephony/java/android/telephony/ims/RcsPart.aidl
+++ b/telephony/java/android/telephony/ims/RcsEvent.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsPart;
+parcelable RcsEvent;
diff --git a/telephony/java/android/telephony/ims/RcsEvent.java b/telephony/java/android/telephony/ims/RcsEvent.java
new file mode 100644
index 0000000..744ac76
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsEvent.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The base class for events that can happen on {@link RcsParticipant}s and {@link RcsThread}s.
+ * @hide - TODO(109759350) make this public
+ */
+public abstract class RcsEvent implements Parcelable {
+ protected long mTimestamp;
+
+ protected RcsEvent(long timestamp) {
+ mTimestamp = timestamp;
+ }
+
+ /**
+ * @return Returns the time of when this event happened. The timestamp is defined as
+ * milliseconds passed after midnight, January 1, 1970 UTC
+ */
+ public long getTimestamp() {
+ return mTimestamp;
+ }
+
+ /**
+ * Persists the event to the data store
+ *
+ * @hide
+ */
+ abstract void persist() throws RcsMessageStoreException;
+
+ RcsEvent(Parcel in) {
+ mTimestamp = in.readLong();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mTimestamp);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsEventQueryParameters.aidl
similarity index 94%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsEventQueryParameters.aidl
index 82d985d..9a3600b 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsEventQueryParameters.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsEventQueryParameters;
diff --git a/telephony/java/android/telephony/ims/RcsEventQueryParameters.java b/telephony/java/android/telephony/ims/RcsEventQueryParameters.java
new file mode 100644
index 0000000..6aee56f
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsEventQueryParameters.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import static android.provider.Telephony.RcsColumns.RcsEventTypes.ICON_CHANGED_EVENT_TYPE;
+import static android.provider.Telephony.RcsColumns.RcsEventTypes.NAME_CHANGED_EVENT_TYPE;
+import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_ALIAS_CHANGED_EVENT_TYPE;
+import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_JOINED_EVENT_TYPE;
+import static android.provider.Telephony.RcsColumns.RcsEventTypes.PARTICIPANT_LEFT_EVENT_TYPE;
+
+import android.annotation.CheckResult;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.security.InvalidParameterException;
+
+/**
+ * The parameters to pass into
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} in order to select a
+ * subset of {@link RcsEvent}s present in the message store.
+ *
+ * @hide TODO - make the Builder and builder() public. The rest should stay internal only.
+ */
+public class RcsEventQueryParameters implements Parcelable {
+ /**
+ * Flag to be used with {@link Builder#setEventType(int)} to make
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return all types of
+ * {@link RcsEvent}s
+ */
+ public static final int ALL_EVENTS = -1;
+
+ /**
+ * Flag to be used with {@link Builder#setEventType(int)} to make
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return sub-types of
+ * {@link RcsGroupThreadEvent}s
+ */
+ public static final int ALL_GROUP_THREAD_EVENTS = 0;
+
+ /**
+ * Flag to be used with {@link Builder#setEventType(int)} to make
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only
+ * {@link RcsParticipantAliasChangedEvent}s
+ */
+ public static final int PARTICIPANT_ALIAS_CHANGED_EVENT =
+ PARTICIPANT_ALIAS_CHANGED_EVENT_TYPE;
+
+ /**
+ * Flag to be used with {@link Builder#setEventType(int)} to make
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only
+ * {@link RcsGroupThreadParticipantJoinedEvent}s
+ */
+ public static final int GROUP_THREAD_PARTICIPANT_JOINED_EVENT =
+ PARTICIPANT_JOINED_EVENT_TYPE;
+
+ /**
+ * Flag to be used with {@link Builder#setEventType(int)} to make
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only
+ * {@link RcsGroupThreadParticipantLeftEvent}s
+ */
+ public static final int GROUP_THREAD_PARTICIPANT_LEFT_EVENT =
+ PARTICIPANT_LEFT_EVENT_TYPE;
+
+ /**
+ * Flag to be used with {@link Builder#setEventType(int)} to make
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only
+ * {@link RcsGroupThreadNameChangedEvent}s
+ */
+ public static final int GROUP_THREAD_NAME_CHANGED_EVENT = NAME_CHANGED_EVENT_TYPE;
+
+ /**
+ * Flag to be used with {@link Builder#setEventType(int)} to make
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)} return only
+ * {@link RcsGroupThreadIconChangedEvent}s
+ */
+ public static final int GROUP_THREAD_ICON_CHANGED_EVENT = ICON_CHANGED_EVENT_TYPE;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ALL_EVENTS, ALL_GROUP_THREAD_EVENTS, PARTICIPANT_ALIAS_CHANGED_EVENT,
+ GROUP_THREAD_PARTICIPANT_JOINED_EVENT, GROUP_THREAD_PARTICIPANT_LEFT_EVENT,
+ GROUP_THREAD_NAME_CHANGED_EVENT, GROUP_THREAD_ICON_CHANGED_EVENT})
+ public @interface EventType {
+ }
+
+ /**
+ * Flag to be used with {@link Builder#setSortProperty(int)} that makes the result set sorted
+ * in the order of creation for faster query results.
+ */
+ public static final int SORT_BY_CREATION_ORDER = 0;
+
+ /**
+ * Flag to be used with {@link Builder#setSortProperty(int)} that makes the result set sorted
+ * with respect to {@link RcsEvent#getTimestamp()}
+ */
+ public static final int SORT_BY_TIMESTAMP = 1;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({SORT_BY_CREATION_ORDER, SORT_BY_TIMESTAMP})
+ public @interface SortingProperty {
+ }
+
+ /**
+ * The key to pass into a Bundle, for usage in RcsProvider.query(Bundle)
+ * @hide - not meant for public use
+ */
+ public static final String EVENT_QUERY_PARAMETERS_KEY = "event_query_parameters";
+
+ // Which types of events the results should be limited to
+ private @EventType int mEventType;
+ // The property which the results should be sorted against
+ private int mSortingProperty;
+ // Whether the results should be sorted in ascending order
+ private boolean mIsAscending;
+ // The number of results that should be returned with this query
+ private int mLimit;
+ // The thread that the results are limited to
+ private int mThreadId;
+
+ RcsEventQueryParameters(@EventType int eventType, int threadId,
+ @SortingProperty int sortingProperty, boolean isAscending, int limit) {
+ mEventType = eventType;
+ mSortingProperty = sortingProperty;
+ mIsAscending = isAscending;
+ mLimit = limit;
+ mThreadId = threadId;
+ }
+
+ /**
+ * @return Returns the type of {@link RcsEvent}s that this {@link RcsEventQueryParameters} is
+ * set to query for.
+ */
+ public @EventType int getEventType() {
+ return mEventType;
+ }
+
+ /**
+ * @return Returns the type of {@link RcsEvent}s that this {@link RcsEventQueryParameters} is
+ * set to query for.
+ */
+ public int getLimit() {
+ return mLimit;
+ }
+
+ /**
+ * @return Returns the property where the results should be sorted against.
+ * @see SortingProperty
+ */
+ public int getSortingProperty() {
+ return mSortingProperty;
+ }
+
+ /**
+ * @return Returns {@code true} if the result set will be sorted in ascending order,
+ * {@code false} if it will be sorted in descending order.
+ */
+ public boolean getSortDirection() {
+ return mIsAscending;
+ }
+
+ /**
+ * @return Returns the ID of the {@link RcsGroupThread} that the results are limited to. As this
+ * API exposes an ID, it should stay hidden.
+ *
+ * @hide
+ */
+ public int getThreadId() {
+ return mThreadId;
+ }
+
+ /**
+ * A helper class to build the {@link RcsEventQueryParameters}.
+ */
+ public static class Builder {
+ private @EventType int mEventType;
+ private @SortingProperty int mSortingProperty;
+ private boolean mIsAscending;
+ private int mLimit = 100;
+ private int mThreadId;
+
+ /**
+ * Creates a new builder for {@link RcsEventQueryParameters} to be used in
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)}
+ */
+ public Builder() {
+ // empty implementation
+ }
+
+ /**
+ * Desired number of events to be returned from the query. Passing in 0 will return all
+ * existing events at once. The limit defaults to 100.
+ *
+ * @param limit The number to limit the query result to.
+ * @return The same instance of the builder to chain parameters.
+ * @throws InvalidParameterException If the given limit is negative.
+ */
+ @CheckResult
+ public Builder setResultLimit(@IntRange(from = 0) int limit)
+ throws InvalidParameterException {
+ if (limit < 0) {
+ throw new InvalidParameterException("The query limit must be non-negative");
+ }
+
+ mLimit = limit;
+ return this;
+ }
+
+ /**
+ * Sets the type of events to be returned from the query.
+ *
+ * @param eventType The type of event to be returned.
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setEventType(@EventType int eventType) {
+ mEventType = eventType;
+ return this;
+ }
+
+ /**
+ * Sets the property where the results should be sorted against. Defaults to
+ * {@link RcsEventQueryParameters.SortingProperty#SORT_BY_CREATION_ORDER}
+ *
+ * @param sortingProperty against which property the results should be sorted
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setSortProperty(@SortingProperty int sortingProperty) {
+ mSortingProperty = sortingProperty;
+ return this;
+ }
+
+ /**
+ * Sets whether the results should be sorted ascending or descending
+ *
+ * @param isAscending whether the results should be sorted ascending
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setSortDirection(boolean isAscending) {
+ mIsAscending = isAscending;
+ return this;
+ }
+
+ /**
+ * Limits the results to the given {@link RcsGroupThread}. Setting this value prevents
+ * returning any instances of {@link RcsParticipantAliasChangedEvent}.
+ *
+ * @param groupThread The thread to limit the results to.
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setGroupThread(@NonNull RcsGroupThread groupThread) {
+ mThreadId = groupThread.getThreadId();
+ return this;
+ }
+
+ /**
+ * Builds the {@link RcsEventQueryParameters} to use in
+ * {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)}
+ *
+ * @return An instance of {@link RcsEventQueryParameters} to use with the event query.
+ */
+ public RcsEventQueryParameters build() {
+ return new RcsEventQueryParameters(mEventType, mThreadId, mSortingProperty,
+ mIsAscending, mLimit);
+ }
+ }
+
+ protected RcsEventQueryParameters(Parcel in) {
+ mEventType = in.readInt();
+ mThreadId = in.readInt();
+ mSortingProperty = in.readInt();
+ mIsAscending = in.readBoolean();
+ mLimit = in.readInt();
+ }
+
+ public static final Creator<RcsEventQueryParameters> CREATOR =
+ new Creator<RcsEventQueryParameters>() {
+ @Override
+ public RcsEventQueryParameters createFromParcel(Parcel in) {
+ return new RcsEventQueryParameters(in);
+ }
+
+ @Override
+ public RcsEventQueryParameters[] newArray(int size) {
+ return new RcsEventQueryParameters[size];
+ }
+ };
+
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mEventType);
+ dest.writeInt(mThreadId);
+ dest.writeInt(mSortingProperty);
+ dest.writeBoolean(mIsAscending);
+ dest.writeInt(mLimit);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsEventQueryResult.aidl
similarity index 94%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsEventQueryResult.aidl
index 82d985d..7d13335 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsEventQueryResult.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsEventQueryResult;
diff --git a/telephony/java/android/telephony/ims/RcsEventQueryResult.java b/telephony/java/android/telephony/ims/RcsEventQueryResult.java
new file mode 100644
index 0000000..27898ab
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsEventQueryResult.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.List;
+
+/**
+ * The result of a {@link RcsMessageStore#getRcsEvents(RcsEventQueryParameters)}
+ * call. This class allows getting the token for querying the next batch of events in order to
+ * prevent handling large amounts of data at once.
+ *
+ * @hide
+ */
+public class RcsEventQueryResult implements Parcelable {
+ private RcsQueryContinuationToken mContinuationToken;
+ private List<RcsEvent> mEvents;
+
+ /**
+ * Internal constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController}
+ * to create query results
+ *
+ * @hide
+ */
+ public RcsEventQueryResult(
+ RcsQueryContinuationToken continuationToken,
+ List<RcsEvent> events) {
+ mContinuationToken = continuationToken;
+ mEvents = events;
+ }
+
+ /**
+ * Returns a token to call
+ * {@link RcsMessageStore#getRcsEvents(RcsQueryContinuationToken)}
+ * to get the next batch of {@link RcsEvent}s.
+ */
+ public RcsQueryContinuationToken getContinuationToken() {
+ return mContinuationToken;
+ }
+
+ /**
+ * Returns all the {@link RcsEvent}s in the current query result. Call {@link
+ * RcsMessageStore#getRcsEvents(RcsQueryContinuationToken)} to get the next batch
+ * of {@link RcsEvent}s.
+ */
+ public List<RcsEvent> getEvents() {
+ return mEvents;
+ }
+
+ protected RcsEventQueryResult(Parcel in) {
+ }
+
+ public static final Creator<RcsEventQueryResult> CREATOR = new Creator<RcsEventQueryResult>() {
+ @Override
+ public RcsEventQueryResult createFromParcel(Parcel in) {
+ return new RcsEventQueryResult(in);
+ }
+
+ @Override
+ public RcsEventQueryResult[] newArray(int size) {
+ return new RcsEventQueryResult[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(mContinuationToken, flags);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.aidl
similarity index 93%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.aidl
index 82d985d..5fec021 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsFileTransferCreationParameters;
diff --git a/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.java b/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.java
new file mode 100644
index 0000000..bd7cb4b
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsFileTransferCreationParameters.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.annotation.CheckResult;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Pass an instance of this class to
+ * {@link RcsMessage#insertFileTransfer(RcsFileTransferCreationParameters)} create an
+ * {@link RcsFileTransferPart} and save it into storage.
+ *
+ * @hide - TODO(109759350) make this public
+ */
+public class RcsFileTransferCreationParameters implements Parcelable {
+ private String mRcsFileTransferSessionId;
+ private Uri mContentUri;
+ private String mContentMimeType;
+ private long mFileSize;
+ private long mTransferOffset;
+ private int mWidth;
+ private int mHeight;
+ private long mMediaDuration;
+ private Uri mPreviewUri;
+ private String mPreviewMimeType;
+ private @RcsFileTransferPart.RcsFileTransferStatus int mFileTransferStatus;
+
+ /**
+ * @return Returns the globally unique RCS file transfer session ID for the
+ * {@link RcsFileTransferPart} to be created
+ */
+ public String getRcsFileTransferSessionId() {
+ return mRcsFileTransferSessionId;
+ }
+
+ /**
+ * @return Returns the URI for the content of the {@link RcsFileTransferPart} to be created
+ */
+ public Uri getContentUri() {
+ return mContentUri;
+ }
+
+ /**
+ * @return Returns the MIME type for the content of the {@link RcsFileTransferPart} to be
+ * created
+ */
+ public String getContentMimeType() {
+ return mContentMimeType;
+ }
+
+ /**
+ * @return Returns the file size in bytes for the {@link RcsFileTransferPart} to be created
+ */
+ public long getFileSize() {
+ return mFileSize;
+ }
+
+ /**
+ * @return Returns the transfer offset for the {@link RcsFileTransferPart} to be created. The
+ * file transfer offset is defined as how many bytes have been successfully transferred to the
+ * receiver of this file transfer.
+ */
+ public long getTransferOffset() {
+ return mTransferOffset;
+ }
+
+ /**
+ * @return Returns the width of the {@link RcsFileTransferPart} to be created. The value is in
+ * pixels.
+ */
+ public int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * @return Returns the height of the {@link RcsFileTransferPart} to be created. The value is in
+ * pixels.
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * @return Returns the duration of the {@link RcsFileTransferPart} to be created.
+ */
+ public long getMediaDuration() {
+ return mMediaDuration;
+ }
+
+ /**
+ * @return Returns the URI of the preview of the content of the {@link RcsFileTransferPart} to
+ * be created. This should only be used for multi-media files.
+ */
+ public Uri getPreviewUri() {
+ return mPreviewUri;
+ }
+
+ /**
+ * @return Returns the MIME type of the preview of the content of the
+ * {@link RcsFileTransferPart} to be created. This should only be used for multi-media files.
+ */
+ public String getPreviewMimeType() {
+ return mPreviewMimeType;
+ }
+
+ /**
+ * @return Returns the status of the {@link RcsFileTransferPart} to be created.
+ */
+ public @RcsFileTransferPart.RcsFileTransferStatus int getFileTransferStatus() {
+ return mFileTransferStatus;
+ }
+
+ /**
+ * @hide
+ */
+ RcsFileTransferCreationParameters(Builder builder) {
+ mRcsFileTransferSessionId = builder.mRcsFileTransferSessionId;
+ mContentUri = builder.mContentUri;
+ mContentMimeType = builder.mContentMimeType;
+ mFileSize = builder.mFileSize;
+ mTransferOffset = builder.mTransferOffset;
+ mWidth = builder.mWidth;
+ mHeight = builder.mHeight;
+ mMediaDuration = builder.mLength;
+ mPreviewUri = builder.mPreviewUri;
+ mPreviewMimeType = builder.mPreviewMimeType;
+ mFileTransferStatus = builder.mFileTransferStatus;
+ }
+
+ /**
+ * A builder to create instances of {@link RcsFileTransferCreationParameters}
+ */
+ public class Builder {
+ private String mRcsFileTransferSessionId;
+ private Uri mContentUri;
+ private String mContentMimeType;
+ private long mFileSize;
+ private long mTransferOffset;
+ private int mWidth;
+ private int mHeight;
+ private long mLength;
+ private Uri mPreviewUri;
+ private String mPreviewMimeType;
+ private @RcsFileTransferPart.RcsFileTransferStatus int mFileTransferStatus;
+
+ /**
+ * Sets the globally unique RCS file transfer session ID for the {@link RcsFileTransferPart}
+ * to be created
+ *
+ * @param sessionId The RCS file transfer session ID
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setFileTransferSessionId(String sessionId) {
+ mRcsFileTransferSessionId = sessionId;
+ return this;
+ }
+
+ /**
+ * Sets the URI for the content of the {@link RcsFileTransferPart} to be created
+ *
+ * @param contentUri The URI for the file
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setContentUri(Uri contentUri) {
+ mContentUri = contentUri;
+ return this;
+ }
+
+ /**
+ * Sets the MIME type for the content of the {@link RcsFileTransferPart} to be created
+ *
+ * @param contentType The MIME type of the file
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setContentMimeType(String contentType) {
+ mContentMimeType = contentType;
+ return this;
+ }
+
+ /**
+ * Sets the file size for the {@link RcsFileTransferPart} to be created
+ *
+ * @param size The size of the file in bytes
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setFileSize(long size) {
+ mFileSize = size;
+ return this;
+ }
+
+ /**
+ * Sets the transfer offset for the {@link RcsFileTransferPart} to be created. The file
+ * transfer offset is defined as how many bytes have been successfully transferred to the
+ * receiver of this file transfer.
+ *
+ * @param offset The transfer offset in bytes
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setTransferOffset(long offset) {
+ mTransferOffset = offset;
+ return this;
+ }
+
+ /**
+ * Sets the width of the {@link RcsFileTransferPart} to be created. This should only be used
+ * for multi-media files.
+ *
+ * @param width The width of the multi-media file in pixels.
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setWidth(int width) {
+ mWidth = width;
+ return this;
+ }
+
+ /**
+ * Sets the height of the {@link RcsFileTransferPart} to be created. This should only be
+ * used for multi-media files.
+ *
+ * @param height The height of the multi-media file in pixels.
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setHeight(int height) {
+ mHeight = height;
+ return this;
+ }
+
+ /**
+ * Sets the length of the {@link RcsFileTransferPart} to be created. This should only be
+ * used for multi-media files such as audio or video.
+ *
+ * @param length The length of the multi-media file in milliseconds
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setMediaDuration(long length) {
+ mLength = length;
+ return this;
+ }
+
+ /**
+ * Sets the URI of the preview of the content of the {@link RcsFileTransferPart} to be
+ * created. This should only be used for multi-media files.
+ *
+ * @param previewUri The URI of the preview of the file transfer
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setPreviewUri(Uri previewUri) {
+ mPreviewUri = previewUri;
+ return this;
+ }
+
+ /**
+ * Sets the MIME type of the preview of the content of the {@link RcsFileTransferPart} to
+ * be created. This should only be used for multi-media files.
+ *
+ * @param previewType The MIME type of the preview of the file transfer
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setPreviewMimeType(String previewType) {
+ mPreviewMimeType = previewType;
+ return this;
+ }
+
+ /**
+ * Sets the status of the {@link RcsFileTransferPart} to be created.
+ *
+ * @param status The status of the file transfer
+ * @return The same instance of {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setFileTransferStatus(
+ @RcsFileTransferPart.RcsFileTransferStatus int status) {
+ mFileTransferStatus = status;
+ return this;
+ }
+
+ /**
+ * Creates an instance of {@link RcsFileTransferCreationParameters} with the given
+ * parameters.
+ *
+ * @return The same instance of {@link Builder} to chain methods
+ * @see RcsMessage#insertFileTransfer(RcsFileTransferCreationParameters)
+ */
+ public RcsFileTransferCreationParameters build() {
+ return new RcsFileTransferCreationParameters(this);
+ }
+ }
+
+ protected RcsFileTransferCreationParameters(Parcel in) {
+ mRcsFileTransferSessionId = in.readString();
+ mContentUri = in.readParcelable(Uri.class.getClassLoader());
+ mContentMimeType = in.readString();
+ mFileSize = in.readLong();
+ mTransferOffset = in.readLong();
+ mWidth = in.readInt();
+ mHeight = in.readInt();
+ mMediaDuration = in.readLong();
+ mPreviewUri = in.readParcelable(Uri.class.getClassLoader());
+ mPreviewMimeType = in.readString();
+ mFileTransferStatus = in.readInt();
+ }
+
+ public static final Creator<RcsFileTransferCreationParameters> CREATOR =
+ new Creator<RcsFileTransferCreationParameters>() {
+ @Override
+ public RcsFileTransferCreationParameters createFromParcel(Parcel in) {
+ return new RcsFileTransferCreationParameters(in);
+ }
+
+ @Override
+ public RcsFileTransferCreationParameters[] newArray(int size) {
+ return new RcsFileTransferCreationParameters[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mRcsFileTransferSessionId);
+ dest.writeParcelable(mContentUri, flags);
+ dest.writeString(mContentMimeType);
+ dest.writeLong(mFileSize);
+ dest.writeLong(mTransferOffset);
+ dest.writeInt(mWidth);
+ dest.writeInt(mHeight);
+ dest.writeLong(mMediaDuration);
+ dest.writeParcelable(mPreviewUri, flags);
+ dest.writeString(mPreviewMimeType);
+ dest.writeInt(mFileTransferStatus);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsFileTransferPart.aidl b/telephony/java/android/telephony/ims/RcsFileTransferPart.aidl
deleted file mode 100644
index eaf3128..0000000
--- a/telephony/java/android/telephony/ims/RcsFileTransferPart.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsFileTransferPart;
diff --git a/telephony/java/android/telephony/ims/RcsFileTransferPart.java b/telephony/java/android/telephony/ims/RcsFileTransferPart.java
index 39c58dd..2eadc4a 100644
--- a/telephony/java/android/telephony/ims/RcsFileTransferPart.java
+++ b/telephony/java/android/telephony/ims/RcsFileTransferPart.java
@@ -15,34 +15,346 @@
*/
package android.telephony.ims;
-import android.os.Parcel;
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.annotation.WorkerThread;
+import android.net.Uri;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
- * A part of a composite {@link RcsMessage} that holds a file transfer.
- * @hide - TODO(sahinc) make this public
+ * A part of a composite {@link RcsMessage} that holds a file transfer. Please see Section 7
+ * (File Transfer) - GSMA RCC.71 (RCS Universal Profile Service Definition Document)
+ *
+ * @hide - TODO(109759350) make this public
*/
-public class RcsFileTransferPart extends RcsPart {
- public static final Creator<RcsFileTransferPart> CREATOR = new Creator<RcsFileTransferPart>() {
- @Override
- public RcsFileTransferPart createFromParcel(Parcel in) {
- return new RcsFileTransferPart(in);
- }
+public class RcsFileTransferPart {
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} is not set yet.
+ */
+ public static final int NOT_SET = 0;
- @Override
- public RcsFileTransferPart[] newArray(int size) {
- return new RcsFileTransferPart[size];
- }
- };
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} is a draft and is not in the
+ * process of sending yet.
+ */
+ public static final int DRAFT = 1;
- protected RcsFileTransferPart(Parcel in) {
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} is actively being sent right
+ * now.
+ */
+ public static final int SENDING = 2;
+
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} was being sent, but the user has
+ * paused the sending process.
+ */
+ public static final int SENDING_PAUSED = 3;
+
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} was attempted, but failed to
+ * send.
+ */
+ public static final int SENDING_FAILED = 4;
+
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} is permanently cancelled to
+ * send.
+ */
+ public static final int SENDING_CANCELLED = 5;
+
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} is actively being downloaded
+ * right now.
+ */
+ public static final int DOWNLOADING = 6;
+
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} was being downloaded, but the
+ * user paused the downloading process.
+ */
+ public static final int DOWNLOADING_PAUSED = 7;
+
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} was attempted, but failed to
+ * download.
+ */
+ public static final int DOWNLOADING_FAILED = 8;
+
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} is permanently cancelled to
+ * download.
+ */
+ public static final int DOWNLOADING_CANCELLED = 9;
+
+ /**
+ * The status to indicate that this {@link RcsFileTransferPart} was successfully sent or
+ * received.
+ */
+ public static final int SUCCEEDED = 10;
+
+ @IntDef({
+ DRAFT, SENDING, SENDING_PAUSED, SENDING_FAILED, SENDING_CANCELLED, DOWNLOADING,
+ DOWNLOADING_PAUSED, DOWNLOADING_FAILED, DOWNLOADING_CANCELLED, SUCCEEDED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RcsFileTransferStatus {
}
- @Override
- public int describeContents() {
- return 0;
+ private int mId;
+
+ /**
+ * @hide
+ */
+ RcsFileTransferPart(int id) {
+ mId = id;
}
- @Override
- public void writeToParcel(Parcel dest, int flags) {
+ /**
+ * @hide
+ */
+ public void setId(int id) {
+ mId = id;
+ }
+
+ /**
+ * @hide
+ */
+ public int getId() {
+ return mId;
+ }
+
+ /**
+ * Sets the RCS file transfer session ID for this file transfer and persists into storage.
+ *
+ * @param sessionId The session ID to be used for this file transfer.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setFileTransferSessionId(String sessionId) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferSessionId(mId, sessionId));
+ }
+
+ /**
+ * @return Returns the file transfer session ID.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public String getFileTransferSessionId() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferSessionId(mId));
+ }
+
+ /**
+ * Sets the content URI for this file transfer and persists into storage. The file transfer
+ * should be reachable using this URI.
+ *
+ * @param contentUri The URI for this file transfer.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setContentUri(Uri contentUri) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferContentUri(mId, contentUri));
+ }
+
+ /**
+ * @return Returns the URI for this file transfer
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @Nullable
+ @WorkerThread
+ public Uri getContentUri() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferContentUri(mId));
+ }
+
+ /**
+ * Sets the MIME type of this file transfer and persists into storage. Whether this type
+ * actually matches any known or supported types is not checked.
+ *
+ * @param contentMimeType The type of this file transfer.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setContentMimeType(String contentMimeType) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setFileTransferContentType(mId, contentMimeType));
+ }
+
+ /**
+ * @return Returns the content type of this file transfer
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ @Nullable
+ public String getContentMimeType() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferContentType(mId));
+ }
+
+ /**
+ * Sets the content length (i.e. file size) for this file transfer and persists into storage.
+ *
+ * @param contentLength The content length of this file transfer
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setFileSize(long contentLength) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setFileTransferFileSize(mId, contentLength));
+ }
+
+ /**
+ * @return Returns the content length (i.e. file size) for this file transfer.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getFileSize() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferFileSize(mId));
+ }
+
+ /**
+ * Sets the transfer offset for this file transfer and persists into storage. The file transfer
+ * offset is defined as how many bytes have been successfully transferred to the receiver of
+ * this file transfer.
+ *
+ * @param transferOffset The transfer offset for this file transfer.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setTransferOffset(long transferOffset) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setFileTransferTransferOffset(mId, transferOffset));
+ }
+
+ /**
+ * @return Returns the number of bytes that have successfully transferred.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getTransferOffset() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferTransferOffset(mId));
+ }
+
+ /**
+ * Sets the status for this file transfer and persists into storage.
+ *
+ * @param status The status of this file transfer.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setFileTransferStatus(@RcsFileTransferStatus int status)
+ throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferStatus(mId, status));
+ }
+
+ /**
+ * @return Returns the status of this file transfer.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public @RcsFileTransferStatus int getFileTransferStatus() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferStatus(mId));
+ }
+
+ /**
+ * @return Returns the width of this multi-media message part in pixels.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public int getWidth() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferWidth(mId));
+ }
+
+ /**
+ * Sets the width of this RCS multi-media message part and persists into storage.
+ *
+ * @param width The width value in pixels
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setWidth(int width) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferWidth(mId, width));
+ }
+
+ /**
+ * @return Returns the height of this multi-media message part in pixels.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public int getHeight() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferHeight(mId));
+ }
+
+ /**
+ * Sets the height of this RCS multi-media message part and persists into storage.
+ *
+ * @param height The height value in pixels
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setHeight(int height) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferHeight(mId, height));
+ }
+
+ /**
+ * @return Returns the length of this multi-media file (e.g. video or audio) in milliseconds.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getLength() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferLength(mId));
+ }
+
+ /**
+ * Sets the length of this multi-media file (e.g. video or audio) and persists into storage.
+ *
+ * @param length The length of the file in milliseconds.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setLength(long length) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferLength(mId, length));
+ }
+
+ /**
+ * @return Returns the URI for the preview of this multi-media file (e.g. an image thumbnail for
+ * a video)
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public Uri getPreviewUri() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferPreviewUri(mId));
+ }
+
+ /**
+ * Sets the URI for the preview of this multi-media file and persists into storage.
+ *
+ * @param previewUri The URI to access to the preview file.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setPreviewUri(Uri previewUri) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setFileTransferPreviewUri(mId, previewUri));
+ }
+
+ /**
+ * @return Returns the MIME type of this multi-media file's preview.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public String getPreviewMimeType() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getFileTransferPreviewType(mId));
+ }
+
+ /**
+ * Sets the MIME type for this multi-media file's preview and persists into storage.
+ *
+ * @param previewMimeType The MIME type for the preview
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setPreviewMimeType(String previewMimeType) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setFileTransferPreviewType(mId, previewMimeType));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsGroupThread.aidl b/telephony/java/android/telephony/ims/RcsGroupThread.aidl
deleted file mode 100644
index c4ce529..0000000
--- a/telephony/java/android/telephony/ims/RcsGroupThread.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsGroupThread;
diff --git a/telephony/java/android/telephony/ims/RcsGroupThread.java b/telephony/java/android/telephony/ims/RcsGroupThread.java
index d954b2d..6f6258e 100644
--- a/telephony/java/android/telephony/ims/RcsGroupThread.java
+++ b/telephony/java/android/telephony/ims/RcsGroupThread.java
@@ -15,38 +15,191 @@
*/
package android.telephony.ims;
-import android.os.Parcel;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.WorkerThread;
+import android.net.Uri;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
/**
* RcsGroupThread represents a single RCS conversation thread where {@link RcsParticipant}s can join
- * or leave.
+ * or leave. Please see Section 6 (Group Chat) - GSMA RCC.71 (RCS Universal Profile Service
+ * Definition Document)
+ *
* @hide - TODO(sahinc) make this public
*/
public class RcsGroupThread extends RcsThread {
- public static final Creator<RcsGroupThread> CREATOR = new Creator<RcsGroupThread>() {
- @Override
- public RcsGroupThread createFromParcel(Parcel in) {
- return new RcsGroupThread(in);
- }
-
- @Override
- public RcsGroupThread[] newArray(int size) {
- return new RcsGroupThread[size];
- }
- };
-
- protected RcsGroupThread(Parcel in) {
- super(in);
+ /**
+ * Public constructor only for RcsMessageStoreController to initialize new threads.
+ *
+ * @hide
+ */
+ public RcsGroupThread(int threadId) {
+ super(threadId);
}
+ /**
+ * @return Returns {@code true} as this is always a group thread
+ */
@Override
- public int describeContents() {
- return 0;
+ public boolean isGroup() {
+ return true;
}
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(RCS_GROUP_TYPE);
- super.writeToParcel(dest, flags);
+ /**
+ * @return Returns the given name of this {@link RcsGroupThread}. Please see US6-2 - GSMA RCC.71
+ * (RCS Universal Profile Service Definition Document)
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @Nullable
+ @WorkerThread
+ public String getGroupName() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getGroupThreadName(mThreadId));
+ }
+
+ /**
+ * Sets the name of this {@link RcsGroupThread} and saves it into storage. Please see US6-2 -
+ * GSMA RCC.71 (RCS Universal Profile Service Definition Document)
+ *
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setGroupName(String groupName) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setGroupThreadName(mThreadId, groupName));
+ }
+
+ /**
+ * @return Returns a URI that points to the group's icon {@link RcsGroupThread}. Please see
+ * US6-2 - GSMA RCC.71 (RCS Universal Profile Service Definition Document)
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @Nullable
+ public Uri getGroupIcon() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getGroupThreadIcon(mThreadId));
+ }
+
+ /**
+ * Sets the icon for this {@link RcsGroupThread} and saves it into storage. Please see US6-2 -
+ * GSMA RCC.71 (RCS Universal Profile Service Definition Document)
+ *
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setGroupIcon(@Nullable Uri groupIcon) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setGroupThreadIcon(mThreadId, groupIcon));
+ }
+
+ /**
+ * @return Returns the owner of this thread or {@code null} if there doesn't exist an owner
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @Nullable
+ @WorkerThread
+ public RcsParticipant getOwner() throws RcsMessageStoreException {
+ return new RcsParticipant(RcsControllerCall.call(
+ iRcs -> iRcs.getGroupThreadOwner(mThreadId)));
+ }
+
+ /**
+ * Sets the owner of this {@link RcsGroupThread} and saves it into storage. This is intended to
+ * be used for selecting a new owner for a group thread if the owner leaves the thread. The
+ * owner needs to be in the list of existing participants.
+ *
+ * @param participant The new owner of the thread. {@code null} values are allowed.
+ * @throws RcsMessageStoreException if the operation could not be persisted into storage
+ */
+ @WorkerThread
+ public void setOwner(@Nullable RcsParticipant participant) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setGroupThreadOwner(mThreadId, participant.getId()));
+ }
+
+ /**
+ * Adds a new {@link RcsParticipant} to this group thread and persists into storage. If the user
+ * is actively participating in this {@link RcsGroupThread}, an {@link RcsParticipant} on behalf
+ * of them should be added.
+ *
+ * @param participant The new participant to be added to the thread.
+ * @throws RcsMessageStoreException if the operation could not be persisted into storage
+ */
+ @WorkerThread
+ public void addParticipant(@NonNull RcsParticipant participant)
+ throws RcsMessageStoreException {
+ if (participant == null) {
+ return;
+ }
+
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.addParticipantToGroupThread(mThreadId, participant.getId()));
+ }
+
+ /**
+ * Removes an {@link RcsParticipant} from this group thread and persists into storage. If the
+ * removed participant was the owner of this group, the owner will become null.
+ *
+ * @throws RcsMessageStoreException if the operation could not be persisted into storage
+ */
+ @WorkerThread
+ public void removeParticipant(@NonNull RcsParticipant participant)
+ throws RcsMessageStoreException {
+ if (participant == null) {
+ return;
+ }
+
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.removeParticipantFromGroupThread(mThreadId, participant.getId()));
+ }
+
+ /**
+ * Returns the set of {@link RcsParticipant}s that contribute to this group thread. The
+ * returned set does not support modifications, please use
+ * {@link RcsGroupThread#addParticipant(RcsParticipant)}
+ * and {@link RcsGroupThread#removeParticipant(RcsParticipant)} instead.
+ *
+ * @return the immutable set of {@link RcsParticipant} in this group thread.
+ * @throws RcsMessageStoreException if the values could not be read from the storage
+ */
+ @WorkerThread
+ @NonNull
+ public Set<RcsParticipant> getParticipants() throws RcsMessageStoreException {
+ RcsParticipantQueryParameters queryParameters =
+ new RcsParticipantQueryParameters.Builder().setThread(this).build();
+
+ RcsParticipantQueryResult queryResult = RcsControllerCall.call(
+ iRcs -> iRcs.getParticipants(queryParameters));
+
+ List<RcsParticipant> participantList = queryResult.getParticipants();
+ Set<RcsParticipant> participantSet = new LinkedHashSet<>(participantList);
+ return Collections.unmodifiableSet(participantSet);
+ }
+
+ /**
+ * Returns the conference URI for this {@link RcsGroupThread}. Please see 4.4.5.2 - GSMA RCC.53
+ * (RCS Device API 1.6 Specification
+ *
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @Nullable
+ @WorkerThread
+ public Uri getConferenceUri() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getGroupThreadConferenceUri(mThreadId));
+ }
+
+ /**
+ * Sets the conference URI for this {@link RcsGroupThread} and persists into storage. Please see
+ * 4.4.5.2 - GSMA RCC.53 (RCS Device API 1.6 Specification
+ *
+ * @param conferenceUri The URI as String to be used as the conference URI.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @Nullable
+ @WorkerThread
+ public void setConferenceUri(Uri conferenceUri) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setGroupThreadConferenceUri(mThreadId, conferenceUri));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsThreadEvent.aidl b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.aidl
similarity index 95%
rename from telephony/java/android/telephony/ims/RcsThreadEvent.aidl
rename to telephony/java/android/telephony/ims/RcsGroupThreadEvent.aidl
index 4a40d89..77a2372 100644
--- a/telephony/java/android/telephony/ims/RcsThreadEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.aidl
@@ -1,5 +1,4 @@
/*
- *
* Copyright 2019, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,4 +16,4 @@
package android.telephony.ims;
-parcelable RcsThreadEvent;
+parcelable RcsGroupThreadEvent;
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java
new file mode 100644
index 0000000..a18437b
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadEvent.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+
+/**
+ * An event that happened on an {@link RcsGroupThread}.
+ *
+ * @hide - TODO(109759350) make this public
+ */
+public abstract class RcsGroupThreadEvent extends RcsEvent {
+ private final int mRcsGroupThreadId;
+ private final int mOriginatingParticipantId;
+
+ RcsGroupThreadEvent(long timestamp, int rcsGroupThreadId,
+ int originatingParticipantId) {
+ super(timestamp);
+ mRcsGroupThreadId = rcsGroupThreadId;
+ mOriginatingParticipantId = originatingParticipantId;
+ }
+
+ /**
+ * @return Returns the {@link RcsGroupThread} that this event happened on.
+ */
+ @NonNull
+ public RcsGroupThread getRcsGroupThread() {
+ return new RcsGroupThread(mRcsGroupThreadId);
+ }
+
+ /**
+ * @return Returns the {@link RcsParticipant} that performed the event.
+ */
+ @NonNull
+ public RcsParticipant getOriginatingParticipant() {
+ return new RcsParticipant(mOriginatingParticipantId);
+ }
+
+ RcsGroupThreadEvent(Parcel in) {
+ super(in);
+ mRcsGroupThreadId = in.readInt();
+ mOriginatingParticipantId = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mRcsGroupThreadId);
+ dest.writeInt(mOriginatingParticipantId);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.aidl
similarity index 93%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.aidl
index 82d985d..daea792 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.aidl
@@ -1,5 +1,4 @@
/*
- *
* Copyright 2019, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,4 +16,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsGroupThreadIconChangedEvent;
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java
new file mode 100644
index 0000000..7beed3b
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadIconChangedEvent.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.Uri;
+import android.os.Parcel;
+
+/**
+ * An event that indicates an {@link RcsGroupThread}'s icon was changed. Please see R6-2-5 - GSMA
+ * RCC.71 (RCS Universal Profile Service Definition Document)
+ *
+ * @hide - TODO(109759350) make this public
+ */
+public class RcsGroupThreadIconChangedEvent extends RcsGroupThreadEvent {
+ private final Uri mNewIcon;
+
+ /**
+ * Creates a new {@link RcsGroupThreadIconChangedEvent}. This event is not persisted into
+ * storage until {@link RcsMessageStore#persistRcsEvent(RcsEvent)} is called.
+ *
+ * @param timestamp The timestamp of when this event happened, in milliseconds passed after
+ * midnight, January 1st, 1970 UTC
+ * @param rcsGroupThread The {@link RcsGroupThread} that this event happened on
+ * @param originatingParticipant The {@link RcsParticipant} that changed the
+ * {@link RcsGroupThread}'s icon.
+ * @param newIcon {@link Uri} to the new icon of this {@link RcsGroupThread}
+ * @see RcsMessageStore#persistRcsEvent(RcsEvent)
+ */
+ public RcsGroupThreadIconChangedEvent(long timestamp, @NonNull RcsGroupThread rcsGroupThread,
+ @NonNull RcsParticipant originatingParticipant, @Nullable Uri newIcon) {
+ super(timestamp, rcsGroupThread.getThreadId(), originatingParticipant.getId());
+ mNewIcon = newIcon;
+ }
+
+ /**
+ * @hide - internal constructor for queries
+ */
+ public RcsGroupThreadIconChangedEvent(long timestamp, int rcsGroupThreadId,
+ int originatingParticipantId, @Nullable Uri newIcon) {
+ super(timestamp, rcsGroupThreadId, originatingParticipantId);
+ mNewIcon = newIcon;
+ }
+
+ /**
+ * @return Returns the {@link Uri} to the icon of the {@link RcsGroupThread} after this
+ * {@link RcsGroupThreadIconChangedEvent} occured.
+ */
+ @Nullable
+ public Uri getNewIcon() {
+ return mNewIcon;
+ }
+
+ /**
+ * Persists the event to the data store.
+ *
+ * @hide - not meant for public use.
+ */
+ @Override
+ public void persist() throws RcsMessageStoreException {
+ // TODO ensure failure throws
+ RcsControllerCall.call(iRcs -> iRcs.createGroupThreadIconChangedEvent(
+ getTimestamp(), getRcsGroupThread().getThreadId(),
+ getOriginatingParticipant().getId(), mNewIcon));
+ }
+
+ public static final Creator<RcsGroupThreadIconChangedEvent> CREATOR =
+ new Creator<RcsGroupThreadIconChangedEvent>() {
+ @Override
+ public RcsGroupThreadIconChangedEvent createFromParcel(Parcel in) {
+ return new RcsGroupThreadIconChangedEvent(in);
+ }
+
+ @Override
+ public RcsGroupThreadIconChangedEvent[] newArray(int size) {
+ return new RcsGroupThreadIconChangedEvent[size];
+ }
+ };
+
+ protected RcsGroupThreadIconChangedEvent(Parcel in) {
+ super(in);
+ mNewIcon = in.readParcelable(Uri.class.getClassLoader());
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeParcelable(mNewIcon, flags);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.aidl
similarity index 93%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.aidl
index 82d985d..3ed9bd1 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsGroupThreadNameChangedEvent;
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java
new file mode 100644
index 0000000..0d2ea4f
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadNameChangedEvent.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+/**
+ * An event that indicates an {@link RcsGroupThread}'s name was changed. Please see R6-2-5 - GSMA
+ * RCC.71 (RCS Universal Profile Service Definition Document)
+ *
+ * @hide - TODO(109759350) make this public
+ */
+public class RcsGroupThreadNameChangedEvent extends RcsGroupThreadEvent {
+ private String mNewName;
+
+ /**
+ * Creates a new {@link RcsGroupThreadNameChangedEvent}. This event is not persisted into
+ * storage until {@link RcsMessageStore#persistRcsEvent(RcsEvent)} is called.
+ *
+ * @param timestamp The timestamp of when this event happened, in milliseconds passed after
+ * midnight, January 1st, 1970 UTC
+ * @param rcsGroupThread The {@link RcsGroupThread} that this event happened on
+ * @param originatingParticipant The {@link RcsParticipant} that changed the
+ * {@link RcsGroupThread}'s icon.
+ * @param newName The new name of the {@link RcsGroupThread}
+ * @see RcsMessageStore#persistRcsEvent(RcsEvent)
+ */
+ public RcsGroupThreadNameChangedEvent(long timestamp, @NonNull RcsGroupThread rcsGroupThread,
+ @NonNull RcsParticipant originatingParticipant, @Nullable String newName) {
+ super(timestamp, rcsGroupThread.getThreadId(), originatingParticipant.getId());
+ mNewName = newName;
+ }
+
+ /**
+ * @hide - internal constructor for queries
+ */
+ public RcsGroupThreadNameChangedEvent(long timestamp, int rcsGroupThreadId,
+ int originatingParticipantId, @Nullable String newName) {
+ super(timestamp, rcsGroupThreadId, originatingParticipantId);
+ mNewName = newName;
+ }
+
+ /**
+ * @return Returns the name of this {@link RcsGroupThread} after this
+ * {@link RcsGroupThreadNameChangedEvent} happened.
+ */
+ @Nullable
+ public String getNewName() {
+ return mNewName;
+ }
+
+ /**
+ * Persists the event to the data store.
+ *
+ * @hide - not meant for public use.
+ */
+ @Override
+ public void persist() throws RcsMessageStoreException {
+ RcsControllerCall.call(iRcs -> iRcs.createGroupThreadNameChangedEvent(
+ getTimestamp(), getRcsGroupThread().getThreadId(),
+ getOriginatingParticipant().getId(), mNewName));
+ }
+
+ public static final Creator<RcsGroupThreadNameChangedEvent> CREATOR =
+ new Creator<RcsGroupThreadNameChangedEvent>() {
+ @Override
+ public RcsGroupThreadNameChangedEvent createFromParcel(Parcel in) {
+ return new RcsGroupThreadNameChangedEvent(in);
+ }
+
+ @Override
+ public RcsGroupThreadNameChangedEvent[] newArray(int size) {
+ return new RcsGroupThreadNameChangedEvent[size];
+ }
+ };
+
+ protected RcsGroupThreadNameChangedEvent(Parcel in) {
+ super(in);
+ mNewName = in.readString();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(mNewName);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsMessage.aidl b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.aidl
similarity index 92%
copy from telephony/java/android/telephony/ims/RcsMessage.aidl
copy to telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.aidl
index b32cd12..420abff 100644
--- a/telephony/java/android/telephony/ims/RcsMessage.aidl
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsMessage;
+parcelable RcsGroupThreadParticipantJoinedEvent;
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java
new file mode 100644
index 0000000..2adafc7
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantJoinedEvent.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+
+/**
+ * An event that indicates an RCS participant has joined an {@link RcsThread}. Please see US6-3 -
+ * GSMA RCC.71 (RCS Universal Profile Service Definition Document)
+ *
+ * @hide - TODO(109759350) make this public
+ */
+public class RcsGroupThreadParticipantJoinedEvent extends RcsGroupThreadEvent {
+ private int mJoinedParticipantId;
+
+ /**
+ * Creates a new {@link RcsGroupThreadParticipantJoinedEvent}. This event is not persisted into
+ * storage until {@link RcsMessageStore#persistRcsEvent(RcsEvent)} is called.
+ *
+ * @param timestamp The timestamp of when this event happened, in milliseconds passed after
+ * midnight, January 1st, 1970 UTC
+ * @param rcsGroupThread The {@link RcsGroupThread} that this event happened on
+ * @param originatingParticipant The {@link RcsParticipant} that added or invited the new
+ * {@link RcsParticipant} into the {@link RcsGroupThread}
+ * @param joinedParticipant The new {@link RcsParticipant} that joined the
+ * {@link RcsGroupThread}
+ * @see RcsMessageStore#persistRcsEvent(RcsEvent)
+ */
+ public RcsGroupThreadParticipantJoinedEvent(long timestamp,
+ @NonNull RcsGroupThread rcsGroupThread, @NonNull RcsParticipant originatingParticipant,
+ @NonNull RcsParticipant joinedParticipant) {
+ super(timestamp, rcsGroupThread.getThreadId(), originatingParticipant.getId());
+ mJoinedParticipantId = joinedParticipant.getId();
+ }
+
+ /**
+ * @hide - internal constructor for queries
+ */
+ public RcsGroupThreadParticipantJoinedEvent(long timestamp, int rcsGroupThreadId,
+ int originatingParticipantId, int joinedParticipantId) {
+ super(timestamp, rcsGroupThreadId, originatingParticipantId);
+ mJoinedParticipantId = joinedParticipantId;
+ }
+
+ /**
+ * @return Returns the {@link RcsParticipant} that joined the associated {@link RcsGroupThread}
+ */
+ public RcsParticipant getJoinedParticipant() {
+ return new RcsParticipant(mJoinedParticipantId);
+ }
+
+ /**
+ * Persists the event to the data store.
+ *
+ * @hide - not meant for public use.
+ */
+ @Override
+ public void persist() throws RcsMessageStoreException {
+ RcsControllerCall.call(
+ iRcs -> iRcs.createGroupThreadParticipantJoinedEvent(getTimestamp(),
+ getRcsGroupThread().getThreadId(), getOriginatingParticipant().getId(),
+ getJoinedParticipant().getId()));
+ }
+
+ public static final Creator<RcsGroupThreadParticipantJoinedEvent> CREATOR =
+ new Creator<RcsGroupThreadParticipantJoinedEvent>() {
+ @Override
+ public RcsGroupThreadParticipantJoinedEvent createFromParcel(Parcel in) {
+ return new RcsGroupThreadParticipantJoinedEvent(in);
+ }
+
+ @Override
+ public RcsGroupThreadParticipantJoinedEvent[] newArray(int size) {
+ return new RcsGroupThreadParticipantJoinedEvent[size];
+ }
+ };
+
+ protected RcsGroupThreadParticipantJoinedEvent(Parcel in) {
+ super(in);
+ mJoinedParticipantId = in.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mJoinedParticipantId);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsMessage.aidl b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.aidl
similarity index 92%
rename from telephony/java/android/telephony/ims/RcsMessage.aidl
rename to telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.aidl
index b32cd12..ff139ac 100644
--- a/telephony/java/android/telephony/ims/RcsMessage.aidl
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsMessage;
+parcelable RcsGroupThreadParticipantLeftEvent;
diff --git a/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java
new file mode 100644
index 0000000..87c1852
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsGroupThreadParticipantLeftEvent.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+
+/**
+ * An event that indicates an RCS participant has left an {@link RcsThread}. Please see US6-23 -
+ * GSMA RCC.71 (RCS Universal Profile Service Definition Document)
+ *
+ * @hide - TODO(109759350) make this public
+ */
+public class RcsGroupThreadParticipantLeftEvent extends RcsGroupThreadEvent {
+ private int mLeavingParticipantId;
+
+ /**
+ * Creates a new {@link RcsGroupThreadParticipantLeftEvent}. his event is not persisted into
+ * storage until {@link RcsMessageStore#persistRcsEvent(RcsEvent)} is called.
+ *
+ * @param timestamp The timestamp of when this event happened, in milliseconds passed after
+ * midnight, January 1st, 1970 UTC
+ * @param rcsGroupThread The {@link RcsGroupThread} that this event happened on
+ * @param originatingParticipant The {@link RcsParticipant} that removed the
+ * {@link RcsParticipant} from the {@link RcsGroupThread}. It is
+ * possible that originatingParticipant and leavingParticipant are
+ * the same (i.e. {@link RcsParticipant} left the group
+ * themselves)
+ * @param leavingParticipant The {@link RcsParticipant} that left the {@link RcsGroupThread}
+ * @see RcsMessageStore#persistRcsEvent(RcsEvent)
+ */
+ public RcsGroupThreadParticipantLeftEvent(long timestamp,
+ @NonNull RcsGroupThread rcsGroupThread, @NonNull RcsParticipant originatingParticipant,
+ @NonNull RcsParticipant leavingParticipant) {
+ super(timestamp, rcsGroupThread.getThreadId(), originatingParticipant.getId());
+ mLeavingParticipantId = leavingParticipant.getId();
+ }
+
+ /**
+ * @hide - internal constructor for queries
+ */
+ public RcsGroupThreadParticipantLeftEvent(long timestamp, int rcsGroupThreadId,
+ int originatingParticipantId, int leavingParticipantId) {
+ super(timestamp, rcsGroupThreadId, originatingParticipantId);
+ mLeavingParticipantId = leavingParticipantId;
+ }
+
+ /**
+ * @return Returns the {@link RcsParticipant} that left the associated {@link RcsGroupThread}
+ * after this {@link RcsGroupThreadParticipantLeftEvent} happened.
+ */
+ @NonNull
+ public RcsParticipant getLeavingParticipantId() {
+ return new RcsParticipant(mLeavingParticipantId);
+ }
+
+ @Override
+ public void persist() throws RcsMessageStoreException {
+ RcsControllerCall.call(
+ iRcs -> iRcs.createGroupThreadParticipantJoinedEvent(getTimestamp(),
+ getRcsGroupThread().getThreadId(), getOriginatingParticipant().getId(),
+ getLeavingParticipantId().getId()));
+ }
+
+ public static final Creator<RcsGroupThreadParticipantLeftEvent> CREATOR =
+ new Creator<RcsGroupThreadParticipantLeftEvent>() {
+ @Override
+ public RcsGroupThreadParticipantLeftEvent createFromParcel(Parcel in) {
+ return new RcsGroupThreadParticipantLeftEvent(in);
+ }
+
+ @Override
+ public RcsGroupThreadParticipantLeftEvent[] newArray(int size) {
+ return new RcsGroupThreadParticipantLeftEvent[size];
+ }
+ };
+
+ protected RcsGroupThreadParticipantLeftEvent(Parcel in) {
+ super(in);
+ mLeavingParticipantId = in.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mLeavingParticipantId);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessage.aidl b/telephony/java/android/telephony/ims/RcsIncomingMessage.aidl
deleted file mode 100644
index 6552a82..0000000
--- a/telephony/java/android/telephony/ims/RcsIncomingMessage.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsIncomingMessage;
diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessage.java b/telephony/java/android/telephony/ims/RcsIncomingMessage.java
index f39e06d..2ea115b 100644
--- a/telephony/java/android/telephony/ims/RcsIncomingMessage.java
+++ b/telephony/java/android/telephony/ims/RcsIncomingMessage.java
@@ -15,34 +15,82 @@
*/
package android.telephony.ims;
-import android.os.Parcel;
+import android.annotation.WorkerThread;
/**
* This is a single instance of a message received over RCS.
- * @hide - TODO(sahinc) make this public
+ *
+ * @hide - TODO(109759350) make this public
*/
public class RcsIncomingMessage extends RcsMessage {
- public static final Creator<RcsIncomingMessage> CREATOR = new Creator<RcsIncomingMessage>() {
- @Override
- public RcsIncomingMessage createFromParcel(Parcel in) {
- return new RcsIncomingMessage(in);
- }
-
- @Override
- public RcsIncomingMessage[] newArray(int size) {
- return new RcsIncomingMessage[size];
- }
- };
-
- protected RcsIncomingMessage(Parcel in) {
+ /**
+ * @hide
+ */
+ RcsIncomingMessage(int id) {
+ super(id);
}
- @Override
- public int describeContents() {
- return 0;
+ /**
+ * Sets the timestamp of arrival for this message and persists into storage. The timestamp is
+ * defined as milliseconds passed after midnight, January 1, 1970 UTC
+ *
+ * @param arrivalTimestamp The timestamp to set to.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setArrivalTimestamp(long arrivalTimestamp) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setMessageArrivalTimestamp(mId, true, arrivalTimestamp));
}
+ /**
+ * @return Returns the timestamp of arrival for this message. The timestamp is defined as
+ * milliseconds passed after midnight, January 1, 1970 UTC
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getArrivalTimestamp() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getMessageArrivalTimestamp(mId, true));
+ }
+
+ /**
+ * Sets the timestamp of when the user saw this message and persists into storage. The timestamp
+ * is defined as milliseconds passed after midnight, January 1, 1970 UTC
+ *
+ * @param notifiedTimestamp The timestamp to set to.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setSeenTimestamp(long notifiedTimestamp) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setMessageSeenTimestamp(mId, true, notifiedTimestamp));
+ }
+
+ /**
+ * @return Returns the timestamp of when the user saw this message. The timestamp is defined as
+ * milliseconds passed after midnight, January 1, 1970 UTC
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getSeenTimestamp() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getMessageSeenTimestamp(mId, true));
+ }
+
+ /**
+ * @return Returns the sender of this incoming message.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public RcsParticipant getSenderParticipant() throws RcsMessageStoreException {
+ return new RcsParticipant(
+ RcsControllerCall.call(iRcs -> iRcs.getSenderParticipant(mId)));
+ }
+
+ /**
+ * @return Returns {@code true} as this is an incoming message
+ */
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public boolean isIncoming() {
+ return true;
}
}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.aidl
similarity index 92%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.aidl
index 82d985d..76073c2 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsIncomingMessageCreationParameters;
diff --git a/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.java b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.java
new file mode 100644
index 0000000..acde8af
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsIncomingMessageCreationParameters.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.CheckResult;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@link RcsIncomingMessageCreationParameters} is a collection of parameters that should be passed
+ * into {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParameters)} to generate an
+ * {@link RcsIncomingMessage} on that {@link RcsThread}
+ *
+ * @hide TODO:make public
+ */
+public class RcsIncomingMessageCreationParameters extends RcsMessageCreationParameters implements
+ Parcelable {
+ // The arrival timestamp for the RcsIncomingMessage to be created
+ private final long mArrivalTimestamp;
+ // The seen timestamp for the RcsIncomingMessage to be created
+ private final long mSeenTimestamp;
+ // The participant that sent this incoming message
+ private final int mSenderParticipantId;
+
+ /**
+ * Builder to help create an {@link RcsIncomingMessageCreationParameters}
+ *
+ * @see RcsThread#addIncomingMessage(RcsIncomingMessageCreationParameters)
+ */
+ public static class Builder extends RcsMessageCreationParameters.Builder {
+ private RcsParticipant mSenderParticipant;
+ private long mArrivalTimestamp;
+ private long mSeenTimestamp;
+
+ /**
+ * Creates a {@link Builder} to create an instance of
+ * {@link RcsIncomingMessageCreationParameters}
+ *
+ * @param originationTimestamp The timestamp of {@link RcsMessage} creation. The origination
+ * timestamp value in milliseconds passed after midnight,
+ * January 1, 1970 UTC
+ * @param arrivalTimestamp The timestamp of arrival, defined as milliseconds passed after
+ * midnight, January 1, 1970 UTC
+ * @param subscriptionId The subscription ID that was used to send or receive this
+ * {@link RcsMessage}
+ */
+ public Builder(long originationTimestamp, long arrivalTimestamp, int subscriptionId) {
+ super(originationTimestamp, subscriptionId);
+ mArrivalTimestamp = arrivalTimestamp;
+ }
+
+ /**
+ * Sets the {@link RcsParticipant} that send this {@link RcsIncomingMessage}
+ *
+ * @param senderParticipant The {@link RcsParticipant} that sent this
+ * {@link RcsIncomingMessage}
+ * @return The same instance of {@link Builder} to chain methods.
+ */
+ @CheckResult
+ public Builder setSenderParticipant(RcsParticipant senderParticipant) {
+ mSenderParticipant = senderParticipant;
+ return this;
+ }
+
+ /**
+ * Sets the time of the arrival of this {@link RcsIncomingMessage}
+
+ * @return The same instance of {@link Builder} to chain methods.
+ * @see RcsIncomingMessage#setArrivalTimestamp(long)
+ */
+ @CheckResult
+ public Builder setArrivalTimestamp(long arrivalTimestamp) {
+ mArrivalTimestamp = arrivalTimestamp;
+ return this;
+ }
+
+ /**
+ * Sets the time of the when this user saw the {@link RcsIncomingMessage}
+ * @param seenTimestamp The seen timestamp , defined as milliseconds passed after midnight,
+ * January 1, 1970 UTC
+ * @return The same instance of {@link Builder} to chain methods.
+ * @see RcsIncomingMessage#setSeenTimestamp(long)
+ */
+ @CheckResult
+ public Builder setSeenTimestamp(long seenTimestamp) {
+ mSeenTimestamp = seenTimestamp;
+ return this;
+ }
+
+ /**
+ * Creates parameters for creating a new incoming message.
+ * @return A new instance of {@link RcsIncomingMessageCreationParameters} to create a new
+ * {@link RcsIncomingMessage}
+ */
+ public RcsIncomingMessageCreationParameters build() {
+ return new RcsIncomingMessageCreationParameters(this);
+ }
+ }
+
+ private RcsIncomingMessageCreationParameters(Builder builder) {
+ super(builder);
+ mArrivalTimestamp = builder.mArrivalTimestamp;
+ mSeenTimestamp = builder.mSeenTimestamp;
+ mSenderParticipantId = builder.mSenderParticipant.getId();
+ }
+
+ protected RcsIncomingMessageCreationParameters(Parcel in) {
+ super(in);
+ mArrivalTimestamp = in.readLong();
+ mSeenTimestamp = in.readLong();
+ mSenderParticipantId = in.readInt();
+ }
+
+ /**
+ * @return Returns the arrival timestamp for the {@link RcsIncomingMessage} to be created.
+ * Timestamp is defined as milliseconds passed after midnight, January 1, 1970 UTC
+ */
+ public long getArrivalTimestamp() {
+ return mArrivalTimestamp;
+ }
+
+ /**
+ * @return Returns the seen timestamp for the {@link RcsIncomingMessage} to be created.
+ * Timestamp is defined as milliseconds passed after midnight, January 1, 1970 UTC
+ */
+ public long getSeenTimestamp() {
+ return mSeenTimestamp;
+ }
+
+ /**
+ * Helper getter for {@link com.android.internal.telephony.ims.RcsMessageStoreController} to
+ * create {@link RcsIncomingMessage}s
+ *
+ * Since the API doesn't expose any ID's to API users, this should be hidden.
+ * @hide
+ */
+ public int getSenderParticipantId() {
+ return mSenderParticipantId;
+ }
+
+ public static final Creator<RcsIncomingMessageCreationParameters> CREATOR =
+ new Creator<RcsIncomingMessageCreationParameters>() {
+ @Override
+ public RcsIncomingMessageCreationParameters createFromParcel(Parcel in) {
+ return new RcsIncomingMessageCreationParameters(in);
+ }
+
+ @Override
+ public RcsIncomingMessageCreationParameters[] newArray(int size) {
+ return new RcsIncomingMessageCreationParameters[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeLong(mArrivalTimestamp);
+ dest.writeLong(mSeenTimestamp);
+ dest.writeInt(mSenderParticipantId);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsLocationPart.aidl b/telephony/java/android/telephony/ims/RcsLocationPart.aidl
deleted file mode 100644
index 4fe5ca9..0000000
--- a/telephony/java/android/telephony/ims/RcsLocationPart.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsLocationPart;
diff --git a/telephony/java/android/telephony/ims/RcsLocationPart.java b/telephony/java/android/telephony/ims/RcsLocationPart.java
deleted file mode 100644
index 19be4ce..0000000
--- a/telephony/java/android/telephony/ims/RcsLocationPart.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcel;
-
-/**
- * A part of a composite {@link RcsMessage} that holds a location
- * @hide - TODO(sahinc) make this public
- */
-public class RcsLocationPart extends RcsPart {
- public static final Creator<RcsLocationPart> CREATOR = new Creator<RcsLocationPart>() {
- @Override
- public RcsLocationPart createFromParcel(Parcel in) {
- return new RcsLocationPart(in);
- }
-
- @Override
- public RcsLocationPart[] newArray(int size) {
- return new RcsLocationPart[size];
- }
- };
-
- protected RcsLocationPart(Parcel in) {
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-}
diff --git a/telephony/java/android/telephony/ims/RcsManager.aidl b/telephony/java/android/telephony/ims/RcsManager.aidl
deleted file mode 100644
index 63bc71c..0000000
--- a/telephony/java/android/telephony/ims/RcsManager.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsManager;
diff --git a/telephony/java/android/telephony/ims/RcsManager.java b/telephony/java/android/telephony/ims/RcsManager.java
index df108c8..e84d4ed 100644
--- a/telephony/java/android/telephony/ims/RcsManager.java
+++ b/telephony/java/android/telephony/ims/RcsManager.java
@@ -28,7 +28,7 @@
private static final RcsMessageStore sRcsMessageStoreInstance = new RcsMessageStore();
/**
- * Returns an instance of RcsMessageStore.
+ * Returns an instance of {@link RcsMessageStore}
*/
public RcsMessageStore getRcsMessageStore() {
return sRcsMessageStoreInstance;
diff --git a/telephony/java/android/telephony/ims/RcsMessage.java b/telephony/java/android/telephony/ims/RcsMessage.java
index d46685c..b70a9a7 100644
--- a/telephony/java/android/telephony/ims/RcsMessage.java
+++ b/telephony/java/android/telephony/ims/RcsMessage.java
@@ -15,11 +15,314 @@
*/
package android.telephony.ims;
-import android.os.Parcelable;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.WorkerThread;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
/**
* This is a single instance of a message sent or received over RCS.
- * @hide - TODO(sahinc) make this public
+ *
+ * @hide - TODO(109759350) make this public
*/
-public abstract class RcsMessage implements Parcelable {
+public abstract class RcsMessage {
+ /**
+ * The value to indicate that this {@link RcsMessage} does not have any location information.
+ */
+ public static final double LOCATION_NOT_SET = Double.MIN_VALUE;
+
+ /**
+ * The status to indicate that this {@link RcsMessage}s status is not set yet.
+ */
+ public static final int NOT_SET = 0;
+
+ /**
+ * The status to indicate that this {@link RcsMessage} is a draft and is not in the process of
+ * sending yet.
+ */
+ public static final int DRAFT = 1;
+
+ /**
+ * The status to indicate that this {@link RcsMessage} was successfully sent.
+ */
+ public static final int QUEUED = 2;
+
+ /**
+ * The status to indicate that this {@link RcsMessage} is actively being sent.
+ */
+ public static final int SENDING = 3;
+
+ /**
+ * The status to indicate that this {@link RcsMessage} was successfully sent.
+ */
+ public static final int SENT = 4;
+
+ /**
+ * The status to indicate that this {@link RcsMessage} failed to send in an attempt before, and
+ * now being retried.
+ */
+ public static final int RETRYING = 5;
+
+ /**
+ * The status to indicate that this {@link RcsMessage} has permanently failed to send.
+ */
+ public static final int FAILED = 6;
+
+ /**
+ * The status to indicate that this {@link RcsMessage} was successfully received.
+ */
+ public static final int RECEIVED = 7;
+
+ /**
+ * The status to indicate that this {@link RcsMessage} was seen.
+ */
+ public static final int SEEN = 9;
+
+ protected int mId;
+
+ @IntDef({
+ DRAFT, QUEUED, SENDING, SENT, RETRYING, FAILED, RECEIVED, SEEN
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RcsMessageStatus {
+ }
+
+ RcsMessage(int id) {
+ mId = id;
+ }
+
+ /**
+ * Returns the row Id from the common message.
+ *
+ * @hide
+ */
+ public int getId() {
+ return mId;
+ }
+
+ /**
+ * @return Returns the subscription ID that this {@link RcsMessage} was sent from, or delivered
+ * to.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ * @see android.telephony.SubscriptionInfo#getSubscriptionId
+ */
+ public int getSubscriptionId() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getMessageSubId(mId, isIncoming()));
+ }
+
+ /**
+ * Sets the subscription ID that this {@link RcsMessage} was sent from, or delivered to and
+ * persists it into storage.
+ *
+ * @param subId The subscription ID to persists into storage.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ * @see android.telephony.SubscriptionInfo#getSubscriptionId
+ */
+ @WorkerThread
+ public void setSubscriptionId(int subId) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setMessageSubId(mId, isIncoming(), subId));
+ }
+
+ /**
+ * Sets the status of this message and persists it into storage. Please see
+ * {@link RcsFileTransferPart#setFileTransferStatus(int)} to set statuses around file transfers.
+ *
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setStatus(@RcsMessageStatus int rcsMessageStatus) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setMessageStatus(mId, isIncoming(), rcsMessageStatus));
+ }
+
+ /**
+ * @return Returns the status of this message. Please see
+ * {@link RcsFileTransferPart#setFileTransferStatus(int)} to set statuses around file transfers.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public @RcsMessageStatus int getStatus() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getMessageStatus(mId, isIncoming()));
+ }
+
+ /**
+ * Sets the origination timestamp of this message and persists it into storage. Origination is
+ * defined as when the sender tapped the send button.
+ *
+ * @param timestamp The origination timestamp value in milliseconds passed after midnight,
+ * January 1, 1970 UTC
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setOriginationTimestamp(long timestamp) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setMessageOriginationTimestamp(mId, isIncoming(), timestamp));
+ }
+
+ /**
+ * @return Returns the origination timestamp of this message in milliseconds passed after
+ * midnight, January 1, 1970 UTC. Origination is defined as when the sender tapped the send
+ * button.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getOriginationTimestamp() throws RcsMessageStoreException {
+ return RcsControllerCall.call(
+ iRcs -> iRcs.getMessageOriginationTimestamp(mId, isIncoming()));
+ }
+
+ /**
+ * Sets the globally unique RCS message identifier for this message and persists it into
+ * storage. This function does not confirm that this message id is unique. Please see 4.4.5.2
+ * - GSMA RCC.53 (RCS Device API 1.6 Specification
+ *
+ * @param rcsMessageGlobalId The globally RCS message identifier
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setRcsMessageId(String rcsMessageGlobalId) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setGlobalMessageIdForMessage(mId, isIncoming(), rcsMessageGlobalId));
+ }
+
+ /**
+ * @return Returns the globally unique RCS message identifier for this message. Please see
+ * 4.4.5.2 - GSMA RCC.53 (RCS Device API 1.6 Specification
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public String getRcsMessageId() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getGlobalMessageIdForMessage(mId, isIncoming()));
+ }
+
+ /**
+ * @return Returns the user visible text included in this message.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public String getText() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getTextForMessage(mId, isIncoming()));
+ }
+
+ /**
+ * Sets the user visible text for this message and persists in storage.
+ *
+ * @param text The text this message now has
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setText(String text) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setTextForMessage(mId, isIncoming(), text));
+ }
+
+ /**
+ * @return Returns the associated latitude for this message, or
+ * {@link RcsMessage#LOCATION_NOT_SET} if it does not contain a location.
+ *
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public double getLatitude() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getLatitudeForMessage(mId, isIncoming()));
+ }
+
+ /**
+ * Sets the latitude for this message and persists in storage.
+ *
+ * @param latitude The latitude for this location message.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setLatitude(double latitude) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setLatitudeForMessage(mId, isIncoming(), latitude));
+ }
+
+ /**
+ * @return Returns the associated longitude for this message, or
+ * {@link RcsMessage#LOCATION_NOT_SET} if it does not contain a location.
+ *
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public double getLongitude() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getLongitudeForMessage(mId, isIncoming()));
+ }
+
+ /**
+ * Sets the longitude for this message and persists in storage.
+ *
+ * @param longitude The longitude for this location message.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setLongitude(double longitude) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.setLongitudeForMessage(mId, isIncoming(), longitude));
+ }
+
+ /**
+ * Attaches an {@link RcsFileTransferPart} to this message and persists into storage.
+ *
+ * @param fileTransferCreationParameters The parameters to be used to create the
+ * {@link RcsFileTransferPart}
+ * @return A new instance of {@link RcsFileTransferPart}
+ * @throws RcsMessageStoreException if the file transfer could not be persisted into storage.
+ */
+ @NonNull
+ @WorkerThread
+ public RcsFileTransferPart insertFileTransfer(
+ RcsFileTransferCreationParameters fileTransferCreationParameters)
+ throws RcsMessageStoreException {
+ return new RcsFileTransferPart(RcsControllerCall.call(
+ iRcs -> iRcs.storeFileTransfer(mId, isIncoming(), fileTransferCreationParameters)));
+ }
+
+ /**
+ * @return Returns all the {@link RcsFileTransferPart}s associated with this message in an
+ * unmodifiable set.
+ * @throws RcsMessageStoreException if the file transfers could not be read from the storage
+ */
+ @NonNull
+ @WorkerThread
+ public Set<RcsFileTransferPart> getFileTransferParts() throws RcsMessageStoreException {
+ Set<RcsFileTransferPart> fileTransferParts = new HashSet<>();
+
+ int[] fileTransferIds = RcsControllerCall.call(
+ iRcs -> iRcs.getFileTransfersAttachedToMessage(mId, isIncoming()));
+
+ for (int fileTransfer : fileTransferIds) {
+ fileTransferParts.add(new RcsFileTransferPart(fileTransfer));
+ }
+
+ return Collections.unmodifiableSet(fileTransferParts);
+ }
+
+ /**
+ * Removes a {@link RcsFileTransferPart} from this message, and deletes it in storage.
+ *
+ * @param fileTransferPart The part to delete.
+ * @throws RcsMessageStoreException if the file transfer could not be removed from storage
+ */
+ @WorkerThread
+ public void removeFileTransferPart(@NonNull RcsFileTransferPart fileTransferPart)
+ throws RcsMessageStoreException {
+ if (fileTransferPart == null) {
+ return;
+ }
+
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.deleteFileTransfer(fileTransferPart.getId()));
+ }
+
+ /**
+ * @return Returns {@code true} if this message was received on this device, {@code false} if it
+ * was sent.
+ */
+ public abstract boolean isIncoming();
}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsMessageCreationParameters.aidl
similarity index 93%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsMessageCreationParameters.aidl
index 82d985d..5774d00 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsMessageCreationParameters.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsMessageCreationParameters;
diff --git a/telephony/java/android/telephony/ims/RcsMessageCreationParameters.java b/telephony/java/android/telephony/ims/RcsMessageCreationParameters.java
new file mode 100644
index 0000000..ff3f33e
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsMessageCreationParameters.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import static android.telephony.ims.RcsMessage.LOCATION_NOT_SET;
+
+import android.annotation.CheckResult;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.SubscriptionInfo;
+
+/**
+ * The collection of parameters to be passed into
+ * {@link RcsThread#addIncomingMessage(RcsIncomingMessageCreationParameters)} and
+ * {@link RcsThread#addOutgoingMessage(RcsMessageCreationParameters)} to create and persist
+ * {@link RcsMessage}s on an {@link RcsThread}
+ *
+ * @hide TODO - make public
+ */
+public class RcsMessageCreationParameters implements Parcelable {
+ // The globally unique id of the RcsMessage to be created.
+ private final String mRcsMessageGlobalId;
+
+ // The subscription that this message was/will be received/sent from.
+ private final int mSubId;
+ // The sending/receiving status of the message
+ private final @RcsMessage.RcsMessageStatus int mMessageStatus;
+ // The timestamp of message creation
+ private final long mOriginationTimestamp;
+ // The user visible content of the message
+ private final String mText;
+ // The latitude of the message if this is a location message
+ private final double mLatitude;
+ // The longitude of the message if this is a location message
+ private final double mLongitude;
+
+ /**
+ * @return Returns the globally unique RCS Message ID for the {@link RcsMessage} to be created.
+ * Please see 4.4.5.2 - GSMA RCC.53 (RCS Device API 1.6 Specification
+ */
+ @Nullable
+ public String getRcsMessageGlobalId() {
+ return mRcsMessageGlobalId;
+ }
+
+ /**
+ * @return Returns the subscription ID that was used to send or receive the {@link RcsMessage}
+ * to be created.
+ */
+ public int getSubId() {
+ return mSubId;
+ }
+
+ /**
+ * @return Returns the status for the {@link RcsMessage} to be created.
+ * @see RcsMessage.RcsMessageStatus
+ */
+ public int getMessageStatus() {
+ return mMessageStatus;
+ }
+
+ /**
+ * @return Returns the origination timestamp of the {@link RcsMessage} to be created in
+ * milliseconds passed after midnight, January 1, 1970 UTC. Origination is defined as when
+ * the sender tapped the send button.
+ */
+ public long getOriginationTimestamp() {
+ return mOriginationTimestamp;
+ }
+
+ /**
+ * @return Returns the user visible text contained in the {@link RcsMessage} to be created
+ */
+ @Nullable
+ public String getText() {
+ return mText;
+ }
+
+ /**
+ * @return Returns the latitude of the {@link RcsMessage} to be created, or
+ * {@link RcsMessage#LOCATION_NOT_SET} if the message does not contain a location.
+ */
+ public double getLatitude() {
+ return mLatitude;
+ }
+
+ /**
+ * @return Returns the longitude of the {@link RcsMessage} to be created, or
+ * {@link RcsMessage#LOCATION_NOT_SET} if the message does not contain a location.
+ */
+ public double getLongitude() {
+ return mLongitude;
+ }
+
+ /**
+ * The base builder for creating {@link RcsMessage}s on {@link RcsThread}s.
+ *
+ * @see RcsIncomingMessageCreationParameters
+ */
+ public static class Builder {
+ private String mRcsMessageGlobalId;
+ private int mSubId;
+ private @RcsMessage.RcsMessageStatus int mMessageStatus;
+ private long mOriginationTimestamp;
+ private String mText;
+ private double mLatitude = LOCATION_NOT_SET;
+ private double mLongitude = LOCATION_NOT_SET;
+
+ /**
+ * Creates a new {@link Builder} to create an instance of
+ * {@link RcsMessageCreationParameters}.
+ *
+ * @param originationTimestamp The timestamp of {@link RcsMessage} creation. The origination
+ * timestamp value in milliseconds passed after midnight,
+ * January 1, 1970 UTC
+ * @param subscriptionId The subscription ID that was used to send or receive this
+ * {@link RcsMessage}
+ * @see SubscriptionInfo#getSubscriptionId()
+ */
+ public Builder(long originationTimestamp, int subscriptionId) {
+ mOriginationTimestamp = originationTimestamp;
+ mSubId = subscriptionId;
+ }
+
+ /**
+ * Sets the status of the {@link RcsMessage} to be built.
+ *
+ * @param rcsMessageStatus The status to be set
+ * @return The same instance of {@link Builder} to chain methods
+ * @see RcsMessage#setStatus(int)
+ */
+ @CheckResult
+ public Builder setStatus(@RcsMessage.RcsMessageStatus int rcsMessageStatus) {
+ mMessageStatus = rcsMessageStatus;
+ return this;
+ }
+
+ /**
+ * Sets the globally unique RCS message identifier for the {@link RcsMessage} to be built.
+ * This function does not confirm that this message id is unique. Please see 4.4.5.2 - GSMA
+ * RCC.53 (RCS Device API 1.6 Specification)
+ *
+ * @param rcsMessageId The ID to be set
+ * @return The same instance of {@link Builder} to chain methods
+ * @see RcsMessage#setRcsMessageId(String)
+ */
+ @CheckResult
+ public Builder setRcsMessageId(String rcsMessageId) {
+ mRcsMessageGlobalId = rcsMessageId;
+ return this;
+ }
+
+ /**
+ * Sets the text of the {@link RcsMessage} to be built.
+ *
+ * @param text The user visible text of the message
+ * @return The same instance of {@link Builder} to chain methods
+ * @see RcsMessage#setText(String)
+ */
+ @CheckResult
+ public Builder setText(String text) {
+ mText = text;
+ return this;
+ }
+
+ /**
+ * Sets the latitude of the {@link RcsMessage} to be built. Please see US5-24 - GSMA RCC.71
+ * (RCS Universal Profile Service Definition Document)
+ *
+ * @param latitude The latitude of the location information associated with this message.
+ * @return The same instance of {@link Builder} to chain methods
+ * @see RcsMessage#setLatitude(double)
+ */
+ @CheckResult
+ public Builder setLatitude(double latitude) {
+ mLatitude = latitude;
+ return this;
+ }
+
+ /**
+ * Sets the longitude of the {@link RcsMessage} to be built. Please see US5-24 - GSMA RCC.71
+ * (RCS Universal Profile Service Definition Document)
+ *
+ * @param longitude The longitude of the location information associated with this message.
+ * @return The same instance of {@link Builder} to chain methods
+ * @see RcsMessage#setLongitude(double)
+ */
+ @CheckResult
+ public Builder setLongitude(double longitude) {
+ mLongitude = longitude;
+ return this;
+ }
+
+ /**
+ * @hide
+ */
+ public RcsMessageCreationParameters build() {
+ return new RcsMessageCreationParameters(this);
+ }
+ }
+
+ protected RcsMessageCreationParameters(Builder builder) {
+ mRcsMessageGlobalId = builder.mRcsMessageGlobalId;
+ mSubId = builder.mSubId;
+ mMessageStatus = builder.mMessageStatus;
+ mOriginationTimestamp = builder.mOriginationTimestamp;
+ mText = builder.mText;
+ mLatitude = builder.mLatitude;
+ mLongitude = builder.mLongitude;
+ }
+
+ protected RcsMessageCreationParameters(Parcel in) {
+ mRcsMessageGlobalId = in.readString();
+ mSubId = in.readInt();
+ mMessageStatus = in.readInt();
+ mOriginationTimestamp = in.readLong();
+ mText = in.readString();
+ mLatitude = in.readDouble();
+ mLongitude = in.readDouble();
+ }
+
+ public static final Creator<RcsMessageCreationParameters> CREATOR =
+ new Creator<RcsMessageCreationParameters>() {
+ @Override
+ public RcsMessageCreationParameters createFromParcel(Parcel in) {
+ return new RcsMessageCreationParameters(in);
+ }
+
+ @Override
+ public RcsMessageCreationParameters[] newArray(int size) {
+ return new RcsMessageCreationParameters[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mRcsMessageGlobalId);
+ dest.writeInt(mSubId);
+ dest.writeInt(mMessageStatus);
+ dest.writeLong(mOriginationTimestamp);
+ dest.writeString(mText);
+ dest.writeDouble(mLatitude);
+ dest.writeDouble(mLongitude);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsMessageQueryParameters.aidl
similarity index 94%
rename from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
rename to telephony/java/android/telephony/ims/RcsMessageQueryParameters.aidl
index 82d985d..c325c23 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryParameters.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsMessageQueryParameters;
diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryParameters.java b/telephony/java/android/telephony/ims/RcsMessageQueryParameters.java
new file mode 100644
index 0000000..c964cf9
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryParameters.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.CheckResult;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.security.InvalidParameterException;
+
+/**
+ * The parameters to pass into
+ * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} in order to select a
+ * subset of {@link RcsMessage}s present in the message store.
+ *
+ * @hide TODO - make the Builder and builder() public. The rest should stay internal only.
+ */
+public class RcsMessageQueryParameters implements Parcelable {
+ /**
+ * @hide - not meant for public use
+ */
+ public static final int THREAD_ID_NOT_SET = -1;
+
+ /**
+ * Flag to be used with {@link Builder#setSortProperty(int)} to denote that the results should
+ * be sorted in the same order of {@link RcsMessage}s that got persisted into storage for faster
+ * results.
+ */
+ public static final int SORT_BY_CREATION_ORDER = 0;
+
+ /**
+ * Flag to be used with {@link Builder#setSortProperty(int)} to denote that the results should
+ * be sorted according to the timestamp of {@link RcsMessage#getOriginationTimestamp()}
+ */
+ public static final int SORT_BY_TIMESTAMP = 1;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({SORT_BY_CREATION_ORDER, SORT_BY_TIMESTAMP})
+ public @interface SortingProperty {
+ }
+
+ /**
+ * Bitmask flag to be used with {@link Builder#setMessageType(int)} to make
+ * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} return
+ * {@link RcsIncomingMessage}s.
+ */
+ public static final int MESSAGE_TYPE_INCOMING = 0x0001;
+
+ /**
+ * Bitmask flag to be used with {@link Builder#setMessageType(int)} to make
+ * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} return
+ * {@link RcsOutgoingMessage}s.
+ */
+ public static final int MESSAGE_TYPE_OUTGOING = 0x0002;
+
+ /**
+ * Bitmask flag to be used with {@link Builder#setFileTransferPresence(int)} to make
+ * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} return {@link RcsMessage}s
+ * that have an {@link RcsFileTransferPart} attached.
+ */
+ public static final int MESSAGES_WITH_FILE_TRANSFERS = 0x0004;
+
+ /**
+ * Bitmask flag to be used with {@link Builder#setFileTransferPresence(int)} to make
+ * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)} return {@link RcsMessage}s
+ * that don't have an {@link RcsFileTransferPart} attached.
+ */
+ public static final int MESSAGES_WITHOUT_FILE_TRANSFERS = 0x0008;
+
+ /**
+ * @hide - not meant for public use
+ */
+ public static final String MESSAGE_QUERY_PARAMETERS_KEY = "message_query_parameters";
+
+ // Whether the result should be filtered against incoming or outgoing messages
+ private int mMessageType;
+ // Whether the result should have file transfer messages attached or not
+ private int mFileTransferPresence;
+ // The SQL "Like" clause to filter messages
+ private String mMessageLike;
+ // The property the messages should be sorted against
+ private @SortingProperty int mSortingProperty;
+ // Whether the messages should be sorted in ascending order
+ private boolean mIsAscending;
+ // The number of results that should be returned with this query
+ private int mLimit;
+ // The thread that the results should be limited to
+ private int mThreadId;
+
+ RcsMessageQueryParameters(int messageType, int fileTransferPresence, String messageLike,
+ int threadId, @SortingProperty int sortingProperty, boolean isAscending, int limit) {
+ mMessageType = messageType;
+ mFileTransferPresence = fileTransferPresence;
+ mMessageLike = messageLike;
+ mSortingProperty = sortingProperty;
+ mIsAscending = isAscending;
+ mLimit = limit;
+ mThreadId = threadId;
+ }
+
+ /**
+ * @return Returns the type of {@link RcsMessage}s that this {@link RcsMessageQueryParameters}
+ * is set to query for.
+ */
+ public int getMessageType() {
+ return mMessageType;
+ }
+
+ /**
+ * @return Returns whether the result query should return {@link RcsMessage}s with
+ * {@link RcsFileTransferPart}s or not
+ */
+ public int getFileTransferPresence() {
+ return mFileTransferPresence;
+ }
+
+ /**
+ * @return Returns the SQL-inspired "LIKE" clause that will be used to match {@link RcsMessage}s
+ */
+ public String getMessageLike() {
+ return mMessageLike;
+ }
+
+ /**
+ * @return Returns the number of {@link RcsThread}s to be returned from the query. A value of
+ * 0 means there is no set limit.
+ */
+ public int getLimit() {
+ return mLimit;
+ }
+
+ /**
+ * @return Returns the property that will be used to sort the result against.
+ * @see SortingProperty
+ */
+ public @SortingProperty int getSortingProperty() {
+ return mSortingProperty;
+ }
+
+ /**
+ * @return Returns {@code true} if the result set will be sorted in ascending order,
+ * {@code false} if it will be sorted in descending order.
+ */
+ public boolean getSortDirection() {
+ return mIsAscending;
+ }
+
+ /**
+ * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get
+ * the thread that the result query should be limited to.
+ *
+ * As we do not expose any sort of integer ID's to public usage, this should be hidden.
+ *
+ * @hide - not meant for public use
+ */
+ public int getThreadId() {
+ return mThreadId;
+ }
+
+ /**
+ * A helper class to build the {@link RcsMessageQueryParameters}.
+ */
+ public static class Builder {
+ private @SortingProperty int mSortingProperty;
+ private int mMessageType;
+ private int mFileTransferPresence;
+ private String mMessageLike;
+ private boolean mIsAscending;
+ private int mLimit = 100;
+ private int mThreadId = THREAD_ID_NOT_SET;
+
+ /**
+ * Creates a new builder for {@link RcsMessageQueryParameters} to be used in
+ * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)}
+ *
+ */
+ public Builder() {
+ // empty implementation
+ }
+
+ /**
+ * Desired number of threads to be returned from the query. Passing in 0 will return all
+ * existing threads at once. The limit defaults to 100.
+ *
+ * @param limit The number to limit the query result to.
+ * @return The same instance of the builder to chain parameters.
+ * @throws InvalidParameterException If the given limit is negative.
+ */
+ @CheckResult
+ public Builder setResultLimit(@IntRange(from = 0) int limit)
+ throws InvalidParameterException {
+ if (limit < 0) {
+ throw new InvalidParameterException("The query limit must be non-negative");
+ }
+
+ mLimit = limit;
+ return this;
+ }
+
+ /**
+ * Sets the type of messages to be returned from the query.
+ *
+ * @param messageType The type of message to be returned.
+ * @return The same instance of the builder to chain parameters.
+ * @see RcsMessageQueryParameters#MESSAGE_TYPE_INCOMING
+ * @see RcsMessageQueryParameters#MESSAGE_TYPE_OUTGOING
+ */
+ @CheckResult
+ public Builder setMessageType(int messageType) {
+ mMessageType = messageType;
+ return this;
+ }
+
+ /**
+ * Sets whether file transfer messages should be included in the query result or not.
+ *
+ * @param fileTransferPresence Whether file transfers should be included in the result
+ * @return The same instance of the builder to chain parameters.
+ * @see RcsMessageQueryParameters#MESSAGES_WITH_FILE_TRANSFERS
+ * @see RcsMessageQueryParameters#MESSAGES_WITHOUT_FILE_TRANSFERS
+ */
+ @CheckResult
+ public Builder setFileTransferPresence(int fileTransferPresence) {
+ mFileTransferPresence = fileTransferPresence;
+ return this;
+ }
+
+ /**
+ * Sets an SQL-inspired "like" clause to match with messages. Using a percent sign ('%')
+ * wildcard matches any sequence of zero or more characters. Using an underscore ('_')
+ * wildcard matches any single character. Not using any wildcards would only perform a
+ * string match. The input string is case-insensitive.
+ *
+ * The input "Wh%" would match messages "who", "where" and "what", while the input "Wh_"
+ * would only match "who"
+ *
+ * @param messageLike The "like" clause for matching {@link RcsMessage}s.
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setMessageLike(String messageLike) {
+ mMessageLike = messageLike;
+ return this;
+ }
+
+ /**
+ * Sets the property where the results should be sorted against. Defaults to
+ * {@link RcsMessageQueryParameters.SortingProperty#SORT_BY_CREATION_ORDER}
+ *
+ * @param sortingProperty against which property the results should be sorted
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setSortProperty(@SortingProperty int sortingProperty) {
+ mSortingProperty = sortingProperty;
+ return this;
+ }
+
+ /**
+ * Sets whether the results should be sorted ascending or descending
+ *
+ * @param isAscending whether the results should be sorted ascending
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setSortDirection(boolean isAscending) {
+ mIsAscending = isAscending;
+ return this;
+ }
+
+ /**
+ * Limits the results to the given thread.
+ *
+ * @param thread the {@link RcsThread} that results should be limited to. If set to
+ * {@code null}, messages on all threads will be queried
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setThread(@Nullable RcsThread thread) {
+ if (thread == null) {
+ mThreadId = THREAD_ID_NOT_SET;
+ } else {
+ mThreadId = thread.getThreadId();
+ }
+ return this;
+ }
+
+ /**
+ * Builds the {@link RcsMessageQueryParameters} to use in
+ * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)}
+ *
+ * @return An instance of {@link RcsMessageQueryParameters} to use with the message
+ * query.
+ */
+ public RcsMessageQueryParameters build() {
+ return new RcsMessageQueryParameters(mMessageType, mFileTransferPresence, mMessageLike,
+ mThreadId, mSortingProperty, mIsAscending, mLimit);
+ }
+ }
+
+ /**
+ * Parcelable boilerplate below.
+ */
+ protected RcsMessageQueryParameters(Parcel in) {
+ mMessageType = in.readInt();
+ mFileTransferPresence = in.readInt();
+ mMessageLike = in.readString();
+ mSortingProperty = in.readInt();
+ mIsAscending = in.readBoolean();
+ mLimit = in.readInt();
+ mThreadId = in.readInt();
+ }
+
+ public static final Creator<RcsMessageQueryParameters> CREATOR =
+ new Creator<RcsMessageQueryParameters>() {
+ @Override
+ public RcsMessageQueryParameters createFromParcel(Parcel in) {
+ return new RcsMessageQueryParameters(in);
+ }
+
+ @Override
+ public RcsMessageQueryParameters[] newArray(int size) {
+ return new RcsMessageQueryParameters[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mMessageType);
+ dest.writeInt(mFileTransferPresence);
+ dest.writeString(mMessageLike);
+ dest.writeInt(mSortingProperty);
+ dest.writeBoolean(mIsAscending);
+ dest.writeInt(mLimit);
+ dest.writeInt(mThreadId);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsMessageQueryResult.aidl
similarity index 94%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsMessageQueryResult.aidl
index 82d985d..a73ba50 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryResult.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsMessageQueryResult;
diff --git a/telephony/java/android/telephony/ims/RcsMessageQueryResult.java b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java
new file mode 100644
index 0000000..c3846fd
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsMessageQueryResult.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import static android.provider.Telephony.RcsColumns.RcsUnifiedMessageColumns.MESSAGE_TYPE_INCOMING;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.ims.RcsTypeIdPair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The result of a {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)}
+ * call. This class allows getting the token for querying the next batch of messages in order to
+ * prevent handling large amounts of data at once.
+ *
+ * @hide
+ */
+public class RcsMessageQueryResult implements Parcelable {
+ // The token to continue the query to get the next batch of results
+ private RcsQueryContinuationToken mContinuationToken;
+ // The message type and message ID pairs for all the messages in this query result
+ private List<RcsTypeIdPair> mMessageTypeIdPairs;
+
+ /**
+ * Internal constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController}
+ * to create query results
+ *
+ * @hide
+ */
+ public RcsMessageQueryResult(
+ RcsQueryContinuationToken continuationToken,
+ List<RcsTypeIdPair> messageTypeIdPairs) {
+ mContinuationToken = continuationToken;
+ mMessageTypeIdPairs = messageTypeIdPairs;
+ }
+
+ /**
+ * Returns a token to call
+ * {@link RcsMessageStore#getRcsMessages(RcsQueryContinuationToken)}
+ * to get the next batch of {@link RcsMessage}s.
+ */
+ @Nullable
+ public RcsQueryContinuationToken getContinuationToken() {
+ return mContinuationToken;
+ }
+
+ /**
+ * Returns all the {@link RcsMessage}s in the current query result. Call {@link
+ * RcsMessageStore#getRcsMessages(RcsQueryContinuationToken)} to get the next batch
+ * of {@link RcsMessage}s.
+ */
+ @NonNull
+ public List<RcsMessage> getMessages() {
+ List<RcsMessage> messages = new ArrayList<>();
+ for (RcsTypeIdPair typeIdPair : mMessageTypeIdPairs) {
+ if (typeIdPair.getType() == MESSAGE_TYPE_INCOMING) {
+ messages.add(new RcsIncomingMessage(typeIdPair.getId()));
+ } else {
+ messages.add(new RcsOutgoingMessage(typeIdPair.getId()));
+ }
+ }
+
+ return messages;
+ }
+
+ protected RcsMessageQueryResult(Parcel in) {
+ mContinuationToken = in.readParcelable(
+ RcsQueryContinuationToken.class.getClassLoader());
+ in.readTypedList(mMessageTypeIdPairs, RcsTypeIdPair.CREATOR);
+ }
+
+ public static final Creator<RcsMessageQueryResult> CREATOR =
+ new Creator<RcsMessageQueryResult>() {
+ @Override
+ public RcsMessageQueryResult createFromParcel(Parcel in) {
+ return new RcsMessageQueryResult(in);
+ }
+
+ @Override
+ public RcsMessageQueryResult[] newArray(int size) {
+ return new RcsMessageQueryResult[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(mContinuationToken, flags);
+ dest.writeTypedList(mMessageTypeIdPairs);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/Rcs1To1Thread.aidl b/telephony/java/android/telephony/ims/RcsMessageSnippet.aidl
similarity index 95%
rename from telephony/java/android/telephony/ims/Rcs1To1Thread.aidl
rename to telephony/java/android/telephony/ims/RcsMessageSnippet.aidl
index 9fdc41d..99b8eb7 100644
--- a/telephony/java/android/telephony/ims/Rcs1To1Thread.aidl
+++ b/telephony/java/android/telephony/ims/RcsMessageSnippet.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable Rcs1To1Thread;
+parcelable RcsMessageSnippet;
diff --git a/telephony/java/android/telephony/ims/RcsMessageSnippet.java b/telephony/java/android/telephony/ims/RcsMessageSnippet.java
new file mode 100644
index 0000000..9399c20
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsMessageSnippet.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.ims.RcsMessage.RcsMessageStatus;
+
+/**
+ * An immutable summary of the latest {@link RcsMessage} on an {@link RcsThread}
+ *
+ * @hide TODO: make public
+ */
+public class RcsMessageSnippet implements Parcelable {
+ private final String mText;
+ private final @RcsMessageStatus int mStatus;
+ private final long mTimestamp;
+
+ /**
+ * @hide
+ */
+ public RcsMessageSnippet(String text, @RcsMessageStatus int status, long timestamp) {
+ mText = text;
+ mStatus = status;
+ mTimestamp = timestamp;
+ }
+
+ /**
+ * @return Returns the text of the {@link RcsMessage} with highest origination timestamp value
+ * (i.e. latest) in this thread
+ */
+ @Nullable
+ public String getSnippetText() {
+ return mText;
+ }
+
+ /**
+ * @return Returns the status of the {@link RcsMessage} with highest origination timestamp value
+ * (i.e. latest) in this thread
+ */
+ public @RcsMessageStatus int getSnippetStatus() {
+ return mStatus;
+ }
+
+ /**
+ * @return Returns the timestamp of the {@link RcsMessage} with highest origination timestamp
+ * value (i.e. latest) in this thread
+ */
+ public long getSnippetTimestamp() {
+ return mTimestamp;
+ }
+
+ protected RcsMessageSnippet(Parcel in) {
+ mText = in.readString();
+ mStatus = in.readInt();
+ mTimestamp = in.readLong();
+ }
+
+ public static final Creator<RcsMessageSnippet> CREATOR =
+ new Creator<RcsMessageSnippet>() {
+ @Override
+ public RcsMessageSnippet createFromParcel(Parcel in) {
+ return new RcsMessageSnippet(in);
+ }
+
+ @Override
+ public RcsMessageSnippet[] newArray(int size) {
+ return new RcsMessageSnippet[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mText);
+ dest.writeInt(mStatus);
+ dest.writeLong(mTimestamp);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsMessageStore.java b/telephony/java/android/telephony/ims/RcsMessageStore.java
index 1bf6ffd..c8c36a8 100644
--- a/telephony/java/android/telephony/ims/RcsMessageStore.java
+++ b/telephony/java/android/telephony/ims/RcsMessageStore.java
@@ -16,106 +16,223 @@
package android.telephony.ims;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.WorkerThread;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.Rlog;
-import android.telephony.ims.aidl.IRcs;
+import android.net.Uri;
+
+import java.util.List;
/**
* RcsMessageStore is the application interface to RcsProvider and provides access methods to
* RCS related database tables.
+ *
* @hide - TODO make this public
*/
public class RcsMessageStore {
- static final String TAG = "RcsMessageStore";
-
/**
* Returns the first chunk of existing {@link RcsThread}s in the common storage.
+ *
* @param queryParameters Parameters to specify to return a subset of all RcsThreads.
* Passing a value of null will return all threads.
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
*/
@WorkerThread
- public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParameters queryParameters) {
- try {
- IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
- if (iRcs != null) {
- return iRcs.getRcsThreads(queryParameters);
- }
- } catch (RemoteException re) {
- Rlog.e(TAG, "RcsMessageStore: Exception happened during getRcsThreads", re);
- }
-
- return null;
+ @NonNull
+ public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParameters queryParameters)
+ throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getRcsThreads(queryParameters));
}
/**
* Returns the next chunk of {@link RcsThread}s in the common storage.
+ *
* @param continuationToken A token to continue the query to get the next chunk. This is
- * obtained through {@link RcsThreadQueryResult#nextChunkToken}.
+ * obtained through {@link RcsThreadQueryResult#getContinuationToken}.
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
*/
@WorkerThread
- public RcsThreadQueryResult getRcsThreads(RcsThreadQueryContinuationToken continuationToken) {
- try {
- IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
- if (iRcs != null) {
- return iRcs.getRcsThreadsWithToken(continuationToken);
- }
- } catch (RemoteException re) {
- Rlog.e(TAG, "RcsMessageStore: Exception happened during getRcsThreads", re);
- }
+ @NonNull
+ public RcsThreadQueryResult getRcsThreads(@NonNull RcsQueryContinuationToken continuationToken)
+ throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getRcsThreadsWithToken(continuationToken));
+ }
- return null;
+ /**
+ * Returns the first chunk of existing {@link RcsParticipant}s in the common storage.
+ *
+ * @param queryParameters Parameters to specify to return a subset of all RcsParticipants.
+ * Passing a value of null will return all participants.
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
+ */
+ @WorkerThread
+ @NonNull
+ public RcsParticipantQueryResult getRcsParticipants(
+ @Nullable RcsParticipantQueryParameters queryParameters)
+ throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getParticipants(queryParameters));
+ }
+
+ /**
+ * Returns the next chunk of {@link RcsParticipant}s in the common storage.
+ *
+ * @param continuationToken A token to continue the query to get the next chunk. This is
+ * obtained through
+ * {@link RcsParticipantQueryResult#getContinuationToken}
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
+ */
+ @WorkerThread
+ @NonNull
+ public RcsParticipantQueryResult getRcsParticipants(
+ @NonNull RcsQueryContinuationToken continuationToken)
+ throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getParticipantsWithToken(continuationToken));
+ }
+
+ /**
+ * Returns the first chunk of existing {@link RcsMessage}s in the common storage.
+ *
+ * @param queryParameters Parameters to specify to return a subset of all RcsMessages.
+ * Passing a value of null will return all messages.
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
+ */
+ @WorkerThread
+ @NonNull
+ public RcsMessageQueryResult getRcsMessages(
+ @Nullable RcsMessageQueryParameters queryParameters) throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getMessages(queryParameters));
+ }
+
+ /**
+ * Returns the next chunk of {@link RcsMessage}s in the common storage.
+ *
+ * @param continuationToken A token to continue the query to get the next chunk. This is
+ * obtained through {@link RcsMessageQueryResult#getContinuationToken}
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
+ */
+ @WorkerThread
+ @NonNull
+ public RcsMessageQueryResult getRcsMessages(
+ @NonNull RcsQueryContinuationToken continuationToken) throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getMessagesWithToken(continuationToken));
+ }
+
+ /**
+ * Returns the first chunk of existing {@link RcsEvent}s in the common storage.
+ *
+ * @param queryParameters Parameters to specify to return a subset of all RcsEvents.
+ * Passing a value of null will return all events.
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
+ */
+ @WorkerThread
+ @NonNull
+ public RcsEventQueryResult getRcsEvents(
+ @Nullable RcsEventQueryParameters queryParameters) throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getEvents(queryParameters));
+ }
+
+ /**
+ * Returns the next chunk of {@link RcsEvent}s in the common storage.
+ *
+ * @param continuationToken A token to continue the query to get the next chunk. This is
+ * obtained through {@link RcsEventQueryResult#getContinuationToken}.
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
+ */
+ @WorkerThread
+ @NonNull
+ public RcsEventQueryResult getRcsEvents(
+ @NonNull RcsQueryContinuationToken continuationToken) throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getEventsWithToken(continuationToken));
+ }
+
+ /**
+ * Persists an {@link RcsEvent} to common storage.
+ *
+ * @param persistableEvent The {@link RcsEvent} to persist into storage.
+ * @throws RcsMessageStoreException if the query could not be completed on the storage
+ *
+ * @see RcsGroupThreadNameChangedEvent
+ * @see RcsGroupThreadIconChangedEvent
+ * @see RcsGroupThreadParticipantJoinedEvent
+ * @see RcsGroupThreadParticipantLeftEvent
+ * @see RcsParticipantAliasChangedEvent
+ */
+ @WorkerThread
+ @NonNull
+ public void persistRcsEvent(RcsEvent persistableEvent) throws RcsMessageStoreException {
+ persistableEvent.persist();
}
/**
* Creates a new 1 to 1 thread with the given participant and persists it in the storage.
+ *
+ * @param recipient The {@link RcsParticipant} that will receive the messages in this thread.
+ * @return The newly created {@link Rcs1To1Thread}
+ * @throws RcsMessageStoreException if the thread could not be persisted in the storage
*/
@WorkerThread
- public Rcs1To1Thread createRcs1To1Thread(RcsParticipant recipient) {
- try {
- IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
- if (iRcs != null) {
- return iRcs.createRcs1To1Thread(recipient);
- }
- } catch (RemoteException re) {
- Rlog.e(TAG, "RcsMessageStore: Exception happened during createRcs1To1Thread", re);
- }
-
- return null;
+ @NonNull
+ public Rcs1To1Thread createRcs1To1Thread(@NonNull RcsParticipant recipient)
+ throws RcsMessageStoreException {
+ return new Rcs1To1Thread(
+ RcsControllerCall.call(iRcs -> iRcs.createRcs1To1Thread(recipient.getId())));
}
/**
- * Delete the {@link RcsThread} identified by the given threadId.
- * @param threadId threadId of the thread to be deleted.
+ * Creates a new group thread with the given participants and persists it in the storage.
+ *
+ * @throws RcsMessageStoreException if the thread could not be persisted in the storage
*/
@WorkerThread
- public void deleteThread(int threadId) {
- try {
- IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
- if (iRcs != null) {
- iRcs.deleteThread(threadId);
+ @NonNull
+ public RcsGroupThread createGroupThread(@Nullable List<RcsParticipant> recipients,
+ @Nullable String groupName, @Nullable Uri groupIcon) throws RcsMessageStoreException {
+ int[] recipientIds = null;
+ if (recipients != null) {
+ recipientIds = new int[recipients.size()];
+
+ for (int i = 0; i < recipients.size(); i++) {
+ recipientIds[i] = recipients.get(i).getId();
}
- } catch (RemoteException re) {
- Rlog.e(TAG, "RcsMessageStore: Exception happened during deleteThread", re);
+ }
+
+ int[] finalRecipientIds = recipientIds;
+ return new RcsGroupThread(RcsControllerCall.call(
+ iRcs -> iRcs.createGroupThread(finalRecipientIds, groupName, groupIcon)));
+ }
+
+ /**
+ * Delete the given {@link RcsThread} from the storage.
+ *
+ * @param thread The thread to be deleted.
+ * @throws RcsMessageStoreException if the thread could not be deleted from the storage
+ */
+ @WorkerThread
+ public void deleteThread(@NonNull RcsThread thread) throws RcsMessageStoreException {
+ if (thread == null) {
+ return;
+ }
+
+ boolean isDeleteSucceeded = RcsControllerCall.call(
+ iRcs -> iRcs.deleteThread(thread.getThreadId(), thread.getThreadType()));
+
+ if (!isDeleteSucceeded) {
+ throw new RcsMessageStoreException("Could not delete RcsThread");
}
}
/**
* Creates a new participant and persists it in the storage.
+ *
* @param canonicalAddress The defining address (e.g. phone number) of the participant.
+ * @param alias The RCS alias for the participant.
+ * @throws RcsMessageStoreException if the participant could not be created on the storage
*/
- public RcsParticipant createRcsParticipant(String canonicalAddress) {
- try {
- IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
- if (iRcs != null) {
- return iRcs.createRcsParticipant(canonicalAddress);
- }
- } catch (RemoteException re) {
- Rlog.e(TAG, "RcsMessageStore: Exception happened during createRcsParticipant", re);
- }
-
- return null;
+ @WorkerThread
+ @NonNull
+ public RcsParticipant createRcsParticipant(String canonicalAddress, @Nullable String alias)
+ throws RcsMessageStoreException {
+ return new RcsParticipant(
+ RcsControllerCall.call(iRcs -> iRcs.createRcsParticipant(canonicalAddress, alias)));
}
}
diff --git a/telephony/java/android/telephony/ims/RcsMessageStoreException.java b/telephony/java/android/telephony/ims/RcsMessageStoreException.java
new file mode 100644
index 0000000..e158f1a
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsMessageStoreException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+/**
+ * An exception that happened on {@link RcsMessageStore} or one of the derived storage classes in
+ * {@link android.telephony.ims}
+ *
+ * @hide TODO: make public
+ */
+public class RcsMessageStoreException extends Exception {
+
+ /**
+ * Constructs an {@link RcsMessageStoreException} with the specified detail message.
+ * @param message The detail message
+ * @see Throwable#getMessage()
+ */
+ public RcsMessageStoreException(String message) {
+ super(message);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsMultiMediaPart.java b/telephony/java/android/telephony/ims/RcsMultiMediaPart.java
deleted file mode 100644
index d295fba..0000000
--- a/telephony/java/android/telephony/ims/RcsMultiMediaPart.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcel;
-
-/**
- * A part of a composite {@link RcsMessage} that holds a media that is rendered on the screen
- * (i.e. image, video etc)
- * @hide - TODO(sahinc) make this public
- */
-public class RcsMultiMediaPart extends RcsFileTransferPart {
- public static final Creator<RcsMultiMediaPart> CREATOR = new Creator<RcsMultiMediaPart>() {
- @Override
- public RcsMultiMediaPart createFromParcel(Parcel in) {
- return new RcsMultiMediaPart(in);
- }
-
- @Override
- public RcsMultiMediaPart[] newArray(int size) {
- return new RcsMultiMediaPart[size];
- }
- };
-
- protected RcsMultiMediaPart(Parcel in) {
- super(in);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-}
diff --git a/telephony/java/android/telephony/ims/RcsMultimediaPart.aidl b/telephony/java/android/telephony/ims/RcsMultimediaPart.aidl
deleted file mode 100644
index 5992d95..0000000
--- a/telephony/java/android/telephony/ims/RcsMultimediaPart.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsMultimediaPart;
diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessage.aidl b/telephony/java/android/telephony/ims/RcsOutgoingMessage.aidl
deleted file mode 100644
index 6e0c80f..0000000
--- a/telephony/java/android/telephony/ims/RcsOutgoingMessage.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsOutgoingMessage;
diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
index bfb1611..0bd55ec 100644
--- a/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
+++ b/telephony/java/android/telephony/ims/RcsOutgoingMessage.java
@@ -15,34 +15,53 @@
*/
package android.telephony.ims;
-import android.os.Parcel;
+import android.annotation.NonNull;
+import android.annotation.WorkerThread;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* This is a single instance of a message sent over RCS.
- * @hide - TODO(sahinc) make this public
+ *
+ * @hide - TODO(109759350) make this public
*/
public class RcsOutgoingMessage extends RcsMessage {
- public static final Creator<RcsOutgoingMessage> CREATOR = new Creator<RcsOutgoingMessage>() {
- @Override
- public RcsOutgoingMessage createFromParcel(Parcel in) {
- return new RcsOutgoingMessage(in);
- }
-
- @Override
- public RcsOutgoingMessage[] newArray(int size) {
- return new RcsOutgoingMessage[size];
- }
- };
-
- protected RcsOutgoingMessage(Parcel in) {
+ RcsOutgoingMessage(int id) {
+ super(id);
}
- @Override
- public int describeContents() {
- return 0;
+ /**
+ * @return Returns the {@link RcsOutgoingMessageDelivery}s associated with this message. Please
+ * note that the deliveries returned for the {@link RcsOutgoingMessage} may not always match the
+ * {@link RcsParticipant}s on the {@link RcsGroupThread} as the group recipients may have
+ * changed.
+ * @throws RcsMessageStoreException if the outgoing deliveries could not be read from storage.
+ */
+ @NonNull
+ @WorkerThread
+ public List<RcsOutgoingMessageDelivery> getOutgoingDeliveries()
+ throws RcsMessageStoreException {
+ int[] deliveryParticipants;
+ List<RcsOutgoingMessageDelivery> messageDeliveries = new ArrayList<>();
+
+ deliveryParticipants = RcsControllerCall.call(
+ iRcs -> iRcs.getMessageRecipients(mId));
+
+ if (deliveryParticipants != null) {
+ for (Integer deliveryParticipant : deliveryParticipants) {
+ messageDeliveries.add(new RcsOutgoingMessageDelivery(deliveryParticipant, mId));
+ }
+ }
+
+ return messageDeliveries;
}
+ /**
+ * @return Returns {@code false} as this is not an incoming message.
+ */
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public boolean isIncoming() {
+ return false;
}
}
diff --git a/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java
new file mode 100644
index 0000000..b93f892
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsOutgoingMessageDelivery.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.WorkerThread;
+
+/**
+ * This class holds the delivery information of an {@link RcsOutgoingMessage} for each
+ * {@link RcsParticipant} that the message was intended for.
+ *
+ * @hide - TODO(109759350) make this public
+ */
+public class RcsOutgoingMessageDelivery {
+ // The participant that this delivery is intended for
+ private final int mRecipientId;
+ // The message this delivery is associated with
+ private final int mRcsOutgoingMessageId;
+
+ /**
+ * Constructor to be used with RcsOutgoingMessage.getDelivery()
+ *
+ * @hide
+ */
+ RcsOutgoingMessageDelivery(int recipientId, int messageId) {
+ mRecipientId = recipientId;
+ mRcsOutgoingMessageId = messageId;
+ }
+
+ /**
+ * Sets the delivery time of this outgoing delivery and persists into storage.
+ *
+ * @param deliveredTimestamp The timestamp to set to delivery. It is defined as milliseconds
+ * passed after midnight, January 1, 1970 UTC
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setDeliveredTimestamp(long deliveredTimestamp) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setOutgoingDeliveryDeliveredTimestamp(
+ mRcsOutgoingMessageId, mRecipientId, deliveredTimestamp));
+ }
+
+ /**
+ * @return Returns the delivered timestamp of the associated message to the associated
+ * participant. Timestamp is defined as milliseconds passed after midnight, January 1, 1970 UTC.
+ * Returns 0 if the {@link RcsOutgoingMessage} is not delivered yet.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getDeliveredTimestamp() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getOutgoingDeliveryDeliveredTimestamp(
+ mRcsOutgoingMessageId, mRecipientId));
+ }
+
+ /**
+ * Sets the seen time of this outgoing delivery and persists into storage.
+ *
+ * @param seenTimestamp The timestamp to set to delivery. It is defined as milliseconds
+ * passed after midnight, January 1, 1970 UTC
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setSeenTimestamp(long seenTimestamp) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setOutgoingDeliverySeenTimestamp(
+ mRcsOutgoingMessageId, mRecipientId, seenTimestamp));
+ }
+
+ /**
+ * @return Returns the seen timestamp of the associated message by the associated
+ * participant. Timestamp is defined as milliseconds passed after midnight, January 1, 1970 UTC.
+ * Returns 0 if the {@link RcsOutgoingMessage} is not seen yet.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public long getSeenTimestamp() throws RcsMessageStoreException {
+ return RcsControllerCall.call(
+ iRcs -> iRcs.getOutgoingDeliverySeenTimestamp(mRcsOutgoingMessageId, mRecipientId));
+ }
+
+ /**
+ * Sets the status of this outgoing delivery and persists into storage.
+ *
+ * @param status The status of the associated {@link RcsMessage}s delivery to the associated
+ * {@link RcsParticipant}
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
+ */
+ @WorkerThread
+ public void setStatus(@RcsMessage.RcsMessageStatus int status) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setOutgoingDeliveryStatus(
+ mRcsOutgoingMessageId, mRecipientId, status));
+ }
+
+ /**
+ * @return Returns the status of this outgoing delivery.
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @WorkerThread
+ public @RcsMessage.RcsMessageStatus int getStatus() throws RcsMessageStoreException {
+ return RcsControllerCall.call(
+ iRcs -> iRcs.getOutgoingDeliveryStatus(mRcsOutgoingMessageId, mRecipientId));
+ }
+
+ /**
+ * @return Returns the recipient associated with this delivery.
+ */
+ @NonNull
+ public RcsParticipant getRecipient() {
+ return new RcsParticipant(mRecipientId);
+ }
+
+ /**
+ * @return Returns the {@link RcsOutgoingMessage} associated with this delivery.
+ */
+ @NonNull
+ public RcsOutgoingMessage getMessage() {
+ return new RcsOutgoingMessage(mRcsOutgoingMessageId);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsParticipant.aidl b/telephony/java/android/telephony/ims/RcsParticipant.aidl
deleted file mode 100644
index 1c44363..0000000
--- a/telephony/java/android/telephony/ims/RcsParticipant.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsParticipant;
diff --git a/telephony/java/android/telephony/ims/RcsParticipant.java b/telephony/java/android/telephony/ims/RcsParticipant.java
index f678ec7..ce0ad2c 100644
--- a/telephony/java/android/telephony/ims/RcsParticipant.java
+++ b/telephony/java/android/telephony/ims/RcsParticipant.java
@@ -15,33 +15,17 @@
*/
package android.telephony.ims;
-import static android.telephony.ims.RcsMessageStore.TAG;
-
-import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.WorkerThread;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.Rlog;
-import android.telephony.ims.aidl.IRcs;
-import android.text.TextUtils;
-
-import com.android.internal.util.Preconditions;
/**
* RcsParticipant is an RCS capable contact that can participate in {@link RcsThread}s.
- * @hide - TODO(sahinc) make this public
+ *
+ * @hide - TODO(109759350) make this public
*/
-public class RcsParticipant implements Parcelable {
+public class RcsParticipant {
// The row ID of this participant in the database
private int mId;
- // The phone number of this participant
- private String mCanonicalAddress;
- // The RCS alias of this participant. This is different than the name of the contact in the
- // Contacts app - i.e. RCS protocol allows users to define aliases for themselves that doesn't
- // require other users to add them as contacts and give them a name.
- private String mAlias;
/**
* Constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController}
@@ -49,68 +33,87 @@
*
* @hide
*/
- public RcsParticipant(int id, @NonNull String canonicalAddress) {
+ public RcsParticipant(int id) {
mId = id;
- mCanonicalAddress = canonicalAddress;
}
/**
- * @return Returns the canonical address (i.e. normalized phone number) for this participant
+ * @return Returns the canonical address (i.e. normalized phone number) for this
+ * {@link RcsParticipant}
+ * @throws RcsMessageStoreException if the value could not be read from the storage
*/
- public String getCanonicalAddress() {
- return mCanonicalAddress;
+ @Nullable
+ @WorkerThread
+ public String getCanonicalAddress() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getRcsParticipantCanonicalAddress(mId));
}
/**
- * Sets the canonical address for this participant and updates it in storage.
- * @param canonicalAddress the canonical address to update to.
+ * @return Returns the alias for this {@link RcsParticipant}. Alias is usually the real name of
+ * the person themselves. Please see US5-15 - GSMA RCC.71 (RCS Universal Profile Service
+ * Definition Document)
+ * @throws RcsMessageStoreException if the value could not be read from the storage
+ */
+ @Nullable
+ @WorkerThread
+ public String getAlias() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getRcsParticipantAlias(mId));
+ }
+
+ /**
+ * Sets the alias for this {@link RcsParticipant} and persists it in storage. Alias is usually
+ * the real name of the person themselves. Please see US5-15 - GSMA RCC.71 (RCS Universal
+ * Profile Service Definition Document)
+ *
+ * @param alias The alias to set to.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
*/
@WorkerThread
- public void setCanonicalAddress(@NonNull String canonicalAddress) {
- Preconditions.checkNotNull(canonicalAddress);
- if (canonicalAddress.equals(mCanonicalAddress)) {
- return;
- }
-
- mCanonicalAddress = canonicalAddress;
-
- try {
- IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
- if (iRcs != null) {
- iRcs.updateRcsParticipantCanonicalAddress(mId, mCanonicalAddress);
- }
- } catch (RemoteException re) {
- Rlog.e(TAG, "RcsParticipant: Exception happened during setCanonicalAddress", re);
- }
+ public void setAlias(String alias) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setRcsParticipantAlias(mId, alias));
}
/**
- * @return Returns the alias for this participant. Alias is usually the real name of the person
- * themselves.
+ * @return Returns the contact ID for this {@link RcsParticipant}. Contact ID is a unique ID for
+ * an {@link RcsParticipant} that is RCS provisioned. Please see 4.4.5 - GSMA RCC.53 (RCS Device
+ * API 1.6 Specification)
+ * @throws RcsMessageStoreException if the value could not be read from the storage
*/
- public String getAlias() {
- return mAlias;
+ @Nullable
+ @WorkerThread
+ public String getContactId() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getRcsParticipantContactId(mId));
}
/**
- * Sets the alias for this participant and persists it in storage. Alias is usually the real
- * name of the person themselves.
+ * Sets the contact ID for this {@link RcsParticipant}. Contact ID is a unique ID for
+ * an {@link RcsParticipant} that is RCS provisioned. Please see 4.4.5 - GSMA RCC.53 (RCS Device
+ * API 1.6 Specification)
+ *
+ * @param contactId The contact ID to set to.
+ * @throws RcsMessageStoreException if the value could not be persisted into storage
*/
@WorkerThread
- public void setAlias(String alias) {
- if (TextUtils.equals(mAlias, alias)) {
- return;
- }
- mAlias = alias;
+ public void setContactId(String contactId) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(iRcs -> iRcs.setRcsParticipantContactId(mId, contactId));
+ }
- try {
- IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
- if (iRcs != null) {
- iRcs.updateRcsParticipantAlias(mId, mAlias);
- }
- } catch (RemoteException re) {
- Rlog.e(TAG, "RcsParticipant: Exception happened during setCanonicalAddress", re);
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
}
+ if (!(obj instanceof RcsParticipant)) {
+ return false;
+ }
+ RcsParticipant other = (RcsParticipant) obj;
+
+ return mId == other.mId;
+ }
+
+ @Override
+ public int hashCode() {
+ return mId;
}
/**
@@ -121,34 +124,4 @@
public int getId() {
return mId;
}
-
- public static final Creator<RcsParticipant> CREATOR = new Creator<RcsParticipant>() {
- @Override
- public RcsParticipant createFromParcel(Parcel in) {
- return new RcsParticipant(in);
- }
-
- @Override
- public RcsParticipant[] newArray(int size) {
- return new RcsParticipant[size];
- }
- };
-
- protected RcsParticipant(Parcel in) {
- mId = in.readInt();
- mCanonicalAddress = in.readString();
- mAlias = in.readString();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mId);
- dest.writeString(mCanonicalAddress);
- dest.writeString(mAlias);
- }
}
diff --git a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java
index b9ca5a8..04cdf86 100644
--- a/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java
+++ b/telephony/java/android/telephony/ims/RcsParticipantAliasChangedEvent.java
@@ -15,27 +15,93 @@
*/
package android.telephony.ims;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Parcel;
/**
- * An event that indicates an {@link RcsParticipant}'s alias was changed.
- * @hide - TODO(sahinc) make this public
+ * An event that indicates an {@link RcsParticipant}'s alias was changed. Please see US18-2 - GSMA
+ * RCC.71 (RCS Universal Profile Service Definition Document)
+ *
+ * @hide - TODO(109759350) make this public
*/
-public class RcsParticipantAliasChangedEvent extends RcsParticipantEvent {
+public class RcsParticipantAliasChangedEvent extends RcsEvent {
+ // The ID of the participant that changed their alias
+ private int mParticipantId;
+ // The new alias of the above participant
+ private String mNewAlias;
+
+ /**
+ * Creates a new {@link RcsParticipantAliasChangedEvent}. This event is not persisted into
+ * storage until {@link RcsMessageStore#persistRcsEvent(RcsEvent)} is called.
+ *
+ * @param timestamp The timestamp of when this event happened, in milliseconds passed after
+ * midnight, January 1st, 1970 UTC
+ * @param participant The {@link RcsParticipant} that got their alias changed
+ * @param newAlias The new alias the {@link RcsParticipant} has.
+ * @see RcsMessageStore#persistRcsEvent(RcsEvent)
+ */
+ public RcsParticipantAliasChangedEvent(long timestamp, @NonNull RcsParticipant participant,
+ @Nullable String newAlias) {
+ super(timestamp);
+ mParticipantId = participant.getId();
+ mNewAlias = newAlias;
+ }
+
+ /**
+ * @hide - internal constructor for queries
+ */
+ public RcsParticipantAliasChangedEvent(long timestamp, int participantId,
+ @Nullable String newAlias) {
+ super(timestamp);
+ mParticipantId = participantId;
+ mNewAlias = newAlias;
+ }
+
+ /**
+ * @return Returns the {@link RcsParticipant} whose alias was changed.
+ */
+ @NonNull
+ public RcsParticipant getParticipantId() {
+ return new RcsParticipant(mParticipantId);
+ }
+
+ /**
+ * @return Returns the alias of the associated {@link RcsParticipant} after this event happened
+ */
+ @Nullable
+ public String getNewAlias() {
+ return mNewAlias;
+ }
+
+ /**
+ * Persists the event to the data store.
+ *
+ * @hide - not meant for public use.
+ */
+ @Override
+ public void persist() throws RcsMessageStoreException {
+ RcsControllerCall.call(iRcs -> iRcs.createParticipantAliasChangedEvent(
+ getTimestamp(), getParticipantId().getId(), getNewAlias()));
+ }
+
public static final Creator<RcsParticipantAliasChangedEvent> CREATOR =
new Creator<RcsParticipantAliasChangedEvent>() {
- @Override
- public RcsParticipantAliasChangedEvent createFromParcel(Parcel in) {
- return new RcsParticipantAliasChangedEvent(in);
- }
+ @Override
+ public RcsParticipantAliasChangedEvent createFromParcel(Parcel in) {
+ return new RcsParticipantAliasChangedEvent(in);
+ }
- @Override
- public RcsParticipantAliasChangedEvent[] newArray(int size) {
- return new RcsParticipantAliasChangedEvent[size];
- }
- };
+ @Override
+ public RcsParticipantAliasChangedEvent[] newArray(int size) {
+ return new RcsParticipantAliasChangedEvent[size];
+ }
+ };
protected RcsParticipantAliasChangedEvent(Parcel in) {
+ super(in);
+ mNewAlias = in.readString();
+ mParticipantId = in.readInt();
}
@Override
@@ -45,5 +111,8 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(mNewAlias);
+ dest.writeInt(mParticipantId);
}
}
diff --git a/telephony/java/android/telephony/ims/RcsParticipantEvent.aidl b/telephony/java/android/telephony/ims/RcsParticipantEvent.aidl
deleted file mode 100644
index c0a7789..0000000
--- a/telephony/java/android/telephony/ims/RcsParticipantEvent.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsParticipantEvent;
diff --git a/telephony/java/android/telephony/ims/RcsParticipantEvent.java b/telephony/java/android/telephony/ims/RcsParticipantEvent.java
deleted file mode 100644
index 371b8b7..0000000
--- a/telephony/java/android/telephony/ims/RcsParticipantEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcelable;
-
-/**
- * An event that is associated with an {@link RcsParticipant}
- * @hide - TODO(sahinc) make this public
- */
-public abstract class RcsParticipantEvent implements Parcelable {
-}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.aidl
similarity index 93%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsParticipantQueryParameters.aidl
index 82d985d..ea8288c 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsParticipantQueryParameters;
diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.java b/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.java
new file mode 100644
index 0000000..3611fc1
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsParticipantQueryParameters.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.CheckResult;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.security.InvalidParameterException;
+
+/**
+ * The parameters to pass into
+ * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParameters)} in order to select a
+ * subset of {@link RcsThread}s present in the message store.
+ *
+ * @hide TODO - make the Builder and builder() public. The rest should stay internal only.
+ */
+public class RcsParticipantQueryParameters implements Parcelable {
+ /**
+ * Flag to set with {@link Builder#setSortProperty(int)} to sort the results in the order of
+ * creation time for faster query results
+ */
+ public static final int SORT_BY_CREATION_ORDER = 0;
+
+ /**
+ * Flag to set with {@link Builder#setSortProperty(int)} to sort depending on the
+ * {@link RcsParticipant} aliases
+ */
+ public static final int SORT_BY_ALIAS = 1;
+
+ /**
+ * Flag to set with {@link Builder#setSortProperty(int)} to sort depending on the
+ * {@link RcsParticipant} canonical addresses
+ */
+ public static final int SORT_BY_CANONICAL_ADDRESS = 2;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({SORT_BY_CREATION_ORDER, SORT_BY_ALIAS, SORT_BY_CANONICAL_ADDRESS})
+ public @interface SortingProperty {
+ }
+
+ // The SQL "like" statement to filter against participant aliases
+ private String mAliasLike;
+ // The SQL "like" statement to filter against canonical addresses
+ private String mCanonicalAddressLike;
+ // The property to sort the result against
+ private @SortingProperty int mSortingProperty;
+ // Whether to sort the result in ascending order
+ private boolean mIsAscending;
+ // The number of results to be returned from the query
+ private int mLimit;
+ // Used to limit the results to participants of a single thread
+ private int mThreadId;
+
+ /**
+ * @hide
+ */
+ public static final String PARTICIPANT_QUERY_PARAMETERS_KEY = "participant_query_parameters";
+
+ RcsParticipantQueryParameters(int rcsThreadId, String aliasLike, String canonicalAddressLike,
+ @SortingProperty int sortingProperty, boolean isAscending,
+ int limit) {
+ mThreadId = rcsThreadId;
+ mAliasLike = aliasLike;
+ mCanonicalAddressLike = canonicalAddressLike;
+ mSortingProperty = sortingProperty;
+ mIsAscending = isAscending;
+ mLimit = limit;
+ }
+
+ /**
+ * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get
+ * the thread that the result query should be limited to.
+ *
+ * As we do not expose any sort of integer ID's to public usage, this should be hidden.
+ *
+ * @hide - not meant for public use
+ */
+ public int getThreadId() {
+ return mThreadId;
+ }
+
+ /**
+ * @return Returns the SQL-inspired "LIKE" clause that will be used to match
+ * {@link RcsParticipant}s with respect to their aliases
+ *
+ * @see RcsParticipant#getAlias()
+ */
+ public String getAliasLike() {
+ return mAliasLike;
+ }
+
+ /**
+ * @return Returns the SQL-inspired "LIKE" clause that will be used to match
+ * {@link RcsParticipant}s with respect to their canonical addresses.
+ *
+ * @see RcsParticipant#getCanonicalAddress()
+ */
+ public String getCanonicalAddressLike() {
+ return mCanonicalAddressLike;
+ }
+
+ /**
+ * @return Returns the number of {@link RcsParticipant}s to be returned from the query. A value
+ * of 0 means there is no set limit.
+ */
+ public int getLimit() {
+ return mLimit;
+ }
+
+ /**
+ * @return Returns the property that will be used to sort the result against.
+ * @see SortingProperty
+ */
+ public int getSortingProperty() {
+ return mSortingProperty;
+ }
+
+ /**
+ * @return Returns {@code true} if the result set will be sorted in ascending order,
+ * {@code false} if it will be sorted in descending order.
+ */
+ public boolean getSortDirection() {
+ return mIsAscending;
+ }
+
+ /**
+ * A helper class to build the {@link RcsParticipantQueryParameters}.
+ */
+ public static class Builder {
+ private String mAliasLike;
+ private String mCanonicalAddressLike;
+ private @SortingProperty int mSortingProperty;
+ private boolean mIsAscending;
+ private int mLimit = 100;
+ private int mThreadId;
+
+ /**
+ * Creates a new builder for {@link RcsParticipantQueryParameters} to be used in
+ * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParameters)}
+ */
+ public Builder() {
+ // empty implementation
+ }
+
+ /**
+ * Limits the resulting {@link RcsParticipant}s to only the given {@link RcsThread}
+ *
+ * @param rcsThread The thread that the participants should be searched in.
+ * @return The same {@link Builder} to chain methods.
+ */
+ @CheckResult
+ public Builder setThread(RcsThread rcsThread) {
+ mThreadId = rcsThread.getThreadId();
+ return this;
+ }
+
+ /**
+ * Sets an SQL-inspired "like" clause to match with participant aliases. Using a percent
+ * sign ('%') wildcard matches any sequence of zero or more characters. Using an underscore
+ * ('_') wildcard matches any single character. Not using any wildcards would only perform a
+ * string match.The input string is case-insensitive.
+ *
+ * The input "An%e" would match {@link RcsParticipant}s with names Anne, Annie, Antonie,
+ * while the input "An_e" would only match Anne.
+ *
+ * @param likeClause The like clause to use for matching {@link RcsParticipant} aliases.
+ * @return The same {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setAliasLike(String likeClause) {
+ mAliasLike = likeClause;
+ return this;
+ }
+
+ /**
+ * Sets an SQL-inspired "like" clause to match with participant addresses. Using a percent
+ * sign ('%') wildcard matches any sequence of zero or more characters. Using an underscore
+ * ('_') wildcard matches any single character. Not using any wildcards would only perform a
+ * string match. The input string is case-insensitive.
+ *
+ * The input "+999%111" would match {@link RcsParticipant}s with addresses like "+9995111"
+ * or "+99955555111", while the input "+999_111" would only match "+9995111".
+ *
+ * @param likeClause The like clause to use for matching {@link RcsParticipant} canonical
+ * addresses.
+ * @return The same {@link Builder} to chain methods
+ */
+ @CheckResult
+ public Builder setCanonicalAddressLike(String likeClause) {
+ mCanonicalAddressLike = likeClause;
+ return this;
+ }
+
+ /**
+ * Desired number of threads to be returned from the query. Passing in 0 will return all
+ * existing threads at once. The limit defaults to 100.
+ *
+ * @param limit The number to limit the query result to.
+ * @return The same instance of the builder to chain parameters.
+ * @throws InvalidParameterException If the given limit is negative.
+ */
+ @CheckResult
+ public Builder setResultLimit(@IntRange(from = 0) int limit)
+ throws InvalidParameterException {
+ if (limit < 0) {
+ throw new InvalidParameterException("The query limit must be non-negative");
+ }
+
+ mLimit = limit;
+ return this;
+ }
+
+ /**
+ * Sets the property where the results should be sorted against. Defaults to
+ * {@link RcsParticipantQueryParameters.SortingProperty#SORT_BY_CREATION_ORDER}
+ *
+ * @param sortingProperty against which property the results should be sorted
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setSortProperty(@SortingProperty int sortingProperty) {
+ mSortingProperty = sortingProperty;
+ return this;
+ }
+
+ /**
+ * Sets whether the results should be sorted ascending or descending
+ *
+ * @param isAscending whether the results should be sorted ascending
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setSortDirection(boolean isAscending) {
+ mIsAscending = isAscending;
+ return this;
+ }
+
+ /**
+ * Builds the {@link RcsParticipantQueryParameters} to use in
+ * {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParameters)}
+ *
+ * @return An instance of {@link RcsParticipantQueryParameters} to use with the participant
+ * query.
+ */
+ public RcsParticipantQueryParameters build() {
+ return new RcsParticipantQueryParameters(mThreadId, mAliasLike, mCanonicalAddressLike,
+ mSortingProperty, mIsAscending, mLimit);
+ }
+ }
+
+ /**
+ * Parcelable boilerplate below.
+ */
+ protected RcsParticipantQueryParameters(Parcel in) {
+ mAliasLike = in.readString();
+ mCanonicalAddressLike = in.readString();
+ mSortingProperty = in.readInt();
+ mIsAscending = in.readByte() == 1;
+ mLimit = in.readInt();
+ mThreadId = in.readInt();
+ }
+
+ public static final Creator<RcsParticipantQueryParameters> CREATOR =
+ new Creator<RcsParticipantQueryParameters>() {
+ @Override
+ public RcsParticipantQueryParameters createFromParcel(Parcel in) {
+ return new RcsParticipantQueryParameters(in);
+ }
+
+ @Override
+ public RcsParticipantQueryParameters[] newArray(int size) {
+ return new RcsParticipantQueryParameters[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mAliasLike);
+ dest.writeString(mCanonicalAddressLike);
+ dest.writeInt(mSortingProperty);
+ dest.writeByte((byte) (mIsAscending ? 1 : 0));
+ dest.writeInt(mLimit);
+ dest.writeInt(mThreadId);
+ }
+
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.aidl
similarity index 94%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsParticipantQueryResult.aidl
index 82d985d..db5c00c 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsParticipantQueryResult;
diff --git a/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java
new file mode 100644
index 0000000..2f4ab46
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsParticipantQueryResult.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The result of a {@link RcsMessageStore#getRcsParticipants(RcsParticipantQueryParameters)}
+ * call. This class allows getting the token for querying the next batch of participants in order to
+ * prevent handling large amounts of data at once.
+ *
+ * @hide
+ */
+public class RcsParticipantQueryResult implements Parcelable {
+ // A token for the caller to continue their query for the next batch of results
+ private RcsQueryContinuationToken mContinuationToken;
+ // The list of participant IDs returned with this query
+ private List<Integer> mParticipants;
+
+ /**
+ * Internal constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController}
+ * to create query results
+ *
+ * @hide
+ */
+ public RcsParticipantQueryResult(
+ RcsQueryContinuationToken continuationToken,
+ List<Integer> participants) {
+ mContinuationToken = continuationToken;
+ mParticipants = participants;
+ }
+
+ /**
+ * Returns a token to call
+ * {@link RcsMessageStore#getRcsParticipants(RcsQueryContinuationToken)}
+ * to get the next batch of {@link RcsParticipant}s.
+ */
+ @Nullable
+ public RcsQueryContinuationToken getContinuationToken() {
+ return mContinuationToken;
+ }
+
+ /**
+ * Returns all the {@link RcsParticipant}s in the current query result. Call {@link
+ * RcsMessageStore#getRcsParticipants(RcsQueryContinuationToken)} to get the next
+ * batch of {@link RcsParticipant}s.
+ */
+ @NonNull
+ public List<RcsParticipant> getParticipants() {
+ List<RcsParticipant> participantList = new ArrayList<>();
+ for (Integer participantId : mParticipants) {
+ participantList.add(new RcsParticipant(participantId));
+ }
+
+ return participantList;
+ }
+
+ protected RcsParticipantQueryResult(Parcel in) {
+ mContinuationToken = in.readParcelable(
+ RcsQueryContinuationToken.class.getClassLoader());
+ }
+
+ public static final Creator<RcsParticipantQueryResult> CREATOR =
+ new Creator<RcsParticipantQueryResult>() {
+ @Override
+ public RcsParticipantQueryResult createFromParcel(Parcel in) {
+ return new RcsParticipantQueryResult(in);
+ }
+
+ @Override
+ public RcsParticipantQueryResult[] newArray(int size) {
+ return new RcsParticipantQueryResult[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(mContinuationToken, flags);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.aidl
similarity index 94%
copy from telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
copy to telephony/java/android/telephony/ims/RcsQueryContinuationToken.aidl
index 82d985d..319379a 100644
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.aidl
+++ b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.aidl
@@ -17,4 +17,4 @@
package android.telephony.ims;
-parcelable RcsThreadIconChangedEvent;
+parcelable RcsQueryContinuationToken;
diff --git a/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java
new file mode 100644
index 0000000..e880651
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsQueryContinuationToken.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.IntDef;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This interface allows using the same implementation for continuation token usage in
+ * {@link com.android.providers.telephony.RcsProvider}
+ * @hide - TODO make getQueryType() and types public - the rest should stay internal
+ */
+public class RcsQueryContinuationToken implements Parcelable {
+ /**
+ * Denotes that this {@link RcsQueryContinuationToken} token is meant to allow continuing
+ * {@link RcsEvent} queries
+ */
+ public static final int EVENT_QUERY_CONTINUATION_TOKEN_TYPE = 0;
+
+ /**
+ * Denotes that this {@link RcsQueryContinuationToken} token is meant to allow continuing
+ * {@link RcsMessage} queries
+ */
+ public static final int MESSAGE_QUERY_CONTINUATION_TOKEN_TYPE = 1;
+
+ /**
+ * Denotes that this {@link RcsQueryContinuationToken} token is meant to allow continuing
+ * {@link RcsParticipant} queries
+ */
+ public static final int PARTICIPANT_QUERY_CONTINUATION_TOKEN_TYPE = 2;
+
+ /**
+ * Denotes that this {@link RcsQueryContinuationToken} token is meant to allow continuing
+ * {@link RcsThread} queries
+ */
+ public static final int THREAD_QUERY_CONTINUATION_TOKEN_TYPE = 3;
+
+ /**
+ * @hide - not meant for public use
+ */
+ public static final String QUERY_CONTINUATION_TOKEN = "query_continuation_token";
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({EVENT_QUERY_CONTINUATION_TOKEN_TYPE, MESSAGE_QUERY_CONTINUATION_TOKEN_TYPE,
+ PARTICIPANT_QUERY_CONTINUATION_TOKEN_TYPE, THREAD_QUERY_CONTINUATION_TOKEN_TYPE})
+ public @interface ContinuationTokenType {}
+
+ // The type of query this token should allow to continue
+ private @ContinuationTokenType int mQueryType;
+ // The raw query string for the initial query
+ private final String mRawQuery;
+ // The number of results that is returned with each query
+ private final int mLimit;
+ // The offset value that this query should start the query from
+ private int mOffset;
+
+ /**
+ * @hide
+ */
+ public RcsQueryContinuationToken(@ContinuationTokenType int queryType, String rawQuery,
+ int limit, int offset) {
+ mQueryType = queryType;
+ mRawQuery = rawQuery;
+ mLimit = limit;
+ mOffset = offset;
+ }
+
+ /**
+ * Returns the original raw query used on {@link com.android.providers.telephony.RcsProvider}
+ * @hide
+ */
+ public String getRawQuery() {
+ return mRawQuery;
+ }
+
+ /**
+ * Returns which index this continuation query should start from
+ * @hide
+ */
+ public int getOffset() {
+ return mOffset;
+ }
+
+ /**
+ * Increments the offset by the amount of result rows returned with the continuation query for
+ * the next query.
+ * @hide
+ */
+ public void incrementOffset() {
+ mOffset += mLimit;
+ }
+
+ /**
+ * Returns the type of query that this {@link RcsQueryContinuationToken} is intended to be used
+ * to continue.
+ */
+ public @ContinuationTokenType int getQueryType() {
+ return mQueryType;
+ }
+
+ protected RcsQueryContinuationToken(Parcel in) {
+ mQueryType = in.readInt();
+ mRawQuery = in.readString();
+ mLimit = in.readInt();
+ mOffset = in.readInt();
+ }
+
+ public static final Creator<RcsQueryContinuationToken> CREATOR =
+ new Creator<RcsQueryContinuationToken>() {
+ @Override
+ public RcsQueryContinuationToken createFromParcel(Parcel in) {
+ return new RcsQueryContinuationToken(in);
+ }
+
+ @Override
+ public RcsQueryContinuationToken[] newArray(int size) {
+ return new RcsQueryContinuationToken[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mQueryType);
+ dest.writeString(mRawQuery);
+ dest.writeInt(mLimit);
+ dest.writeInt(mOffset);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsTextPart.aidl b/telephony/java/android/telephony/ims/RcsTextPart.aidl
deleted file mode 100644
index 4f9fe1f..0000000
--- a/telephony/java/android/telephony/ims/RcsTextPart.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsTextPart;
diff --git a/telephony/java/android/telephony/ims/RcsTextPart.java b/telephony/java/android/telephony/ims/RcsTextPart.java
deleted file mode 100644
index 2a72df1..0000000
--- a/telephony/java/android/telephony/ims/RcsTextPart.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcel;
-
-/**
- * A part of a composite {@link RcsMessage} that holds a string
- * @hide - TODO(sahinc) make this public
- */
-public class RcsTextPart extends RcsPart {
- public static final Creator<RcsTextPart> CREATOR = new Creator<RcsTextPart>() {
- @Override
- public RcsTextPart createFromParcel(Parcel in) {
- return new RcsTextPart(in);
- }
-
- @Override
- public RcsTextPart[] newArray(int size) {
- return new RcsTextPart[size];
- }
- };
-
- protected RcsTextPart(Parcel in) {
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-}
diff --git a/telephony/java/android/telephony/ims/RcsThread.aidl b/telephony/java/android/telephony/ims/RcsThread.aidl
deleted file mode 100644
index d9cf6db..0000000
--- a/telephony/java/android/telephony/ims/RcsThread.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-parcelable RcsThread;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java
index c0a0d94..238f5e7 100644
--- a/telephony/java/android/telephony/ims/RcsThread.java
+++ b/telephony/java/android/telephony/ims/RcsThread.java
@@ -16,60 +16,117 @@
package android.telephony.ims;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
+import static android.provider.Telephony.RcsColumns.RcsUnifiedThreadColumns.THREAD_TYPE_1_TO_1;
+import static android.provider.Telephony.RcsColumns.RcsUnifiedThreadColumns.THREAD_TYPE_GROUP;
+
+import android.annotation.NonNull;
+import android.annotation.WorkerThread;
+
+import com.android.internal.annotations.VisibleForTesting;
/**
* RcsThread represents a single RCS conversation thread. It holds messages that were sent and
* received and events that occurred on that thread.
- * @hide - TODO(sahinc) make this public
+ *
+ * @hide - TODO(109759350) make this public
*/
-public abstract class RcsThread implements Parcelable {
- // Since this is an abstract class that gets parcelled, the sub-classes need to write these
- // magic values into the parcel so that we know which type to unparcel into.
- protected static final int RCS_1_TO_1_TYPE = 998;
- protected static final int RCS_GROUP_TYPE = 999;
-
+public abstract class RcsThread {
+ // The rcs_participant_thread_id that represents this thread in the database
protected int mThreadId;
+ /**
+ * @hide
+ */
protected RcsThread(int threadId) {
mThreadId = threadId;
}
- protected RcsThread(Parcel in) {
- mThreadId = in.readInt();
+ /**
+ * @return Returns the summary of the latest message in this {@link RcsThread} packaged in an
+ * {@link RcsMessageSnippet} object
+ */
+ @WorkerThread
+ @NonNull
+ public RcsMessageSnippet getSnippet() throws RcsMessageStoreException {
+ return RcsControllerCall.call(iRcs -> iRcs.getMessageSnippet(mThreadId));
}
- public static final Creator<RcsThread> CREATOR = new Creator<RcsThread>() {
- @Override
- public RcsThread createFromParcel(Parcel in) {
- int type = in.readInt();
-
- switch (type) {
- case RCS_1_TO_1_TYPE:
- return new Rcs1To1Thread(in);
- case RCS_GROUP_TYPE:
- return new RcsGroupThread(in);
- default:
- Log.e(RcsMessageStore.TAG, "Cannot unparcel RcsThread, wrong type: " + type);
- }
- return null;
- }
-
- @Override
- public RcsThread[] newArray(int size) {
- return new RcsThread[0];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
+ /**
+ * Adds a new {@link RcsIncomingMessage} to this RcsThread and persists it in storage.
+ *
+ * @throws RcsMessageStoreException if the message could not be persisted into storage.
+ */
+ @WorkerThread
+ @NonNull
+ public RcsIncomingMessage addIncomingMessage(
+ @NonNull RcsIncomingMessageCreationParameters rcsIncomingMessageCreationParameters)
+ throws RcsMessageStoreException {
+ return new RcsIncomingMessage(RcsControllerCall.call(iRcs -> iRcs.addIncomingMessage(
+ mThreadId, rcsIncomingMessageCreationParameters)));
}
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mThreadId);
+ /**
+ * Adds a new {@link RcsOutgoingMessage} to this RcsThread and persists it in storage.
+ *
+ * @throws RcsMessageStoreException if the message could not be persisted into storage.
+ */
+ @WorkerThread
+ @NonNull
+ public RcsOutgoingMessage addOutgoingMessage(
+ @NonNull RcsMessageCreationParameters rcsMessageCreationParameters)
+ throws RcsMessageStoreException {
+ int messageId = RcsControllerCall.call(iRcs -> iRcs.addOutgoingMessage(
+ mThreadId, rcsMessageCreationParameters));
+
+ return new RcsOutgoingMessage(messageId);
+ }
+
+ /**
+ * Deletes an {@link RcsMessage} from this RcsThread and updates the storage.
+ *
+ * @param rcsMessage The message to delete from the thread
+ * @throws RcsMessageStoreException if the message could not be deleted
+ */
+ @WorkerThread
+ public void deleteMessage(@NonNull RcsMessage rcsMessage) throws RcsMessageStoreException {
+ RcsControllerCall.callWithNoReturn(
+ iRcs -> iRcs.deleteMessage(rcsMessage.getId(), rcsMessage.isIncoming(), mThreadId,
+ isGroup()));
+ }
+
+ /**
+ * Convenience function for loading all the {@link RcsMessage}s in this {@link RcsThread}. For
+ * a more detailed and paginated query, please use
+ * {@link RcsMessageStore#getRcsMessages(RcsMessageQueryParameters)}
+ *
+ * @return Loads the {@link RcsMessage}s in this thread and returns them in an immutable list.
+ * @throws RcsMessageStoreException if the messages could not be read from the storage
+ */
+ @WorkerThread
+ @NonNull
+ public RcsMessageQueryResult getMessages() throws RcsMessageStoreException {
+ RcsMessageQueryParameters queryParameters =
+ new RcsMessageQueryParameters.Builder().setThread(this).build();
+ return RcsControllerCall.call(iRcs -> iRcs.getMessages(queryParameters));
+ }
+
+ /**
+ * @return Returns whether this is a group thread or not
+ */
+ public abstract boolean isGroup();
+
+ /**
+ * @hide
+ */
+ @VisibleForTesting
+ public int getThreadId() {
+ return mThreadId;
+ }
+
+ /**
+ * @hide
+ */
+ public int getThreadType() {
+ return isGroup() ? THREAD_TYPE_GROUP : THREAD_TYPE_1_TO_1;
}
}
diff --git a/telephony/java/android/telephony/ims/RcsThreadEvent.java b/telephony/java/android/telephony/ims/RcsThreadEvent.java
deleted file mode 100644
index e10baab..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcelable;
-
-/**
- * An event that happened on an {@link RcsThread}.
- * @hide - TODO(sahinc) make this public
- */
-public abstract class RcsThreadEvent implements Parcelable {
-}
diff --git a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.java b/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.java
deleted file mode 100644
index b308fef..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadIconChangedEvent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcel;
-
-/**
- * An event that indicates an {@link RcsGroupThread}'s icon was changed.
- * @hide - TODO(sahinc) make this public
- */
-public class RcsThreadIconChangedEvent extends RcsThreadEvent {
- public static final Creator<RcsThreadIconChangedEvent> CREATOR =
- new Creator<RcsThreadIconChangedEvent>() {
- @Override
- public RcsThreadIconChangedEvent createFromParcel(Parcel in) {
- return new RcsThreadIconChangedEvent(in);
- }
-
- @Override
- public RcsThreadIconChangedEvent[] newArray(int size) {
- return new RcsThreadIconChangedEvent[size];
- }
- };
-
- protected RcsThreadIconChangedEvent(Parcel in) {
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-}
diff --git a/telephony/java/android/telephony/ims/RcsThreadNameChangedEvent.aidl b/telephony/java/android/telephony/ims/RcsThreadNameChangedEvent.aidl
deleted file mode 100644
index 54a311d..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadNameChangedEvent.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsThreadNameChangedEvent;
diff --git a/telephony/java/android/telephony/ims/RcsThreadNameChangedEvent.java b/telephony/java/android/telephony/ims/RcsThreadNameChangedEvent.java
deleted file mode 100644
index 6f5cfdf..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadNameChangedEvent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcel;
-
-/**
- * An event that indicates an {@link RcsGroupThread}'s name was changed.
- * @hide - TODO(sahinc) make this public
- */
-public class RcsThreadNameChangedEvent extends RcsThreadEvent {
- public static final Creator<RcsThreadNameChangedEvent> CREATOR =
- new Creator<RcsThreadNameChangedEvent>() {
- @Override
- public RcsThreadNameChangedEvent createFromParcel(Parcel in) {
- return new RcsThreadNameChangedEvent(in);
- }
-
- @Override
- public RcsThreadNameChangedEvent[] newArray(int size) {
- return new RcsThreadNameChangedEvent[size];
- }
- };
-
- protected RcsThreadNameChangedEvent(Parcel in) {
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-}
diff --git a/telephony/java/android/telephony/ims/RcsThreadParticipantJoinedEvent.aidl b/telephony/java/android/telephony/ims/RcsThreadParticipantJoinedEvent.aidl
deleted file mode 100644
index 047a424..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadParticipantJoinedEvent.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsThreadParticipantJoinedEvent;
diff --git a/telephony/java/android/telephony/ims/RcsThreadParticipantJoinedEvent.java b/telephony/java/android/telephony/ims/RcsThreadParticipantJoinedEvent.java
deleted file mode 100644
index 5c4073c..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadParticipantJoinedEvent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcel;
-
-/**
- * An event that indicates an RCS participant has joined an {@link RcsGroupThread}.
- * @hide - TODO(sahinc) make this public
- */
-public class RcsThreadParticipantJoinedEvent extends RcsThreadEvent {
- public static final Creator<RcsThreadParticipantJoinedEvent> CREATOR =
- new Creator<RcsThreadParticipantJoinedEvent>() {
- @Override
- public RcsThreadParticipantJoinedEvent createFromParcel(Parcel in) {
- return new RcsThreadParticipantJoinedEvent(in);
- }
-
- @Override
- public RcsThreadParticipantJoinedEvent[] newArray(int size) {
- return new RcsThreadParticipantJoinedEvent[size];
- }
- };
-
- protected RcsThreadParticipantJoinedEvent(Parcel in) {
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-}
diff --git a/telephony/java/android/telephony/ims/RcsThreadParticipantLeftEvent.aidl b/telephony/java/android/telephony/ims/RcsThreadParticipantLeftEvent.aidl
deleted file mode 100644
index 52f9bbd..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadParticipantLeftEvent.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-parcelable RcsThreadParticipantLeftEvent;
diff --git a/telephony/java/android/telephony/ims/RcsThreadParticipantLeftEvent.java b/telephony/java/android/telephony/ims/RcsThreadParticipantLeftEvent.java
deleted file mode 100644
index 4bf86b9..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadParticipantLeftEvent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.telephony.ims;
-
-import android.os.Parcel;
-
-/**
- * An event that indicates an RCS participant has left an {@link RcsGroupThread}.
- * @hide - TODO(sahinc) make this public
- */
-public class RcsThreadParticipantLeftEvent extends RcsThreadEvent {
- public static final Creator<RcsThreadParticipantLeftEvent> CREATOR =
- new Creator<RcsThreadParticipantLeftEvent>() {
- @Override
- public RcsThreadParticipantLeftEvent createFromParcel(Parcel in) {
- return new RcsThreadParticipantLeftEvent(in);
- }
-
- @Override
- public RcsThreadParticipantLeftEvent[] newArray(int size) {
- return new RcsThreadParticipantLeftEvent[size];
- }
- };
-
- protected RcsThreadParticipantLeftEvent(Parcel in) {
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-}
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl
deleted file mode 100644
index 7bcebfa..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-**
-** Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.telephony.ims;
-
-parcelable RcsThreadQueryContinuationToken;
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java b/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java
deleted file mode 100644
index 931e93d..0000000
--- a/telephony/java/android/telephony/ims/RcsThreadQueryContinuationToken.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A continuation token to provide for {@link RcsMessageStore#getRcsThreads}. Use this token to
- * break large queries into manageable chunks
- * @hide - TODO make this public
- */
-public class RcsThreadQueryContinuationToken implements Parcelable {
- protected RcsThreadQueryContinuationToken(Parcel in) {
- }
-
- public static final Creator<RcsThreadQueryContinuationToken> CREATOR =
- new Creator<RcsThreadQueryContinuationToken>() {
- @Override
- public RcsThreadQueryContinuationToken createFromParcel(Parcel in) {
- return new RcsThreadQueryContinuationToken(in);
- }
-
- @Override
- public RcsThreadQueryContinuationToken[] newArray(int size) {
- return new RcsThreadQueryContinuationToken[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-}
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl
index feb2d4d..52e73ce 100644
--- a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.aidl
@@ -1,19 +1,19 @@
/*
-**
-** Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ *
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package android.telephony.ims;
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java
index f2c4ab1..4aa4207 100644
--- a/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryParameters.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,72 +17,133 @@
package android.telephony.ims;
import android.annotation.CheckResult;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.security.InvalidParameterException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
/**
* The parameters to pass into {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} in
* order to select a subset of {@link RcsThread}s present in the message store.
+ *
* @hide TODO - make the Builder and builder() public. The rest should stay internal only.
*/
public class RcsThreadQueryParameters implements Parcelable {
- private final boolean mIsGroup;
- private final Set<RcsParticipant> mRcsParticipants;
+ /**
+ * Bitmask flag to be used with {@link Builder#setThreadType(int)} to make
+ * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} return
+ * {@link RcsGroupThread}s.
+ */
+ public static final int THREAD_TYPE_GROUP = 0x0001;
+
+ /**
+ * Bitmask flag to be used with {@link Builder#setThreadType(int)} to make
+ * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)} return
+ * {@link Rcs1To1Thread}s.
+ */
+ public static final int THREAD_TYPE_1_TO_1 = 0x0002;
+
+ // The type of threads to be filtered with the query
+ private final int mThreadType;
+ // The list of participants that are expected in the resulting threads
+ private final List<Integer> mRcsParticipantIds;
+ // The number of RcsThread's that should be returned with this query
private final int mLimit;
+ // The property which the result of the query should be sorted against
+ private final @SortingProperty int mSortingProperty;
+ // Whether the sorting should be done in ascending
private final boolean mIsAscending;
- RcsThreadQueryParameters(boolean isGroup, Set<RcsParticipant> participants, int limit,
- boolean isAscending) {
- mIsGroup = isGroup;
- mRcsParticipants = participants;
+ /**
+ * Flag to be used with {@link Builder#setSortProperty(int)} to denote that the results should
+ * be sorted in the order of {@link RcsThread} creation time for faster results.
+ */
+ public static final int SORT_BY_CREATION_ORDER = 0;
+
+ /**
+ * Flag to be used with {@link Builder#setSortProperty(int)} to denote that the results should
+ * be sorted according to the timestamp of {@link RcsThread#getSnippet()}
+ */
+ public static final int SORT_BY_TIMESTAMP = 1;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({SORT_BY_CREATION_ORDER, SORT_BY_TIMESTAMP})
+ public @interface SortingProperty {
+ }
+
+ /**
+ * @hide
+ */
+ public static final String THREAD_QUERY_PARAMETERS_KEY = "thread_query_parameters";
+
+ RcsThreadQueryParameters(int threadType, Set<RcsParticipant> participants,
+ int limit, int sortingProperty, boolean isAscending) {
+ mThreadType = threadType;
+ mRcsParticipantIds = convertParticipantSetToIdList(participants);
mLimit = limit;
+ mSortingProperty = sortingProperty;
mIsAscending = isAscending;
}
- /**
- * Returns a new builder to build a query with.
- * TODO - make public
- */
- public static Builder builder() {
- return new Builder();
+ private static List<Integer> convertParticipantSetToIdList(Set<RcsParticipant> participants) {
+ List<Integer> ids = new ArrayList<>(participants.size());
+ for (RcsParticipant participant : participants) {
+ ids.add(participant.getId());
+ }
+ return ids;
}
/**
* This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get
- * the list of participants.
- * @hide
+ * the list of participant IDs.
+ *
+ * As we don't expose any integer ID's to API users, this should stay hidden
+ *
+ * @hide - not meant for public use
*/
- public Set<RcsParticipant> getRcsParticipants() {
- return mRcsParticipants;
+ public List<Integer> getRcsParticipantsIds() {
+ return Collections.unmodifiableList(mRcsParticipantIds);
}
/**
- * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get
- * whether group threads should be queried
- * @hide
+ * @return Returns the bitmask flag for types of {@link RcsThread}s that this query should
+ * return.
*/
- public boolean isGroupThread() {
- return mIsGroup;
+ public int getThreadType() {
+ return mThreadType;
}
/**
- * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to get
- * the number of tuples the result query should be limited to.
+ * @return Returns the number of {@link RcsThread}s to be returned from the query. A value
+ * of 0 means there is no set limit.
*/
public int getLimit() {
return mLimit;
}
/**
- * This is used in {@link com.android.internal.telephony.ims.RcsMessageStoreController} to
- * determine the sort order.
+ * @return Returns the property that will be used to sort the result against.
+ * @see SortingProperty
*/
- public boolean isAscending() {
+ public @SortingProperty int getSortingProperty() {
+ return mSortingProperty;
+ }
+
+ /**
+ * @return Returns {@code true} if the result set will be sorted in ascending order,
+ * {@code false} if it will be sorted in descending order.
+ */
+ public boolean getSortDirection() {
return mIsAscending;
}
@@ -90,64 +151,74 @@
* A helper class to build the {@link RcsThreadQueryParameters}.
*/
public static class Builder {
- private boolean mIsGroupThread;
+ private int mThreadType;
private Set<RcsParticipant> mParticipants;
private int mLimit = 100;
+ private @SortingProperty int mSortingProperty;
private boolean mIsAscending;
/**
- * Package private constructor for {@link RcsThreadQueryParameters.Builder}. To obtain this,
- * {@link RcsThreadQueryParameters#builder()} needs to be called.
+ * Constructs a {@link RcsThreadQueryParameters.Builder} to help build an
+ * {@link RcsThreadQueryParameters}
*/
- Builder() {
+ public Builder() {
mParticipants = new HashSet<>();
}
/**
* Limits the query to only return group threads.
- * @param isGroupThread Whether to limit the query result to group threads.
+ *
+ * @param threadType Whether to limit the query result to group threads.
* @return The same instance of the builder to chain parameters.
+ * @see RcsThreadQueryParameters#THREAD_TYPE_GROUP
+ * @see RcsThreadQueryParameters#THREAD_TYPE_1_TO_1
*/
@CheckResult
- public Builder isGroupThread(boolean isGroupThread) {
- mIsGroupThread = isGroupThread;
+ public Builder setThreadType(int threadType) {
+ mThreadType = threadType;
return this;
}
/**
- * Limits the query to only return threads that contain the given participant.
+ * Limits the query to only return threads that contain the given participant. If this
+ * property was not set, participants will not be taken into account while querying for
+ * threads.
+ *
* @param participant The participant that must be included in all of the returned threads.
* @return The same instance of the builder to chain parameters.
*/
@CheckResult
- public Builder withParticipant(RcsParticipant participant) {
+ public Builder setParticipant(@NonNull RcsParticipant participant) {
mParticipants.add(participant);
return this;
}
/**
- * Limits the query to only return threads that contain the given list of participants.
+ * Limits the query to only return threads that contain the given list of participants. If
+ * this property was not set, participants will not be taken into account while querying
+ * for threads.
+ *
* @param participants An iterable list of participants that must be included in all of the
* returned threads.
* @return The same instance of the builder to chain parameters.
*/
@CheckResult
- public Builder withParticipants(Iterable<RcsParticipant> participants) {
- for (RcsParticipant participant : participants) {
- mParticipants.add(participant);
- }
+ public Builder setParticipants(@NonNull List<RcsParticipant> participants) {
+ mParticipants.addAll(participants);
return this;
}
/**
* Desired number of threads to be returned from the query. Passing in 0 will return all
* existing threads at once. The limit defaults to 100.
+ *
* @param limit The number to limit the query result to.
* @return The same instance of the builder to chain parameters.
* @throws InvalidParameterException If the given limit is negative.
*/
@CheckResult
- public Builder limitResultsTo(int limit) throws InvalidParameterException {
+ public Builder setResultLimit(@IntRange(from = 0) int limit)
+ throws InvalidParameterException {
if (limit < 0) {
throw new InvalidParameterException("The query limit must be non-negative");
}
@@ -157,15 +228,26 @@
}
/**
- * Sorts the results returned from the query via thread IDs.
+ * Sets the property where the results should be sorted against. Defaults to
+ * {@link SortingProperty#SORT_BY_CREATION_ORDER}
*
- * TODO - add sorting support for other fields
- *
- * @param isAscending whether to sort in ascending order or not
+ * @param sortingProperty whether to sort in ascending order or not
* @return The same instance of the builder to chain parameters.
*/
@CheckResult
- public Builder sort(boolean isAscending) {
+ public Builder setSortProperty(@SortingProperty int sortingProperty) {
+ mSortingProperty = sortingProperty;
+ return this;
+ }
+
+ /**
+ * Sets whether the results should be sorted ascending or descending
+ *
+ * @param isAscending whether the results should be sorted ascending
+ * @return The same instance of the builder to chain parameters.
+ */
+ @CheckResult
+ public Builder setSortDirection(boolean isAscending) {
mIsAscending = isAscending;
return this;
}
@@ -177,8 +259,8 @@
* @return An instance of {@link RcsThreadQueryParameters} to use with the thread query.
*/
public RcsThreadQueryParameters build() {
- return new RcsThreadQueryParameters(
- mIsGroupThread, mParticipants, mLimit, mIsAscending);
+ return new RcsThreadQueryParameters(mThreadType, mParticipants, mLimit,
+ mSortingProperty, mIsAscending);
}
}
@@ -186,14 +268,12 @@
* Parcelable boilerplate below.
*/
protected RcsThreadQueryParameters(Parcel in) {
- mIsGroup = in.readBoolean();
-
- ArrayList<RcsParticipant> participantArrayList = new ArrayList<>();
- in.readTypedList(participantArrayList, RcsParticipant.CREATOR);
- mRcsParticipants = new HashSet<>(participantArrayList);
-
+ mThreadType = in.readInt();
+ mRcsParticipantIds = new ArrayList<>();
+ in.readList(mRcsParticipantIds, Integer.class.getClassLoader());
mLimit = in.readInt();
- mIsAscending = in.readBoolean();
+ mSortingProperty = in.readInt();
+ mIsAscending = in.readByte() == 1;
}
public static final Creator<RcsThreadQueryParameters> CREATOR =
@@ -216,10 +296,10 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeBoolean(mIsGroup);
- dest.writeTypedList(new ArrayList<>(mRcsParticipants));
+ dest.writeInt(mThreadType);
+ dest.writeList(mRcsParticipantIds);
dest.writeInt(mLimit);
- dest.writeBoolean(mIsAscending);
+ dest.writeInt(mSortingProperty);
+ dest.writeByte((byte) (mIsAscending ? 1 : 0));
}
-
}
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl b/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl
index 4b06529..b1d5cf4 100644
--- a/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.aidl
@@ -1,19 +1,19 @@
/*
-**
-** Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+ *
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package android.telephony.ims;
diff --git a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
index 47715f8..6515933 100644
--- a/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
+++ b/telephony/java/android/telephony/ims/RcsThreadQueryResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,22 +16,30 @@
package android.telephony.ims;
+import static android.provider.Telephony.RcsColumns.RcsUnifiedThreadColumns.THREAD_TYPE_1_TO_1;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.ims.RcsTypeIdPair;
+
+import java.util.ArrayList;
import java.util.List;
/**
- * The result of a {@link RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken,
- * RcsThreadQueryParameters)}
+ * The result of a {@link RcsMessageStore#getRcsThreads(RcsThreadQueryParameters)}
* call. This class allows getting the token for querying the next batch of threads in order to
* prevent handling large amounts of data at once.
*
* @hide
*/
public class RcsThreadQueryResult implements Parcelable {
- private RcsThreadQueryContinuationToken mContinuationToken;
- private List<RcsThread> mRcsThreads;
+ // A token for the caller to continue their query for the next batch of results
+ private RcsQueryContinuationToken mContinuationToken;
+ // The list of thread IDs returned with this query
+ private List<RcsTypeIdPair> mRcsThreadIds;
/**
* Internal constructor for {@link com.android.internal.telephony.ims.RcsMessageStoreController}
@@ -40,31 +48,47 @@
* @hide
*/
public RcsThreadQueryResult(
- RcsThreadQueryContinuationToken continuationToken, List<RcsThread> rcsThreads) {
+ RcsQueryContinuationToken continuationToken,
+ List<RcsTypeIdPair> rcsThreadIds) {
mContinuationToken = continuationToken;
- mRcsThreads = rcsThreads;
+ mRcsThreadIds = rcsThreadIds;
}
/**
* Returns a token to call
- * {@link RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken)}
+ * {@link RcsMessageStore#getRcsThreads(RcsQueryContinuationToken)}
* to get the next batch of {@link RcsThread}s.
*/
- public RcsThreadQueryContinuationToken nextChunkToken() {
+ @Nullable
+ public RcsQueryContinuationToken getContinuationToken() {
return mContinuationToken;
}
/**
* Returns all the RcsThreads in the current query result. Call {@link
- * RcsMessageStore#getRcsThreads(RcsThreadQueryContinuationToken)} to get the next batch of
+ * RcsMessageStore#getRcsThreads(RcsQueryContinuationToken)} to get the next batch of
* {@link RcsThread}s.
*/
+ @NonNull
public List<RcsThread> getThreads() {
- return mRcsThreads;
+ List<RcsThread> rcsThreads = new ArrayList<>();
+
+ for (RcsTypeIdPair typeIdPair : mRcsThreadIds) {
+ if (typeIdPair.getType() == THREAD_TYPE_1_TO_1) {
+ rcsThreads.add(new Rcs1To1Thread(typeIdPair.getId()));
+ } else {
+ rcsThreads.add(new RcsGroupThread(typeIdPair.getId()));
+ }
+ }
+
+ return rcsThreads;
}
protected RcsThreadQueryResult(Parcel in) {
- // TODO - implement
+ mContinuationToken = in.readParcelable(
+ RcsQueryContinuationToken.class.getClassLoader());
+ mRcsThreadIds = new ArrayList<>();
+ in.readList(mRcsThreadIds, Integer.class.getClassLoader());
}
public static final Creator<RcsThreadQueryResult> CREATOR =
@@ -87,6 +111,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- // TODO - implement
+ dest.writeParcelable(mContinuationToken, flags);
+ dest.writeList(mRcsThreadIds);
}
}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcs.aidl b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
index 0c958ba..a399786 100644
--- a/telephony/java/android/telephony/ims/aidl/IRcs.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
@@ -16,9 +16,18 @@
package android.telephony.ims.aidl;
-import android.telephony.ims.RcsParticipant;
-import android.telephony.ims.Rcs1To1Thread;
-import android.telephony.ims.RcsThreadQueryContinuationToken;
+import android.net.Uri;
+import android.telephony.ims.RcsEventQueryParameters;
+import android.telephony.ims.RcsEventQueryResult;
+import android.telephony.ims.RcsFileTransferCreationParameters;
+import android.telephony.ims.RcsIncomingMessageCreationParameters;
+import android.telephony.ims.RcsMessageCreationParameters;
+import android.telephony.ims.RcsMessageSnippet;
+import android.telephony.ims.RcsMessageQueryParameters;
+import android.telephony.ims.RcsMessageQueryResult;
+import android.telephony.ims.RcsParticipantQueryParameters;
+import android.telephony.ims.RcsParticipantQueryResult;
+import android.telephony.ims.RcsQueryContinuationToken;
import android.telephony.ims.RcsThreadQueryParameters;
import android.telephony.ims.RcsThreadQueryResult;
@@ -27,23 +36,231 @@
* {@hide}
*/
interface IRcs {
+ /////////////////////////
// RcsMessageStore APIs
+ /////////////////////////
RcsThreadQueryResult getRcsThreads(in RcsThreadQueryParameters queryParameters);
RcsThreadQueryResult getRcsThreadsWithToken(
- in RcsThreadQueryContinuationToken continuationToken);
+ in RcsQueryContinuationToken continuationToken);
- void deleteThread(int threadId);
+ RcsParticipantQueryResult getParticipants(in RcsParticipantQueryParameters queryParameters);
- Rcs1To1Thread createRcs1To1Thread(in RcsParticipant participant);
+ RcsParticipantQueryResult getParticipantsWithToken(
+ in RcsQueryContinuationToken continuationToken);
+ RcsMessageQueryResult getMessages(in RcsMessageQueryParameters queryParameters);
+
+ RcsMessageQueryResult getMessagesWithToken(
+ in RcsQueryContinuationToken continuationToken);
+
+ RcsEventQueryResult getEvents(in RcsEventQueryParameters queryParameters);
+
+ RcsEventQueryResult getEventsWithToken(
+ in RcsQueryContinuationToken continuationToken);
+
+ // returns true if the thread was successfully deleted
+ boolean deleteThread(int threadId, int threadType);
+
+ // Creates an Rcs1To1Thread and returns its row ID
+ int createRcs1To1Thread(int participantId);
+
+ // Creates an RcsGroupThread and returns its row ID
+ int createGroupThread(in int[] participantIds, String groupName, in Uri groupIcon);
+
+ /////////////////////////
// RcsThread APIs
- int getMessageCount(int rcsThreadId);
+ /////////////////////////
+ // Creates a new RcsIncomingMessage on the given thread and returns its row ID
+ int addIncomingMessage(int rcsThreadId,
+ in RcsIncomingMessageCreationParameters rcsIncomingMessageCreationParameters);
+
+ // Creates a new RcsOutgoingMessage on the given thread and returns its row ID
+ int addOutgoingMessage(int rcsThreadId,
+ in RcsMessageCreationParameters rcsMessageCreationParameters);
+
+ // TODO: modify RcsProvider URI's to allow deleting a message without specifying its thread
+ void deleteMessage(int rcsMessageId, boolean isIncoming, int rcsThreadId, boolean isGroup);
+
+ RcsMessageSnippet getMessageSnippet(int rcsThreadId);
+
+ /////////////////////////
+ // Rcs1To1Thread APIs
+ /////////////////////////
+ void set1To1ThreadFallbackThreadId(int rcsThreadId, long fallbackId);
+
+ long get1To1ThreadFallbackThreadId(int rcsThreadId);
+
+ int get1To1ThreadOtherParticipantId(int rcsThreadId);
+
+ /////////////////////////
+ // RcsGroupThread APIs
+ /////////////////////////
+ void setGroupThreadName(int rcsThreadId, String groupName);
+
+ String getGroupThreadName(int rcsThreadId);
+
+ void setGroupThreadIcon(int rcsThreadId, in Uri groupIcon);
+
+ Uri getGroupThreadIcon(int rcsThreadId);
+
+ void setGroupThreadOwner(int rcsThreadId, int participantId);
+
+ int getGroupThreadOwner(int rcsThreadId);
+
+ void setGroupThreadConferenceUri(int rcsThreadId, in Uri conferenceUri);
+
+ Uri getGroupThreadConferenceUri(int rcsThreadId);
+
+ void addParticipantToGroupThread(int rcsThreadId, int participantId);
+
+ void removeParticipantFromGroupThread(int rcsThreadId, int participantId);
+
+ /////////////////////////
// RcsParticipant APIs
- RcsParticipant createRcsParticipant(String canonicalAddress);
+ /////////////////////////
- void updateRcsParticipantCanonicalAddress(int id, String canonicalAddress);
+ // Creates a new RcsParticipant and returns its rowId
+ int createRcsParticipant(String canonicalAddress, String alias);
- void updateRcsParticipantAlias(int id, String alias);
+ String getRcsParticipantCanonicalAddress(int participantId);
+
+ String getRcsParticipantAlias(int participantId);
+
+ void setRcsParticipantAlias(int id, String alias);
+
+ String getRcsParticipantContactId(int participantId);
+
+ void setRcsParticipantContactId(int participantId, String contactId);
+
+ /////////////////////////
+ // RcsMessage APIs
+ /////////////////////////
+ void setMessageSubId(int messageId, boolean isIncoming, int subId);
+
+ int getMessageSubId(int messageId, boolean isIncoming);
+
+ void setMessageStatus(int messageId, boolean isIncoming, int status);
+
+ int getMessageStatus(int messageId, boolean isIncoming);
+
+ void setMessageOriginationTimestamp(int messageId, boolean isIncoming, long originationTimestamp);
+
+ long getMessageOriginationTimestamp(int messageId, boolean isIncoming);
+
+ void setGlobalMessageIdForMessage(int messageId, boolean isIncoming, String globalId);
+
+ String getGlobalMessageIdForMessage(int messageId, boolean isIncoming);
+
+ void setMessageArrivalTimestamp(int messageId, boolean isIncoming, long arrivalTimestamp);
+
+ long getMessageArrivalTimestamp(int messageId, boolean isIncoming);
+
+ void setMessageSeenTimestamp(int messageId, boolean isIncoming, long seenTimestamp);
+
+ long getMessageSeenTimestamp(int messageId, boolean isIncoming);
+
+ void setTextForMessage(int messageId, boolean isIncoming, String text);
+
+ String getTextForMessage(int messageId, boolean isIncoming);
+
+ void setLatitudeForMessage(int messageId, boolean isIncoming, double latitude);
+
+ double getLatitudeForMessage(int messageId, boolean isIncoming);
+
+ void setLongitudeForMessage(int messageId, boolean isIncoming, double longitude);
+
+ double getLongitudeForMessage(int messageId, boolean isIncoming);
+
+ // Returns the ID's of the file transfers attached to the given message
+ int[] getFileTransfersAttachedToMessage(int messageId, boolean isIncoming);
+
+ int getSenderParticipant(int messageId);
+
+ /////////////////////////
+ // RcsOutgoingMessageDelivery APIs
+ /////////////////////////
+
+ // Returns the participant ID's that this message is intended to be delivered to
+ int[] getMessageRecipients(int messageId);
+
+ long getOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId);
+
+ void setOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, long deliveredTimestamp);
+
+ long getOutgoingDeliverySeenTimestamp(int messageId, int participantId);
+
+ void setOutgoingDeliverySeenTimestamp(int messageId, int participantId, long seenTimestamp);
+
+ int getOutgoingDeliveryStatus(int messageId, int participantId);
+
+ void setOutgoingDeliveryStatus(int messageId, int participantId, int status);
+
+ /////////////////////////
+ // RcsFileTransferPart APIs
+ /////////////////////////
+
+ // Performs the initial write to storage and returns the row ID.
+ int storeFileTransfer(int messageId, boolean isIncoming,
+ in RcsFileTransferCreationParameters fileTransferCreationParameters);
+
+ void deleteFileTransfer(int partId);
+
+ void setFileTransferSessionId(int partId, String sessionId);
+
+ String getFileTransferSessionId(int partId);
+
+ void setFileTransferContentUri(int partId, in Uri contentUri);
+
+ Uri getFileTransferContentUri(int partId);
+
+ void setFileTransferContentType(int partId, String contentType);
+
+ String getFileTransferContentType(int partId);
+
+ void setFileTransferFileSize(int partId, long fileSize);
+
+ long getFileTransferFileSize(int partId);
+
+ void setFileTransferTransferOffset(int partId, long transferOffset);
+
+ long getFileTransferTransferOffset(int partId);
+
+ void setFileTransferStatus(int partId, int transferStatus);
+
+ int getFileTransferStatus(int partId);
+
+ void setFileTransferWidth(int partId, int width);
+
+ int getFileTransferWidth(int partId);
+
+ void setFileTransferHeight(int partId, int height);
+
+ int getFileTransferHeight(int partId);
+
+ void setFileTransferLength(int partId, long length);
+
+ long getFileTransferLength(int partId);
+
+ void setFileTransferPreviewUri(int partId, in Uri uri);
+
+ Uri getFileTransferPreviewUri(int partId);
+
+ void setFileTransferPreviewType(int partId, String type);
+
+ String getFileTransferPreviewType(int partId);
+
+ /////////////////////////
+ // RcsEvent APIs
+ /////////////////////////
+ int createGroupThreadNameChangedEvent(long timestamp, int threadId, int originationParticipantId, String newName);
+
+ int createGroupThreadIconChangedEvent(long timestamp, int threadId, int originationParticipantId, in Uri newIcon);
+
+ int createGroupThreadParticipantJoinedEvent(long timestamp, int threadId, int originationParticipantId, int participantId);
+
+ int createGroupThreadParticipantLeftEvent(long timestamp, int threadId, int originationParticipantId, int participantId);
+
+ int createParticipantAliasChangedEvent(long timestamp, int participantId, String newAlias);
}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/mbms/GroupCallCallback.java b/telephony/java/android/telephony/mbms/GroupCallCallback.java
index 77e36bb..603f4e6 100644
--- a/telephony/java/android/telephony/mbms/GroupCallCallback.java
+++ b/telephony/java/android/telephony/mbms/GroupCallCallback.java
@@ -57,7 +57,7 @@
* @param errorCode The error code.
* @param message A human-readable message generated by the middleware for debugging purposes.
*/
- void onError(@GroupCallError int errorCode, @Nullable String message);
+ default void onError(@GroupCallError int errorCode, @Nullable String message) {}
/**
* Called to indicate this call has changed state.
@@ -65,8 +65,8 @@
* See {@link GroupCall#STATE_STOPPED}, {@link GroupCall#STATE_STARTED}
* and {@link GroupCall#STATE_STALLED}.
*/
- void onGroupCallStateChanged(@GroupCall.GroupCallState int state,
- @GroupCall.GroupCallStateChangeReason int reason);
+ default void onGroupCallStateChanged(@GroupCall.GroupCallState int state,
+ @GroupCall.GroupCallStateChangeReason int reason) {}
/**
* Broadcast Signal Strength updated.
@@ -78,5 +78,6 @@
* {@link #SIGNAL_STRENGTH_UNAVAILABLE} if broadcast is not available
* for this call due to timing, geography or popularity.
*/
- void onBroadcastSignalStrengthUpdated(@IntRange(from = -1, to = 4) int signalStrength);
+ default void onBroadcastSignalStrengthUpdated(
+ @IntRange(from = -1, to = 4) int signalStrength) {}
}
diff --git a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
index 04e7ba1..ac7e172 100644
--- a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
+++ b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
@@ -57,7 +57,7 @@
* @param errorCode The error code.
* @param message A human-readable message generated by the middleware for debugging purposes.
*/
- void onError(@GroupCallError int errorCode, @Nullable String message);
+ default void onError(@GroupCallError int errorCode, @Nullable String message) {}
/**
* Indicates that the list of currently available SAIs has been updated. The app may use this
@@ -70,8 +70,8 @@
* @param availableSais A list of lists of available SAIS in neighboring cells, where each list
* contains the available SAIs in an individual cell.
*/
- void onAvailableSaisUpdated(@NonNull List<Integer> currentSais,
- @NonNull List<List<Integer>> availableSais);
+ default void onAvailableSaisUpdated(@NonNull List<Integer> currentSais,
+ @NonNull List<List<Integer>> availableSais) {}
/**
* Called soon after the app calls {@link MbmsGroupCallSession#create}. The information supplied
@@ -85,7 +85,7 @@
* @param interfaceName The interface name for the data link.
* @param index The index for the data link.
*/
- void onServiceInterfaceAvailable(@NonNull String interfaceName, int index);
+ default void onServiceInterfaceAvailable(@NonNull String interfaceName, int index) {}
/**
* Called to indicate that the middleware has been initialized and is ready.
@@ -95,5 +95,5 @@
* delivered via {@link #onError(int, String)} with error code
* {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}.
*/
- void onMiddlewareReady();
+ default void onMiddlewareReady() {}
}
diff --git a/telephony/java/com/android/ims/RcsTypeIdPair.java b/telephony/java/com/android/ims/RcsTypeIdPair.java
new file mode 100644
index 0000000..a517735
--- /dev/null
+++ b/telephony/java/com/android/ims/RcsTypeIdPair.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ims;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A utility class to pass RCS IDs and types in RPC calls
+ *
+ * @hide
+ */
+public class RcsTypeIdPair implements Parcelable {
+ private int mType;
+ private int mId;
+
+ public RcsTypeIdPair(int type, int id) {
+ mType = type;
+ mId = id;
+ }
+
+ public int getType() {
+ return mType;
+ }
+
+ public void setType(int type) {
+ mType = type;
+ }
+
+ public int getId() {
+ return mId;
+ }
+
+ public void setId(int id) {
+ mId = id;
+ }
+
+ public RcsTypeIdPair(Parcel in) {
+ mType = in.readInt();
+ mId = in.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mType);
+ dest.writeInt(mId);
+ }
+
+ public static final Creator<RcsTypeIdPair> CREATOR =
+ new Creator<RcsTypeIdPair>() {
+ @Override
+ public RcsTypeIdPair createFromParcel(Parcel in) {
+ return new RcsTypeIdPair(in);
+ }
+
+ @Override
+ public RcsTypeIdPair[] newArray(int size) {
+ return new RcsTypeIdPair[size];
+ }
+ };
+}
diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java
index d3420ee..7478a00 100644
--- a/telephony/java/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/java/com/android/internal/telephony/SmsApplication.java
@@ -636,7 +636,7 @@
// Update the setting.
RoleManagerCallback.Future res = new RoleManagerCallback.Future();
context.getSystemService(RoleManager.class).addRoleHolderAsUser(
- RoleManager.ROLE_SMS, applicationData.mPackageName, UserHandle.of(userId),
+ RoleManager.ROLE_SMS, applicationData.mPackageName, 0, UserHandle.of(userId),
AsyncTask.THREAD_POOL_EXECUTOR, res);
try {
res.get(5, TimeUnit.SECONDS);
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index c76d153..b9ec7bf 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -29,14 +29,20 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
+import android.util.StatsLog;
import com.android.internal.annotations.VisibleForTesting;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
import java.util.function.Supplier;
/** Utility class for Telephony permission enforcement. */
@@ -48,6 +54,14 @@
private static final Supplier<ITelephony> TELEPHONY_SUPPLIER = () ->
ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
+ // Contains a mapping of packages that did not meet the new requirements to access device
+ // identifiers and the methods they were attempting to invoke; used to prevent duplicate
+ // reporting of packages / methods.
+ private static final Map<String, Set<String>> sReportedDeviceIDPackages;
+ static {
+ sReportedDeviceIDPackages = new HashMap<>();
+ }
+
private TelephonyPermissions() {}
/**
@@ -284,46 +298,63 @@
*/
private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid,
int uid, String callingPackage, String message) {
- // Check if the application is a 3P app; if so then a separate setting is required to relax
- // the check to begin flagging problems with 3P apps early.
+ // Check if the application is not preinstalled; if not then a separate setting is required
+ // to relax the check to begin flagging problems with non-preinstalled apps early.
boolean relax3PDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED, 0) == 1;
- boolean is3PApp = true;
+ boolean isPreinstalled = false;
// Also check if the application is a preloaded non-privileged app; if so there is a
// separate setting to relax the check for these apps to ensure users can relax the check
- // for 3P or non-priv apps as needed while continuing to test the other.
+ // for non-preinstalled or non-priv apps as needed while continuing to test the other.
boolean relaxNonPrivDeviceIdentifierCheck = Settings.Global.getInt(
context.getContentResolver(),
Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_NON_PRIV_CHECK_RELAXED, 0) == 1;
- boolean isNonPrivApp = false;
+ boolean isPrivApp = false;
// Similar to above support relaxing the check for privileged apps while still enforcing it
- // for non-privileged and 3P apps.
+ // for non-privileged and non-preinstalled apps.
boolean relaxPrivDeviceIdentifierCheck = Settings.Global.getInt(
context.getContentResolver(),
Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_PRIV_CHECK_RELAXED, 0) == 1;
ApplicationInfo callingPackageInfo = null;
try {
callingPackageInfo = context.getPackageManager().getApplicationInfo(callingPackage, 0);
- if (callingPackageInfo.isPrivilegedApp()) {
- is3PApp = false;
- } else if (callingPackageInfo.isSystemApp()) {
- is3PApp = false;
- isNonPrivApp = true;
+ if (callingPackageInfo.isSystemApp()) {
+ isPreinstalled = true;
+ if (callingPackageInfo.isPrivilegedApp()) {
+ isPrivApp = true;
+ }
}
} catch (PackageManager.NameNotFoundException e) {
// If the application info for the calling package could not be found then assume the
- // calling app is a 3P app to detect any issues with the check
+ // calling app is a non-preinstalled app to detect any issues with the check
Log.e(LOG_TAG, "Exception caught obtaining package info for package " + callingPackage,
e);
}
// The new Q restrictions for device identifier access will be enforced for all apps with
// settings to individually disable the new restrictions for privileged, preloaded
- // non-privileged, and 3P apps.
- if ((!is3PApp && !isNonPrivApp && !relaxPrivDeviceIdentifierCheck)
- || (is3PApp && !relax3PDeviceIdentifierCheck)
- || (isNonPrivApp && !relaxNonPrivDeviceIdentifierCheck)) {
- Log.wtf(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
- + ":is3PApp=" + is3PApp + ":isNonPrivApp=" + isNonPrivApp);
+ // non-privileged, and non-preinstalled apps.
+ if (!isIdentifierCheckDisabled() && (
+ (isPrivApp && !relaxPrivDeviceIdentifierCheck)
+ || (!isPreinstalled && !relax3PDeviceIdentifierCheck)
+ || (isPreinstalled && !isPrivApp && !relaxNonPrivDeviceIdentifierCheck))) {
+ // The current package should only be reported in StatsLog if it has not previously been
+ // reported for the currently invoked device identifier method.
+ boolean packageReported = sReportedDeviceIDPackages.containsKey(callingPackage);
+ if (!packageReported || !sReportedDeviceIDPackages.get(callingPackage).contains(
+ message)) {
+ Set invokedMethods;
+ if (!packageReported) {
+ invokedMethods = new HashSet<String>();
+ sReportedDeviceIDPackages.put(callingPackage, invokedMethods);
+ } else {
+ invokedMethods = sReportedDeviceIDPackages.get(callingPackage);
+ }
+ invokedMethods.add(message);
+ StatsLog.write(StatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, callingPackage, message,
+ isPreinstalled, isPrivApp);
+ }
+ Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
+ + ":isPreinstalled=" + isPreinstalled + ":isPrivApp=" + isPrivApp);
// if the target SDK is pre-Q then check if the calling package would have previously
// had access to device identifiers.
if (callingPackageInfo != null && (
@@ -348,6 +379,14 @@
}
/**
+ * Returns true if the new device identifier access restrictions are disabled.
+ */
+ private static boolean isIdentifierCheckDisabled() {
+ return Boolean.parseBoolean(DeviceConfig.getProperty(DeviceConfig.Privacy.NAMESPACE,
+ DeviceConfig.Privacy.PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED));
+ }
+
+ /**
* Check whether the app with the given pid/uid can read the call log.
* @return {@code true} if the specified app has the read call log permission and AppOpp granted
* to it, {@code false} otherwise.
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 964a313..9080e23 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -21,7 +21,6 @@
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsCbLocation;
import android.telephony.SmsCbMessage;
-import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaSmsCbProgramData;
import android.telephony.Rlog;
import android.util.Log;
@@ -746,8 +745,10 @@
/**
* Parses a broadcast SMS, possibly containing a CMAS alert.
+ *
+ * @param plmn the PLMN for a broadcast SMS
*/
- public SmsCbMessage parseBroadcastSms() {
+ public SmsCbMessage parseBroadcastSms(String plmn) {
BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory);
if (bData == null) {
Rlog.w(LOG_TAG, "BearerData.decode() returned null");
@@ -758,7 +759,6 @@
Rlog.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData));
}
- String plmn = TelephonyManager.getDefault().getNetworkOperator();
SmsCbLocation location = new SmsCbLocation(plmn);
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2,
@@ -858,11 +858,11 @@
bearerData.userData = userData;
byte[] encodedBearerData = BearerData.encode(bearerData);
+ if (encodedBearerData == null) return null;
if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
Rlog.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData);
Rlog.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'");
}
- if (encodedBearerData == null) return null;
int teleservice = bearerData.hasUserDataHeader ?
SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT;
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java
new file mode 100644
index 0000000..915a260
--- /dev/null
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.ims;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.RcsGroupThread;
+import android.telephony.ims.RcsGroupThreadIconChangedEvent;
+import android.telephony.ims.RcsParticipant;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RcsGroupThreadIconChangedEventTest {
+
+ @Test
+ public void testCanUnparcel() {
+ RcsGroupThread rcsGroupThread = new RcsGroupThread(1);
+ RcsParticipant rcsParticipant = new RcsParticipant(2);
+ Uri newIconUri = Uri.parse("content://new_icon");
+
+ RcsGroupThreadIconChangedEvent iconChangedEvent =
+ new RcsGroupThreadIconChangedEvent(1234567890, rcsGroupThread, rcsParticipant,
+ newIconUri);
+
+ Parcel parcel = Parcel.obtain();
+ iconChangedEvent.writeToParcel(parcel, iconChangedEvent.describeContents());
+
+ parcel.setDataPosition(0);
+
+ iconChangedEvent = RcsGroupThreadIconChangedEvent.CREATOR.createFromParcel(parcel);
+
+ assertThat(iconChangedEvent.getNewIcon()).isEqualTo(newIconUri);
+ assertThat(iconChangedEvent.getRcsGroupThread().getThreadId()).isEqualTo(1);
+ assertThat(iconChangedEvent.getOriginatingParticipant().getId()).isEqualTo(2);
+ assertThat(iconChangedEvent.getTimestamp()).isEqualTo(1234567890);
+ }
+}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java
new file mode 100644
index 0000000..1384c01
--- /dev/null
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.ims;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.RcsGroupThread;
+import android.telephony.ims.RcsGroupThreadNameChangedEvent;
+import android.telephony.ims.RcsParticipant;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RcsGroupThreadNameChangedEventTest {
+ @Test
+ public void testCanUnparcel() {
+ String newName = "new name";
+
+ RcsGroupThread rcsGroupThread = new RcsGroupThread(1);
+ RcsParticipant rcsParticipant = new RcsParticipant(2);
+
+ RcsGroupThreadNameChangedEvent nameChangedEvent =
+ new RcsGroupThreadNameChangedEvent(1234567890, rcsGroupThread, rcsParticipant,
+ newName);
+
+ Parcel parcel = Parcel.obtain();
+ nameChangedEvent.writeToParcel(parcel, nameChangedEvent.describeContents());
+
+ parcel.setDataPosition(0);
+
+ nameChangedEvent = RcsGroupThreadNameChangedEvent.CREATOR.createFromParcel(
+ parcel);
+
+ assertThat(nameChangedEvent.getNewName()).isEqualTo(newName);
+ assertThat(nameChangedEvent.getRcsGroupThread().getThreadId()).isEqualTo(1);
+ assertThat(nameChangedEvent.getOriginatingParticipant().getId()).isEqualTo(2);
+ assertThat(nameChangedEvent.getTimestamp()).isEqualTo(1234567890);
+ }
+}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java
new file mode 100644
index 0000000..d0af7db
--- /dev/null
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.ims;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.RcsGroupThread;
+import android.telephony.ims.RcsGroupThreadParticipantJoinedEvent;
+import android.telephony.ims.RcsParticipant;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RcsGroupThreadParticipantJoinedEventTest {
+
+ @Test
+ public void testCanUnparcel() {
+ RcsGroupThread rcsGroupThread = new RcsGroupThread(1);
+ RcsParticipant rcsParticipant = new RcsParticipant(2);
+
+ RcsGroupThreadParticipantJoinedEvent participantJoinedEvent =
+ new RcsGroupThreadParticipantJoinedEvent(1234567890, rcsGroupThread, rcsParticipant,
+ rcsParticipant);
+
+ Parcel parcel = Parcel.obtain();
+ participantJoinedEvent.writeToParcel(parcel, participantJoinedEvent.describeContents());
+
+ parcel.setDataPosition(0);
+
+ participantJoinedEvent = RcsGroupThreadParticipantJoinedEvent.CREATOR.createFromParcel(
+ parcel);
+
+ assertThat(participantJoinedEvent.getJoinedParticipant().getId()).isEqualTo(2);
+ assertThat(participantJoinedEvent.getRcsGroupThread().getThreadId()).isEqualTo(1);
+ assertThat(participantJoinedEvent.getOriginatingParticipant().getId()).isEqualTo(2);
+ assertThat(participantJoinedEvent.getTimestamp()).isEqualTo(1234567890);
+ }
+}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java
new file mode 100644
index 0000000..7ba5fa6
--- /dev/null
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.ims;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.RcsGroupThread;
+import android.telephony.ims.RcsGroupThreadParticipantLeftEvent;
+import android.telephony.ims.RcsParticipant;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RcsGroupThreadParticipantLeftEventTest {
+ @Test
+ public void testCanUnparcel() {
+ RcsGroupThread rcsGroupThread = new RcsGroupThread(1);
+ RcsParticipant rcsParticipant = new RcsParticipant(2);
+
+ RcsGroupThreadParticipantLeftEvent participantLeftEvent =
+ new RcsGroupThreadParticipantLeftEvent(1234567890, rcsGroupThread, rcsParticipant,
+ rcsParticipant);
+
+ Parcel parcel = Parcel.obtain();
+ participantLeftEvent.writeToParcel(parcel, participantLeftEvent.describeContents());
+
+ parcel.setDataPosition(0);
+
+ // create from parcel
+ parcel.setDataPosition(0);
+ participantLeftEvent = RcsGroupThreadParticipantLeftEvent.CREATOR.createFromParcel(
+ parcel);
+ assertThat(participantLeftEvent.getRcsGroupThread().getThreadId()).isEqualTo(1);
+ assertThat(participantLeftEvent.getLeavingParticipantId().getId()).isEqualTo(2);
+ assertThat(participantLeftEvent.getTimestamp()).isEqualTo(1234567890);
+ }
+}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsMessageStoreTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsMessageStoreTest.java
deleted file mode 100644
index 44277ed..0000000
--- a/tests/RcsTests/src/com/android/tests/ims/RcsMessageStoreTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tests.ims;
-
-import android.support.test.runner.AndroidJUnit4;
-import android.telephony.ims.RcsMessageStore;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class RcsMessageStoreTest {
- //TODO(sahinc): Add meaningful tests once we have more of the implementation in place
- @Test
- public void testDeleteThreadDoesntCrash() {
- RcsMessageStore mRcsMessageStore = new RcsMessageStore();
- mRcsMessageStore.deleteThread(0);
- }
-}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java
new file mode 100644
index 0000000..3e2bbbf
--- /dev/null
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.ims;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.RcsParticipant;
+import android.telephony.ims.RcsParticipantAliasChangedEvent;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RcsParticipantAliasChangedEventTest {
+ private static final String OLD_ALIAS = "old alias";
+ private static final String NEW_ALIAS = "new alias";
+ private RcsParticipant mParticipant;
+
+ @Before
+ public void setUp() {
+ mParticipant = new RcsParticipant(3);
+ }
+
+ @Test
+ public void testCanUnparcel() {
+ RcsParticipantAliasChangedEvent aliasChangedEvent =
+ new RcsParticipantAliasChangedEvent(1234567890, mParticipant, NEW_ALIAS);
+
+ Parcel parcel = Parcel.obtain();
+ aliasChangedEvent.writeToParcel(parcel, aliasChangedEvent.describeContents());
+
+ parcel.setDataPosition(0);
+
+ aliasChangedEvent = RcsParticipantAliasChangedEvent.CREATOR.createFromParcel(
+ parcel);
+
+ assertThat(aliasChangedEvent.getParticipantId().getId()).isEqualTo(3);
+ assertThat(aliasChangedEvent.getNewAlias()).isEqualTo(NEW_ALIAS);
+ assertThat(aliasChangedEvent.getTimestamp()).isEqualTo(1234567890);
+ }
+}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParametersTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParametersTest.java
new file mode 100644
index 0000000..b4bcb5d
--- /dev/null
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParametersTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tests.ims;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.RcsParticipantQueryParameters;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RcsParticipantQueryParametersTest {
+
+ @Test
+ public void testCanUnparcel() {
+ RcsParticipantQueryParameters rcsParticipantQueryParameters =
+ new RcsParticipantQueryParameters.Builder()
+ .setAliasLike("%alias_")
+ .setCanonicalAddressLike("_canonical%")
+ .setSortProperty(RcsParticipantQueryParameters.SORT_BY_CANONICAL_ADDRESS)
+ .setSortDirection(true)
+ .setResultLimit(432)
+ .build();
+
+
+ Parcel parcel = Parcel.obtain();
+ rcsParticipantQueryParameters.writeToParcel(parcel,
+ rcsParticipantQueryParameters.describeContents());
+
+ parcel.setDataPosition(0);
+ rcsParticipantQueryParameters = RcsParticipantQueryParameters.CREATOR.createFromParcel(
+ parcel);
+
+ assertThat(rcsParticipantQueryParameters.getAliasLike()).isEqualTo("%alias_");
+ assertThat(rcsParticipantQueryParameters.getCanonicalAddressLike()).contains("_canonical%");
+ assertThat(rcsParticipantQueryParameters.getLimit()).isEqualTo(432);
+ assertThat(rcsParticipantQueryParameters.getSortingProperty()).isEqualTo(
+ RcsParticipantQueryParameters.SORT_BY_CANONICAL_ADDRESS);
+ assertThat(rcsParticipantQueryParameters.getSortDirection()).isTrue();
+ }
+}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantTest.java
deleted file mode 100644
index c402dbf..0000000
--- a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tests.ims;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-import android.support.test.runner.AndroidJUnit4;
-import android.telephony.ims.RcsParticipant;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class RcsParticipantTest {
- private static final int ID = 123;
- private static final String ALIAS = "alias";
- private static final String CANONICAL_ADDRESS = "+1234567890";
-
- @Test
- public void testCanUnparcel() {
- RcsParticipant rcsParticipant = new RcsParticipant(ID, CANONICAL_ADDRESS);
- rcsParticipant.setAlias(ALIAS);
-
- Bundle bundle = new Bundle();
- bundle.putParcelable("Some key", rcsParticipant);
- rcsParticipant = bundle.getParcelable("Some key");
-
- assertThat(rcsParticipant.getId()).isEqualTo(ID);
- assertThat(rcsParticipant.getAlias()).isEqualTo(ALIAS);
- assertThat(rcsParticipant.getCanonicalAddress()).isEqualTo(CANONICAL_ADDRESS);
- }
-}
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java
index a890a38..0a70eec 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParametersTest.java
@@ -15,39 +15,44 @@
*/
package com.android.tests.ims;
+import static android.telephony.ims.RcsThreadQueryParameters.SORT_BY_TIMESTAMP;
+import static android.telephony.ims.RcsThreadQueryParameters.THREAD_TYPE_GROUP;
+
import static com.google.common.truth.Truth.assertThat;
-import android.os.Bundle;
+import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.RcsParticipant;
import android.telephony.ims.RcsThreadQueryParameters;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
@RunWith(AndroidJUnit4.class)
public class RcsThreadQueryParametersTest {
- private RcsThreadQueryParameters mRcsThreadQueryParameters;
- @Mock RcsParticipant mMockParticipant;
@Test
- public void testUnparceling() {
- String key = "some key";
- mRcsThreadQueryParameters = RcsThreadQueryParameters.builder()
- .isGroupThread(true)
- .withParticipant(mMockParticipant)
- .limitResultsTo(50)
- .sort(true)
+ public void testCanUnparcel() {
+ RcsParticipant rcsParticipant = new RcsParticipant(1);
+ RcsThreadQueryParameters rcsThreadQueryParameters = new RcsThreadQueryParameters.Builder()
+ .setThreadType(THREAD_TYPE_GROUP)
+ .setParticipant(rcsParticipant)
+ .setResultLimit(50)
+ .setSortProperty(SORT_BY_TIMESTAMP)
+ .setSortDirection(true)
.build();
- Bundle bundle = new Bundle();
- bundle.putParcelable(key, mRcsThreadQueryParameters);
- mRcsThreadQueryParameters = bundle.getParcelable(key);
+ Parcel parcel = Parcel.obtain();
+ rcsThreadQueryParameters.writeToParcel(parcel, rcsThreadQueryParameters.describeContents());
- assertThat(mRcsThreadQueryParameters.isGroupThread()).isTrue();
- assertThat(mRcsThreadQueryParameters.getRcsParticipants()).contains(mMockParticipant);
- assertThat(mRcsThreadQueryParameters.getLimit()).isEqualTo(50);
- assertThat(mRcsThreadQueryParameters.isAscending()).isTrue();
+ parcel.setDataPosition(0);
+ rcsThreadQueryParameters = RcsThreadQueryParameters.CREATOR.createFromParcel(parcel);
+
+ assertThat(rcsThreadQueryParameters.getThreadType()).isEqualTo(THREAD_TYPE_GROUP);
+ assertThat(rcsThreadQueryParameters.getRcsParticipantsIds())
+ .contains(rcsParticipant.getId());
+ assertThat(rcsThreadQueryParameters.getLimit()).isEqualTo(50);
+ assertThat(rcsThreadQueryParameters.getSortingProperty()).isEqualTo(SORT_BY_TIMESTAMP);
+ assertThat(rcsThreadQueryParameters.getSortDirection()).isTrue();
}
}
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
deleted file mode 100644
index 3d57d56..0000000
--- a/tests/RollbackTest/Android.bp
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-android_app {
- name: "RollbackTestAppAv1",
- manifest: "TestApp/Av1.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
-}
-
-android_app {
- name: "RollbackTestAppAv2",
- manifest: "TestApp/Av2.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
-}
-
-android_app {
- name: "RollbackTestAppACrashingV2",
- manifest: "TestApp/ACrashingV2.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
-}
-
-android_app {
- name: "RollbackTestAppBv1",
- manifest: "TestApp/Bv1.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
-}
-
-android_app {
- name: "RollbackTestAppBv2",
- manifest: "TestApp/Bv2.xml",
- sdk_version: "current",
- srcs: ["TestApp/src/**/*.java"],
-}
-
-android_test {
- name: "RollbackTest",
- srcs: ["src/**/*.java"],
- static_libs: ["android-support-test"],
- test_suites: ["general-tests"],
- java_resources: [
- ":RollbackTestAppAv1",
- ":RollbackTestAppAv2",
- ":RollbackTestAppACrashingV2",
- ":RollbackTestAppBv1",
- ":RollbackTestAppBv2",
- ],
- test_config: "RollbackTest.xml",
- sdk_version: "system_current",
-}
diff --git a/tests/RollbackTest/Android.mk b/tests/RollbackTest/Android.mk
new file mode 100644
index 0000000..40d4eff
--- /dev/null
+++ b/tests/RollbackTest/Android.mk
@@ -0,0 +1,96 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+# RollbackTestAppAv1.apk
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/Av1.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppAv1
+include $(BUILD_PACKAGE)
+ROLLBACK_TEST_APP_AV1 := $(LOCAL_INSTALLED_MODULE)
+
+# RollbackTestAppAv2.apk
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/Av2.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppAv2
+include $(BUILD_PACKAGE)
+ROLLBACK_TEST_APP_AV2 := $(LOCAL_INSTALLED_MODULE)
+
+# RollbackTestAppACrashingV2.apk
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/ACrashingV2.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppACrashingV2
+include $(BUILD_PACKAGE)
+ROLLBACK_TEST_APP_A_CRASHING_V2 := $(LOCAL_INSTALLED_MODULE)
+
+# RollbackTestAppBv1.apk
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/Bv1.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppBv1
+include $(BUILD_PACKAGE)
+ROLLBACK_TEST_APP_BV1 := $(LOCAL_INSTALLED_MODULE)
+
+# RollbackTestAppBv2.apk
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, TestApp/src)
+LOCAL_MANIFEST_FILE := TestApp/Bv2.xml
+LOCAL_PACKAGE_NAME := RollbackTestAppBv2
+include $(BUILD_PACKAGE)
+ROLLBACK_TEST_APP_BV2 := $(LOCAL_INSTALLED_MODULE)
+
+# RollbackTest
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := RollbackTest
+LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_COMPATIBILITY_SUITE := general-tests
+LOCAL_COMPATIBILITY_SUPPORT_FILES := $(ROLLBACK_TEST_APEX_V1)
+LOCAL_JAVA_RESOURCE_FILES := \
+ $(ROLLBACK_TEST_APP_AV1) \
+ $(ROLLBACK_TEST_APP_AV2) \
+ $(ROLLBACK_TEST_APP_A_CRASHING_V2) \
+ $(ROLLBACK_TEST_APP_BV1) \
+ $(ROLLBACK_TEST_APP_BV2) \
+ $(ROLLBACK_TEST_APEX_V2)
+LOCAL_SDK_VERSION := system_current
+LOCAL_TEST_CONFIG := RollbackTest.xml
+include $(BUILD_PACKAGE)
+
+# Clean up local variables
+ROLLBACK_TEST_APP_AV1 :=
+ROLLBACK_TEST_APP_AV2 :=
+ROLLBACK_TEST_APP_A_CRASHING_V2 :=
+ROLLBACK_TEST_APP_BV1 :=
+ROLLBACK_TEST_APP_BV2 :=
diff --git a/tests/RollbackTest/TestApex/Android.bp b/tests/RollbackTest/TestApex/Android.bp
new file mode 100644
index 0000000..a2a8e17
--- /dev/null
+++ b/tests/RollbackTest/TestApex/Android.bp
@@ -0,0 +1,56 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+apex {
+ name: "com.android.tests.rollback.testapex.RollbackTestApexV1",
+ manifest: "RollbackTestApexV1.json",
+ file_contexts: "apex.test",
+ prebuilts: ["RollbackTestApex.prebuilt.txt"],
+ key: "RollbackTestApex.key",
+ installable: false,
+}
+
+apex {
+ name: "com.android.tests.rollback.testapex.RollbackTestApexV2",
+ manifest: "RollbackTestApexV2.json",
+ file_contexts: "apex.test",
+ prebuilts: ["RollbackTestApex.prebuilt.txt"],
+ key: "RollbackTestApex.key",
+ installable: false,
+}
+
+apex_key {
+ name: "RollbackTestApex.key",
+ public_key: "com.android.tests.rollback.testapex.avbpubkey",
+ private_key: "com.android.tests.rollback.testapex.pem",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "RollbackTestApex.prebuilt.txt",
+ src: "RollbackTestApex.prebuilt.txt",
+}
+
+filegroup {
+ name: "RollbackTestApexV1_filegroup",
+ srcs: [":com.android.tests.rollback.testapex.RollbackTestApexV1"],
+ export_to_make_var: "ROLLBACK_TEST_APEX_V1",
+}
+
+filegroup {
+ name: "RollbackTestApexV2_filegroup",
+ srcs: [":com.android.tests.rollback.testapex.RollbackTestApexV2"],
+ export_to_make_var: "ROLLBACK_TEST_APEX_V2",
+}
+
diff --git a/tests/RollbackTest/TestApex/RollbackTestApex.prebuilt.txt b/tests/RollbackTest/TestApex/RollbackTestApex.prebuilt.txt
new file mode 100644
index 0000000..e871146
--- /dev/null
+++ b/tests/RollbackTest/TestApex/RollbackTestApex.prebuilt.txt
@@ -0,0 +1,3 @@
+
+This file contains dummy content to include in the RollbackTestApex.
+
diff --git a/tests/RollbackTest/TestApex/RollbackTestApexV1.json b/tests/RollbackTest/TestApex/RollbackTestApexV1.json
new file mode 100644
index 0000000..c3239ca
--- /dev/null
+++ b/tests/RollbackTest/TestApex/RollbackTestApexV1.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.tests.rollback.testapex",
+ "version": 1
+}
diff --git a/tests/RollbackTest/TestApex/RollbackTestApexV2.json b/tests/RollbackTest/TestApex/RollbackTestApexV2.json
new file mode 100644
index 0000000..9de3f45
--- /dev/null
+++ b/tests/RollbackTest/TestApex/RollbackTestApexV2.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.tests.rollback.testapex",
+ "version": 2
+}
diff --git a/tests/RollbackTest/TestApex/com.android.tests.rollback.testapex.avbpubkey b/tests/RollbackTest/TestApex/com.android.tests.rollback.testapex.avbpubkey
new file mode 100644
index 0000000..b347331
--- /dev/null
+++ b/tests/RollbackTest/TestApex/com.android.tests.rollback.testapex.avbpubkey
Binary files differ
diff --git a/tests/RollbackTest/TestApex/com.android.tests.rollback.testapex.pem b/tests/RollbackTest/TestApex/com.android.tests.rollback.testapex.pem
new file mode 100644
index 0000000..7181ce5
--- /dev/null
+++ b/tests/RollbackTest/TestApex/com.android.tests.rollback.testapex.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEArBLX+v6RMiK6soQFgbc0RZ+wticTD5sCbu9Q5B5WT7UnV1Wt
+cNI/n2bjks3UYNxTneOzMQOVjd4ln0BYZoNvoDtrc1BsYABpt4FywSq1zz/3sp3L
+3Vp8vaUyRsx0Da+PcOdYHPFs1WPX3Shw3MSPhUO/72KTm6GhO/cHEPEzSQLaw/zO
+8FiPpDdRqILqVJlu1DZ+i1DO+To9mKt59uLlxy3F+HAMnQaNW6+2NCV/vdCxQrEL
+m7PpsM6DymsFKcvVra1Il4apKkYNgcgTQ+AlmyPxGo6twfZvRMrU3bcrUmrg3OAx
+tMD7MufXlKkoFMlT5clrQ7P2ErKoFxhTVWhBL5ZJv/lKwaTfxCLyNvYQ7JALKtOL
+9xx4c77NdyYVjxMDAJ7E+Uj3QjdOv3FxM38Fcvt0zN4SSlmDjEDtm2e2w53Ztgz1
+zHAuNllIW1zGdPqa+ROoa9JLJePlyNXG9Rn1sSkjM9WwteaJ3nrdje6uBsvo7I9g
+1MWab2XNXQwJNHACICtyU7QPryGP4U/lyHqWEkdoXrs8O36gmTGU/EsJYSIVILax
+0HZC3zkmxHgiN95ZvD+Y5Y9HDXAN04kT8O1V/QD4QUCP8MGXNrkQP/JZAnu5Y2D1
+Wrn/7Tft2ON3OpH5vUgR99bKR549LcRrYgxeTnci3xkOsnTjZRxEUJFQgVUCAwEA
+AQKCAgEAlBzIMbDLk+cW4rAG+WeTo9ZXygKKQqV/i7OM4j5GtudMTL1fxDwFLZTn
+kCaBhzo+8ynaxPa71ViA87n0HZFHFRnwXFq+XkgctyrCdwjnY9RAxktS/l5z/t1i
+EFTOFDWod1t6mbcpoegGF8RGmZDLpL7zR/+G5LBUU4RHXcrwBQli+s3x5imkwoon
+TLAbOeSz5BBgDlTpQtdhy7bWDa+ybya0QCtagBLyvBfb8rjQYrduzOQOBODw5xJr
+mGFUGWztqUf9swfjNpMD71EjXApk9EwUrXJgmBMiJYmdfpa6wH9kvFpyDo8J6gBr
+rPeJm5LMF3+vR6Bw0Bld3DtBB8PsTrockOdeJNHfnY54480e7AahfM5gkeuIYC4P
+E3CIbyAgpS8+OLpsXP207AOjFz1TLiOqyDUDsBqSMNEQ7QbIPTQw8UZ/o0vEoqEv
+RrJAvIAv0KUcFNUL0t6VX2OXbV+i+T85wPey3XqK9P8Zzc8NUEGJ2paDUkSuemKC
+nF9/siGaoBHXsNUkQuV9xYo4co66MHDGAx/OdUM5lPiUcrF/bR+ZUA3p1BLUQXbQ
+aJD9uKlvJ4ZRSwhR/fQc5UiVWl3l76k+0Ia/Ddd1ArphVhbvGPOsm3W7wJ6KukSk
+rBJh1PPV1HnA+icS2Wvu2kVdz9+39cQUYJIICO1uwWfPIb/R5MUCggEBAOSwkwXs
+jqewNc6X4mc19RGKIMUvOrRrQkOOY33pI+BjoqI8cl+NOHNB7F8/gVnHIfhZpOG6
+WD5St1/qlSPT1Nte+38P+woAp5mdclZyRgYb4MjZybZihUPIPVgUbxiZTDHy1Sw0
+kRgmvaV3ccvG9/9bBUKNr9Z+XySsIhq5DzY+yIZ33vhLB/0g05x2HVIsSlsRWzri
+lw0iX/v07bdIRUIv7QB8xcLY/23pIbHAXS8DaknN8YxpKtjilOnUWVp/dx4SIcJY
+6PtSBfPcwVJ2MA/xXWBvDP82/XxvbxKnjj8lvkbfqMC6jrXJBw3NT/he8b932IBb
+PwLGU4hoKvjXfUcCggEBAMCfa4N1KUXW0Mo3BcDk2Hk8zVYuTPDNTWg1Mxb46sn+
+HNVJKU0OrejM2hNNCwzJG7eVQBorJj5XefhaQFTvWoLKbf1YZuWKaQrRwKkHEqDi
+edplA2RkpUebeS4KYIr22rzu3ZrZqiJmRU5kAS9hwOzwFvnXUgGy7IoZKXhpo0HK
+xvwylb/C5FXh97tecDdH/5evB/DC515TIhPzUQ5tpT0oAl9MU7Pe1E/opzrD/0sR
+dqKVJcl9vBRbtcAIkCOVpLoA9T2VvisafZAJaRXc3ACFMceewgpVAtBCsWUtLfvW
+fHMHWfti5je19SWg7bUK56uHJ0vdAI+irkfpe1t0aoMCggEAR5cPL3eSYOREs9vQ
+QEcf5NG82H2kfv5kzAkzFCN7267VJryNgWQQG+SzPk3/DD/OXpSRjShsn3X9ecVR
+0tlpdRMS3//8snDqBqjHNlCnoxnvEHE9OB83YLS6n2wmKykyNSCzoxcBpPHbxITT
+1tr+n626w87fEOKWnkBUnND59h1JYO79mfTDF3bDR+Oh4iuDS2bvjEuKxc3RBmry
+T8IMDGA8bT6iGhEcRSgKKD7z7NfA2kHiL/ZsN2EXBOw43J+yhnNephx3MtXGj0S4
+MDxXZ2ZDuQCKrQpl6CJqPwi8+v+xxTYW+d5s9nNsBeIT+sieHTZDTEtEOnYjiDwz
+15p92QKCAQEAkMwGNQawpOhLgYcFEzC0LcbwEFWzztx10N0U77LkRD16jTZ3Do73
+WmYLlLC4mr7e0A0o58MB96EodfHaJD7dSi5Dqkt25hw6xEBS1H0Vms1EjlCa0S/7
+Mq4D1QFF+5B/c8EX4ty20S8R8FCqt2SDc1kz3FHpOo+20kUB8Jtwdveox1J7UXB+
+1rSL1lSyhEviLbMMhAbvh+90UYz5pJ/1s9hMmDi3PyJFdWBNvZYyZcrV5He7tRCI
+fsFGCfol6CoIby5jLA1Rq/M46jq4vQ+ObfGyLv3/nWa0O7u2wHjK9WIRoSKomJmK
+t9xXURb9Obfd2Qo7FwMl9dNzsWkpKuGDYwKCAQB+hiWu2C+0foJ4Z8auM1SK8be4
+waplfD7qIvONE/vtl+VAN+eVpz5kkQJfXiafktAHahgEdSx43bofR0Kv0/R7IRs3
+M1WYAr0w+19TXLXkuh2oYIbcoGrIN3HMmlKMv44xh/QUhRe337cCLejP0SESNN+k
+5wT91SbJwuCw/QsG3sD6NIMtCNWdcsAQq/ruhz7pQ/JZUFOueV0tkzbK+oNHWbNU
+lS99qjPaVCXZFlz/t2/89cljh9mtRjcfXIBfuTijN9sXNcLTXsfLsyHJ86eEbI2U
+o2JQ7Sjs10LpiwBbNNHBmulARgRONNMgik6tpNIS0tk9eke0lCX42bDFtAD4
+-----END RSA PRIVATE KEY-----
diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index ace0e6d..f07ae9f 100644
--- a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -37,7 +37,6 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -629,12 +628,9 @@
assertEquals(versionRolledBackTo, info.getVersionRolledBackTo().getLongVersionCode());
}
- // TODO: Allow installing test app along atomically with module metadata package so that
- // a failed test app will be flagged as a failed mainline app
/**
* Test bad update automatic rollback.
*/
- @Ignore
@Test
public void testBadUpdateRollback() throws Exception {
BroadcastReceiver crashCountReceiver = null;
@@ -689,7 +685,7 @@
ActivityManager am = context.getSystemService(ActivityManager.class);
am.killBackgroundProcesses(TEST_APP_A);
// Allow another package launch
- crashQueue.offer(intent.getIntExtra("count", 0), 5, TimeUnit.SECONDS);
+ crashQueue.put(intent.getIntExtra("count", 0));
} catch (InterruptedException e) {
fail("Failed to communicate with test app");
}
@@ -698,14 +694,9 @@
context.registerReceiver(crashCountReceiver, crashCountFilter);
// Start apps PackageWatchdog#TRIGGER_FAILURE_COUNT times so TEST_APP_A crashes
- Integer crashCount = null;
do {
RollbackTestUtils.launchPackage(TEST_APP_A);
- crashCount = crashQueue.poll(5, TimeUnit.SECONDS);
- if (crashCount == null) {
- fail("Timed out waiting for crash signal from test app");
- }
- } while(crashCount < 5);
+ } while(crashQueue.take() < 5);
// TEST_APP_A is automatically rolled back by the RollbackPackageHealthObserver
assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
diff --git a/tests/net/java/android/net/LinkPropertiesTest.java b/tests/net/java/android/net/LinkPropertiesTest.java
index 299fbef..bdde096 100644
--- a/tests/net/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/java/android/net/LinkPropertiesTest.java
@@ -22,18 +22,15 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
import android.net.LinkProperties.CompareResult;
import android.net.LinkProperties.ProvisioningChange;
-import android.net.RouteInfo;
-import android.os.Parcel;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.system.OsConstants;
import android.util.ArraySet;
+import com.android.internal.util.TestUtils;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -849,18 +846,6 @@
assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed)));
}
- private void assertParcelingIsLossless(LinkProperties source) {
- Parcel p = Parcel.obtain();
- source.writeToParcel(p, /* flags */ 0);
- p.setDataPosition(0);
- final byte[] marshalled = p.marshall();
- p = Parcel.obtain();
- p.unmarshall(marshalled, 0, marshalled.length);
- p.setDataPosition(0);
- LinkProperties dest = LinkProperties.CREATOR.createFromParcel(p);
- assertEquals(source, dest);
- }
-
@Test
public void testLinkPropertiesParcelable() throws Exception {
LinkProperties source = new LinkProperties();
@@ -882,12 +867,12 @@
source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
- assertParcelingIsLossless(source);
+ TestUtils.assertParcelingIsLossless(source, LinkProperties.CREATOR);
}
@Test
public void testParcelUninitialized() throws Exception {
LinkProperties empty = new LinkProperties();
- assertParcelingIsLossless(empty);
+ TestUtils.assertParcelingIsLossless(empty, LinkProperties.CREATOR);
}
}
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
new file mode 100644
index 0000000..1f2dd27
--- /dev/null
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.net.SocketKeepalive.InvalidPacketException;
+import android.net.TcpKeepalivePacketData.TcpSocketInfo;
+
+import com.android.internal.util.TestUtils;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+
+@RunWith(JUnit4.class)
+public final class TcpKeepalivePacketDataTest {
+
+ @Before
+ public void setUp() {}
+
+ @Test
+ public void testV4TcpKeepalivePacket() {
+ final InetAddress srcAddr = InetAddressUtils.parseNumericAddress("192.168.0.1");
+ final InetAddress dstAddr = InetAddressUtils.parseNumericAddress("192.168.0.10");
+ final int srcPort = 1234;
+ final int dstPort = 4321;
+ final int seq = 0x11111111;
+ final int ack = 0x22222222;
+ final int wnd = 8000;
+ final int wndScale = 2;
+ TcpKeepalivePacketData resultData = null;
+ TcpSocketInfo testInfo = new TcpSocketInfo(
+ srcAddr, srcPort, dstAddr, dstPort, seq, ack, wnd, wndScale);
+ try {
+ resultData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
+ } catch (InvalidPacketException e) {
+ fail("InvalidPacketException: " + e);
+ }
+
+ assertEquals(testInfo.srcAddress, resultData.srcAddress);
+ assertEquals(testInfo.dstAddress, resultData.dstAddress);
+ assertEquals(testInfo.srcPort, resultData.srcPort);
+ assertEquals(testInfo.dstPort, resultData.dstPort);
+ assertEquals(testInfo.seq, resultData.tcpSeq);
+ assertEquals(testInfo.ack, resultData.tcpAck);
+ assertEquals(testInfo.rcvWndScale, resultData.tcpWndScale);
+
+ TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR);
+
+ final byte[] packet = resultData.getPacket();
+ // IP version and TOS.
+ ByteBuffer buf = ByteBuffer.wrap(packet);
+ assertEquals(buf.getShort(), 0x4500);
+ // Source IP address.
+ byte[] ip = new byte[4];
+ buf = ByteBuffer.wrap(packet, 12, 4);
+ buf.get(ip);
+ assertArrayEquals(ip, srcAddr.getAddress());
+ // Destination IP address.
+ buf = ByteBuffer.wrap(packet, 16, 4);
+ buf.get(ip);
+ assertArrayEquals(ip, dstAddr.getAddress());
+
+ buf = ByteBuffer.wrap(packet, 20, 12);
+ // Source port.
+ assertEquals(buf.getShort(), srcPort);
+ // Destination port.
+ assertEquals(buf.getShort(), dstPort);
+ // Sequence number.
+ assertEquals(buf.getInt(), seq);
+ // Ack.
+ assertEquals(buf.getInt(), ack);
+ // Window size.
+ buf = ByteBuffer.wrap(packet, 34, 2);
+ assertEquals(buf.getShort(), wnd >> wndScale);
+ }
+
+ //TODO: add ipv6 test when ipv6 supported
+
+ @Test
+ public void testParcel() throws Exception {
+ final InetAddress srcAddr = InetAddresses.parseNumericAddress("192.168.0.1");
+ final InetAddress dstAddr = InetAddresses.parseNumericAddress("192.168.0.10");
+ final int srcPort = 1234;
+ final int dstPort = 4321;
+ final int sequence = 0x11111111;
+ final int ack = 0x22222222;
+ final int wnd = 48_000;
+ final int wndScale = 2;
+ TcpKeepalivePacketData testData = null;
+ TcpKeepalivePacketDataParcelable resultData = null;
+ TcpSocketInfo testInfo = new TcpSocketInfo(
+ srcAddr, srcPort, dstAddr, dstPort, sequence, ack, wnd, wndScale);
+ testData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
+ resultData = testData.toStableParcelable();
+ assertArrayEquals(resultData.srcAddress, srcAddr.getAddress());
+ assertArrayEquals(resultData.dstAddress, dstAddr.getAddress());
+ assertEquals(resultData.srcPort, srcPort);
+ assertEquals(resultData.dstPort, dstPort);
+ assertEquals(resultData.seq, sequence);
+ assertEquals(resultData.ack, ack);
+ }
+}
diff --git a/tests/net/java/com/android/internal/util/TestUtils.java b/tests/net/java/com/android/internal/util/TestUtils.java
index 6db01d3..7e5a1d3 100644
--- a/tests/net/java/com/android/internal/util/TestUtils.java
+++ b/tests/net/java/com/android/internal/util/TestUtils.java
@@ -16,12 +16,15 @@
package com.android.internal.util;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
+import android.os.Parcel;
+import android.os.Parcelable;
public final class TestUtils {
private TestUtils() { }
@@ -50,4 +53,18 @@
fail(handler.toString() + " did not become idle after " + timeoutMs + " ms");
}
}
+
+ // TODO : fetch the creator through reflection or something instead of passing it
+ public static <T extends Parcelable, C extends Parcelable.Creator<T>>
+ void assertParcelingIsLossless(T source, C creator) {
+ Parcel p = Parcel.obtain();
+ source.writeToParcel(p, /* flags */ 0);
+ p.setDataPosition(0);
+ final byte[] marshalled = p.marshall();
+ p = Parcel.obtain();
+ p.unmarshall(marshalled, 0, marshalled.length);
+ p.setDataPosition(0);
+ T dest = creator.createFromParcel(p);
+ assertEquals(source, dest);
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index c50e6a7..c5b9cf1 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -1099,9 +1099,13 @@
*/
public static final int DISABLED_BY_WRONG_PASSWORD = 13;
/**
+ * This network is disabled because service is not subscribed
+ */
+ public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 14;
+ /**
* This Maximum disable reason value
*/
- public static final int NETWORK_SELECTION_DISABLED_MAX = 14;
+ public static final int NETWORK_SELECTION_DISABLED_MAX = 15;
/**
* Quality network selection disable reason String (for debug purpose)
@@ -1120,7 +1124,8 @@
"NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT",
"NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER",
"NETWORK_SELECTION_DISABLED_BY_USER_SWITCH",
- "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD"
+ "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD",
+ "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_SUBSCRIPTION"
};
/**