summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt50
-rw-r--r--api/system-current.txt50
-rw-r--r--api/test-current.txt50
-rw-r--r--core/java/android/app/Activity.java79
-rw-r--r--core/java/android/app/ActivityOptions.java8
-rw-r--r--core/java/android/app/Notification.java1
-rw-r--r--core/java/android/app/WaitResult.java11
-rw-r--r--core/java/android/content/Context.java24
-rw-r--r--core/java/android/content/IntentFilter.java13
-rw-r--r--core/java/android/content/pm/PackageManager.java8
-rw-r--r--core/java/android/content/pm/PackageParser.java18
-rwxr-xr-xcore/java/android/provider/Settings.java2
-rw-r--r--core/java/android/service/autofill/AutofillService.java3
-rw-r--r--core/java/android/service/autofill/SaveInfo.java57
-rw-r--r--core/java/android/text/method/DateTimeKeyListener.java11
-rw-r--r--core/java/android/text/method/TimeKeyListener.java11
-rw-r--r--core/java/android/view/SurfaceView.java3
-rw-r--r--core/java/android/view/View.java42
-rw-r--r--core/java/android/view/ViewRootImpl.java15
-rw-r--r--core/java/android/view/Window.java7
-rw-r--r--core/java/android/view/WindowCallbackWrapper.java5
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java23
-rw-r--r--core/java/android/view/autofill/AutofillManager.java481
-rw-r--r--core/java/android/view/autofill/IAutoFillManager.aidl15
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java20
-rw-r--r--core/java/com/android/internal/policy/DecorView.java1
-rw-r--r--core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java6
-rwxr-xr-xcore/jni/android/graphics/Bitmap.cpp91
-rw-r--r--core/res/res/layout/notification_template_material_ambient.xml1
-rw-r--r--core/res/res/values/strings.xml8
-rw-r--r--core/res/res/values/symbols.xml5
-rw-r--r--graphics/java/android/graphics/Bitmap.java201
-rw-r--r--libs/hwui/SkiaCanvas.cpp9
-rw-r--r--libs/hwui/hwui/Bitmap.cpp6
-rw-r--r--libs/hwui/hwui/Bitmap.h2
-rw-r--r--media/java/android/media/BufferingParams.java1
-rw-r--r--media/java/android/media/MediaPlayer.java21
-rw-r--r--packages/CarrierDefaultApp/res/values-af/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-am/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ar/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-az/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-bg/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-bn/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ca/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-cs/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-da/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-de/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-el/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-en-rAU/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-en-rGB/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-en-rIN/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-es-rUS/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-es/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-et/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-eu/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-fa/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-fi/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-fr/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-gl/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-gu/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-hi/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-hr/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-hu/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-hy/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-in/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-is/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-it/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-iw/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-ja/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ka/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-kk/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-km/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-kn/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ko/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ky/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-lo/strings.xml9
-rw-r--r--packages/CarrierDefaultApp/res/values-lt/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-lv/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-mk/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ml/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-mn/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-mr/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-ms/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-my/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-nb/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-ne/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-nl/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-pa/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-pl/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-pt/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ro/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ru/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-si/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-sk/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-sl/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-sq/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-sr/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-sv/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-sw/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ta/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-te/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-th/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-tl/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-tr/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-uk/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-ur/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-uz/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-vi/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml1
-rw-r--r--packages/CarrierDefaultApp/res/values-zu/strings.xml1
-rw-r--r--packages/ExternalStorageProvider/res/values-eu/strings.xml2
-rw-r--r--packages/ExternalStorageProvider/res/values-lo/strings.xml2
-rw-r--r--packages/PrintRecommendationService/res/values/strings.xml1
-rw-r--r--packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java9
-rw-r--r--packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/google/CloudPrintPlugin.java168
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_shelf.xml1
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java2
-rw-r--r--proto/src/metrics_constants.proto5
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java58
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java183
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java127
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/SaveUi.java57
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java7
-rw-r--r--services/core/java/com/android/server/AnimationThread.java58
-rw-r--r--services/core/java/com/android/server/DisplayThread.java5
-rw-r--r--services/core/java/com/android/server/ThreadPriorityBooster.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java29
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java18
-rw-r--r--services/core/java/com/android/server/am/ActivityMetricsLogger.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java12
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java80
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java169
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java102
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java15
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java81
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java3
-rw-r--r--services/core/java/com/android/server/os/SchedulingPolicyService.java12
-rw-r--r--services/core/java/com/android/server/vr/CompatibilityDisplay.java4
-rw-r--r--services/core/java/com/android/server/webkit/WebViewUpdater.java9
-rw-r--r--services/core/java/com/android/server/wm/AlertWindowNotification.java15
-rw-r--r--services/core/java/com/android/server/wm/AppWindowContainerController.java2
-rw-r--r--services/core/java/com/android/server/wm/BoundsAnimationController.java4
-rw-r--r--services/core/java/com/android/server/wm/Session.java16
-rw-r--r--services/core/java/com/android/server/wm/StackWindowController.java8
-rw-r--r--services/core/java/com/android/server/wm/TaskPositioner.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimator.java31
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java47
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfacePlacer.java12
-rw-r--r--services/core/jni/Android.mk2
-rw-r--r--services/core/jni/com_android_server_SystemServer.cpp17
-rw-r--r--services/tests/notification/src/com/android/server/notification/RankingHelperTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java3
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java8
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java24
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl3
-rw-r--r--tools/aapt2/link/Link.cpp2
170 files changed, 2011 insertions, 950 deletions
diff --git a/api/current.txt b/api/current.txt
index 1c7b6bab406a..cbe4195e4c26 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10616,6 +10616,7 @@ package android.content.pm {
field public static final int DONT_KILL_APP = 1; // 0x1
field public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID";
field public static final java.lang.String EXTRA_VERIFICATION_RESULT = "android.content.pm.extra.VERIFICATION_RESULT";
+ field public static final java.lang.String FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS = "android.software.activities_on_secondary_displays";
field public static final java.lang.String FEATURE_APP_WIDGETS = "android.software.app_widgets";
field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
field public static final java.lang.String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
@@ -12429,7 +12430,9 @@ package android.graphics {
method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean);
+ method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean, android.graphics.ColorSpace);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean);
+ method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean, android.graphics.ColorSpace);
method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
@@ -21478,40 +21481,6 @@ package android.media {
method public default void onRoutingChanged(android.media.AudioRouting);
}
- public final class BufferingParams implements android.os.Parcelable {
- method public int describeContents();
- method public int getInitialBufferingMode();
- method public int getInitialBufferingWatermarkKB();
- method public int getInitialBufferingWatermarkMs();
- method public int getRebufferingMode();
- method public int getRebufferingWatermarkHighKB();
- method public int getRebufferingWatermarkHighMs();
- method public int getRebufferingWatermarkLowKB();
- method public int getRebufferingWatermarkLowMs();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int BUFFERING_MODE_NONE = 0; // 0x0
- field public static final int BUFFERING_MODE_SIZE_ONLY = 2; // 0x2
- field public static final int BUFFERING_MODE_TIME_ONLY = 1; // 0x1
- field public static final int BUFFERING_MODE_TIME_THEN_SIZE = 3; // 0x3
- field public static final android.os.Parcelable.Creator<android.media.BufferingParams> CREATOR;
- }
-
- public static class BufferingParams.Builder {
- ctor public BufferingParams.Builder();
- ctor public BufferingParams.Builder(android.media.BufferingParams);
- method public android.media.BufferingParams build();
- method public android.media.BufferingParams.Builder setInitialBufferingMode(int);
- method public android.media.BufferingParams.Builder setInitialBufferingWatermarkKB(int);
- method public android.media.BufferingParams.Builder setInitialBufferingWatermarkMs(int);
- method public android.media.BufferingParams.Builder setRebufferingMode(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkHighKB(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkHighMs(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkLowKB(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkLowMs(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarksKB(int, int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarksMs(int, int);
- }
-
public class CamcorderProfile {
method public static android.media.CamcorderProfile get(int);
method public static android.media.CamcorderProfile get(int, int);
@@ -22816,9 +22785,7 @@ package android.media {
method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
method public void deselectTrack(int) throws java.lang.IllegalStateException;
method public int getAudioSessionId();
- method public android.media.BufferingParams getBufferingParams();
method public int getCurrentPosition();
- method public android.media.BufferingParams getDefaultBufferingParams();
method public android.media.MediaPlayer.DrmInfo getDrmInfo();
method public java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer.NoDrmSchemeException;
method public int getDuration();
@@ -22849,7 +22816,6 @@ package android.media {
method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public deprecated void setAudioStreamType(int);
method public void setAuxEffectSendLevel(float);
- method public void setBufferingParams(android.media.BufferingParams);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -22892,6 +22858,7 @@ package android.media {
field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
+ field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
@@ -22900,6 +22867,7 @@ package android.media {
field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
+ field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -37073,11 +37041,11 @@ package android.service.autofill {
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
- field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 3; // 0x3
- field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 5; // 0x5
+ field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
+ field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
field public static final int SAVE_DATA_TYPE_GENERIC = 0; // 0x0
field public static final int SAVE_DATA_TYPE_PASSWORD = 1; // 0x1
- field public static final int SAVE_DATA_TYPE_USERNAME = 4; // 0x4
+ field public static final int SAVE_DATA_TYPE_USERNAME = 8; // 0x8
}
public static final class SaveInfo.Builder {
@@ -39528,6 +39496,7 @@ package android.telephony {
field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+ field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
@@ -40153,7 +40122,6 @@ package android.telephony {
method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
method public boolean isWorldPhone();
method public void listen(android.telephony.PhoneStateListener, int);
- method public deprecated boolean sendDialerCode(java.lang.String);
method public void sendDialerSpecialCode(java.lang.String);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
diff --git a/api/system-current.txt b/api/system-current.txt
index a912145400dd..34f05da5b367 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -11300,6 +11300,7 @@ package android.content.pm {
field public static final java.lang.String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
field public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID";
field public static final java.lang.String EXTRA_VERIFICATION_RESULT = "android.content.pm.extra.VERIFICATION_RESULT";
+ field public static final java.lang.String FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS = "android.software.activities_on_secondary_displays";
field public static final java.lang.String FEATURE_APP_WIDGETS = "android.software.app_widgets";
field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
field public static final java.lang.String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
@@ -13192,7 +13193,9 @@ package android.graphics {
method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean);
+ method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean, android.graphics.ColorSpace);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean);
+ method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean, android.graphics.ColorSpace);
method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
@@ -23303,40 +23306,6 @@ package android.media {
method public default void onRoutingChanged(android.media.AudioRouting);
}
- public final class BufferingParams implements android.os.Parcelable {
- method public int describeContents();
- method public int getInitialBufferingMode();
- method public int getInitialBufferingWatermarkKB();
- method public int getInitialBufferingWatermarkMs();
- method public int getRebufferingMode();
- method public int getRebufferingWatermarkHighKB();
- method public int getRebufferingWatermarkHighMs();
- method public int getRebufferingWatermarkLowKB();
- method public int getRebufferingWatermarkLowMs();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int BUFFERING_MODE_NONE = 0; // 0x0
- field public static final int BUFFERING_MODE_SIZE_ONLY = 2; // 0x2
- field public static final int BUFFERING_MODE_TIME_ONLY = 1; // 0x1
- field public static final int BUFFERING_MODE_TIME_THEN_SIZE = 3; // 0x3
- field public static final android.os.Parcelable.Creator<android.media.BufferingParams> CREATOR;
- }
-
- public static class BufferingParams.Builder {
- ctor public BufferingParams.Builder();
- ctor public BufferingParams.Builder(android.media.BufferingParams);
- method public android.media.BufferingParams build();
- method public android.media.BufferingParams.Builder setInitialBufferingMode(int);
- method public android.media.BufferingParams.Builder setInitialBufferingWatermarkKB(int);
- method public android.media.BufferingParams.Builder setInitialBufferingWatermarkMs(int);
- method public android.media.BufferingParams.Builder setRebufferingMode(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkHighKB(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkHighMs(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkLowKB(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkLowMs(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarksKB(int, int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarksMs(int, int);
- }
-
public class CamcorderProfile {
method public static android.media.CamcorderProfile get(int);
method public static android.media.CamcorderProfile get(int, int);
@@ -24641,9 +24610,7 @@ package android.media {
method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
method public void deselectTrack(int) throws java.lang.IllegalStateException;
method public int getAudioSessionId();
- method public android.media.BufferingParams getBufferingParams();
method public int getCurrentPosition();
- method public android.media.BufferingParams getDefaultBufferingParams();
method public android.media.MediaPlayer.DrmInfo getDrmInfo();
method public java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer.NoDrmSchemeException;
method public int getDuration();
@@ -24674,7 +24641,6 @@ package android.media {
method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public deprecated void setAudioStreamType(int);
method public void setAuxEffectSendLevel(float);
- method public void setBufferingParams(android.media.BufferingParams);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -24717,6 +24683,7 @@ package android.media {
field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
+ field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
@@ -24725,6 +24692,7 @@ package android.media {
field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
+ field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -40169,11 +40137,11 @@ package android.service.autofill {
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
- field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 3; // 0x3
- field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 5; // 0x5
+ field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
+ field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
field public static final int SAVE_DATA_TYPE_GENERIC = 0; // 0x0
field public static final int SAVE_DATA_TYPE_PASSWORD = 1; // 0x1
- field public static final int SAVE_DATA_TYPE_USERNAME = 4; // 0x4
+ field public static final int SAVE_DATA_TYPE_USERNAME = 8; // 0x8
}
public static final class SaveInfo.Builder {
@@ -42975,6 +42943,7 @@ package android.telephony {
field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+ field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
@@ -43653,7 +43622,6 @@ package android.telephony {
method public boolean isWorldPhone();
method public void listen(android.telephony.PhoneStateListener, int);
method public boolean needsOtaServiceProvisioning();
- method public deprecated boolean sendDialerCode(java.lang.String);
method public void sendDialerSpecialCode(java.lang.String);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
diff --git a/api/test-current.txt b/api/test-current.txt
index f08a22bb4de6..ac49a9bc720f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -10655,6 +10655,7 @@ package android.content.pm {
field public static final int DONT_KILL_APP = 1; // 0x1
field public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID";
field public static final java.lang.String EXTRA_VERIFICATION_RESULT = "android.content.pm.extra.VERIFICATION_RESULT";
+ field public static final java.lang.String FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS = "android.software.activities_on_secondary_displays";
field public static final java.lang.String FEATURE_APP_WIDGETS = "android.software.app_widgets";
field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
field public static final java.lang.String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
@@ -12479,7 +12480,9 @@ package android.graphics {
method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean);
+ method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean, android.graphics.ColorSpace);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean);
+ method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean, android.graphics.ColorSpace);
method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
@@ -21591,40 +21594,6 @@ package android.media {
method public default void onRoutingChanged(android.media.AudioRouting);
}
- public final class BufferingParams implements android.os.Parcelable {
- method public int describeContents();
- method public int getInitialBufferingMode();
- method public int getInitialBufferingWatermarkKB();
- method public int getInitialBufferingWatermarkMs();
- method public int getRebufferingMode();
- method public int getRebufferingWatermarkHighKB();
- method public int getRebufferingWatermarkHighMs();
- method public int getRebufferingWatermarkLowKB();
- method public int getRebufferingWatermarkLowMs();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int BUFFERING_MODE_NONE = 0; // 0x0
- field public static final int BUFFERING_MODE_SIZE_ONLY = 2; // 0x2
- field public static final int BUFFERING_MODE_TIME_ONLY = 1; // 0x1
- field public static final int BUFFERING_MODE_TIME_THEN_SIZE = 3; // 0x3
- field public static final android.os.Parcelable.Creator<android.media.BufferingParams> CREATOR;
- }
-
- public static class BufferingParams.Builder {
- ctor public BufferingParams.Builder();
- ctor public BufferingParams.Builder(android.media.BufferingParams);
- method public android.media.BufferingParams build();
- method public android.media.BufferingParams.Builder setInitialBufferingMode(int);
- method public android.media.BufferingParams.Builder setInitialBufferingWatermarkKB(int);
- method public android.media.BufferingParams.Builder setInitialBufferingWatermarkMs(int);
- method public android.media.BufferingParams.Builder setRebufferingMode(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkHighKB(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkHighMs(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkLowKB(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarkLowMs(int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarksKB(int, int);
- method public android.media.BufferingParams.Builder setRebufferingWatermarksMs(int, int);
- }
-
public class CamcorderProfile {
method public static android.media.CamcorderProfile get(int);
method public static android.media.CamcorderProfile get(int, int);
@@ -22929,9 +22898,7 @@ package android.media {
method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
method public void deselectTrack(int) throws java.lang.IllegalStateException;
method public int getAudioSessionId();
- method public android.media.BufferingParams getBufferingParams();
method public int getCurrentPosition();
- method public android.media.BufferingParams getDefaultBufferingParams();
method public android.media.MediaPlayer.DrmInfo getDrmInfo();
method public java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer.NoDrmSchemeException;
method public int getDuration();
@@ -22962,7 +22929,6 @@ package android.media {
method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public deprecated void setAudioStreamType(int);
method public void setAuxEffectSendLevel(float);
- method public void setBufferingParams(android.media.BufferingParams);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -23005,6 +22971,7 @@ package android.media {
field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
+ field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
@@ -23013,6 +22980,7 @@ package android.media {
field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
+ field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -37231,11 +37199,11 @@ package android.service.autofill {
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
- field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 3; // 0x3
- field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 5; // 0x5
+ field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
+ field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
field public static final int SAVE_DATA_TYPE_GENERIC = 0; // 0x0
field public static final int SAVE_DATA_TYPE_PASSWORD = 1; // 0x1
- field public static final int SAVE_DATA_TYPE_USERNAME = 4; // 0x4
+ field public static final int SAVE_DATA_TYPE_USERNAME = 8; // 0x8
}
public static final class SaveInfo.Builder {
@@ -39727,6 +39695,7 @@ package android.telephony {
field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+ field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
@@ -40352,7 +40321,6 @@ package android.telephony {
method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
method public boolean isWorldPhone();
method public void listen(android.telephony.PhoneStateListener, int);
- method public deprecated boolean sendDialerCode(java.lang.String);
method public void sendDialerSpecialCode(java.lang.String);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index af3bf2aee049..42192356ed10 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -724,8 +724,9 @@ public class Activity extends ContextThemeWrapper
public static final int FINISH_TASK_WITH_ACTIVITY = 2;
static final String FRAGMENTS_TAG = "android:fragments";
- static final String AUTOFILL_RESET_NEEDED_TAG = "android:autofillResetNeeded";
+ private static final String LAST_ACCESSIBILITY_ID = "android:lastAccessibilityId";
+ private static final String AUTOFILL_RESET_NEEDED = "@android:autofillResetNeeded";
private static final String WINDOW_HIERARCHY_TAG = "android:viewHierarchyState";
private static final String SAVED_DIALOG_IDS_KEY = "android:savedDialogIds";
private static final String SAVED_DIALOGS_TAG = "android:savedDialogs";
@@ -773,6 +774,9 @@ public class Activity extends ContextThemeWrapper
private SearchManager mSearchManager;
private MenuInflater mMenuInflater;
+ /** The autofill manager. Always access via {@link #getAutofillManager()}. */
+ @Nullable private AutofillManager mAutofillManager;
+
static final class NonConfigurationInstances {
Object activity;
HashMap<String, Object> children;
@@ -853,6 +857,9 @@ public class Activity extends ContextThemeWrapper
private boolean mAutoFillResetNeeded;
+ /** The last accessibility id that was returned from {@link #getNextAccessibilityId()} */
+ private int mLastAccessibilityId = View.LAST_APP_ACCESSIBILITY_ID;
+
private AutofillPopupWindow mAutofillPopupWindow;
private static native String getDlWarning();
@@ -930,6 +937,19 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * (Create and) return the autofill manager
+ *
+ * @return The autofill manager
+ */
+ @NonNull private AutofillManager getAutofillManager() {
+ if (mAutofillManager == null) {
+ mAutofillManager = getSystemService(AutofillManager.class);
+ }
+
+ return mAutofillManager;
+ }
+
+ /**
* Called when the activity is starting. This is where most initialization
* should go: calling {@link #setContentView(int)} to inflate the
* activity's UI, using {@link #findViewById} to programmatically interact
@@ -970,6 +990,13 @@ public class Activity extends ContextThemeWrapper
}
}
if (savedInstanceState != null) {
+ mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
+ mLastAccessibilityId = savedInstanceState.getInt(LAST_ACCESSIBILITY_ID, View.NO_ID);
+
+ if (mAutoFillResetNeeded) {
+ getAutofillManager().onCreate(savedInstanceState);
+ }
+
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.fragments : null);
@@ -1058,12 +1085,6 @@ public class Activity extends ContextThemeWrapper
* @see #onSaveInstanceState
*/
protected void onRestoreInstanceState(Bundle savedInstanceState) {
- mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED_TAG, false);
-
- if (mAutoFillResetNeeded) {
- getSystemService(AutofillManager.class).onRestoreInstanceState(savedInstanceState);
- }
-
if (mWindow != null) {
Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
if (windowState != null) {
@@ -1312,6 +1333,27 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * Gets the next accessibility ID.
+ *
+ * <p>All IDs will be bigger than {@link View#LAST_APP_ACCESSIBILITY_ID}. All IDs returned
+ * will be unique.
+ *
+ * @return A ID that is unique in the activity
+ *
+ * {@hide}
+ */
+ @Override
+ public int getNextAccessibilityId() {
+ if (mLastAccessibilityId == Integer.MAX_VALUE - 1) {
+ mLastAccessibilityId = View.LAST_APP_ACCESSIBILITY_ID;
+ }
+
+ mLastAccessibilityId++;
+
+ return mLastAccessibilityId;
+ }
+
+ /**
* Check whether this activity is running as part of a voice interaction with the user.
* If true, it should perform its interaction with the user through the
* {@link VoiceInteractor} returned by {@link #getVoiceInteractor}.
@@ -1505,13 +1547,15 @@ public class Activity extends ContextThemeWrapper
*/
protected void onSaveInstanceState(Bundle outState) {
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
+
+ outState.putInt(LAST_ACCESSIBILITY_ID, mLastAccessibilityId);
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mAutoFillResetNeeded) {
- outState.putBoolean(AUTOFILL_RESET_NEEDED_TAG, mAutoFillResetNeeded);
- getSystemService(AutofillManager.class).onSaveInstanceState(outState);
+ outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
+ getAutofillManager().onSaveInstanceState(outState);
}
getApplication().dispatchActivitySaveInstanceState(this, outState);
}
@@ -1802,7 +1846,7 @@ public class Activity extends ContextThemeWrapper
mTranslucentCallback = null;
mCalled = true;
if (isFinishing() && mAutoFillResetNeeded) {
- getSystemService(AutofillManager.class).commit();
+ getAutofillManager().commit();
}
}
@@ -3057,6 +3101,19 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * Called before {@link #onAttachedToWindow}.
+ *
+ * @hide
+ */
+ @CallSuper
+ public void onBeforeAttachedToWindow() {
+ if (mAutoFillResetNeeded) {
+ getAutofillManager().onAttachedToWindow(
+ getWindow().getDecorView().getRootView().getWindowToken());
+ }
+ }
+
+ /**
* Called when the main window associated with the activity has been
* attached to the window manager.
* See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
@@ -7125,7 +7182,7 @@ public class Activity extends ContextThemeWrapper
}
} else if (who.startsWith(AUTO_FILL_AUTH_WHO_PREFIX)) {
Intent resultData = (resultCode == Activity.RESULT_OK) ? data : null;
- getSystemService(AutofillManager.class).onAuthenticationResult(resultData);
+ getAutofillManager().onAuthenticationResult(resultData);
} else {
Fragment frag = mFragments.findFragmentByWho(who);
if (frag != null) {
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index aa7cdf7b475e..02d18841f489 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -155,6 +155,7 @@ public class ActivityOptions {
/**
* The display id the activity should be launched into.
+ * @see #setLaunchDisplayId(int)
* @hide
*/
private static final String KEY_LAUNCH_DISPLAY_ID = "android.activity.launchDisplayId";
@@ -1038,6 +1039,7 @@ public class ActivityOptions {
* Gets the id of the display where activity should be launched.
* @return The id of the display where activity should be launched,
* {@link android.view.Display#INVALID_DISPLAY} if not set.
+ * @see #setLaunchDisplayId(int)
*/
public int getLaunchDisplayId() {
return mLaunchDisplayId;
@@ -1045,6 +1047,12 @@ public class ActivityOptions {
/**
* Sets the id of the display where activity should be launched.
+ * An app can launch activities on public displays or private displays that are owned by the app
+ * or where an app already has activities. Otherwise, trying to launch on a private display
+ * or providing an invalid display id will result in an exception.
+ * <p>
+ * Setting launch display id will be ignored on devices that don't have
+ * {@link android.content.pm.PackageManager#FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS}.
* @param launchDisplayId The id of the display where the activity should be launched.
* @return {@code this} {@link ActivityOptions} instance.
*/
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 6d7486b5311e..7f26f4fd7050 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3667,7 +3667,6 @@ public class Notification implements Parcelable
contentView.setTextViewText(R.id.text, null);
contentView.setViewVisibility(R.id.text_line_1, View.GONE);
contentView.setTextViewText(R.id.text_line_1, null);
- contentView.setViewVisibility(R.id.progress, View.GONE);
}
/**
diff --git a/core/java/android/app/WaitResult.java b/core/java/android/app/WaitResult.java
index af196cfe4db4..898d0cabee3e 100644
--- a/core/java/android/app/WaitResult.java
+++ b/core/java/android/app/WaitResult.java
@@ -20,6 +20,8 @@ import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;
+import java.io.PrintWriter;
+
/**
* Information returned after waiting for an activity start.
*
@@ -69,4 +71,13 @@ public class WaitResult implements Parcelable {
thisTime = source.readLong();
totalTime = source.readLong();
}
+
+ public void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "WaitResult:");
+ pw.println(prefix + " result=" + result);
+ pw.println(prefix + " timeout=" + timeout);
+ pw.println(prefix + " who=" + who);
+ pw.println(prefix + " thisTime=" + thisTime);
+ pw.println(prefix + " totalTime=" + totalTime);
+ }
} \ No newline at end of file
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 368c7b8106b3..88bade1691a6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -61,6 +61,7 @@ import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.Display;
import android.view.DisplayAdjustments;
+import android.view.View;
import android.view.ViewDebug;
import android.view.WindowManager;
import android.view.textclassifier.TextClassificationManager;
@@ -436,6 +437,29 @@ public abstract class Context {
*/
public abstract Context getApplicationContext();
+ /** Non-activity related accessibility ids are unique in the app */
+ private static int sLastAccessibilityId = View.NO_ID;
+
+ /**
+ * Gets the next accessibility ID.
+ *
+ * <p>All IDs will be smaller or the same as {@link View#LAST_APP_ACCESSIBILITY_ID}. All IDs
+ * returned will be unique.
+ *
+ * @return A ID that is unique in the process
+ *
+ * {@hide}
+ */
+ public int getNextAccessibilityId() {
+ if (sLastAccessibilityId == View.LAST_APP_ACCESSIBILITY_ID - 1) {
+ sLastAccessibilityId = View.NO_ID;
+ }
+
+ sLastAccessibilityId++;
+
+ return sLastAccessibilityId;
+ }
+
/**
* Add a new {@link ComponentCallbacks} to the base application of the
* Context, which will be called at the same times as the ComponentCallbacks
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 93204d1264eb..23e54baab622 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -284,8 +284,8 @@ public class IntentFilter implements Parcelable {
private int mVerifyState;
- /** Whether or not the intent filter is visible to ephemeral apps. */
- private boolean mVisibleToEphemeral;
+ /** Whether or not the intent filter is visible to instant apps. */
+ private boolean mVisibleToInstantApp;
// These functions are the start of more optimized code for managing
// the string sets... not yet implemented.
@@ -452,6 +452,7 @@ public class IntentFilter implements Parcelable {
}
mHasPartialTypes = o.mHasPartialTypes;
mVerifyState = o.mVerifyState;
+ mVisibleToInstantApp = o.mVisibleToInstantApp;
}
/**
@@ -654,12 +655,12 @@ public class IntentFilter implements Parcelable {
}
/** @hide */
- public void setVisibleToEphemeral(boolean visibleToEmphemeral) {
- mVisibleToEphemeral = visibleToEmphemeral;
+ public void setVisibleToInstantApp(boolean visibleToInstantApp) {
+ mVisibleToInstantApp = visibleToInstantApp;
}
/** @hide */
public boolean isVisibleToInstantApp() {
- return mVisibleToEphemeral;
+ return mVisibleToInstantApp;
}
/**
@@ -1858,6 +1859,7 @@ public class IntentFilter implements Parcelable {
dest.writeInt(mPriority);
dest.writeInt(mHasPartialTypes ? 1 : 0);
dest.writeInt(getAutoVerify() ? 1 : 0);
+ dest.writeInt(isVisibleToInstantApp() ? 1 : 0);
}
/**
@@ -1926,6 +1928,7 @@ public class IntentFilter implements Parcelable {
mPriority = source.readInt();
mHasPartialTypes = source.readInt() > 0;
setAutoVerify(source.readInt() > 0);
+ setVisibleToInstantApp(source.readInt() > 0);
}
private final boolean findMimeType(String type) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 50e3e6863d4f..fa3e4e98b551 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2285,6 +2285,14 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+ * The device supports running activities on secondary displays.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS
+ = "android.software.activities_on_secondary_displays";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
* The device supports creating secondary users and managed profiles via
* {@link DevicePolicyManager}.
*/
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 940447ca5f08..d44d0dcf00f2 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4258,7 +4258,7 @@ public class PackageParser {
a.intents.add(intent);
}
// adjust activity flags when we implicitly expose it via a browsable filter
- intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+ intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
if (intent.isVisibleToInstantApp()) {
a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
@@ -4291,7 +4291,7 @@ public class PackageParser {
owner.preferredActivityFilters.add(intent);
}
// adjust activity flags when we implicitly expose it via a browsable filter
- intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+ intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
if (intent.isVisibleToInstantApp()) {
a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
@@ -4307,12 +4307,12 @@ public class PackageParser {
owner.visibleToInstantApps = true;
// cycle through any filters already seen
for (int i = a.intents.size() - 1; i >= 0; --i) {
- a.intents.get(i).setVisibleToEphemeral(true /*visibleToEmphemeral*/);
+ a.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
}
if (owner.preferredActivityFilters != null) {
for (int i = owner.preferredActivityFilters.size() - 1; i >= 0; --i) {
owner.preferredActivityFilters.get(i)
- .setVisibleToEphemeral(true /*visibleToEmphemeral*/);
+ .setVisibleToInstantApp(true /*visibleToInstantApp*/);
}
}
}
@@ -4618,7 +4618,7 @@ public class PackageParser {
+ mArchiveSourcePath + " "
+ parser.getPositionDescription());
} else {
- intent.setVisibleToEphemeral(
+ intent.setVisibleToInstantApp(
visibleToEphemeral || isWebBrowsableIntent(intent));
a.intents.add(intent);
}
@@ -4821,7 +4821,7 @@ public class PackageParser {
}
outInfo.intents.add(intent);
// adjust provider flags when we implicitly expose it via a browsable filter
- intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+ intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
if (intent.isVisibleToInstantApp()) {
outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
@@ -4838,7 +4838,7 @@ public class PackageParser {
owner.visibleToInstantApps = true;
// cycle through any filters already seen
for (int i = outInfo.intents.size() - 1; i >= 0; --i) {
- outInfo.intents.get(i).setVisibleToEphemeral(true /*visibleToEmphemeral*/);
+ outInfo.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
}
}
@@ -5126,7 +5126,7 @@ public class PackageParser {
return null;
}
// adjust activity flags when we implicitly expose it via a browsable filter
- intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+ intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
if (intent.isVisibleToInstantApp()) {
s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
@@ -5143,7 +5143,7 @@ public class PackageParser {
owner.visibleToInstantApps = true;
// cycle through any filters already seen
for (int i = s.intents.size() - 1; i >= 0; --i) {
- s.intents.get(i).setVisibleToEphemeral(true /*visibleToEmphemeral*/);
+ s.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
}
}
} else {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 660d53a91b99..cac643fc8b5f 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7091,6 +7091,8 @@ public final class Settings {
INSTANT_APP_SETTINGS.add(ENABLED_INPUT_METHODS);
INSTANT_APP_SETTINGS.add(ANDROID_ID);
+
+ INSTANT_APP_SETTINGS.add(PACKAGE_VERIFIER_USER_CONSENT);
}
/**
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index aae22c1bb750..c82b9ebb6b39 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -82,8 +82,7 @@ public abstract class AutofillService extends Service {
// Internal extras
/** @hide */
- public static final String EXTRA_ACTIVITY_TOKEN =
- "android.service.autofill.extra.ACTIVITY_TOKEN";
+ public static final String EXTRA_SESSION_ID = "android.service.autofill.extra.SESSION_ID";
// Handler messages.
private static final int MSG_CONNECT = 1;
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index f75b7afe4c46..4ad0f086691a 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -25,6 +25,7 @@ import android.content.IntentSender;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.DebugUtils;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
@@ -111,52 +112,41 @@ public final class SaveInfo implements Parcelable {
* Type used on when the service can save the contents of an activity, but cannot describe what
* the content is for.
*/
- public static final int SAVE_DATA_TYPE_GENERIC = 0;
+ public static final int SAVE_DATA_TYPE_GENERIC = 0x0;
/**
* Type used when the {@link FillResponse} represents user credentials that have a password.
*/
- public static final int SAVE_DATA_TYPE_PASSWORD = 1;
+ public static final int SAVE_DATA_TYPE_PASSWORD = 0x01;
/**
* Type used on when the {@link FillResponse} represents a physical address (such as street,
* city, state, etc).
*/
- public static final int SAVE_DATA_TYPE_ADDRESS = 2;
+ public static final int SAVE_DATA_TYPE_ADDRESS = 0x02;
/**
* Type used when the {@link FillResponse} represents a credit card.
*/
- public static final int SAVE_DATA_TYPE_CREDIT_CARD = 3;
+ public static final int SAVE_DATA_TYPE_CREDIT_CARD = 0x04;
/**
* Type used when the {@link FillResponse} represents just an username, without a password.
*/
- public static final int SAVE_DATA_TYPE_USERNAME = 4;
+ public static final int SAVE_DATA_TYPE_USERNAME = 0x08;
/**
* Type used when the {@link FillResponse} represents just an email address, without a password.
*/
- public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 5;
+ public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 0x10;
- private final @SaveDataType int mType;
+ private final int mType;
private final CharSequence mNegativeActionTitle;
private final IntentSender mNegativeActionListener;
private final AutofillId[] mRequiredIds;
private final AutofillId[] mOptionalIds;
private final CharSequence mDescription;
- /** @hide */
- @IntDef({
- SAVE_DATA_TYPE_GENERIC,
- SAVE_DATA_TYPE_PASSWORD,
- SAVE_DATA_TYPE_ADDRESS,
- SAVE_DATA_TYPE_CREDIT_CARD
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SaveDataType {
- }
-
private SaveInfo(Builder builder) {
mType = builder.mType;
mNegativeActionTitle = builder.mNegativeActionTitle;
@@ -201,7 +191,7 @@ public final class SaveInfo implements Parcelable {
*/
public static final class Builder {
- private final @SaveDataType int mType;
+ private final int mType;
private CharSequence mNegativeActionTitle;
private IntentSender mNegativeActionListener;
// TODO(b/33197203): make mRequiredIds final once addSavableIds() is gone
@@ -213,32 +203,24 @@ public final class SaveInfo implements Parcelable {
/**
* Creates a new builder.
*
- * @param type the type of information the associated {@link FillResponse} represents. Must
- * be {@link SaveInfo#SAVE_DATA_TYPE_GENERIC}, {@link SaveInfo#SAVE_DATA_TYPE_PASSWORD},
- * {@link SaveInfo#SAVE_DATA_TYPE_ADDRESS}, or {@link SaveInfo#SAVE_DATA_TYPE_CREDIT_CARD};
- * otherwise it will assume {@link SaveInfo#SAVE_DATA_TYPE_GENERIC}.
+ * @param type the type of information the associated {@link FillResponse} represents, can
+ * be any combination of {@link SaveInfo#SAVE_DATA_TYPE_GENERIC},
+ * {@link SaveInfo#SAVE_DATA_TYPE_PASSWORD},
+ * {@link SaveInfo#SAVE_DATA_TYPE_ADDRESS}, {@link SaveInfo#SAVE_DATA_TYPE_CREDIT_CARD},
+ * {@link SaveInfo#SAVE_DATA_TYPE_USERNAME}, or
+ * {@link SaveInfo#SAVE_DATA_TYPE_EMAIL_ADDRESS}.
* @param requiredIds ids of all required views that will trigger a save request.
*
* <p>See {@link SaveInfo} for more info.
*
* @throws IllegalArgumentException if {@code requiredIds} is {@code null} or empty.
*/
- public Builder(@SaveDataType int type, @NonNull AutofillId[] requiredIds) {
+ public Builder(int type, @NonNull AutofillId[] requiredIds) {
if (false) {// TODO(b/33197203): re-move when clients use it
Preconditions.checkArgument(requiredIds != null && requiredIds.length > 0,
"must have at least one required id: " + Arrays.toString(requiredIds));
}
- switch (type) {
- case SAVE_DATA_TYPE_PASSWORD:
- case SAVE_DATA_TYPE_ADDRESS:
- case SAVE_DATA_TYPE_CREDIT_CARD:
- case SAVE_DATA_TYPE_USERNAME:
- case SAVE_DATA_TYPE_EMAIL_ADDRESS:
- mType = type;
- break;
- default:
- mType = SAVE_DATA_TYPE_GENERIC;
- }
+ mType = type;
mRequiredIds = requiredIds;
}
@@ -248,7 +230,7 @@ public final class SaveInfo implements Parcelable {
* // TODO(b/33197203): make sure is removed when clients migrated
*/
@Deprecated
- public Builder(@SaveDataType int type) {
+ public Builder(int type) {
this(type, null);
}
@@ -355,7 +337,8 @@ public final class SaveInfo implements Parcelable {
public String toString() {
if (!DEBUG) return super.toString();
- return new StringBuilder("SaveInfo: [type=").append(mType)
+ return new StringBuilder("SaveInfo: [type=")
+ .append(DebugUtils.flagsToString(SaveInfo.class, "SAVE_DATA_TYPE_", mType))
.append(", requiredIds=").append(Arrays.toString(mRequiredIds))
.append(", optionalIds=").append(Arrays.toString(mOptionalIds))
.append(", description=").append(mDescription)
diff --git a/core/java/android/text/method/DateTimeKeyListener.java b/core/java/android/text/method/DateTimeKeyListener.java
index 551db5560128..1593db5de641 100644
--- a/core/java/android/text/method/DateTimeKeyListener.java
+++ b/core/java/android/text/method/DateTimeKeyListener.java
@@ -68,7 +68,7 @@ public class DateTimeKeyListener extends NumberKeyListener
final LinkedHashSet<Character> chars = new LinkedHashSet<>();
// First add the digits. Then, add all the character in AM and PM markers. Finally, add all
// the non-pattern characters seen in the patterns for "yMdhms" and "yMdHms".
- boolean success = NumberKeyListener.addDigits(chars, locale)
+ final boolean success = NumberKeyListener.addDigits(chars, locale)
&& NumberKeyListener.addAmPmChars(chars, locale)
&& NumberKeyListener.addFormatCharsFromSkeleton(
chars, locale, SKELETON_12HOUR, SYMBOLS_TO_IGNORE)
@@ -76,7 +76,14 @@ public class DateTimeKeyListener extends NumberKeyListener
chars, locale, SKELETON_24HOUR, SYMBOLS_TO_IGNORE);
if (success) {
mCharacters = NumberKeyListener.collectionToArray(chars);
- mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
+ if (locale != null && "en".equals(locale.getLanguage())) {
+ // For backward compatibility reasons, assume we don't need advanced input for
+ // English locales, although English locales literally also need a comma and perhaps
+ // uppercase letters for AM and PM.
+ mNeedsAdvancedInput = false;
+ } else {
+ mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
+ }
} else {
mCharacters = CHARACTERS;
mNeedsAdvancedInput = false;
diff --git a/core/java/android/text/method/TimeKeyListener.java b/core/java/android/text/method/TimeKeyListener.java
index 5b1db11777dd..f11f40099d9c 100644
--- a/core/java/android/text/method/TimeKeyListener.java
+++ b/core/java/android/text/method/TimeKeyListener.java
@@ -68,7 +68,7 @@ public class TimeKeyListener extends NumberKeyListener
final LinkedHashSet<Character> chars = new LinkedHashSet<>();
// First add the digits. Then, add all the character in AM and PM markers. Finally, add all
// the non-pattern characters seen in the patterns for "hms" and "Hms".
- boolean success = NumberKeyListener.addDigits(chars, locale)
+ final boolean success = NumberKeyListener.addDigits(chars, locale)
&& NumberKeyListener.addAmPmChars(chars, locale)
&& NumberKeyListener.addFormatCharsFromSkeleton(
chars, locale, SKELETON_12HOUR, SYMBOLS_TO_IGNORE)
@@ -76,7 +76,14 @@ public class TimeKeyListener extends NumberKeyListener
chars, locale, SKELETON_24HOUR, SYMBOLS_TO_IGNORE);
if (success) {
mCharacters = NumberKeyListener.collectionToArray(chars);
- mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
+ if (locale != null && "en".equals(locale.getLanguage())) {
+ // For backward compatibility reasons, assume we don't need advanced input for
+ // English locales, although English locales may need uppercase letters for
+ // AM and PM.
+ mNeedsAdvancedInput = false;
+ } else {
+ mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
+ }
} else {
mCharacters = CHARACTERS;
mNeedsAdvancedInput = false;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 076b33cc9d6a..31911cb5b6fd 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -683,7 +683,8 @@ public class SurfaceView extends View {
mTranslator.translateRectInAppWindowToScreen(mScreenRect);
}
- if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
+ if (mSurfaceControl != null
+ && (!isHardwareAccelerated() || !mRtHandlingPositionUpdates)) {
try {
if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
"postion = [%d, %d, %d, %d]", System.identityHashCode(this),
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b4100123a5b8..a09db9c3972d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -797,6 +797,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public static final int NO_ID = -1;
/**
+ * Last ID that is given to Views that are no part of activities.
+ *
+ * {@hide}
+ */
+ public static final int LAST_APP_ACCESSIBILITY_ID = Integer.MAX_VALUE / 2;
+
+ /**
* Signals that compatibility booleans have been initialized according to
* target SDK versions.
*/
@@ -1967,11 +1974,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private SparseArray<Object> mKeyedTags;
/**
- * The next available accessibility id.
- */
- private static int sNextAccessibilityViewId;
-
- /**
* The animation currently associated with this view.
* @hide
*/
@@ -2013,10 +2015,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@ViewDebug.ExportedProperty(resolveId = true)
int mID = NO_ID;
- /**
- * The stable ID of this view for accessibility purposes.
+ /** The ID of this view for accessibility and autofill purposes.
+ * <ul>
+ * <li>== {@link #NO_ID}: ID has not been assigned yet
+ * <li>&le; {@link #LAST_APP_ACCESSIBILITY_ID}: View is not part of a activity. The ID is
+ * unique in the process. This might change
+ * over activity lifecycle events.
+ * <li>&gt; {@link #LAST_APP_ACCESSIBILITY_ID}: View is part of a activity. The ID is
+ * unique in the activity. This stays the same
+ * over activity lifecycle events.
*/
- int mAccessibilityViewId = NO_ID;
+ private int mAccessibilityViewId = NO_ID;
private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
@@ -8144,7 +8153,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public int getAccessibilityViewId() {
if (mAccessibilityViewId == NO_ID) {
- mAccessibilityViewId = sNextAccessibilityViewId++;
+ mAccessibilityViewId = mContext.getNextAccessibilityId();
}
return mAccessibilityViewId;
}
@@ -17159,7 +17168,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@CallSuper
protected Parcelable onSaveInstanceState() {
mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
- if (mStartActivityRequestWho != null || isAutofilled()) {
+ if (mStartActivityRequestWho != null || isAutofilled()
+ || mAccessibilityViewId > LAST_APP_ACCESSIBILITY_ID) {
BaseSavedState state = new BaseSavedState(AbsSavedState.EMPTY_STATE);
if (mStartActivityRequestWho != null) {
@@ -17170,8 +17180,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
state.mSavedData |= BaseSavedState.IS_AUTOFILLED;
}
+ if (mAccessibilityViewId > LAST_APP_ACCESSIBILITY_ID) {
+ state.mSavedData |= BaseSavedState.ACCESSIBILITY_ID;
+ }
+
state.mStartActivityRequestWhoSaved = mStartActivityRequestWho;
state.mIsAutofilled = isAutofilled();
+ state.mAccessibilityViewId = mAccessibilityViewId;
return state;
}
return BaseSavedState.EMPTY_STATE;
@@ -17249,6 +17264,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if ((baseState.mSavedData & BaseSavedState.IS_AUTOFILLED) != 0) {
setAutofilled(baseState.mIsAutofilled);
}
+ if ((baseState.mSavedData & BaseSavedState.ACCESSIBILITY_ID) != 0) {
+ mAccessibilityViewId = baseState.mAccessibilityViewId;
+ }
}
}
@@ -24408,11 +24426,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public static class BaseSavedState extends AbsSavedState {
static final int START_ACTIVITY_REQUESTED_WHO_SAVED = 0b1;
static final int IS_AUTOFILLED = 0b10;
+ static final int ACCESSIBILITY_ID = 0b100;
// Flags that describe what data in this state is valid
int mSavedData;
String mStartActivityRequestWhoSaved;
boolean mIsAutofilled;
+ int mAccessibilityViewId;
/**
* Constructor used when reading from a parcel. Reads the state of the superclass.
@@ -24435,6 +24455,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mSavedData = source.readInt();
mStartActivityRequestWhoSaved = source.readString();
mIsAutofilled = source.readBoolean();
+ mAccessibilityViewId = source.readInt();
}
/**
@@ -24453,6 +24474,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
out.writeInt(mSavedData);
out.writeString(mStartActivityRequestWhoSaved);
out.writeBoolean(mIsAutofilled);
+ out.writeInt(mAccessibilityViewId);
}
public static final Parcelable.Creator<BaseSavedState> CREATOR
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 58ef0af3fe79..4a7b16eff93c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1249,6 +1249,13 @@ public final class ViewRootImpl implements ViewParent,
mIsAmbientMode = ambient;
}
+ void setWindowVisibility(int visibility) {
+ if (visibility != mAttachInfo.mWindowVisibility) {
+ mAttachInfo.mWindowVisibility = visibility;
+ mView.dispatchWindowVisibilityChanged(visibility);
+ }
+ }
+
void setWindowStopped(boolean stopped) {
if (mStopped != stopped) {
mStopped = stopped;
@@ -1263,6 +1270,7 @@ public final class ViewRootImpl implements ViewParent,
if (renderer != null) {
renderer.destroyHardwareResources(mView);
}
+ mView.dispatchWindowVisibilityChanged(View.GONE);
}
}
}
@@ -1297,7 +1305,8 @@ public final class ViewRootImpl implements ViewParent,
}
int getHostVisibility() {
- return (mAppVisible || mForceDecorViewVisibility) ? mView.getVisibility() : View.GONE;
+ return (mAppVisible || mForceDecorViewVisibility) && !mStopped
+ ? mView.getVisibility() : View.GONE;
}
/**
@@ -1654,8 +1663,8 @@ public final class ViewRootImpl implements ViewParent,
}
if (viewVisibilityChanged) {
- mAttachInfo.mWindowVisibility = viewVisibility;
- host.dispatchWindowVisibilityChanged(viewVisibility);
+ setWindowVisibility(viewVisibility);
+
if (viewUserVisibilityChanged) {
host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE);
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 6dd8ecfa12e3..a432d30f86ca 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -480,6 +480,13 @@ public abstract class Window {
public void onWindowFocusChanged(boolean hasFocus);
/**
+ * @hide
+ */
+ default void onBeforeAttachedToWindow() {
+ // empty
+ }
+
+ /**
* Called when the window has been attached to the window manager.
* See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
* for more information.
diff --git a/core/java/android/view/WindowCallbackWrapper.java b/core/java/android/view/WindowCallbackWrapper.java
index 02c8945d9fce..7018529cd52a 100644
--- a/core/java/android/view/WindowCallbackWrapper.java
+++ b/core/java/android/view/WindowCallbackWrapper.java
@@ -109,6 +109,11 @@ public class WindowCallbackWrapper implements Window.Callback {
}
@Override
+ public void onBeforeAttachedToWindow() {
+ mWrapped.onBeforeAttachedToWindow();
+ }
+
+ @Override
public void onAttachedToWindow() {
mWrapped.onAttachedToWindow();
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 50f17e089585..255574f8cee7 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3073,16 +3073,19 @@ public class AccessibilityNodeInfo implements Parcelable {
if (mActions != null && !mActions.isEmpty()) {
final int actionCount = mActions.size();
- parcel.writeInt(actionCount);
+ int nonLegacyActionCount = 0;
int defaultLegacyStandardActions = 0;
for (int i = 0; i < actionCount; i++) {
AccessibilityAction action = mActions.get(i);
if (isDefaultLegacyStandardAction(action)) {
defaultLegacyStandardActions |= action.getId();
+ } else {
+ nonLegacyActionCount++;
}
}
parcel.writeInt(defaultLegacyStandardActions);
+ parcel.writeInt(nonLegacyActionCount);
for (int i = 0; i < actionCount; i++) {
AccessibilityAction action = mActions.get(i);
@@ -3093,6 +3096,7 @@ public class AccessibilityNodeInfo implements Parcelable {
}
} else {
parcel.writeInt(0);
+ parcel.writeInt(0);
}
parcel.writeInt(mMaxTextLength);
@@ -3270,16 +3274,13 @@ public class AccessibilityNodeInfo implements Parcelable {
mBoundsInScreen.left = parcel.readInt();
mBoundsInScreen.right = parcel.readInt();
- final int actionCount = parcel.readInt();
- if (actionCount > 0) {
- final int legacyStandardActions = parcel.readInt();
- addLegacyStandardActions(legacyStandardActions);
- final int nonLegacyActionCount = actionCount - Integer.bitCount(legacyStandardActions);
- for (int i = 0; i < nonLegacyActionCount; i++) {
- final AccessibilityAction action = new AccessibilityAction(
- parcel.readInt(), parcel.readCharSequence());
- addActionUnchecked(action);
- }
+ final int legacyStandardActions = parcel.readInt();
+ addLegacyStandardActions(legacyStandardActions);
+ final int nonLegacyActionCount = parcel.readInt();
+ for (int i = 0; i < nonLegacyActionCount; i++) {
+ final AccessibilityAction action = new AccessibilityAction(
+ parcel.readInt(), parcel.readCharSequence());
+ addActionUnchecked(action);
}
mMaxTextLength = parcel.readInt();
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 07fad60e5b6a..d429d379876f 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -37,6 +37,7 @@ import android.util.SparseArray;
import android.view.View;
import android.view.WindowManagerGlobal;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
@@ -48,6 +49,8 @@ import java.util.Objects;
/**
* App entry point to the AutoFill Framework.
+ *
+ * <p>It is safe to call into this from any thread.
*/
// TODO(b/33197203): improve this javadoc
//TODO(b/33197203): restrict manager calls to activity
@@ -92,6 +95,7 @@ public final class AutofillManager {
*/
public static final String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
+ static final String SESSION_ID_TAG = "android:sessionId";
static final String LAST_AUTOFILLED_DATA_TAG = "android:lastAutoFilledData";
// Public flags start from the lowest bit
@@ -108,17 +112,32 @@ public final class AutofillManager {
private final MetricsLogger mMetricsLogger = new MetricsLogger();
+ /**
+ * There is currently no session running.
+ * {@hide}
+ */
+ public static final int NO_SESSION = Integer.MIN_VALUE;
+
private final IAutoFillManager mService;
+
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
private IAutoFillManagerClient mServiceClient;
+ @GuardedBy("mLock")
private AutofillCallback mCallback;
- private Context mContext;
+ private final Context mContext;
- private boolean mHasSession;
+ @GuardedBy("mLock")
+ private int mSessionId = NO_SESSION;
+
+ @GuardedBy("mLock")
private boolean mEnabled;
/** If a view changes to this mapping the autofill operation was successful */
+ @GuardedBy("mLock")
@Nullable private ParcelableMap mLastAutofilledData;
/** @hide */
@@ -172,8 +191,63 @@ public final class AutofillManager {
*
* {@hide}
*/
- public void onRestoreInstanceState(Bundle savedInstanceState) {
- mLastAutofilledData = savedInstanceState.getParcelable(LAST_AUTOFILLED_DATA_TAG);
+ public void onCreate(Bundle savedInstanceState) {
+ synchronized (mLock) {
+ mLastAutofilledData = savedInstanceState.getParcelable(LAST_AUTOFILLED_DATA_TAG);
+
+ if (mSessionId != NO_SESSION) {
+ Log.w(TAG, "New session was started before onCreate()");
+ return;
+ }
+
+ mSessionId = savedInstanceState.getInt(SESSION_ID_TAG, NO_SESSION);
+
+ if (mSessionId != NO_SESSION) {
+ ensureServiceClientAddedIfNeededLocked();
+
+ final AutofillClient client = getClientLocked();
+ if (client != null) {
+ try {
+ final boolean sessionWasRestored = mService.restoreSession(mSessionId,
+ mContext.getActivityToken(), mServiceClient.asBinder());
+
+ if (!sessionWasRestored) {
+ Log.w(TAG, "Session " + mSessionId + " could not be restored");
+ mSessionId = NO_SESSION;
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "session " + mSessionId + " was restored");
+ }
+
+ client.autofillCallbackResetableStateAvailable();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not figure out if there was an autofill session", e);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Set window future popup windows should be attached to.
+ *
+ * @param windowToken The window the popup windows should be attached to
+ *
+ * {@hide}
+ */
+ public void onAttachedToWindow(@NonNull IBinder windowToken) {
+ synchronized (mLock) {
+ if (mSessionId == NO_SESSION) {
+ return;
+ }
+
+ try {
+ mService.setWindow(mSessionId, windowToken);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not attach window to session " + mSessionId);
+ }
+ }
}
/**
@@ -184,8 +258,14 @@ public final class AutofillManager {
* {@hide}
*/
public void onSaveInstanceState(Bundle outState) {
- if (mLastAutofilledData != null) {
- outState.putParcelable(LAST_AUTOFILLED_DATA_TAG, mLastAutofilledData);
+ synchronized (mLock) {
+ if (mSessionId != NO_SESSION) {
+ outState.putInt(SESSION_ID_TAG, mSessionId);
+ }
+
+ if (mLastAutofilledData != null) {
+ outState.putParcelable(LAST_AUTOFILLED_DATA_TAG, mLastAutofilledData);
+ }
}
}
@@ -198,8 +278,10 @@ public final class AutofillManager {
* @return whether autofill is enabled for the current user.
*/
public boolean isEnabled() {
- ensureServiceClientAddedIfNeeded();
- return mEnabled;
+ synchronized (mLock) {
+ ensureServiceClientAddedIfNeededLocked();
+ return mEnabled;
+ }
}
/**
@@ -212,16 +294,18 @@ public final class AutofillManager {
* @param view view requesting the new autofill context.
*/
public void requestAutofill(@NonNull View view) {
- ensureServiceClientAddedIfNeeded();
+ synchronized (mLock) {
+ ensureServiceClientAddedIfNeededLocked();
- if (!mEnabled) {
- return;
- }
+ if (!mEnabled) {
+ return;
+ }
- final AutofillId id = getAutofillId(view);
- final AutofillValue value = view.getAutofillValue();
+ final AutofillId id = getAutofillId(view);
+ final AutofillValue value = view.getAutofillValue();
- startSession(id, view.getWindowToken(), null, value, FLAG_MANUAL_REQUEST);
+ startSessionLocked(id, view.getWindowToken(), null, value, FLAG_MANUAL_REQUEST);
+ }
}
/**
@@ -236,14 +320,16 @@ public final class AutofillManager {
* @param bounds child boundaries, relative to the top window.
*/
public void requestAutofill(@NonNull View view, int childId, @NonNull Rect bounds) {
- ensureServiceClientAddedIfNeeded();
+ synchronized (mLock) {
+ ensureServiceClientAddedIfNeededLocked();
- if (!mEnabled) {
- return;
- }
+ if (!mEnabled) {
+ return;
+ }
- final AutofillId id = getAutofillId(view, childId);
- startSession(id, view.getWindowToken(), bounds, null, FLAG_MANUAL_REQUEST);
+ final AutofillId id = getAutofillId(view, childId);
+ startSessionLocked(id, view.getWindowToken(), bounds, null, FLAG_MANUAL_REQUEST);
+ }
}
@@ -253,24 +339,30 @@ public final class AutofillManager {
* @param view {@link View} that was entered.
*/
public void notifyViewEntered(@NonNull View view) {
- ensureServiceClientAddedIfNeeded();
+ AutofillCallback callback = null;
+ synchronized (mLock) {
+ ensureServiceClientAddedIfNeededLocked();
- if (!mEnabled) {
- if (mCallback != null) {
- mCallback.onAutofillEvent(view, AutofillCallback.EVENT_INPUT_UNAVAILABLE);
+ if (!mEnabled) {
+ if (mCallback != null) {
+ callback = mCallback;
+ }
+ } else {
+ final AutofillId id = getAutofillId(view);
+ final AutofillValue value = view.getAutofillValue();
+
+ if (mSessionId == NO_SESSION) {
+ // Starts new session.
+ startSessionLocked(id, view.getWindowToken(), null, value, 0);
+ } else {
+ // Update focus on existing session.
+ updateSessionLocked(id, null, value, FLAG_VIEW_ENTERED);
+ }
}
- return;
}
- final AutofillId id = getAutofillId(view);
- final AutofillValue value = view.getAutofillValue();
-
- if (!mHasSession) {
- // Starts new session.
- startSession(id, view.getWindowToken(), null, value, 0);
- } else {
- // Update focus on existing session.
- updateSession(id, null, value, FLAG_VIEW_ENTERED);
+ if (callback != null) {
+ mCallback.onAutofillEvent(view, AutofillCallback.EVENT_INPUT_UNAVAILABLE);
}
}
@@ -280,13 +372,15 @@ public final class AutofillManager {
* @param view {@link View} that was exited.
*/
public void notifyViewExited(@NonNull View view) {
- ensureServiceClientAddedIfNeeded();
+ synchronized (mLock) {
+ ensureServiceClientAddedIfNeededLocked();
- if (mEnabled && mHasSession) {
- final AutofillId id = getAutofillId(view);
+ if (mEnabled && mSessionId != NO_SESSION) {
+ final AutofillId id = getAutofillId(view);
- // Update focus on existing session.
- updateSession(id, null, null, FLAG_VIEW_EXITED);
+ // Update focus on existing session.
+ updateSessionLocked(id, null, null, FLAG_VIEW_EXITED);
+ }
}
}
@@ -298,23 +392,30 @@ public final class AutofillManager {
* @param bounds child boundaries, relative to the top window.
*/
public void notifyViewEntered(@NonNull View view, int childId, @NonNull Rect bounds) {
- ensureServiceClientAddedIfNeeded();
+ AutofillCallback callback = null;
+ synchronized (mLock) {
+ ensureServiceClientAddedIfNeededLocked();
+
+ if (!mEnabled) {
+ if (mCallback != null) {
+ callback = mCallback;
+ }
+ } else {
+ final AutofillId id = getAutofillId(view, childId);
- if (!mEnabled) {
- if (mCallback != null) {
- mCallback.onAutofillEvent(view, childId, AutofillCallback.EVENT_INPUT_UNAVAILABLE);
+ if (mSessionId == NO_SESSION) {
+ // Starts new session.
+ startSessionLocked(id, view.getWindowToken(), bounds, null, 0);
+ } else {
+ // Update focus on existing session.
+ updateSessionLocked(id, bounds, null, FLAG_VIEW_ENTERED);
+ }
}
- return;
}
- final AutofillId id = getAutofillId(view, childId);
-
- if (!mHasSession) {
- // Starts new session.
- startSession(id, view.getWindowToken(), bounds, null, 0);
- } else {
- // Update focus on existing session.
- updateSession(id, bounds, null, FLAG_VIEW_ENTERED);
+ if (callback != null) {
+ callback.onAutofillEvent(view, childId,
+ AutofillCallback.EVENT_INPUT_UNAVAILABLE);
}
}
@@ -325,13 +426,15 @@ public final class AutofillManager {
* @param childId id identifying the virtual child inside the view.
*/
public void notifyViewExited(@NonNull View view, int childId) {
- ensureServiceClientAddedIfNeeded();
+ synchronized (mLock) {
+ ensureServiceClientAddedIfNeededLocked();
- if (mEnabled && mHasSession) {
- final AutofillId id = getAutofillId(view, childId);
+ if (mEnabled && mSessionId != NO_SESSION) {
+ final AutofillId id = getAutofillId(view, childId);
- // Update focus on existing session.
- updateSession(id, null, null, FLAG_VIEW_EXITED);
+ // Update focus on existing session.
+ updateSessionLocked(id, null, null, FLAG_VIEW_EXITED);
+ }
}
}
@@ -345,40 +448,42 @@ public final class AutofillManager {
boolean valueWasRead = false;
AutofillValue value = null;
- // If the session is gone some fields might still be highlighted, hence we have to remove
- // the isAutofilled property even if no sessions are active.
- if (mLastAutofilledData == null) {
- view.setAutofilled(false);
- } else {
- id = getAutofillId(view);
- if (mLastAutofilledData.containsKey(id)) {
- value = view.getAutofillValue();
- valueWasRead = true;
-
- if (Objects.equals(mLastAutofilledData.get(id), value)) {
- view.setAutofilled(true);
+ synchronized (mLock) {
+ // If the session is gone some fields might still be highlighted, hence we have to
+ // remove the isAutofilled property even if no sessions are active.
+ if (mLastAutofilledData == null) {
+ view.setAutofilled(false);
+ } else {
+ id = getAutofillId(view);
+ if (mLastAutofilledData.containsKey(id)) {
+ value = view.getAutofillValue();
+ valueWasRead = true;
+
+ if (Objects.equals(mLastAutofilledData.get(id), value)) {
+ view.setAutofilled(true);
+ } else {
+ view.setAutofilled(false);
+ mLastAutofilledData.remove(id);
+ }
} else {
view.setAutofilled(false);
- mLastAutofilledData.remove(id);
}
- } else {
- view.setAutofilled(false);
}
- }
- if (!mEnabled || !mHasSession) {
- return;
- }
+ if (!mEnabled || mSessionId == NO_SESSION) {
+ return;
+ }
- if (id == null) {
- id = getAutofillId(view);
- }
+ if (id == null) {
+ id = getAutofillId(view);
+ }
- if (!valueWasRead) {
- value = view.getAutofillValue();
- }
+ if (!valueWasRead) {
+ value = view.getAutofillValue();
+ }
- updateSession(id, null, value, FLAG_VALUE_CHANGED);
+ updateSessionLocked(id, null, value, FLAG_VALUE_CHANGED);
+ }
}
@@ -390,12 +495,14 @@ public final class AutofillManager {
* @param value new value of the child.
*/
public void notifyValueChanged(View view, int childId, AutofillValue value) {
- if (!mEnabled || !mHasSession) {
- return;
- }
+ synchronized (mLock) {
+ if (!mEnabled || mSessionId == NO_SESSION) {
+ return;
+ }
- final AutofillId id = getAutofillId(view, childId);
- updateSession(id, null, value, FLAG_VALUE_CHANGED);
+ final AutofillId id = getAutofillId(view, childId);
+ updateSessionLocked(id, null, value, FLAG_VALUE_CHANGED);
+ }
}
/**
@@ -405,11 +512,13 @@ public final class AutofillManager {
* call this method after the form is submitted and another page is rendered.
*/
public void commit() {
- if (!mEnabled && !mHasSession) {
- return;
- }
+ synchronized (mLock) {
+ if (!mEnabled && mSessionId == NO_SESSION) {
+ return;
+ }
- finishSession();
+ finishSessionLocked();
+ }
}
/**
@@ -419,14 +528,16 @@ public final class AutofillManager {
* call this method if the user does not post the form but moves to another form in this page.
*/
public void cancel() {
- if (!mEnabled && !mHasSession) {
- return;
- }
+ synchronized (mLock) {
+ if (!mEnabled && mSessionId == NO_SESSION) {
+ return;
+ }
- cancelSession();
+ cancelSessionLocked();
+ }
}
- private AutofillClient getClient() {
+ private AutofillClient getClientLocked() {
if (mContext instanceof AutofillClient) {
return (AutofillClient) mContext;
}
@@ -442,21 +553,21 @@ public final class AutofillManager {
if (DEBUG) Log.d(TAG, "onAuthenticationResult(): d=" + data);
- if (data == null) {
- return;
- }
- final Parcelable result = data.getParcelableExtra(EXTRA_AUTHENTICATION_RESULT);
- final Bundle responseData = new Bundle();
- responseData.putParcelable(EXTRA_AUTHENTICATION_RESULT, result);
- try {
- mService.setAuthenticationResult(responseData,
- mContext.getActivityToken(), mContext.getUserId());
- } catch (RemoteException e) {
- Log.e(TAG, "Error delivering authentication result", e);
+ synchronized (mLock) {
+ if (mSessionId == NO_SESSION || data == null) {
+ return;
+ }
+ final Parcelable result = data.getParcelableExtra(EXTRA_AUTHENTICATION_RESULT);
+ final Bundle responseData = new Bundle();
+ responseData.putParcelable(EXTRA_AUTHENTICATION_RESULT, result);
+ try {
+ mService.setAuthenticationResult(responseData, mSessionId, mContext.getUserId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error delivering authentication result", e);
+ }
}
}
-
private static AutofillId getAutofillId(View view) {
return new AutofillId(view.getAccessibilityViewId());
}
@@ -465,71 +576,74 @@ public final class AutofillManager {
return new AutofillId(parent.getAccessibilityViewId(), childId);
}
- private void startSession(@NonNull AutofillId id, @NonNull IBinder windowToken,
+ private void startSessionLocked(@NonNull AutofillId id, @NonNull IBinder windowToken,
@NonNull Rect bounds, @NonNull AutofillValue value, int flags) {
if (DEBUG) {
- Log.d(TAG, "startSession(): id=" + id + ", bounds=" + bounds + ", value=" + value
+ Log.d(TAG, "startSessionLocked(): id=" + id + ", bounds=" + bounds + ", value=" + value
+ ", flags=" + flags);
}
try {
- mService.startSession(mContext.getActivityToken(), windowToken,
+ mSessionId = mService.startSession(mContext.getActivityToken(), windowToken,
mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
mCallback != null, flags, mContext.getOpPackageName());
- AutofillClient client = getClient();
+ AutofillClient client = getClientLocked();
if (client != null) {
client.autofillCallbackResetableStateAvailable();
}
- mHasSession = true;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- private void finishSession() {
+ private void finishSessionLocked() {
if (DEBUG) {
- Log.d(TAG, "finishSession()");
+ Log.d(TAG, "finishSessionLocked()");
}
- mHasSession = false;
+
try {
- mService.finishSession(mContext.getActivityToken(), mContext.getUserId());
+ mService.finishSession(mSessionId, mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
+
+ mSessionId = NO_SESSION;
}
- private void cancelSession() {
+ private void cancelSessionLocked() {
if (DEBUG) {
- Log.d(TAG, "cancelSession()");
+ Log.d(TAG, "cancelSessionLocked()");
}
- mHasSession = false;
+
try {
- mService.cancelSession(mContext.getActivityToken(), mContext.getUserId());
+ mService.cancelSession(mSessionId, mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
+
+ mSessionId = NO_SESSION;
}
- private void updateSession(AutofillId id, Rect bounds, AutofillValue value, int flags) {
+ private void updateSessionLocked(AutofillId id, Rect bounds, AutofillValue value, int flags) {
if (DEBUG) {
if (VERBOSE || (flags & FLAG_VIEW_EXITED) != 0) {
- Log.d(TAG, "updateSession(): id=" + id + ", bounds=" + bounds + ", value=" + value
- + ", flags=" + flags);
+ Log.d(TAG, "updateSessionLocked(): id=" + id + ", bounds=" + bounds
+ + ", value=" + value + ", flags=" + flags);
}
}
try {
- mService.updateSession(mContext.getActivityToken(), id, bounds, value, flags,
- mContext.getUserId());
+ mService.updateSession(mSessionId, id, bounds, value, flags, mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- private void ensureServiceClientAddedIfNeeded() {
- if (getClient() == null) {
+ private void ensureServiceClientAddedIfNeededLocked() {
+ if (getClientLocked() == null) {
return;
}
+
if (mServiceClient == null) {
mServiceClient = new AutofillManagerClient(this);
try {
@@ -546,16 +660,18 @@ public final class AutofillManager {
* @param callback callback to receive events.
*/
public void registerCallback(@Nullable AutofillCallback callback) {
- if (callback == null) return;
+ synchronized (mLock) {
+ if (callback == null) return;
- final boolean hadCallback = mCallback != null;
- mCallback = callback;
+ final boolean hadCallback = mCallback != null;
+ mCallback = callback;
- if (mHasSession && !hadCallback) {
- try {
- mService.setHasCallback(mContext.getActivityToken(), mContext.getUserId(), true);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ if (!hadCallback) {
+ try {
+ mService.setHasCallback(mSessionId, mContext.getUserId(), true);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
}
}
@@ -566,13 +682,13 @@ public final class AutofillManager {
* @param callback callback to stop receiving events.
*/
public void unregisterCallback(@Nullable AutofillCallback callback) {
- if (callback == null || mCallback == null || callback != mCallback) return;
+ synchronized (mLock) {
+ if (callback == null || mCallback == null || callback != mCallback) return;
- mCallback = null;
+ mCallback = null;
- if (mHasSession) {
try {
- mService.setHasCallback(mContext.getActivityToken(), mContext.getUserId(), false);
+ mService.setHasCallback(mSessionId, mContext.getUserId(), false);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -585,13 +701,21 @@ public final class AutofillManager {
if (anchor == null) {
return;
}
- if (getClient().autofillCallbackRequestShowFillUi(anchor, width, height,
- anchorBounds, presenter) && mCallback != null) {
+
+ AutofillCallback callback = null;
+ synchronized (mLock) {
+ if (getClientLocked().autofillCallbackRequestShowFillUi(anchor, width, height,
+ anchorBounds, presenter) && mCallback != null) {
+ callback = mCallback;
+ }
+ }
+
+ if (callback != null) {
if (id.isVirtual()) {
- mCallback.onAutofillEvent(anchor, id.getVirtualChildId(),
+ callback.onAutofillEvent(anchor, id.getVirtualChildId(),
AutofillCallback.EVENT_INPUT_SHOWN);
} else {
- mCallback.onAutofillEvent(anchor, AutofillCallback.EVENT_INPUT_SHOWN);
+ callback.onAutofillEvent(anchor, AutofillCallback.EVENT_INPUT_SHOWN);
}
}
}
@@ -605,10 +729,12 @@ public final class AutofillManager {
private void setAutofilledIfValuesIs(@NonNull View view, @Nullable AutofillValue targetValue) {
AutofillValue currentValue = view.getAutofillValue();
if (Objects.equals(currentValue, targetValue)) {
- if (mLastAutofilledData == null) {
- mLastAutofilledData = new ParcelableMap(1);
+ synchronized (mLock) {
+ if (mLastAutofilledData == null) {
+ mLastAutofilledData = new ParcelableMap(1);
+ }
+ mLastAutofilledData.put(getAutofillId(view), targetValue);
}
- mLastAutofilledData.put(getAutofillId(view), targetValue);
view.setAutofilled(true);
}
}
@@ -646,11 +772,13 @@ public final class AutofillManager {
}
valuesByParent.put(id.getVirtualChildId(), value);
} else {
- // Mark the view as to be autofilled with 'value'
- if (mLastAutofilledData == null) {
- mLastAutofilledData = new ParcelableMap(itemCount - i);
+ synchronized (mLock) {
+ // Mark the view as to be autofilled with 'value'
+ if (mLastAutofilledData == null) {
+ mLastAutofilledData = new ParcelableMap(itemCount - i);
+ }
+ mLastAutofilledData.put(id, value);
}
- mLastAutofilledData.put(id, value);
view.autofill(value);
@@ -679,26 +807,41 @@ public final class AutofillManager {
}
private void requestHideFillUi(IBinder windowToken, AutofillId id) {
- if (getClient().autofillCallbackRequestHideFillUi() && mCallback != null) {
- final View anchor = findAchorView(windowToken, id);
+ final View anchor = findAchorView(windowToken, id);
+
+ AutofillCallback callback = null;
+ synchronized (mLock) {
+ if (getClientLocked().autofillCallbackRequestHideFillUi() && mCallback != null) {
+ callback = mCallback;
+ }
+ }
+
+ if (callback != null) {
if (id.isVirtual()) {
- mCallback.onAutofillEvent(anchor, id.getVirtualChildId(),
+ callback.onAutofillEvent(anchor, id.getVirtualChildId(),
AutofillCallback.EVENT_INPUT_HIDDEN);
} else {
- mCallback.onAutofillEvent(anchor, AutofillCallback.EVENT_INPUT_HIDDEN);
+ callback.onAutofillEvent(anchor, AutofillCallback.EVENT_INPUT_HIDDEN);
}
}
}
private void notifyNoFillUi(IBinder windowToken, AutofillId id) {
- if (mCallback != null) {
- final View anchor = findAchorView(windowToken, id);
+ final View anchor = findAchorView(windowToken, id);
+
+ AutofillCallback callback;
+ synchronized (mLock) {
+ callback = mCallback;
+ }
+
+ if (callback != null) {
if (id.isVirtual()) {
- mCallback.onAutofillEvent(anchor, id.getVirtualChildId(),
+ callback.onAutofillEvent(anchor, id.getVirtualChildId(),
AutofillCallback.EVENT_INPUT_UNAVAILABLE);
} else {
- mCallback.onAutofillEvent(anchor, AutofillCallback.EVENT_INPUT_UNAVAILABLE);
+ callback.onAutofillEvent(anchor, AutofillCallback.EVENT_INPUT_UNAVAILABLE);
}
+
}
}
@@ -787,7 +930,11 @@ public final class AutofillManager {
public void setState(boolean enabled) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> afm.mEnabled = enabled);
+ afm.mContext.getMainThreadHandler().post(() -> {
+ synchronized (afm.mLock) {
+ afm.mEnabled = enabled;
+ }
+ });
}
}
@@ -808,8 +955,8 @@ public final class AutofillManager {
final AutofillManager afm = mAfm.get();
if (afm != null) {
afm.mContext.getMainThreadHandler().post(() -> {
- if (afm.getClient() != null) {
- afm.getClient().autofillCallbackAuthenticate(intent, fillInIntent);
+ if (afm.getClientLocked() != null) {
+ afm.getClientLocked().autofillCallbackAuthenticate(intent, fillInIntent);
}
});
}
@@ -821,7 +968,7 @@ public final class AutofillManager {
final AutofillManager afm = mAfm.get();
if (afm != null) {
afm.mContext.getMainThreadHandler().post(() -> {
- if (afm.getClient() != null) {
+ if (afm.getClientLocked() != null) {
afm.requestShowFillUi(windowToken, id, width,
height, anchorBounds, presenter);
}
@@ -834,7 +981,7 @@ public final class AutofillManager {
final AutofillManager afm = mAfm.get();
if (afm != null) {
afm.mContext.getMainThreadHandler().post(() -> {
- if (afm.getClient() != null) {
+ if (afm.getClientLocked() != null) {
afm.requestHideFillUi(windowToken, id);
}
});
@@ -846,7 +993,7 @@ public final class AutofillManager {
final AutofillManager afm = mAfm.get();
if (afm != null) {
afm.mContext.getMainThreadHandler().post(() -> {
- if (afm.getClient() != null) {
+ if (afm.getClientLocked() != null) {
afm.notifyNoFillUi(windowToken, id);
}
});
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 97210cc919a5..20d09ae13a60 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -30,14 +30,15 @@ import android.view.autofill.IAutoFillManagerClient;
*/
interface IAutoFillManager {
boolean addClient(in IAutoFillManagerClient client, int userId);
- oneway void startSession(in IBinder activityToken, IBinder windowToken, in IBinder appCallback,
+ int startSession(IBinder activityToken, IBinder windowToken, in IBinder appCallback,
in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId,
boolean hasCallback, int flags, String packageName);
- oneway void updateSession(in IBinder activityToken, in AutofillId id, in Rect bounds,
+ boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback);
+ void setWindow(int sessionId, in IBinder windowToken);
+ oneway void updateSession(int sessionId, in AutofillId id, in Rect bounds,
in AutofillValue value, int flags, int userId);
- oneway void finishSession(in IBinder activityToken, int userId);
- oneway void cancelSession(in IBinder activityToken, int userId);
- oneway void setAuthenticationResult(in Bundle data,
- in IBinder activityToken, int userId);
- oneway void setHasCallback(in IBinder activityToken, int userId, boolean hasIt);
+ void finishSession(int sessionId, int userId);
+ void cancelSession(int sessionId, int userId);
+ void setAuthenticationResult(in Bundle data, int sessionId, int userId);
+ oneway void setHasCallback(int sessionId, int userId, boolean hasIt);
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 67bce8c59309..44fa99df7b73 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -26,7 +26,9 @@ import android.icu.text.DecimalFormatSymbols;
import android.icu.util.ULocale;
import android.net.LocalServerSocket;
import android.opengl.EGL14;
+import android.os.Build;
import android.os.IInstalld;
+import android.os.Environment;
import android.os.Process;
import android.os.RemoteException;
import android.os.Seccomp;
@@ -60,6 +62,7 @@ import dalvik.system.ZygoteHooks;
import libcore.io.IoUtils;
import java.io.BufferedReader;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -457,6 +460,23 @@ public class ZygoteInit {
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
+ // Capturing profiles is only supported for debug or eng builds since selinux normally
+ // prevents it.
+ boolean profileSystemServer = SystemProperties.getBoolean(
+ "dalvik.vm.profilesystemserver", false);
+ if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
+ try {
+ File profileDir = Environment.getDataProfilesDePackageDirectory(
+ Process.SYSTEM_UID, "system_server");
+ File profile = new File(profileDir, "primary.prof");
+ profile.getParentFile().mkdirs();
+ profile.createNewFile();
+ String[] codePaths = systemServerClasspath.split(":");
+ VMRuntime.registerAppInfo(profile.getPath(), codePaths);
+ } catch (Exception e) {
+ Log.wtf(TAG, "Failed to set up system server profile", e);
+ }
+ }
}
if (parsedArgs.invokeWith != null) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index a8e16c96acfa..9760f8111ec3 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1474,6 +1474,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
final Window.Callback cb = mWindow.getCallback();
if (cb != null && !mWindow.isDestroyed() && mFeatureId < 0) {
+ cb.onBeforeAttachedToWindow();
cb.onAttachedToWindow();
}
diff --git a/core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java b/core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java
index e40090f63a76..924b3f704f5b 100644
--- a/core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java
+++ b/core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java
@@ -31,7 +31,7 @@ public class SurfaceFlingerVsyncChoreographer {
private static final long ONE_S_IN_NS = ONE_MS_IN_NS * 1000;
private final Handler mHandler;
- private final Choreographer mChoreographer = Choreographer.getInstance();
+ private final Choreographer mChoreographer;
/**
* The offset between vsync-app and vsync-surfaceflinger. See
@@ -39,8 +39,10 @@ public class SurfaceFlingerVsyncChoreographer {
*/
private long mSurfaceFlingerOffsetMs;
- public SurfaceFlingerVsyncChoreographer(Handler handler, Display display) {
+ public SurfaceFlingerVsyncChoreographer(Handler handler, Display display,
+ Choreographer choreographer) {
mHandler = handler;
+ mChoreographer = choreographer;
mSurfaceFlingerOffsetMs = calculateAppSurfaceFlingerVsyncOffsetMs(display);
}
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index de5e505af3da..3a03af60efce 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -44,6 +44,14 @@ static jmethodID gBitmap_constructorMethodID;
static jmethodID gBitmap_reinitMethodID;
static jmethodID gBitmap_getAllocationByteCountMethodID;
+static jfieldID gTransferParams_aFieldID;
+static jfieldID gTransferParams_bFieldID;
+static jfieldID gTransferParams_cFieldID;
+static jfieldID gTransferParams_dFieldID;
+static jfieldID gTransferParams_eFieldID;
+static jfieldID gTransferParams_fFieldID;
+static jfieldID gTransferParams_gFieldID;
+
namespace android {
class BitmapWrapper {
@@ -685,6 +693,22 @@ static ToColorProc ChooseToColorProc(const SkBitmap& src) {
return NULL;
}
+static void ToF16_SA8(void* dst, const void* src, int width) {
+ SkASSERT(width > 0);
+ uint64_t* d = (uint64_t*)dst;
+ const uint8_t* s = (const uint8_t*)src;
+
+ for (int i = 0; i < width; i++) {
+ uint8_t c = *s++;
+ SkPM4f a;
+ a.fVec[SkPM4f::R] = 0.0f;
+ a.fVec[SkPM4f::G] = 0.0f;
+ a.fVec[SkPM4f::B] = 0.0f;
+ a.fVec[SkPM4f::A] = c / 255.0f;
+ *d++ = a.toF16();
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -696,7 +720,8 @@ static int getPremulBitmapCreateFlags(bool isMutable) {
static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
jint offset, jint stride, jint width, jint height,
- jint configHandle, jboolean isMutable) {
+ jint configHandle, jboolean isMutable,
+ jfloatArray xyzD50, jobject transferParameters) {
SkColorType colorType = GraphicsJNI::legacyBitmapConfigToColorType(configHandle);
if (NULL != jColors) {
size_t n = env->GetArrayLength(jColors);
@@ -712,8 +737,37 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
}
SkBitmap bitmap;
- bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType,
- GraphicsJNI::colorSpaceForType(colorType)));
+ sk_sp<SkColorSpace> colorSpace;
+
+ if (colorType != kN32_SkColorType || xyzD50 == nullptr || transferParameters == nullptr) {
+ colorSpace = GraphicsJNI::colorSpaceForType(colorType);
+ } else {
+ SkColorSpaceTransferFn p;
+ p.fA = (float) env->GetDoubleField(transferParameters, gTransferParams_aFieldID);
+ p.fB = (float) env->GetDoubleField(transferParameters, gTransferParams_bFieldID);
+ p.fC = (float) env->GetDoubleField(transferParameters, gTransferParams_cFieldID);
+ p.fD = (float) env->GetDoubleField(transferParameters, gTransferParams_dFieldID);
+ p.fE = (float) env->GetDoubleField(transferParameters, gTransferParams_eFieldID);
+ p.fF = (float) env->GetDoubleField(transferParameters, gTransferParams_fFieldID);
+ p.fG = (float) env->GetDoubleField(transferParameters, gTransferParams_gFieldID);
+
+ SkMatrix44 xyzMatrix(SkMatrix44::kIdentity_Constructor);
+ jfloat* array = env->GetFloatArrayElements(xyzD50, NULL);
+ xyzMatrix.setFloat(0, 0, array[0]);
+ xyzMatrix.setFloat(1, 0, array[1]);
+ xyzMatrix.setFloat(2, 0, array[2]);
+ xyzMatrix.setFloat(0, 1, array[3]);
+ xyzMatrix.setFloat(1, 1, array[4]);
+ xyzMatrix.setFloat(2, 1, array[5]);
+ xyzMatrix.setFloat(0, 2, array[6]);
+ xyzMatrix.setFloat(1, 2, array[7]);
+ xyzMatrix.setFloat(2, 2, array[8]);
+ env->ReleaseFloatArrayElements(xyzD50, array, 0);
+
+ colorSpace = SkColorSpace::MakeRGB(p, xyzMatrix);
+ }
+
+ bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType, colorSpace));
sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL);
if (!nativeBitmap) {
@@ -739,6 +793,9 @@ static bool bitmapCopyTo(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src,
SkPixmap srcPixmap = srcUnlocker.pixmap();
SkImageInfo dstInfo = src.info().makeColorType(dstCT);
+ if (dstCT == kRGBA_F16_SkColorType) {
+ dstInfo = dstInfo.makeColorSpace(SkColorSpace::MakeSRGBLinear());
+ }
if (!dst->setInfo(dstInfo)) {
return false;
}
@@ -763,6 +820,14 @@ static bool bitmapCopyTo(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src,
}
return true;
}
+ case kRGBA_F16_SkColorType: {
+ for (int y = 0; y < src.height(); y++) {
+ const uint8_t* srcRow = srcPixmap.addr8(0, y);
+ void* dstRow = dst->getAddr(0, y);
+ ToF16_SA8(dstRow, srcRow, src.width());
+ }
+ return true;
+ }
default:
return false;
}
@@ -1562,6 +1627,13 @@ static jobject Bitmap_createGraphicBufferHandle(JNIEnv* env, jobject, jlong bitm
return createJavaGraphicBuffer(env, buffer);
}
+static void Bitmap_copyColorSpace(JNIEnv* env, jobject, jlong srcBitmapPtr, jlong dstBitmapPtr) {
+ LocalScopedBitmap srcBitmapHandle(srcBitmapPtr);
+ LocalScopedBitmap dstBitmapHandle(dstBitmapPtr);
+
+ dstBitmapHandle->bitmap().setColorSpace(srcBitmapHandle->bitmap().info().refColorSpace());
+}
+
///////////////////////////////////////////////////////////////////////////////
static jclass make_globalref(JNIEnv* env, const char classname[])
{
@@ -1579,7 +1651,7 @@ static jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
}
static const JNINativeMethod gBitmapMethods[] = {
- { "nativeCreate", "([IIIIIIZ)Landroid/graphics/Bitmap;",
+ { "nativeCreate", "([IIIIIIZ[FLandroid/graphics/ColorSpace$Rgb$TransferParameters;)Landroid/graphics/Bitmap;",
(void*)Bitmap_creator },
{ "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;",
(void*)Bitmap_copy },
@@ -1628,10 +1700,21 @@ static const JNINativeMethod gBitmapMethods[] = {
(void*) Bitmap_createGraphicBufferHandle },
{ "nativeGetColorSpace", "(J[F[F)Z", (void*)Bitmap_getColorSpace },
{ "nativeIsSRGB", "(J)Z", (void*)Bitmap_isSRGB },
+ { "nativeCopyColorSpace", "(JJ)V",
+ (void*)Bitmap_copyColorSpace },
};
int register_android_graphics_Bitmap(JNIEnv* env)
{
+ jclass transfer_params_class = FindClassOrDie(env, "android/graphics/ColorSpace$Rgb$TransferParameters");
+ gTransferParams_aFieldID = GetFieldIDOrDie(env, transfer_params_class, "a", "D");
+ gTransferParams_bFieldID = GetFieldIDOrDie(env, transfer_params_class, "b", "D");
+ gTransferParams_cFieldID = GetFieldIDOrDie(env, transfer_params_class, "c", "D");
+ gTransferParams_dFieldID = GetFieldIDOrDie(env, transfer_params_class, "d", "D");
+ gTransferParams_eFieldID = GetFieldIDOrDie(env, transfer_params_class, "e", "D");
+ gTransferParams_fFieldID = GetFieldIDOrDie(env, transfer_params_class, "f", "D");
+ gTransferParams_gFieldID = GetFieldIDOrDie(env, transfer_params_class, "g", "D");
+
gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
gBitmap_nativePtr = getFieldIDCheck(env, gBitmap_class, "mNativePtr", "J");
gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(JIIIZZ[BLandroid/graphics/NinePatch$InsetStruct;)V");
diff --git a/core/res/res/layout/notification_template_material_ambient.xml b/core/res/res/layout/notification_template_material_ambient.xml
index 026bc6e5cb43..74f0e57c709b 100644
--- a/core/res/res/layout/notification_template_material_ambient.xml
+++ b/core/res/res/layout/notification_template_material_ambient.xml
@@ -33,6 +33,7 @@
android:layout_gravity="top"
android:layout_marginTop="@dimen/notification_content_margin_top"
android:layout_marginBottom="@dimen/notification_action_list_height"
+ android:paddingTop="10dp"
android:clipToPadding="false"
android:orientation="vertical">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ae28797c32aa..75de4dad3390 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4594,6 +4594,14 @@
<!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
by an autofill service, and the service does knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
<string name="autofill_save_title_with_type">Save <xliff:g id="type" example="Credit Card">%1$s</xliff:g> to <xliff:g id="label" example="MyPass">%2$s</xliff:g>?</string>
+ <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
+ by an autofill service, and the service does knows what the activity represents, and it represents 2 types of
+ data (for example, password and credit card info) [CHAR LIMIT=NONE] -->
+ <string name="autofill_save_title_with_2types">Save <xliff:g id="type" example="Password">%1$s</xliff:g>, <xliff:g id="type" example="Credit Card">%2$s</xliff:g> to <xliff:g id="label" example="MyPass">%3$s</xliff:g>?</string>
+ <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
+ by an autofill service, and the service does knows what the activity represents, and it represents 3 types of
+ data (for example, username, password and credit card info) [CHAR LIMIT=NONE] -->
+ <string name="autofill_save_title_with_3types">Save <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, <xliff:g id="type" example="Credit Card">%3$s</xliff:g> to <xliff:g id="label" example="MyPass">%4$s</xliff:g>?</string>
<!-- Label for the autofill save button [CHAR LIMIT=NONE] -->
<string name="autofill_save_yes">Save</string>
<!-- Label for the autofill cancel button [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 379c376bf2ff..7cb9ba8cd64b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2881,6 +2881,8 @@
<java-symbol type="string" name="autofill_picker_accessibility_title " />
<java-symbol type="string" name="autofill_save_title" />
<java-symbol type="string" name="autofill_save_title_with_type" />
+ <java-symbol type="string" name="autofill_save_title_with_2types" />
+ <java-symbol type="string" name="autofill_save_title_with_3types" />
<java-symbol type="string" name="autofill_save_yes" />
<java-symbol type="string" name="autofill_save_no" />
<java-symbol type="string" name="autofill_save_type_password" />
@@ -2961,5 +2963,8 @@
<java-symbol type="string" name="etws_primary_default_message_test" />
<java-symbol type="string" name="etws_primary_default_message_others" />
+
<java-symbol type="bool" name="config_quickSettingsSupported" />
+
+ <java-symbol type="style" name="Theme.DeviceDefault.QuickSettings" />
</resources>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index ed587bbaed24..919068500e6f 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -20,6 +20,7 @@ import android.annotation.CheckResult;
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.Size;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Trace;
@@ -78,8 +79,6 @@ public final class Bitmap implements Parcelable {
/** @hide */
public int mDensity = getDefaultDensity();
- private static volatile Matrix sScaleMatrix;
-
private static volatile int sDefaultDensity = -1;
/**
@@ -606,7 +605,7 @@ public final class Bitmap implements Parcelable {
* setting the new bitmap's config to the one specified, and then copying
* this bitmap's pixels into the new bitmap. If the conversion is not
* supported, or the allocator fails, then this returns NULL. The returned
- * bitmap initially has the same density as the original.
+ * bitmap has the same density and color space as the original.
*
* @param config The desired config for the resulting bitmap
* @param isMutable True if the resulting bitmap should be mutable (i.e.
@@ -629,7 +628,8 @@ public final class Bitmap implements Parcelable {
/**
* Creates a new immutable bitmap backed by ashmem which can efficiently
- * be passed between processes.
+ * be passed between processes. The bitmap is assumed to be in the sRGB
+ * color space.
*
* @hide
*/
@@ -645,7 +645,8 @@ public final class Bitmap implements Parcelable {
/**
* Creates a new immutable bitmap backed by ashmem which can efficiently
- * be passed between processes.
+ * be passed between processes. The bitmap is assumed to be in the sRGB
+ * color space.
*
* @hide
*/
@@ -666,7 +667,7 @@ public final class Bitmap implements Parcelable {
* currently PIXEL_FORMAT_RGBA_8888 is the only supported format
* @hide
*/
- public static Bitmap createHardwareBitmap(GraphicBuffer graphicBuffer) {
+ public static Bitmap createHardwareBitmap(@NonNull GraphicBuffer graphicBuffer) {
return nativeCreateHardwareBitmap(graphicBuffer);
}
@@ -683,50 +684,34 @@ public final class Bitmap implements Parcelable {
* @return The new scaled bitmap or the source bitmap if no scaling is required.
* @throws IllegalArgumentException if width is <= 0, or height is <= 0
*/
- public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,
+ public static Bitmap createScaledBitmap(@NonNull Bitmap src, int dstWidth, int dstHeight,
boolean filter) {
- Matrix m;
- synchronized (Bitmap.class) {
- // small pool of just 1 matrix
- m = sScaleMatrix;
- sScaleMatrix = null;
- }
-
- if (m == null) {
- m = new Matrix();
- }
+ Matrix m = new Matrix();
final int width = src.getWidth();
final int height = src.getHeight();
- final float sx = dstWidth / (float)width;
- final float sy = dstHeight / (float)height;
- m.setScale(sx, sy);
- Bitmap b = Bitmap.createBitmap(src, 0, 0, width, height, m, filter);
-
- synchronized (Bitmap.class) {
- // do we need to check for null? why not just assign everytime?
- if (sScaleMatrix == null) {
- sScaleMatrix = m;
- }
+ if (width != dstWidth || height != dstHeight) {
+ final float sx = dstWidth / (float) width;
+ final float sy = dstHeight / (float) height;
+ m.setScale(sx, sy);
}
-
- return b;
+ return Bitmap.createBitmap(src, 0, 0, width, height, m, filter);
}
/**
* Returns an immutable bitmap from the source bitmap. The new bitmap may
* be the same object as source, or a copy may have been made. It is
- * initialized with the same density as the original bitmap.
+ * initialized with the same density and color space as the original bitmap.
*/
- public static Bitmap createBitmap(Bitmap src) {
+ public static Bitmap createBitmap(@NonNull Bitmap src) {
return createBitmap(src, 0, 0, src.getWidth(), src.getHeight());
}
/**
* Returns an immutable bitmap from the specified subset of the source
* bitmap. The new bitmap may be the same object as source, or a copy may
- * have been made. It is initialized with the same density as the original
- * bitmap.
+ * have been made. It is initialized with the same density and color space
+ * as the original bitmap.
*
* @param source The bitmap we are subsetting
* @param x The x coordinate of the first pixel in source
@@ -738,7 +723,7 @@ public final class Bitmap implements Parcelable {
* outside of the dimensions of the source bitmap, or width is <= 0,
* or height is <= 0
*/
- public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) {
+ public static Bitmap createBitmap(@NonNull Bitmap source, int x, int y, int width, int height) {
return createBitmap(source, x, y, width, height, null, false);
}
@@ -746,7 +731,8 @@ public final class Bitmap implements Parcelable {
* Returns an immutable bitmap from subset of the source bitmap,
* transformed by the optional matrix. The new bitmap may be the
* same object as source, or a copy may have been made. It is
- * initialized with the same density as the original bitmap.
+ * initialized with the same density and color space as the original
+ * bitmap.
*
* If the source bitmap is immutable and the requested subset is the
* same as the source bitmap itself, then the source bitmap is
@@ -766,8 +752,8 @@ public final class Bitmap implements Parcelable {
* outside of the dimensions of the source bitmap, or width is <= 0,
* or height is <= 0
*/
- public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
- Matrix m, boolean filter) {
+ public static Bitmap createBitmap(@NonNull Bitmap source, int x, int y, int width, int height,
+ @Nullable Matrix m, boolean filter) {
checkXYSign(x, y);
checkWidthHeight(width, height);
@@ -847,6 +833,8 @@ public final class Bitmap implements Parcelable {
}
}
+ nativeCopyColorSpace(source.mNativePtr, bitmap.mNativePtr);
+
// The new bitmap was created from a known bitmap source so assume that
// they use the same density
bitmap.mDensity = source.mDensity;
@@ -866,7 +854,8 @@ public final class Bitmap implements Parcelable {
/**
* Returns a mutable bitmap with the specified width and height. Its
- * initial density is as per {@link #getDensity}.
+ * initial density is as per {@link #getDensity}. The newly created
+ * bitmap is in the {@link ColorSpace.Named#SRGB sRGB} color space.
*
* @param width The width of the bitmap
* @param height The height of the bitmap
@@ -874,13 +863,15 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0, or if
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
*/
- public static Bitmap createBitmap(int width, int height, Config config) {
+ public static Bitmap createBitmap(int width, int height, @NonNull Config config) {
return createBitmap(width, height, config, true);
}
/**
* Returns a mutable bitmap with the specified width and height. Its
* initial density is determined from the given {@link DisplayMetrics}.
+ * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
+ * color space.
*
* @param display Display metrics for the display this bitmap will be
* drawn on.
@@ -890,14 +881,15 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0, or if
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
*/
- public static Bitmap createBitmap(DisplayMetrics display, int width,
- int height, Config config) {
+ public static Bitmap createBitmap(@Nullable DisplayMetrics display, int width,
+ int height, @NonNull Config config) {
return createBitmap(display, width, height, config, true);
}
/**
* Returns a mutable bitmap with the specified width and height. Its
- * initial density is as per {@link #getDensity}.
+ * initial density is as per {@link #getDensity}. The newly created
+ * bitmap is in the {@link ColorSpace.Named#SRGB sRGB} color space.
*
* @param width The width of the bitmap
* @param height The height of the bitmap
@@ -909,13 +901,41 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0, or if
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
*/
- public static Bitmap createBitmap(int width, int height, Config config, boolean hasAlpha) {
+ public static Bitmap createBitmap(int width, int height,
+ @NonNull Config config, boolean hasAlpha) {
return createBitmap(null, width, height, config, hasAlpha);
}
/**
* Returns a mutable bitmap with the specified width and height. Its
+ * initial density is as per {@link #getDensity}.
+ *
+ * @param width The width of the bitmap
+ * @param height The height of the bitmap
+ * @param config The bitmap config to create.
+ * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
+ * mark the bitmap as opaque. Doing so will clear the bitmap in black
+ * instead of transparent.
+ * @param colorSpace The color space of the bitmap. If null,
+ * {@link ColorSpace.Named#SRGB sRGB} is assumed. This argument is
+ * ignored if the config is not {@link Config#ARGB_8888}.
+ *
+ * @throws IllegalArgumentException if the width or height are <= 0, if
+ * Config is Config.HARDWARE (because hardware bitmaps are always
+ * immutable), if the specified color space is not {@link ColorSpace.Model#RGB RGB},
+ * or if the specified color space's transfer function is not an
+ * {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}
+ */
+ public static Bitmap createBitmap(int width, int height, @NonNull Config config,
+ boolean hasAlpha, @Nullable ColorSpace colorSpace) {
+ return createBitmap(null, width, height, config, hasAlpha, colorSpace);
+ }
+
+ /**
+ * Returns a mutable bitmap with the specified width and height. Its
* initial density is determined from the given {@link DisplayMetrics}.
+ * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
+ * color space.
*
* @param display Display metrics for the display this bitmap will be
* drawn on.
@@ -929,15 +949,63 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0, or if
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
*/
- public static Bitmap createBitmap(DisplayMetrics display, int width, int height,
- Config config, boolean hasAlpha) {
+ public static Bitmap createBitmap(@Nullable DisplayMetrics display, int width, int height,
+ @NonNull Config config, boolean hasAlpha) {
+ return createBitmap(display, width, height, config, hasAlpha, null);
+ }
+
+ /**
+ * Returns a mutable bitmap with the specified width and height. Its
+ * initial density is determined from the given {@link DisplayMetrics}.
+ * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
+ * color space.
+ *
+ * @param display Display metrics for the display this bitmap will be
+ * drawn on.
+ * @param width The width of the bitmap
+ * @param height The height of the bitmap
+ * @param config The bitmap config to create.
+ * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
+ * mark the bitmap as opaque. Doing so will clear the bitmap in black
+ * instead of transparent.
+ * @param colorSpace The color space of the bitmap. If null,
+ * {@link ColorSpace.Named#SRGB sRGB} is assumed. This argument is
+ * ignored if the config is not {@link Config#ARGB_8888}.
+ *
+ * @throws IllegalArgumentException if the width or height are <= 0, if
+ * Config is Config.HARDWARE (because hardware bitmaps are always
+ * immutable), if the specified color space is not {@link ColorSpace.Model#RGB RGB},
+ * or if the specified color space's transfer function is not an
+ * {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}
+ */
+ public static Bitmap createBitmap(@Nullable DisplayMetrics display, int width, int height,
+ @NonNull Config config, boolean hasAlpha, @Nullable ColorSpace colorSpace) {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("width and height must be > 0");
}
if (config == Config.HARDWARE) {
throw new IllegalArgumentException("can't create mutable bitmap with Config.HARDWARE");
}
- Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true);
+
+ Bitmap bm;
+ if (colorSpace == null || config != Config.ARGB_8888) {
+ bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true, null, null);
+ } else {
+ if (!(colorSpace instanceof ColorSpace.Rgb)) {
+ throw new IllegalArgumentException("colorSpace must be an RGB color space");
+ }
+ ColorSpace.Rgb rgb = (ColorSpace.Rgb) colorSpace;
+ ColorSpace.Rgb.TransferParameters parameters = rgb.getTransferParameters();
+ if (parameters == null) {
+ throw new IllegalArgumentException("colorSpace must use an ICC "
+ + "parametric transfer function");
+ }
+
+ ColorSpace.Rgb d50 = (ColorSpace.Rgb) ColorSpace.adapt(rgb, ColorSpace.ILLUMINANT_D50);
+ bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true,
+ d50.getTransform(), parameters);
+ }
+
if (display != null) {
bm.mDensity = display.densityDpi;
}
@@ -954,9 +1022,10 @@ public final class Bitmap implements Parcelable {
/**
* Returns a immutable bitmap with the specified width and height, with each
* pixel value set to the corresponding value in the colors array. Its
- * initial density is as per {@link #getDensity}.
+ * initial density is as per {@link #getDensity}. The newly created
+ * bitmap is in the {@link ColorSpace.Named#SRGB sRGB} color space.
*
- * @param colors Array of {@link Color} used to initialize the pixels.
+ * @param colors Array of sRGB {@link Color colors} used to initialize the pixels.
* @param offset Number of values to skip before the first color in the
* array of colors.
* @param stride Number of colors in the array between rows (must be >=
@@ -969,8 +1038,8 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0, or if
* the color array's length is less than the number of pixels.
*/
- public static Bitmap createBitmap(int colors[], int offset, int stride,
- int width, int height, Config config) {
+ public static Bitmap createBitmap(@NonNull @ColorInt int[] colors, int offset, int stride,
+ int width, int height, @NonNull Config config) {
return createBitmap(null, colors, offset, stride, width, height, config);
}
@@ -978,10 +1047,12 @@ public final class Bitmap implements Parcelable {
* Returns a immutable bitmap with the specified width and height, with each
* pixel value set to the corresponding value in the colors array. Its
* initial density is determined from the given {@link DisplayMetrics}.
+ * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
+ * color space.
*
* @param display Display metrics for the display this bitmap will be
* drawn on.
- * @param colors Array of {@link Color} used to initialize the pixels.
+ * @param colors Array of sRGB {@link Color colors} used to initialize the pixels.
* @param offset Number of values to skip before the first color in the
* array of colors.
* @param stride Number of colors in the array between rows (must be >=
@@ -994,8 +1065,9 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0, or if
* the color array's length is less than the number of pixels.
*/
- public static Bitmap createBitmap(DisplayMetrics display, int colors[],
- int offset, int stride, int width, int height, Config config) {
+ public static Bitmap createBitmap(@NonNull DisplayMetrics display,
+ @NonNull @ColorInt int[] colors, int offset, int stride,
+ int width, int height, @NonNull Config config) {
checkWidthHeight(width, height);
if (Math.abs(stride) < width) {
@@ -1011,7 +1083,7 @@ public final class Bitmap implements Parcelable {
throw new IllegalArgumentException("width and height must be > 0");
}
Bitmap bm = nativeCreate(colors, offset, stride, width, height,
- config.nativeInt, false);
+ config.nativeInt, false, null, null);
if (display != null) {
bm.mDensity = display.densityDpi;
}
@@ -1021,9 +1093,10 @@ public final class Bitmap implements Parcelable {
/**
* Returns a immutable bitmap with the specified width and height, with each
* pixel value set to the corresponding value in the colors array. Its
- * initial density is as per {@link #getDensity}.
+ * initial density is as per {@link #getDensity}. The newly created
+ * bitmap is in the {@link ColorSpace.Named#SRGB sRGB} color space.
*
- * @param colors Array of {@link Color} used to initialize the pixels.
+ * @param colors Array of sRGB {@link Color colors} used to initialize the pixels.
* This array must be at least as large as width * height.
* @param width The width of the bitmap
* @param height The height of the bitmap
@@ -1033,7 +1106,8 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0, or if
* the color array's length is less than the number of pixels.
*/
- public static Bitmap createBitmap(int colors[], int width, int height, Config config) {
+ public static Bitmap createBitmap(@NonNull @ColorInt int[] colors,
+ int width, int height, Config config) {
return createBitmap(null, colors, 0, width, width, height, config);
}
@@ -1041,10 +1115,12 @@ public final class Bitmap implements Parcelable {
* Returns a immutable bitmap with the specified width and height, with each
* pixel value set to the corresponding value in the colors array. Its
* initial density is determined from the given {@link DisplayMetrics}.
+ * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
+ * color space.
*
* @param display Display metrics for the display this bitmap will be
* drawn on.
- * @param colors Array of {@link Color} used to initialize the pixels.
+ * @param colors Array of sRGB {@link Color colors} used to initialize the pixels.
* This array must be at least as large as width * height.
* @param width The width of the bitmap
* @param height The height of the bitmap
@@ -1054,8 +1130,8 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0, or if
* the color array's length is less than the number of pixels.
*/
- public static Bitmap createBitmap(DisplayMetrics display, int colors[],
- int width, int height, Config config) {
+ public static Bitmap createBitmap(@Nullable DisplayMetrics display,
+ @NonNull @ColorInt int colors[], int width, int height, @NonNull Config config) {
return createBitmap(display, colors, 0, width, width, height, config);
}
@@ -1806,7 +1882,9 @@ public final class Bitmap implements Parcelable {
private static native Bitmap nativeCreate(int[] colors, int offset,
int stride, int width, int height,
- int nativeConfig, boolean mutable);
+ int nativeConfig, boolean mutable,
+ @Nullable @Size(9) float[] xyzD50,
+ @Nullable ColorSpace.Rgb.TransferParameters p);
private static native Bitmap nativeCopy(long nativeSrcBitmap, int nativeConfig,
boolean isMutable);
private static native Bitmap nativeCopyAshmem(long nativeSrcBitmap);
@@ -1865,4 +1943,5 @@ public final class Bitmap implements Parcelable {
private static native GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap);
private static native boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params);
private static native boolean nativeIsSRGB(long nativePtr);
+ private static native void nativeCopyColorSpace(long srcBitmap, long dstBitmap);
}
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 13d7e09b6e79..9f649ead2b52 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -58,8 +58,10 @@ SkiaCanvas::SkiaCanvas(SkCanvas* canvas, XformToSRGB xformToSRGB)
}
SkiaCanvas::SkiaCanvas(const SkBitmap& bitmap) {
+ sk_sp<SkColorSpace> cs = bitmap.refColorSpace();
mCanvasOwned = std::unique_ptr<SkCanvas>(new SkCanvas(bitmap));
- mCanvasWrapper = SkCreateColorSpaceXformCanvas(mCanvasOwned.get(), SkColorSpace::MakeSRGB());
+ mCanvasWrapper = SkCreateColorSpaceXformCanvas(mCanvasOwned.get(),
+ cs == nullptr ? SkColorSpace::MakeSRGB() : std::move(cs));
mCanvas = mCanvasWrapper.get();
}
@@ -97,9 +99,10 @@ private:
};
void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
+ sk_sp<SkColorSpace> cs = bitmap.refColorSpace();
std::unique_ptr<SkCanvas> newCanvas = std::unique_ptr<SkCanvas>(new SkCanvas(bitmap));
- std::unique_ptr<SkCanvas> newCanvasWrapper =
- SkCreateColorSpaceXformCanvas(newCanvas.get(), SkColorSpace::MakeSRGB());
+ std::unique_ptr<SkCanvas> newCanvasWrapper = SkCreateColorSpaceXformCanvas(newCanvas.get(),
+ cs == nullptr ? SkColorSpace::MakeSRGB() : std::move(cs));
if (!bitmap.isNull()) {
// Copy the canvas matrix & clip state.
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 729c7b8a1ecb..d7f75fc7fd65 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -322,6 +322,12 @@ sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer) {
return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info));
}
+void Bitmap::setColorSpace(sk_sp<SkColorSpace> colorSpace) {
+ // TODO: See todo in reconfigure() below
+ SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
+ *myInfo = info().makeColorSpace(std::move(colorSpace));
+}
+
void Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
if (kIndex_8_SkColorType != newInfo.colorType()) {
ctable = nullptr;
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 518be032c0eb..da45f7697f56 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -16,6 +16,7 @@
#pragma once
#include <SkBitmap.h>
+#include <SkColorSpace.h>
#include <SkColorTable.h>
#include <SkImageInfo.h>
#include <SkPixelRef.h>
@@ -82,6 +83,7 @@ public:
void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
void reconfigure(const SkImageInfo& info);
+ void setColorSpace(sk_sp<SkColorSpace> colorSpace);
void setAlphaType(SkAlphaType alphaType);
void getSkBitmap(SkBitmap* outBitmap);
diff --git a/media/java/android/media/BufferingParams.java b/media/java/android/media/BufferingParams.java
index fdcd6baa7d18..681271b1a6f0 100644
--- a/media/java/android/media/BufferingParams.java
+++ b/media/java/android/media/BufferingParams.java
@@ -63,6 +63,7 @@ import java.lang.annotation.RetentionPolicy;
* </ul>
* </ul>
* <p>Users should use {@link Builder} to change {@link BufferingParams}.
+ * @hide
*/
public final class BufferingParams implements Parcelable {
/**
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 1ee05b8c3a9a..71a968b4d4b5 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -46,7 +46,6 @@ import android.view.SurfaceHolder;
import android.widget.VideoView;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
-import android.media.BufferingParams;
import android.media.MediaDrm;
import android.media.MediaFormat;
import android.media.MediaMetricsSet;
@@ -493,11 +492,6 @@ import java.util.Vector;
* <td>{} </p></td>
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
- * <tr><td>setBufferingParams</p></td>
- * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error}</p></td>
- * <td>{Idle} </p></td>
- * <td>This method does not change the object state.
- * </p></td></tr>
* <tr><td>setPlaybackParams</p></td>
* <td>{Initialized, Prepared, Started, Paused, PlaybackCompleted, Error}</p></td>
* <td>{Idle, Stopped} </p></td>
@@ -1529,6 +1523,7 @@ public class MediaPlayer extends PlayerBase
* @return the default buffering management params supported by the source component.
* @throws IllegalStateException if the internal player engine has not been
* initialized, or {@code setDataSource} has not been called.
+ * @hide
*/
@NonNull
public native BufferingParams getDefaultBufferingParams();
@@ -1540,6 +1535,7 @@ public class MediaPlayer extends PlayerBase
* @return the current buffering management params used by the source component.
* @throws IllegalStateException if the internal player engine has not been
* initialized, or {@code setDataSource} has not been called.
+ * @hide
*/
@NonNull
public native BufferingParams getBufferingParams();
@@ -1557,6 +1553,7 @@ public class MediaPlayer extends PlayerBase
* @throws IllegalStateException if the internal player engine has not been
* initialized or has been released, or {@code setDataSource} has not been called.
* @throws IllegalArgumentException if params is invalid or not supported.
+ * @hide
*/
public native void setBufferingParams(@NonNull BufferingParams params);
@@ -3825,6 +3822,18 @@ public class MediaPlayer extends PlayerBase
*/
public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
+ /** Informs that audio is not playing. Note that playback of the video
+ * is not interrupted.
+ * @see android.media.MediaPlayer.OnInfoListener
+ */
+ public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804;
+
+ /** Informs that video is not playing. Note that playback of the audio
+ * is not interrupted.
+ * @see android.media.MediaPlayer.OnInfoListener
+ */
+ public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805;
+
/** Failed to handle timed text track properly.
* @see android.media.MediaPlayer.OnInfoListener
*
diff --git a/packages/CarrierDefaultApp/res/values-af/strings.xml b/packages/CarrierDefaultApp/res/values-af/strings.xml
index 7747dad3b384..8cff2faefe8a 100644
--- a/packages/CarrierDefaultApp/res/values-af/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-af/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Jou mobiele data is gedeaktiveer"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tik om die %s-webwerf te besoek"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Kontak asseblief jou diensverskaffer %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status van mobiele data"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Meld by mobiele netwerk aan"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Die netwerk waarby jy probeer aansluit, het sekuriteitkwessies."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Byvoorbeeld, die aanmeldbladsy behoort dalk nie aan die organisasie wat gewys word nie."</string>
diff --git a/packages/CarrierDefaultApp/res/values-am/strings.xml b/packages/CarrierDefaultApp/res/values-am/strings.xml
index 1f0624801ecd..8326b4c9b944 100644
--- a/packages/CarrierDefaultApp/res/values-am/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-am/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"የእርስዎ የተንቀሳቃሽ ስልክ ውሂብ ቦዝኗል"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"የ%s ድር-ጣቢያን ለመጎብኘት መታ ያድርጉ"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"እባክዎ የአገልግሎት አቅራቢዎን %s ያነጋግሩ"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"የተንቀሳቃሽ ስልክ ውሂብ ሁኔታ"</string>
<string name="action_bar_label" msgid="4290345990334377177">"ወደ የተንቀሳቃሽ ስልክ አውታረ መረብ ይግቡ"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"ለመቀላቀል እየሞከሩ ያሉት አውታረ መረብ የደህንነት ችግሮች አሉበት።"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ለምሳሌ፣ የመግቢያ ገጹ የሚታየው ድርጅት ላይሆን ይችላል።"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ar/strings.xml b/packages/CarrierDefaultApp/res/values-ar/strings.xml
index 7041cd6873ea..4257a3172d41 100644
--- a/packages/CarrierDefaultApp/res/values-ar/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ar/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"تم إلغاء تنشيط بيانات الجوال"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"‏النقر للانتقال إلى موقع %s الإلكتروني"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"‏يُرجى الاتصال بمقدم الخدمة %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"حالة بيانات الجوّال"</string>
<string name="action_bar_label" msgid="4290345990334377177">"تسجيل الدخول إلى شبكة الجوّال"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"الشبكة التي تحاول الانضمام إليها بها مشكلات أمنية."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"على سبيل المثال، قد لا تنتمي صفحة تسجيل الدخول إلى المؤسسة المعروضة."</string>
diff --git a/packages/CarrierDefaultApp/res/values-az/strings.xml b/packages/CarrierDefaultApp/res/values-az/strings.xml
index 2b7f82d03d58..911bb77b783f 100644
--- a/packages/CarrierDefaultApp/res/values-az/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-az/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobil data deaktiv edilib"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s veb saytına daxil olmaq üçün klikləyin"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Xidmət provayderi ilə əlaqə saxlayın %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobil data statusu"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Mobil şəbəkəyə daxil olun"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Qoşulmaq istədiyiniz şəbəkənin təhlükəsizlik problemləri var."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Məsələn, giriş səhifəsi göstərilən təşkilata aid olmaya bilər."</string>
diff --git a/packages/CarrierDefaultApp/res/values-bg/strings.xml b/packages/CarrierDefaultApp/res/values-bg/strings.xml
index 6e2f03e2f1e2..5f6f818b55bb 100644
--- a/packages/CarrierDefaultApp/res/values-bg/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bg/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилните ви данни са деактивирани"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Докоснете, за да посетите уебсайта на %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Моля, свържете се с доставчика си на услуги %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Състояние на мобилните данни"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Вход в мобилна мрежа"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Мрежата, към която опитвате да се присъедините, има проблеми със сигурността."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Например страницата за вход може да не принадлежи на показаната организация."</string>
diff --git a/packages/CarrierDefaultApp/res/values-bn/strings.xml b/packages/CarrierDefaultApp/res/values-bn/strings.xml
index 3f02b2e4a5bb..5d6f07793d35 100644
--- a/packages/CarrierDefaultApp/res/values-bn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bn/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"আপনার মোবাইল ডেটা নিষ্ক্রিয় করা হয়েছে"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s এর ওয়েবসাইটটি দেখার জন্য ট্যাপ করুন"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"অনুগ্রহ করে আপনার পরিষেবা প্রদানকারী %s এর সাথে যোগাযোগ করুন"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"মোবাইল ডেটার স্ট্যাটাস"</string>
<string name="action_bar_label" msgid="4290345990334377177">"মোবাইল নেটওয়ার্কে প্রবেশ করুন"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন সেটিতে নিরাপত্তাজনিত সমস্যা আছে।"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"যেমন, লগইন পৃষ্ঠাটি যে প্রতিষ্ঠানের পৃষ্ঠা বলে দেখানো আছে, আসলে তা নাও হতে পারে৷"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ca/strings.xml b/packages/CarrierDefaultApp/res/values-ca/strings.xml
index ff560745c8f6..4f1245c6e62c 100644
--- a/packages/CarrierDefaultApp/res/values-ca/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ca/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"S\'han desactivat les dades mòbils"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Toca per visitar el lloc web de: %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Contacta amb el teu proveïdor de serveis: %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estat de les dades mòbils"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Inicia la sessió a la xarxa de telefonia mòbil"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"La xarxa a què et vols connectar té problemes de seguretat."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string>
diff --git a/packages/CarrierDefaultApp/res/values-cs/strings.xml b/packages/CarrierDefaultApp/res/values-cs/strings.xml
index bca0efd8e4c6..a3ad316bde87 100644
--- a/packages/CarrierDefaultApp/res/values-cs/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-cs/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilní data byla deaktivována"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Klepnutím přejdete na web %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Kontaktujte poskytovatele služeb %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stav mobilních dat"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Přihlásit se k mobilní síti"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Síť, ke které se pokoušíte připojit, má bezpečnostní problémy."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Přihlašovací stránka například nemusí patřit zobrazované organizaci."</string>
diff --git a/packages/CarrierDefaultApp/res/values-da/strings.xml b/packages/CarrierDefaultApp/res/values-da/strings.xml
index 7152c47ee412..8d831d5ee7d5 100644
--- a/packages/CarrierDefaultApp/res/values-da/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-da/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobildata er blevet deaktiveret"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tryk for at besøge websitet for %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Kontakt din tjenesteudbyder %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status for mobildata"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Log ind på mobilnetværk"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Der er sikkerhedsproblemer på det netværk, du forsøger at logge ind på."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Det er f.eks. ikke sikkert, at loginsiden tilhører den anførte organisation."</string>
diff --git a/packages/CarrierDefaultApp/res/values-de/strings.xml b/packages/CarrierDefaultApp/res/values-de/strings.xml
index 0d5f65922d8c..8b8ca3f7667d 100644
--- a/packages/CarrierDefaultApp/res/values-de/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-de/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Deine mobilen Daten wurden deaktiviert"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tippe, um die Website \"%s\" zu besuchen"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Bitte wende dich an deinen Internetanbieter %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status der mobilen Datennutzung"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Bei Mobilfunknetz anmelden"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Im Netzwerk, zu dem du eine Verbindung herstellen möchtest, liegen Sicherheitsprobleme vor."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Beispiel: Die Log-in-Seite gehört möglicherweise nicht zur angezeigten Organisation."</string>
diff --git a/packages/CarrierDefaultApp/res/values-el/strings.xml b/packages/CarrierDefaultApp/res/values-el/strings.xml
index 53d2dbc3f77f..064941e557b8 100644
--- a/packages/CarrierDefaultApp/res/values-el/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-el/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Τα δεδομένα κινητής τηλεφωνίας έχουν απενεργοποιηθεί"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Πατήστε για να επισκεφτείτε τον ιστότοπο %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Επικοινωνήστε με τον παροχέα υπηρεσιών σας %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Κατάσταση δεδομένων κινητής τηλεφωνίας"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Σύνδεση σε δίκτυο κινητής τηλεφωνίας"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Παρουσιάζονται προβλήματα ασφάλειας στο δίκτυο στο οποίο προσπαθείτε να συνδεθείτε."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Για παράδειγμα, η σελίδα σύνδεσης ενδέχεται να μην ανήκει στον οργανισμό που εμφανίζεται."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml b/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
index b4732bfa79b9..666c67590908 100644
--- a/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tap to visit the %s website"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Please contact your service provider %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobile data status"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Sign in to mobile network"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"The network that you’re trying to join has security issues."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml b/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
index b4732bfa79b9..666c67590908 100644
--- a/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tap to visit the %s website"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Please contact your service provider %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobile data status"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Sign in to mobile network"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"The network that you’re trying to join has security issues."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml b/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
index b4732bfa79b9..666c67590908 100644
--- a/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tap to visit the %s website"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Please contact your service provider %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobile data status"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Sign in to mobile network"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"The network that you’re trying to join has security issues."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
diff --git a/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml b/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
index 24d1d0dfe06e..041421c9d46a 100644
--- a/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Se desactivaron los datos móviles"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Presiona para visitar el sitio web de %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Comunícate con tu proveedor de servicios %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estado de datos móviles"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Acceder a una red móvil"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"La red a la que intentas conectarte tiene problemas de seguridad."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Por ejemplo, es posible que la página de acceso no pertenezca a la organización que aparece."</string>
diff --git a/packages/CarrierDefaultApp/res/values-es/strings.xml b/packages/CarrierDefaultApp/res/values-es/strings.xml
index e24b2a25c49d..7a0623f9bcc9 100644
--- a/packages/CarrierDefaultApp/res/values-es/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-es/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Se han desactivado los datos móviles"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Toca para acceder al sitio web de %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Ponte en contacto con tu proveedor de servicios (%s)"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estado de la conexión de datos móviles"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Iniciar sesión en una red móvil"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"La red a la que intentas unirte tiene problemas de seguridad."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Por ejemplo, es posible que la página de inicio de sesión no pertenezca a la organización mostrada."</string>
diff --git a/packages/CarrierDefaultApp/res/values-et/strings.xml b/packages/CarrierDefaultApp/res/values-et/strings.xml
index 1cc81bc1d014..1404c86922f3 100644
--- a/packages/CarrierDefaultApp/res/values-et/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-et/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Teie mobiilne andmeside on inaktiveeritud"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Puudutage teenuse %s veebisaidi külastamiseks"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Võtke ühendust teenusepakkujaga %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobiilse andmeside olek"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Logi mobiilsidevõrku sisse"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Võrgul, millega üritate ühenduse luua, on turvaprobleeme."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Näiteks ei pruugi sisselogimisleht kuuluda kuvatavale organisatsioonile."</string>
diff --git a/packages/CarrierDefaultApp/res/values-eu/strings.xml b/packages/CarrierDefaultApp/res/values-eu/strings.xml
index 416667e5afa0..63005ca55ade 100644
--- a/packages/CarrierDefaultApp/res/values-eu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-eu/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Desaktibatu da datu-konexioa"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Sakatu hau %s gunera joateko"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Jarri harremanetan %s operadorearekin"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Datu mugikorren egoera"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Hasi saioa sare mugikorrean"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Erabili nahi duzun sareak segurtasun-arazoak ditu."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml
index a65f68beb754..9e13ef661dde 100644
--- a/packages/CarrierDefaultApp/res/values-fa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml
@@ -9,6 +9,7 @@
<!-- String.format failed for translation -->
<!-- no translation found for no_data_notification_detail (3112125343857014825) -->
<skip />
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"وضعیت داده تلفن همراه"</string>
<string name="action_bar_label" msgid="4290345990334377177">"ورود به سیستم شبکه تلفن همراه"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"شبکه‌ای که می‌خواهید به آن بپیوندید مشکلات امنیتی دارد."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"به عنوان مثال، صفحه ورود به سیستم ممکن است متعلق به سازمان نشان داده شده نباشد."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fi/strings.xml b/packages/CarrierDefaultApp/res/values-fi/strings.xml
index 5512557d99dd..ddf3a14a624d 100644
--- a/packages/CarrierDefaultApp/res/values-fi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fi/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobiilidata poistettu käytöstä"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Siirry sivustolle %s napauttamalla."</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Ota yhteyttä palveluntarjoajaan %s."</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobiilidatan tila"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Kirjaudu mobiiliverkkoon"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Verkossa, johon yrität muodostaa yhteyttä, havaittiin turvallisuusongelmia."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Kirjautumissivu ei välttämättä kuulu näytetylle organisaatiolle."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
index 62648628e4b0..3e4802a4cf41 100644
--- a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Les données cellulaires ont été désactivées pour votre compte"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Touchez ici pour visiter le site Web de %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Veuillez communiquer avec votre fournisseur de services %s."</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"État des données cellulaires"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Connexion au réseau cellulaire"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Le réseau que vous essayez de joindre présente des problèmes de sécurité."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Par exemple, la page de connexion pourrait ne pas appartenir à l\'organisation représentée."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr/strings.xml b/packages/CarrierDefaultApp/res/values-fr/strings.xml
index 25d709e14645..804c400afed3 100644
--- a/packages/CarrierDefaultApp/res/values-fr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Les données mobiles ont été désactivées pour votre compte"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Appuyez ici pour consulter le site Web suivant : %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Veuillez contacter votre fournisseur de services, %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"État des données mobiles"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Se connecter au réseau mobile"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Le réseau auquel vous essayez de vous connecter présente des problèmes de sécurité."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Par exemple, la page de connexion peut ne pas appartenir à l\'organisation représentée."</string>
diff --git a/packages/CarrierDefaultApp/res/values-gl/strings.xml b/packages/CarrierDefaultApp/res/values-gl/strings.xml
index 478f4b0d0496..91c3073dc549 100644
--- a/packages/CarrierDefaultApp/res/values-gl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-gl/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Desactiváronse os datos móbiles"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Toca para acceder ao sitio web de %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Ponte en contacto co teu fornecedor de servizo %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estado dos datos móbiles"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Iniciar sesión na rede de telefonía móbil"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"A rede á que tentas unirte ten problemas de seguranza."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, é posible que a páxina de inicio de sesión non pertenza á organización que se mostra."</string>
diff --git a/packages/CarrierDefaultApp/res/values-gu/strings.xml b/packages/CarrierDefaultApp/res/values-gu/strings.xml
index 5c1792efc4d9..0d1981169d0e 100644
--- a/packages/CarrierDefaultApp/res/values-gu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-gu/strings.xml
@@ -7,6 +7,8 @@
<string name="no_data_notification_id" msgid="668400731803969521">"તમારો મોબાઇલ ડેટા નિષ્ક્રિય કરવામાં આવ્યો છે"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s વેબસાઇટની મુલાકાત લેવા માટે ટૅપ કરો"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"કૃપા કરીને તમારા સેવા પ્રદાતા %sનો સંપર્ક કરો"</string>
+ <!-- no translation found for mobile_data_status_notification_channel_name (833999690121305708) -->
+ <skip />
<string name="action_bar_label" msgid="4290345990334377177">"મોબાઇલ નેટવર્કમાં સાઇન ઇન કરો"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"તમે જોડાવાનો પ્રયાસ કરી રહ્યા છો તે નેટવર્કમાં સુરક્ષા સંબંધી સમસ્યાઓ છે."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ઉદાહરણ તરીકે, લોગિન પૃષ્ઠ બતાવવામાં આવેલી સંસ્થાનું ન પણ હોય."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hi/strings.xml b/packages/CarrierDefaultApp/res/values-hi/strings.xml
index 4eb5e7aa9fd5..0ca7980d9417 100644
--- a/packages/CarrierDefaultApp/res/values-hi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hi/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"आपका मोबाइल डेटा निष्क्रिय कर दिया गया है"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s वेबसाइट पर जाने के लिए टैप करें"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"कृपया अपने सेवा प्रदाता %s से संपर्क करें"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"मोबाइल डेटा की स्थिति"</string>
<string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्क में प्रवेश करें"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"आप जिस नेटवर्क में शामिल होने की कोशिश कर रहे हैं उसमें सुरक्षा से जुड़ी समस्‍याएं हैं."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरण के लिए, हो सकता है कि लॉगिन पेज दिखाए गए संगठन का ना हो."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hr/strings.xml b/packages/CarrierDefaultApp/res/values-hr/strings.xml
index 41e7c39c3383..0f91cda4077f 100644
--- a/packages/CarrierDefaultApp/res/values-hr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hr/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilni su podaci deaktivirani"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da biste posjetili web-lokaciju tvrtke %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Obratite se svojem davatelju usluga %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status mobilnih podataka"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Prijava na mobilnu mrežu"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj se pokušavate pridružiti ima sigurnosne poteškoće."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Na primjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hu/strings.xml b/packages/CarrierDefaultApp/res/values-hu/strings.xml
index 44648903f89c..0afaefff9a81 100644
--- a/packages/CarrierDefaultApp/res/values-hu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hu/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"A rendszer deaktiválta a mobiladat-forgalmat"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Koppintson a(z) %s webhely meglátogatásához"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Vegye fel a kapcsolatot szolgáltatójával (%s)"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobiladat-állapot"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Bejelentkezés a mobilhálózatra"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Biztonsági problémák vannak azzal a hálózattal, amelyhez csatlakozni szeretne."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Például lehetséges, hogy a bejelentkezési oldal nem a megjelenített szervezethez tartozik."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hy/strings.xml b/packages/CarrierDefaultApp/res/values-hy/strings.xml
index 4ed3e6e014cf..d88e0df4f5f2 100644
--- a/packages/CarrierDefaultApp/res/values-hy/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hy/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Ձեր բջջային ինտերնետն ապակտիվացված է"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Հպեք՝ %s կայք այցելելու համար"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Դիմեք ձեր ծառայություններ մատուցողին %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Բջջային ինտերնետի կարգավիճակը"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Մուտք գործել բջջային ցանց"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Ցանցը, որին փորձում եք միանալ, անվտանգության խնդիրներ ունի:"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Օրինակ՝ մուտքի էջը կարող է ցուցադրված կազմակերպության էջը չլինել:"</string>
diff --git a/packages/CarrierDefaultApp/res/values-in/strings.xml b/packages/CarrierDefaultApp/res/values-in/strings.xml
index 116bb2f4f115..915933b77320 100644
--- a/packages/CarrierDefaultApp/res/values-in/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-in/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Data seluler telah dinonaktifkan"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tap untuk membuka situs web %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Hubungi penyedia layanan %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status data seluler"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Login ke jaringan seluler"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Jaringan yang ingin Anda masuki memiliki masalah keamanan."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Misalnya, halaman login mungkin bukan milik organisasi yang ditampilkan."</string>
diff --git a/packages/CarrierDefaultApp/res/values-is/strings.xml b/packages/CarrierDefaultApp/res/values-is/strings.xml
index b4460f0e0d48..8a74446fe897 100644
--- a/packages/CarrierDefaultApp/res/values-is/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-is/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Slökkt hefur verið á farsímagögnum"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Ýttu til að fara á vefsvæði %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Hafðu samband við þjónustuaðilann %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Staða farsímagagna"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Skrá inn á farsímakerfi"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Öryggisvandamál eru á netinu sem þú ert að reyna að tengjast."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Til dæmis getur verið að innskráningarsíðan tilheyri ekki fyrirtækinu sem birtist."</string>
diff --git a/packages/CarrierDefaultApp/res/values-it/strings.xml b/packages/CarrierDefaultApp/res/values-it/strings.xml
index a834f3dc7bc3..a6e004f913a8 100644
--- a/packages/CarrierDefaultApp/res/values-it/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-it/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"I dati mobili sono stati disattivati"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tocca per visitare il sito web %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Contatta il tuo operatore telefonico %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stato dati mobili"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Accedi alla rete mobile"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"La rete a cui stai tentando di accedere presenta problemi di sicurezza."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Ad esempio, la pagina di accesso potrebbe non appartenere all\'organizzazione indicata."</string>
diff --git a/packages/CarrierDefaultApp/res/values-iw/strings.xml b/packages/CarrierDefaultApp/res/values-iw/strings.xml
index 2fb986ad9640..e220b692a087 100644
--- a/packages/CarrierDefaultApp/res/values-iw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-iw/strings.xml
@@ -7,6 +7,8 @@
<string name="no_data_notification_id" msgid="668400731803969521">"חבילת הגלישה שלך הושבתה"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"‏הקש כדי לעבור לאתר של %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"‏פנה לספק השירות %s"</string>
+ <!-- no translation found for mobile_data_status_notification_channel_name (833999690121305708) -->
+ <skip />
<string name="action_bar_label" msgid="4290345990334377177">"היכנס לרשת סלולרית"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"יש בעיות אבטחה ברשת שאליה אתה מנסה להתחבר."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"לדוגמה, ייתכן שדף ההתחברות אינו שייך לארגון המוצג."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ja/strings.xml b/packages/CarrierDefaultApp/res/values-ja/strings.xml
index 893b46d58bb1..8e046cbafac6 100644
--- a/packages/CarrierDefaultApp/res/values-ja/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ja/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"モバイルデータが無効になっています"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"タップして %s のウェブサイトにアクセス"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"ご利用のサービス プロバイダ %s にお問い合わせください"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"モバイルデータのステータス"</string>
<string name="action_bar_label" msgid="4290345990334377177">"モバイル ネットワークにログイン"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"接続しようとしているネットワークにセキュリティの問題があります。"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"たとえば、ログインページが表示されている組織に属していない可能性があります。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ka/strings.xml b/packages/CarrierDefaultApp/res/values-ka/strings.xml
index c96395ae0bd8..68c4490a0d96 100644
--- a/packages/CarrierDefaultApp/res/values-ka/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ka/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"მობილური ინტერნეტი დეაქტივირებულია"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"შეეხეთ, რათა ეწვიოთ ვებსაიტს: %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"გთხოვთ, დაუკავშირდეთ სერვისის პროვაიდერს (%s)"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"მობილური ინტერნეტის სტატუსი"</string>
<string name="action_bar_label" msgid="4290345990334377177">"მობილურ ქსელში შესვლა"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"ქსელს, რომელთან დაკავშრებასაც ცდილობთ, უსაფრთხოების პრობლემები აქვს."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"მაგალითად, სისტემაში შესვლის გვერდი შეიძლება არ ეკუთვნოდეს ნაჩვენებ ორგანიზაციას."</string>
diff --git a/packages/CarrierDefaultApp/res/values-kk/strings.xml b/packages/CarrierDefaultApp/res/values-kk/strings.xml
index c423eb356f0d..77555aa64b85 100644
--- a/packages/CarrierDefaultApp/res/values-kk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-kk/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Мобильдік деректер өшірілді"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s вебсайтына кіру үшін түртіңіз"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Қызмет көрсетушіге (%s) хабарласыңыз"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Мобильді деректер күйі"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Мобильдік желіге тіркелу"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Қосылайын деп жатқан желіңізде қауіпсіздік мәселелері бар."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Мысалы, кіру беті көрсетілген ұйымға тиесілі болмауы мүмкін."</string>
diff --git a/packages/CarrierDefaultApp/res/values-km/strings.xml b/packages/CarrierDefaultApp/res/values-km/strings.xml
index dac54224255a..30984cd0ac19 100644
--- a/packages/CarrierDefaultApp/res/values-km/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-km/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"ទិន្នន័យ​ចល័ត​របស់អ្នក​ត្រូវបាន​បិទដំណើរការហើយ"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"ចុច​ដើម្បី​ចូលទៅកាន់គេហទំព័រ %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"សូម​ទាក់ទង​ទៅ​ក្រុមហ៊ុន​ផ្តល់​សេវា​របស់​អ្នក %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ស្ថានភាព​ទិន្នន័យ​ទូរសព្ទ​ចល័ត"</string>
<string name="action_bar_label" msgid="4290345990334377177">"ចូលទៅបណ្តាញទូរសព្ទចល័ត"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"បណ្តាញដែលអ្នកកំពុងព្យាយាមចូលមានបញ្ហាសុវត្ថិភាព។"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ឧទាហរណ៍៖ ទំព័រចូលនេះអាចនឹងមិនមែនជាកម្មសិទ្ធិរបស់ស្ថាប័នដែលបានបង្ហាញនេះទេ។"</string>
diff --git a/packages/CarrierDefaultApp/res/values-kn/strings.xml b/packages/CarrierDefaultApp/res/values-kn/strings.xml
index 8295ce9440e2..ad83f3860064 100644
--- a/packages/CarrierDefaultApp/res/values-kn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-kn/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"ನಿಮ್ಮ ಮೊಬೈಲ್ ಡೇಟಾ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s ವೆಬ್‌ಸೈಟ್‌ಗೆ ಭೇಟಿ ನೀಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"ನಿಮಗೆ ಸೇವೆ ಒದಗಿಸುವವರನ್ನು ದಯವಿಟ್ಟು ಸಂಪರ್ಕಿಸಿ %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ಮೊಬೈಲ್ ಡೇಟಾ ಸ್ಥಿತಿ"</string>
<string name="action_bar_label" msgid="4290345990334377177">"ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"ನೀವು ಸೇರಬೇಕೆಂದಿರುವ ನೆಟ್‌ವರ್ಕ್, ಭದ್ರತೆ ಸಮಸ್ಯೆಗಳನ್ನು ಹೊಂದಿದೆ."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ಉದಾಹರಣೆಗೆ, ಲಾಗಿನ್ ಪುಟವು ತೋರಿಸಲಾಗಿರುವ ಸಂಸ್ಥೆಗೆ ಸಂಬಂಧಿಸಿಲ್ಲದಿರಬಹುದು."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ko/strings.xml b/packages/CarrierDefaultApp/res/values-ko/strings.xml
index 599ff75548bd..a620e1c46799 100644
--- a/packages/CarrierDefaultApp/res/values-ko/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ko/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"모바일 데이터가 비활성화되었습니다."</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s 웹사이트를 방문하려면 탭하세요."</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"서비스 제공업체 %s에 문의하세요."</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"모바일 데이터 상태"</string>
<string name="action_bar_label" msgid="4290345990334377177">"모바일 네트워크에 로그인"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"가입하려는 네트워크에 보안 문제가 있습니다."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"예를 들어 로그인 페이지가 표시된 조직에 속하지 않을 수 있습니다."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ky/strings.xml b/packages/CarrierDefaultApp/res/values-ky/strings.xml
index f647fc1a5d36..d638e60b2704 100644
--- a/packages/CarrierDefaultApp/res/values-ky/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ky/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилдик дайындарды колдонуу өчүрүлгөн"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s сайтына баш багуу үчүн басыңыз"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"%s Интернет провайдери менен байланышыңыз"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Мобилдик түзмөктүн статусу"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Мобилдик тармакка кирүү"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Кошулайын деген тармагыңызда коопсуздук көйгөйлөрү бар."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Мисалы, каттоо эсебине кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lo/strings.xml b/packages/CarrierDefaultApp/res/values-lo/strings.xml
index 7712275f2a65..47a8d05e5287 100644
--- a/packages/CarrierDefaultApp/res/values-lo/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lo/strings.xml
@@ -7,8 +7,9 @@
<string name="no_data_notification_id" msgid="668400731803969521">"ປິດການນຳໃຊ້ອິນເຕີເນັດມືຖືຂອງທ່ານແລ້ວ"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"ແຕະເພື່ອເຂົ້າເບິ່ງເວັບໄຊ %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການຂອງທ່ານ %s"</string>
- <string name="action_bar_label" msgid="4290345990334377177">"Sign in to mobile network"</string>
- <string name="ssl_error_warning" msgid="3127935140338254180">"ເຄືອ​ຂ່າຍ​ທີ່​ທ່ານ​ກຳ​ລັງ​ເຂົ້າ​ຮ່ວມ​ມີ​ບັນ​ຫາ​ຄວາມ​ປອດ​ໄພ."</string>
- <string name="ssl_error_example" msgid="6188711843183058764">"ຕົວ​ຢ່າງ, ໜ້າ​ລົງ​ຊື່​ເຂົ້າ​ໃຊ້​ອາດ​ຈະ​ບໍ່​ເປັນ​ຂອງ​ອົງ​ການ​ທີ່​ສະ​ແດງ​ຂຶ້ນ."</string>
- <string name="ssl_error_continue" msgid="1138548463994095584">"ແນວ​ໃດ​ກໍ່​ສືບ​ຕໍ່​ຜ່ານບ​ຣາວ​ເຊີ"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ສະຖານະຂໍ້ມູນມືຖື"</string>
+ <string name="action_bar_label" msgid="4290345990334377177">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍມືຖື"</string>
+ <string name="ssl_error_warning" msgid="3127935140338254180">"ເຄືອຂ່າຍທີ່ທ່ານກຳລັງເຂົ້າຮ່ວມມີບັນຫາຄວາມປອດໄພ."</string>
+ <string name="ssl_error_example" msgid="6188711843183058764">"ຕົວຢ່າງ, ໜ້າເຂົ້າສູ່ລະບົບອາດຈະບໍ່ແມ່ນຂອງອົງກອນທີ່ປາກົດ."</string>
+ <string name="ssl_error_continue" msgid="1138548463994095584">"ດຳເນີນການຕໍ່ຜ່ານໂປຣແກຣມທ່ອງເວັບ"</string>
</resources>
diff --git a/packages/CarrierDefaultApp/res/values-lt/strings.xml b/packages/CarrierDefaultApp/res/values-lt/strings.xml
index f7cb26736bac..173a29744af8 100644
--- a/packages/CarrierDefaultApp/res/values-lt/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lt/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobiliojo ryšio duomenys išaktyvinti"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Palieskite ir apsilankykite svetainėje %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Susisiekite su paslaugos teikėju „%s“"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobiliojo ryšio duomenų būsena"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Prisijungti prie mobiliojo ryšio tinklo"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Kilo tinklo, prie kurio bandote prisijungti, saugos problemų."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Pavyzdžiui, prisijungimo puslapis gali nepriklausyti rodomai organizacijai."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lv/strings.xml b/packages/CarrierDefaultApp/res/values-lv/strings.xml
index 008e3bf3b37e..aadb5bc5f9e6 100644
--- a/packages/CarrierDefaultApp/res/values-lv/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lv/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Jūsu mobilie dati ir deaktivizēti"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Pieskarieties, lai apmeklētu %s vietni"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Lūdzu, sazinieties ar pakalpojuma sniedzēju %s."</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobilo datu statuss"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Pierakstīties mobilajā tīklā"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Tīklā, kuram mēģināt pievienoties, ir drošības problēmas."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Piemēram, pieteikšanās lapa, iespējams, nepieder norādītajai organizācijai."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mk/strings.xml b/packages/CarrierDefaultApp/res/values-mk/strings.xml
index 2bd90c1533ab..5cb283792b45 100644
--- a/packages/CarrierDefaultApp/res/values-mk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mk/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилниот интернет ви е деактивиран"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Допрете за да го посетите веб-сајтот на %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Контактирајте со давателот на услуги %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус на мобилна мрежа"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Најавете се на мобилна мрежа"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Мрежата на која се обидувате да се придружите има проблеми со безбедноста."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"На пример, страницата за најавување може да не припаѓа на прикажаната организација."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ml/strings.xml b/packages/CarrierDefaultApp/res/values-ml/strings.xml
index 84e7980b5325..22f5fc42beb1 100644
--- a/packages/CarrierDefaultApp/res/values-ml/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ml/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"നിങ്ങളുടെ മൊബൈൽ ഡാറ്റ നിർജീവമാക്കി"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s ‌എന്ന വെബ്‌സൈറ്റ് സന്ദർശിക്കാൻ ടാപ്പുചെയ്യുക"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"നിങ്ങളുടെ ‌%s എന്ന സേവന‌ദാതാവിനെ ‌ബന്ധപ്പെടുക"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"മൊബൈൽ ഡാറ്റാ നില"</string>
<string name="action_bar_label" msgid="4290345990334377177">"മൊബൈൽ നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"നിങ്ങൾ ചേരാൻ ശ്രമിക്കുന്ന നെറ്റ്‌വർക്കിൽ സുരക്ഷാ പ്രശ്‌നങ്ങളുണ്ടായിരിക്കാം."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ഉദാഹരണത്തിന്, കാണിച്ചിരിക്കുന്ന ഓർഗനൈസേഷന്റേതായിരിക്കില്ല ലോഗിൻ പേജ്."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mn/strings.xml b/packages/CarrierDefaultApp/res/values-mn/strings.xml
index b95ae6240032..16613b4e9775 100644
--- a/packages/CarrierDefaultApp/res/values-mn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mn/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Таны мобайл датаг идэвхгүй болгосон"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s вэб хуудсанд зочлохын тулд товших"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"%s үйлчилгээ үзүүлэгчтэйгээ холбогдоно уу"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Мобайл датаны төлөв"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Мобайл сүлжээнд нэвтрэх"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Таны холбогдох гэж буй сүлжээ аюулгүй байдлын асуудалтай байна."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Жишээлбэл нэвтрэх хуудас нь харагдаж буй байгууллагынх биш байж болно."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mr/strings.xml b/packages/CarrierDefaultApp/res/values-mr/strings.xml
index 09709a089d90..a04ae3161421 100644
--- a/packages/CarrierDefaultApp/res/values-mr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mr/strings.xml
@@ -7,6 +7,8 @@
<string name="no_data_notification_id" msgid="668400731803969521">"आपला मोबाइल डेटा निष्क्रिय केला गेला"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s वेबसाइटला भेट देण्‍यासाठी टॅप करा"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"कृपया आपल्या %s सेवा प्रदात्याशी संपर्क साधा"</string>
+ <!-- no translation found for mobile_data_status_notification_channel_name (833999690121305708) -->
+ <skip />
<string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्कमध्ये साइन इन करा"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"आपण ज्या नेटवर्कमध्‍ये सामील होण्याचा प्रयत्न करत आहात त्यात सुरक्षितता समस्या आहेत."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणार्थ, लॉग इन पृष्‍ठ दर्शवलेल्या संस्थेच्या मालकीचे नसू शकते."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ms/strings.xml b/packages/CarrierDefaultApp/res/values-ms/strings.xml
index a015c2f76858..202ad5930228 100644
--- a/packages/CarrierDefaultApp/res/values-ms/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ms/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Data mudah alih anda telah dinyahaktifkan"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Ketik untuk melawat tapak web %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Sila hubungi penyedia perkhidmatan anda, %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status data mudah alih"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Log masuk ke rangkaian mudah alih"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Rangkaian yang cuba anda sertai mempunyai isu keselamatan."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Contohnya, halaman log masuk mungkin bukan milik organisasi yang ditunjukkan."</string>
diff --git a/packages/CarrierDefaultApp/res/values-my/strings.xml b/packages/CarrierDefaultApp/res/values-my/strings.xml
index b46c4e985d2c..876708044788 100644
--- a/packages/CarrierDefaultApp/res/values-my/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-my/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"သင်၏ မိုဘိုင်း ဒေတာကို ပိတ်ထားပါသည်"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s ဝဘ်ဆိုက်ကို ကြည့်ရှုရန် တို့ပါ"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"သင်၏ဝန်ဆောင်မှုပေးသူ %s ကို ဆက်သွယ်ပါ"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"မိုဘိုင်းဒေတာ အခြေအနေ"</string>
<string name="action_bar_label" msgid="4290345990334377177">"မိုဘိုင်းကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"သင်ချိတ်ဆက်ရန် ကြိုးစားနေသည့် ကွန်ရက်တွင် လုံခြုံရေးပြဿနာများ ရှိနေသည်။"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ဥပမာ− ဝင်ရောက်ရန် စာမျက်နှာသည် ပြသထားသည့် အဖွဲ့အစည်းနှင့် သက်ဆိုင်မှုမရှိခြင်း ဖြစ်နိုင်ပါသည်။"</string>
diff --git a/packages/CarrierDefaultApp/res/values-nb/strings.xml b/packages/CarrierDefaultApp/res/values-nb/strings.xml
index 75cd2e706416..d032bdad4f5d 100644
--- a/packages/CarrierDefaultApp/res/values-nb/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-nb/strings.xml
@@ -7,6 +7,8 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobildata er deaktivert"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Trykk for å besøke %s-nettstedet"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Ta kontakt med tjenesteleverandøren din, %s"</string>
+ <!-- no translation found for mobile_data_status_notification_channel_name (833999690121305708) -->
+ <skip />
<string name="action_bar_label" msgid="4290345990334377177">"Logg på mobilnettverk"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Nettverket du prøver å logge på, har sikkerhetsproblemer."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Det er for eksempel mulig at påloggingssiden ikke tilhører organisasjonen som vises."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ne/strings.xml b/packages/CarrierDefaultApp/res/values-ne/strings.xml
index 718ff63fe09c..694adfe185d3 100644
--- a/packages/CarrierDefaultApp/res/values-ne/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ne/strings.xml
@@ -7,6 +7,8 @@
<string name="no_data_notification_id" msgid="668400731803969521">"तपाईंको मोबाइल डेटा निष्क्रिय पारिएको छ"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s वेबसाइटमा जानका लागि ट्याप गर्नुहोस्"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"कृपया आफ्नो सेवा प्रदायक %s लाई सम्पर्क गर्नुहोस्"</string>
+ <!-- no translation found for mobile_data_status_notification_channel_name (833999690121305708) -->
+ <skip />
<string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्कमा साइन इन गर्नुहोस्"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"तपाईंले सामेल हुने प्रयास गरिरहनु भएको नेटवर्कमा सुरक्षा सम्बन्धी समस्याहरू छन्।"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणका लागि, लग इन पृष्ठ देखाइएको संस्थाको नहुन सक्छ।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-nl/strings.xml b/packages/CarrierDefaultApp/res/values-nl/strings.xml
index b96e7683ce6f..b4991acf0bca 100644
--- a/packages/CarrierDefaultApp/res/values-nl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-nl/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Je mobiele data zijn uitgeschakeld"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tik om de website van %s te bezoeken"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Neem contact op met je serviceprovider %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status van mobiele data"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Inloggen bij mobiel netwerk"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Het netwerk waarmee je verbinding probeert te maken, heeft beveiligingsproblemen."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Zo hoort de weergegeven inlogpagina misschien niet bij de weergegeven organisatie."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pa/strings.xml b/packages/CarrierDefaultApp/res/values-pa/strings.xml
index bfe6534fdd10..a0692403ce57 100644
--- a/packages/CarrierDefaultApp/res/values-pa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pa/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"ਤੁਹਾਡਾ ਮੋਬਾਈਲ ਡੈਟਾ ਅਕਿਰਿਆਸ਼ੀਲ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s ਵੈੱਬਸਾਈਟ \'ਤੇ ਜਾਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਸੇਵਾ ਪ੍ਰਦਾਨਕ %s ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"ਮੋਬਾਈਲ ਡੈਟੇ ਦੀ ਸਥਿਤੀ"</string>
<string name="action_bar_label" msgid="4290345990334377177">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"ਤੁਸੀਂ ਜਿਸ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸ਼ਾਮਲ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਹੇ ਹੋ ਉਸ ਵਿੱਚ ਸੁਰੱਖਿਆ ਸਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ।"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ਉਦਾਹਰਣ ਵਜੋਂ, ਹੋ ਸਕਦਾ ਹੈ ਲੌਗਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸਬੰਧਿਤ ਨਾ ਹੋਵੇ।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-pl/strings.xml b/packages/CarrierDefaultApp/res/values-pl/strings.xml
index a96a89857c13..427e12ad9b3d 100644
--- a/packages/CarrierDefaultApp/res/values-pl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pl/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilna transmisja danych została wyłączona"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Kliknij, by odwiedzić stronę: %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Skontaktuj się z operatorem %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stan danych mobilnych"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Zaloguj się w sieci komórkowej"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"W sieci, z którą próbujesz się połączyć, występują problemy z zabezpieczeniami."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Na przykład strona logowania może nie należeć do wyświetlanej organizacji."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml b/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
index 3f31a56dfc7c..1028ef8299d0 100644
--- a/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Os dados móveis foram desativados"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Toque para visitar o website %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Entre em contato com seu provedor de serviços %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status dos dados móveis"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Fazer login na rede móvel"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml b/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
index 52d498914cb5..0f42e01ad5d6 100644
--- a/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Os seus dados móveis foram desativados"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tocar para aceder ao Website %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Contacte o seu fornecedor de serviços %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Estado dos dados móveis"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Iniciar sessão na rede móvel"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"A rede à qual está a tentar aceder tem problemas de segurança."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de início de sessão pode não pertencer à entidade apresentada."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt/strings.xml b/packages/CarrierDefaultApp/res/values-pt/strings.xml
index 3f31a56dfc7c..1028ef8299d0 100644
--- a/packages/CarrierDefaultApp/res/values-pt/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Os dados móveis foram desativados"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Toque para visitar o website %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Entre em contato com seu provedor de serviços %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status dos dados móveis"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Fazer login na rede móvel"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ro/strings.xml b/packages/CarrierDefaultApp/res/values-ro/strings.xml
index 829e673c6ec7..5a1f9f48c86a 100644
--- a/packages/CarrierDefaultApp/res/values-ro/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ro/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Datele mobile au fost dezactivate"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Atingeți pentru a accesa site-ul %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Contactați furnizorul de servicii %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Starea datelor mobile"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Conectați-vă la rețeaua mobilă"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Rețeaua la care încercați să vă conectați are probleme de securitate."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"De exemplu, este posibil ca pagina de conectare să nu aparțină organizației afișate."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ru/strings.xml b/packages/CarrierDefaultApp/res/values-ru/strings.xml
index e49881e9849a..9436d61afc71 100644
--- a/packages/CarrierDefaultApp/res/values-ru/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ru/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Мобильный Интернет отключен"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Нажмите, чтобы открыть сайт %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Обратитесь к своему поставщику услуг \"%s\""</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Состояние мобильного Интернета"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Подключиться к мобильной сети"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Сеть, к которой вы хотите подключиться, небезопасна."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Например, страница входа в аккаунт может быть фиктивной."</string>
diff --git a/packages/CarrierDefaultApp/res/values-si/strings.xml b/packages/CarrierDefaultApp/res/values-si/strings.xml
index fa06c65cc840..108c3e2820ff 100644
--- a/packages/CarrierDefaultApp/res/values-si/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-si/strings.xml
@@ -7,6 +7,8 @@
<string name="no_data_notification_id" msgid="668400731803969521">"ඔබගේ ජංගම දත්ත අක්‍රිය කර ඇත"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s වෙබ් අඩවිය වෙත යාමට තට්ටු කරන්න"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"කරුණාකර ඔබගේ සේවා සැපයුම්කරු %s අමතන්න"</string>
+ <!-- no translation found for mobile_data_status_notification_channel_name (833999690121305708) -->
+ <skip />
<string name="action_bar_label" msgid="4290345990334377177">"ජංගම ජාලය වෙත පුරනය වෙන්න"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"ඔබ සම්බන්ධ වීමට උත්සහ කරන ජාලයේ ආරක්ෂක ගැටළු ඇත."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"උදාහරණයක් ලෙස, පුරනය වන පිටුව පෙන්වා ඇති සංවිධානයට අයිති නැති විය හැක."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sk/strings.xml b/packages/CarrierDefaultApp/res/values-sk/strings.xml
index fe0bff672775..811ef9d4bcb1 100644
--- a/packages/CarrierDefaultApp/res/values-sk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sk/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Vaše mobilné dáta boli deaktivované"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Klepnutím navštívite web %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Kontaktujte svojho poskytovateľa služieb %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stav mobilných dát"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Prihlásiť sa do mobilnej siete"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Sieť, ku ktorej sa pokúšate pripojiť, má problémy so zabezpečením"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Napríklad prihlasovacia stránka nemusí patriť uvedenej organizácii."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sl/strings.xml b/packages/CarrierDefaultApp/res/values-sl/strings.xml
index 3ae30416fdbc..482a5c87309c 100644
--- a/packages/CarrierDefaultApp/res/values-sl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sl/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Prenos podatkov v mobilnih omrežjih je deaktiviran"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Dotaknite se, če želite obiskati spletno mesto %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Obrnite se na ponudnika storitev %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Stanje prenosa podatkov v mobilnem omrežju"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Prijava v mobilno omrežje"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Omrežje, ki se mu poskušate pridružiti, ima varnostne težave."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Stran za prijavo na primer morda ne pripada prikazani organizaciji."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sq/strings.xml b/packages/CarrierDefaultApp/res/values-sq/strings.xml
index 82bf0bae1980..b384115c4ecc 100644
--- a/packages/CarrierDefaultApp/res/values-sq/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sq/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Të dhënat celulare janë çaktivizuar"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Trokit për të vizituar sajtin e uebit të %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Kontakto me ofruesin e shërbimit %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Statusi i të dhënave celulare"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Identifikohu në rrjetin celular"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Rrjeti në të cilin po përpiqesh të bashkohesh ka probleme sigurie."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"për shembull, faqja e identifikimit mund të mos i përkasë organizatës së shfaqur."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sr/strings.xml b/packages/CarrierDefaultApp/res/values-sr/strings.xml
index 596660524797..cd7587de234c 100644
--- a/packages/CarrierDefaultApp/res/values-sr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sr/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилни подаци су деактивирани"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Додирните да бисте посетили веб-сајт %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Контактирајте добављача услуге %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус мобилних података"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Пријавите се на мобилну мрежу"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Мрежа којој покушавате да се придружите има безбедносних проблема."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sv/strings.xml b/packages/CarrierDefaultApp/res/values-sv/strings.xml
index 2869eb788a25..360e04ea0756 100644
--- a/packages/CarrierDefaultApp/res/values-sv/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sv/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Din mobildata har inaktiverats"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Tryck här för att besöka webbplatsen %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Kontakta operatören %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status för mobildata"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Logga in på mobilnätverk"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Nätverket du försöker ansluta till har säkerhetsproblem."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Det kan t.ex. hända att inloggningssidan inte tillhör den organisation som visas."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sw/strings.xml b/packages/CarrierDefaultApp/res/values-sw/strings.xml
index b69d88300084..e908563b6972 100644
--- a/packages/CarrierDefaultApp/res/values-sw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sw/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Data yako ya mtandao wa simu imezimwa"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Gonga ili utembelee tovuti ya %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Tafadhali wasiliana na mtoa huduma wako %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Hali ya data ya mtandao wa simu"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Ingia katika akaunti ya mtandao wa simu"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Mtandao unaojaribu kujiunga nao una matatizo ya usalama."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Kwa mfano, ukurasa wa kuingia katika akaunti unaweza usiwe unamilikiwa na shirika lililoonyeshwa."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ta/strings.xml b/packages/CarrierDefaultApp/res/values-ta/strings.xml
index 38e3fe706848..515368630bbb 100644
--- a/packages/CarrierDefaultApp/res/values-ta/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ta/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"மொபைல் தரவு முடக்கப்பட்டது"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s இணையதளத்திற்குச் செல்ல, தட்டவும்"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"%s எனும் உங்கள் சேவை வழங்குநரைத் தொடர்புகொள்ளவும்"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"மொபைல் தரவின் நிலை"</string>
<string name="action_bar_label" msgid="4290345990334377177">"மொபைல் நெட்வொர்க்கில் உள்நுழையவும்"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"நீங்கள் சேர முயலும் நெட்வொர்க்கில் பாதுகாப்புச் சிக்கல்கள் உள்ளன."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"எடுத்துக்காட்டாக, உள்நுழைவுப் பக்கமானது காட்டப்படும் அமைப்பிற்குச் சொந்தமானதாக இல்லாமல் இருக்கலாம்."</string>
diff --git a/packages/CarrierDefaultApp/res/values-te/strings.xml b/packages/CarrierDefaultApp/res/values-te/strings.xml
index 09595fba1269..b849c4c8518c 100644
--- a/packages/CarrierDefaultApp/res/values-te/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-te/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"మీ మొబైల్ డేటా నిష్క్రియం చేయబడింది"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s వెబ్‌సైట్‌ని సందర్శించడం కోసం నొక్కండి"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"దయచేసి మీ సేవా ప్రదాత %sని సంప్రదించండి"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"మొబైల్ డేటా స్థితి"</string>
<string name="action_bar_label" msgid="4290345990334377177">"మొబైల్ నెట్‌వర్క్‌కి సైన్ ఇన్ చేయి"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"మీరు చేరడానికి ప్రయత్నిస్తున్న నెట్‌వర్క్ భద్రతా సమస్యలను కలిగి ఉంది."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ఉదాహరణకు, లాగిన్ పేజీ చూపిన సంస్థకు చెందినది కాకపోవచ్చు."</string>
diff --git a/packages/CarrierDefaultApp/res/values-th/strings.xml b/packages/CarrierDefaultApp/res/values-th/strings.xml
index 25aea25540d2..c374f9bfae36 100644
--- a/packages/CarrierDefaultApp/res/values-th/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-th/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"อินเทอร์เน็ตมือถือของคุณถูกปิดใช้งานแล้ว"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"แตะเพื่อเข้าชมเว็บไซต์ %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"โปรดติดต่อผู้ให้บริการ %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"สถานะเน็ตมือถือ"</string>
<string name="action_bar_label" msgid="4290345990334377177">"ลงชื่อเข้าใช้เครือข่ายมือถือ"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"เครือข่ายที่คุณพยายามเข้าร่วมมีปัญหาด้านความปลอดภัย"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"ตัวอย่างเช่น หน้าเข้าสู่ระบบอาจไม่ใช่ขององค์กรที่แสดงไว้"</string>
diff --git a/packages/CarrierDefaultApp/res/values-tl/strings.xml b/packages/CarrierDefaultApp/res/values-tl/strings.xml
index 1ae8ed4d2143..3ef550cffbc9 100644
--- a/packages/CarrierDefaultApp/res/values-tl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-tl/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Na-deactivate na ang iyong mobile data"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"I-tap upang bisitahin ang website ng %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Makipag-ugnayan sa iyong service provider %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status ng mobile data"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Mag-sign in sa mobile network"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"May mga isyu sa seguridad ang network na sinusubukan mong salihan."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Halimbawa, maaaring hindi pag-aari ng ipinapakitang organisasyon ang page ng login."</string>
diff --git a/packages/CarrierDefaultApp/res/values-tr/strings.xml b/packages/CarrierDefaultApp/res/values-tr/strings.xml
index 80a6845ecf2c..7f5cc4bfd9e4 100644
--- a/packages/CarrierDefaultApp/res/values-tr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-tr/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobil veriniz devre dışı bırakıldı"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s web sitesini ziyaret etmek için dokunun"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Lütfen servis sağlayıcınıza (%s) başvurun"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobil veri durumu"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Mobil ağda oturum aç"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Katılmaya çalıştığınız ağda güvenlik sorunları var."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Örneğin, giriş sayfası, gösterilen kuruluşa ait olmayabilir."</string>
diff --git a/packages/CarrierDefaultApp/res/values-uk/strings.xml b/packages/CarrierDefaultApp/res/values-uk/strings.xml
index 0a6b5ba083f5..8b0f85e717c2 100644
--- a/packages/CarrierDefaultApp/res/values-uk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-uk/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Мобільний трафік дезактивовано"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Торкніться, щоб перейти на веб-сайт %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Зв’яжіться зі своїм постачальником послуг %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Статус мобільного передавання даних"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Під’єднайте пристрій до мобільної мережі"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"У мережі, до якої ви намагаєтеся під’єднатись, є проблеми з безпекою."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Наприклад, сторінка входу може не належати вказаній організації."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ur/strings.xml b/packages/CarrierDefaultApp/res/values-ur/strings.xml
index e5a0d1a73f2d..0627a8d7ce1e 100644
--- a/packages/CarrierDefaultApp/res/values-ur/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ur/strings.xml
@@ -7,6 +7,8 @@
<string name="no_data_notification_id" msgid="668400731803969521">"آپ کا موبائل ڈیٹا غیر فعال کر دیا گیا ہے"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"‏‎%s ویب سائٹ ملاحظہ کرنے کیلئے تھپتھپائیں"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"‏براہ کرم اپنے خدمت کے فراہم کنندہ %s سے رابطہ کریں"</string>
+ <!-- no translation found for mobile_data_status_notification_channel_name (833999690121305708) -->
+ <skip />
<string name="action_bar_label" msgid="4290345990334377177">"موبائل نیٹ ورک میں سائن ان کریں"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"آپ جس نیٹ ورک میں شامل ہونے کی کوشش کر رہے ہیں، اس میں سیکیورٹی کے مسائل ہیں۔"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"مثال کے طور پر ہو سکتا ہے کہ لاگ ان صفحہ دکھائی گئی تنظیم سے تعلق نہ رکھتا ہو۔"</string>
diff --git a/packages/CarrierDefaultApp/res/values-uz/strings.xml b/packages/CarrierDefaultApp/res/values-uz/strings.xml
index e9fcf3e511b2..c65f2cba27d6 100644
--- a/packages/CarrierDefaultApp/res/values-uz/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-uz/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Mobil internet o‘chirildi"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"%s saytiga o‘tish uchun bosing"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"%s xizmat ta’minotchisi bilan bog‘laning"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Mobil internet holati"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Mobil tarmoqqa ulanish"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Siz ulanmoqchi bo‘lgan tarmoqda xavfsizlik bilan bog‘liq muammolar mavjud."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Masalan, tizimga kirish sahifasi ko‘rsatilgan tashkilotga tegishli bo‘lmasligi mumkin."</string>
diff --git a/packages/CarrierDefaultApp/res/values-vi/strings.xml b/packages/CarrierDefaultApp/res/values-vi/strings.xml
index a0eb8a8f2f09..1d302da9929b 100644
--- a/packages/CarrierDefaultApp/res/values-vi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-vi/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Dữ liệu di động của bạn đã bị hủy kích hoạt"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Nhấn để truy cập trang web %s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Hãy liên hệ với nhà cung cấp dịch vụ của bạn %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Trạng thái dữ liệu di động"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Đăng nhập vào mạng di động"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Mạng mà bạn đang cố gắng tham gia có vấn đề về bảo mật."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Ví dụ: trang đăng nhập có thể không thuộc về tổ chức được hiển thị."</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
index 053362a83f5c..ce1e2fa0736c 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"您的移动数据网络已停用"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"点按即可访问%s网站"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"请与您的服务提供商(%s)联系"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"移动数据状态"</string>
<string name="action_bar_label" msgid="4290345990334377177">"登录到移动网络"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"您尝试加入的网络存在安全问题。"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"例如,登录页面可能并不属于页面上显示的单位。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
index 7eb120a091dd..23e0acc612de 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"您的流動數據已停用"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"輕按即可瀏覽 %s 網站"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"請與您的服務供應商 (%s) 聯絡"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"流動數據狀態"</string>
<string name="action_bar_label" msgid="4290345990334377177">"登入流動網絡"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"您正在嘗試加入的網絡有安全性問題。"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"例如,登入頁面可能並不屬於所顯示的機構。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
index 5867ba7e775b..b3a799210d00 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"你的行動數據已停用"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"輕觸即可造訪 %s 網站"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"請與你的服務供應商 (%s) 聯絡"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"行動數據狀態"</string>
<string name="action_bar_label" msgid="4290345990334377177">"登入行動網路"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"你嘗試加入的網路有安全性問題。"</string>
<string name="ssl_error_example" msgid="6188711843183058764">"例如,登入網頁中顯示的機構可能並非該網頁實際隸屬的機構。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zu/strings.xml b/packages/CarrierDefaultApp/res/values-zu/strings.xml
index ab44231ccf08..48e4637ed6da 100644
--- a/packages/CarrierDefaultApp/res/values-zu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zu/strings.xml
@@ -7,6 +7,7 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Idatha yakho yeselula yenziwe yangasebenzi"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Thepha ukuze uvakashele iwebhusayithi engu-%s"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Sicela uxhumane nomhlinzeki wakho wesevisi ongu-%s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Isimo sedatha yeselula"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Ngena ngemvume kunethiwekhi yeselula"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Inethiwekhi ozama ukuyijoyina inezinkinga zokuvikela."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Isibonelo, ikhasi lokungena ngemvume kungenzeka lingelenhlangano ebonisiwe."</string>
diff --git a/packages/ExternalStorageProvider/res/values-eu/strings.xml b/packages/ExternalStorageProvider/res/values-eu/strings.xml
index e229d50040a0..c0e8cdd4f7e0 100644
--- a/packages/ExternalStorageProvider/res/values-eu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-eu/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="7123375275748530234">"Kanpoko memoria"</string>
- <string name="storage_description" msgid="8541974407321172792">"Gailuko biltegia"</string>
+ <string name="storage_description" msgid="8541974407321172792">"Biltegi lokala"</string>
<string name="root_internal_storage" msgid="827844243068584127">"Barneko memoria"</string>
<string name="root_documents" msgid="4051252304075469250">"Dokumentuak"</string>
</resources>
diff --git a/packages/ExternalStorageProvider/res/values-lo/strings.xml b/packages/ExternalStorageProvider/res/values-lo/strings.xml
index e3f1a786768a..ba344e3981ed 100644
--- a/packages/ExternalStorageProvider/res/values-lo/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-lo/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="7123375275748530234">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍນອກ"</string>
- <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
+ <string name="storage_description" msgid="8541974407321172792">"ບ່ອນຈັດເກັບຂໍ້ມູນໃນເຄື່ອງ"</string>
<string name="root_internal_storage" msgid="827844243068584127">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
<string name="root_documents" msgid="4051252304075469250">"ເອ​ກະ​ສານ"</string>
</resources>
diff --git a/packages/PrintRecommendationService/res/values/strings.xml b/packages/PrintRecommendationService/res/values/strings.xml
index b6c45b7a23c8..2bab1b65529b 100644
--- a/packages/PrintRecommendationService/res/values/strings.xml
+++ b/packages/PrintRecommendationService/res/values/strings.xml
@@ -18,6 +18,7 @@
-->
<resources>
+ <string name="plugin_vendor_google_cloud_print">Cloud Print</string>
<string name="plugin_vendor_hp">HP</string>
<string name="plugin_vendor_lexmark">Lexmark</string>
<string name="plugin_vendor_brother">Brother</string>
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
index e18ee90d39d7..128ed5085529 100644
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
@@ -22,6 +22,7 @@ import android.printservice.recommendation.RecommendationInfo;
import android.printservice.recommendation.RecommendationService;
import android.util.Log;
+import com.android.printservice.recommendation.plugin.google.CloudPrintPlugin;
import com.android.printservice.recommendation.plugin.hp.HPRecommendationPlugin;
import com.android.printservice.recommendation.plugin.mdnsFilter.MDNSFilterPlugin;
import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig;
@@ -65,6 +66,14 @@ public class RecommendationServiceImpl extends RecommendationService
}
try {
+ mPlugins.add(new RemotePrintServicePlugin(new CloudPrintPlugin(this), this,
+ true));
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Could not initiate "
+ + getString(R.string.plugin_vendor_google_cloud_print) + " plugin", e);
+ }
+
+ try {
mPlugins.add(new RemotePrintServicePlugin(new HPRecommendationPlugin(this), this,
false));
} catch (Exception e) {
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/google/CloudPrintPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/google/CloudPrintPlugin.java
new file mode 100644
index 000000000000..05b0c862ebd5
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/google/CloudPrintPlugin.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 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.printservice.recommendation.plugin.google;
+
+import static com.android.printservice.recommendation.util.MDNSUtils.ATTRIBUTE_TY;
+
+import android.annotation.NonNull;
+import android.annotation.StringRes;
+import android.content.Context;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.printservice.recommendation.PrintServicePlugin;
+import com.android.printservice.recommendation.R;
+import com.android.printservice.recommendation.util.MDNSFilteredDiscovery;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Plugin detecting <a href="https://developers.google.com/cloud-print/docs/privet">Google Cloud
+ * Print</a> printers.
+ */
+public class CloudPrintPlugin implements PrintServicePlugin {
+ private static final String LOG_TAG = CloudPrintPlugin.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private static final String ATTRIBUTE_TXTVERS = "txtvers";
+ private static final String ATTRIBUTE_URL = "url";
+ private static final String ATTRIBUTE_TYPE = "type";
+ private static final String ATTRIBUTE_ID = "id";
+ private static final String ATTRIBUTE_CS = "cs";
+
+ private static final String TYPE = "printer";
+
+ private static final String PRIVET_SERVICE = "_privet._tcp";
+
+ /** The required mDNS service types */
+ private static final Set<String> PRINTER_SERVICE_TYPE = new HashSet<String>() {{
+ // Not checking _printer_._sub
+ add(PRIVET_SERVICE);
+ }};
+
+ /** All possible connection states */
+ private static final Set<String> POSSIBLE_CONNECTION_STATES = new HashSet<String>() {{
+ add("online");
+ add("offline");
+ add("connecting");
+ add("not-configured");
+ }};
+
+ private static final byte SUPPORTED_TXTVERS = '1';
+
+ /** The mDNS filtered discovery */
+ private final MDNSFilteredDiscovery mMDNSFilteredDiscovery;
+
+ /**
+ * Create a plugin detecting Google Cloud Print printers.
+ *
+ * @param context The context the plugin runs in
+ */
+ public CloudPrintPlugin(@NonNull Context context) {
+ mMDNSFilteredDiscovery = new MDNSFilteredDiscovery(context, PRINTER_SERVICE_TYPE,
+ nsdServiceInfo -> {
+ // The attributes are case insensitive. For faster searching create a clone of
+ // the map with the attribute-keys all in lower case.
+ ArrayMap<String, byte[]> caseInsensitiveAttributes =
+ new ArrayMap<>(nsdServiceInfo.getAttributes().size());
+ for (Map.Entry<String, byte[]> entry : nsdServiceInfo.getAttributes()
+ .entrySet()) {
+ caseInsensitiveAttributes.put(entry.getKey().toLowerCase(),
+ entry.getValue());
+ }
+
+ if (DEBUG) {
+ Log.i(LOG_TAG, nsdServiceInfo.getServiceName() + ":");
+ Log.i(LOG_TAG, "type: " + nsdServiceInfo.getServiceType());
+ Log.i(LOG_TAG, "host: " + nsdServiceInfo.getHost());
+ for (Map.Entry<String, byte[]> entry : caseInsensitiveAttributes.entrySet()) {
+ if (entry.getValue() == null) {
+ Log.i(LOG_TAG, entry.getKey() + "= null");
+ } else {
+ Log.i(LOG_TAG, entry.getKey() + "=" + new String(entry.getValue(),
+ StandardCharsets.UTF_8));
+ }
+ }
+ }
+
+ byte[] txtvers = caseInsensitiveAttributes.get(ATTRIBUTE_TXTVERS);
+ if (txtvers == null || txtvers.length != 1 || txtvers[0] != SUPPORTED_TXTVERS) {
+ // The spec requires this to be the first attribute, but at this time we
+ // lost the order of the attributes
+ return false;
+ }
+
+ if (caseInsensitiveAttributes.get(ATTRIBUTE_TY) == null) {
+ return false;
+ }
+
+ byte[] url = caseInsensitiveAttributes.get(ATTRIBUTE_URL);
+ if (url == null || url.length == 0) {
+ return false;
+ }
+
+ byte[] type = caseInsensitiveAttributes.get(ATTRIBUTE_TYPE);
+ if (type == null || !TYPE.equals(
+ new String(type, StandardCharsets.UTF_8).toLowerCase())) {
+ return false;
+ }
+
+ if (caseInsensitiveAttributes.get(ATTRIBUTE_ID) == null) {
+ return false;
+ }
+
+ byte[] cs = caseInsensitiveAttributes.get(ATTRIBUTE_CS);
+ if (cs == null || !POSSIBLE_CONNECTION_STATES.contains(
+ new String(cs, StandardCharsets.UTF_8).toLowerCase())) {
+ return false;
+ }
+
+ InetAddress address = nsdServiceInfo.getHost();
+ if (!(address instanceof Inet4Address)) {
+ // Not checking for link local address
+ return false;
+ }
+
+ return true;
+ });
+ }
+
+ @Override
+ @NonNull public CharSequence getPackageName() {
+ return "com.google.android.apps.cloudprint";
+ }
+
+ @Override
+ public void start(@NonNull PrinterDiscoveryCallback callback) throws Exception {
+ mMDNSFilteredDiscovery.start(callback);
+ }
+
+ @Override
+ @StringRes public int getName() {
+ return R.string.plugin_vendor_google_cloud_print;
+ }
+
+ @Override
+ public void stop() throws Exception {
+ mMDNSFilteredDiscovery.stop();
+ }
+}
diff --git a/packages/SystemUI/res/layout/status_bar_notification_shelf.xml b/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
index 6db16fec5428..7bfbd3c542e1 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
@@ -19,7 +19,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_shelf_height"
- android:contentDescription="@string/notification_shelf_content_description"
android:focusable="true"
android:clickable="true"
>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 43aeaa3c9314..7bd9526cb274 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -412,7 +412,7 @@
<string name="accessibility_notifications_button">Notifications.</string>
<!-- Content description of overflow icon container of the notifications for accessibility (not shown on the screen)[CHAR LIMIT=NONE] -->
- <string name="notification_shelf_content_description">Notification overflow container</string>
+ <string name="accessibility_overflow_action">See all notifications</string>
<!-- Content description of the button for removing a notification in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_remove_notification">Clear notification.</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 80b4da8e2acf..b2b0ee463a97 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -301,7 +301,7 @@ public class KeyguardStatusView extends GridLayout {
private void updateDozeVisibleViews() {
for (View child : mVisibleInDoze) {
- child.setAlpha(mDark && mPulsing ? 0.5f : 1);
+ child.setAlpha(mDark && mPulsing ? 0.8f : 1);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 79190cbb129f..429e859b5403 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -265,7 +265,7 @@ public class Dependency extends SystemUI {
}
@Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
super.dump(fd, pw, args);
pw.println("Dumping existing controllers:");
mDependencies.values().stream().filter(obj -> obj instanceof Dumpable)
@@ -273,7 +273,7 @@ public class Dependency extends SystemUI {
}
@Override
- protected void onConfigurationChanged(Configuration newConfig) {
+ protected synchronized void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDependencies.values().stream().filter(obj -> obj instanceof ConfigurationChangedReceiver)
.forEach(o -> ((ConfigurationChangedReceiver) o).onConfigurationChanged(newConfig));
@@ -287,7 +287,7 @@ public class Dependency extends SystemUI {
return getDependencyInner(key);
}
- private <T> T getDependencyInner(Object key) {
+ private synchronized <T> T getDependencyInner(Object key) {
@SuppressWarnings("unchecked")
T obj = (T) mDependencies.get(key);
if (obj == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java
index 59f6d56ac1be..c58d889270e2 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java
@@ -34,7 +34,9 @@ public class PluginDependencyProvider extends DependencyProvider {
}
public <T> void allowPluginDependency(Class<T> cls, T obj) {
- mDependencies.put(cls, obj);
+ synchronized (mDependencies) {
+ mDependencies.put(cls, obj);
+ }
}
@Override
@@ -42,9 +44,11 @@ public class PluginDependencyProvider extends DependencyProvider {
if (!mManager.dependsOn(p, cls)) {
throw new IllegalArgumentException(p.getClass() + " does not depend on " + cls);
}
- if (!mDependencies.containsKey(cls)) {
- throw new IllegalArgumentException("Unknown dependency " + cls);
+ synchronized (mDependencies) {
+ if (!mDependencies.containsKey(cls)) {
+ throw new IllegalArgumentException("Unknown dependency " + cls);
+ }
+ return (T) mDependencies.get(cls);
}
- return (T) mDependencies.get(cls);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index 901d47d6cde8..7d847a3ea111 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -18,8 +18,11 @@ package com.android.systemui.settings;
import android.app.Activity;
import android.os.Bundle;
+import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
@@ -43,7 +46,13 @@ public class BrightnessDialog extends Activity {
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
window.requestFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.quick_settings_brightness_dialog);
+ // Use a dialog theme as the activity theme, but inflate the content as
+ // the QS content.
+ ContextThemeWrapper themedContext = new ContextThemeWrapper(this,
+ com.android.internal.R.style.Theme_DeviceDefault_QuickSettings);
+ View v = LayoutInflater.from(themedContext).inflate(
+ R.layout.quick_settings_brightness_dialog, null);
+ setContentView(v);
final ImageView icon = (ImageView) findViewById(R.id.brightness_icon);
final ToggleSliderView slider = (ToggleSliderView) findViewById(R.id.brightness_slider);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 0ee3e1917117..c48ecdbe838a 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -33,6 +33,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
+import android.view.Choreographer;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.GestureDetector;
@@ -312,7 +313,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
protected void onAttachedToWindow() {
super.onAttachedToWindow();
EventBus.getDefault().register(this);
- mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, getDisplay());
+ mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, getDisplay(),
+ Choreographer.getInstance());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 715dc82d1a1f..51345c20abe1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -22,6 +22,7 @@ import android.os.SystemProperties;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -577,7 +578,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
setClickable(mInteractive);
setFocusable(mInteractive);
setImportantForAccessibility(mInteractive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
- : View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
@Override
@@ -604,6 +605,19 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
@Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ if (mInteractive) {
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
+ AccessibilityNodeInfo.AccessibilityAction unlock
+ = new AccessibilityNodeInfo.AccessibilityAction(
+ AccessibilityNodeInfo.ACTION_CLICK,
+ getContext().getString(R.string.accessibility_overflow_action));
+ info.addAction(unlock);
+ }
+ }
+
+ @Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
updateRelativeOffset();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
index 0dad52f2942e..7a72afdbdfd4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
@@ -24,7 +24,6 @@ import android.view.View;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,7 +37,6 @@ public class NotificationViewWrapperTest {
mContext = InstrumentationRegistry.getTargetContext();
}
- @Ignore("Broken")
@Test
public void constructor_doesntUseViewContext() throws Exception {
new TestableNotificationViewWrapper(mContext, null /* view */, null /* row */);
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index b59e00d1956c..579c54cd311e 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3901,6 +3901,11 @@ message MetricsEvent {
// FIELD: Action for a nav button event
FIELD_NAV_ACTION = 933;
+ // OPEN: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
+ // CATEGORY: SETTINGS
+ // OS: O
+ FINGERPRINT_REMOVE_SIDECAR = 934;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 2bcc260b1c70..89645f457a55 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -333,23 +333,23 @@ public final class AutofillManagerService extends SystemService {
}
@Override
- public void setAuthenticationResult(Bundle data, IBinder activityToken, int userId) {
+ public void setAuthenticationResult(Bundle data, int sessionId, int userId) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
- service.setAuthenticationResultLocked(data, activityToken);
+ service.setAuthenticationResultLocked(data, sessionId, getCallingUid());
}
}
@Override
- public void setHasCallback(IBinder activityToken, int userId, boolean hasIt) {
+ public void setHasCallback(int sessionId, int userId, boolean hasIt) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
- service.setHasCallback(activityToken, hasIt);
+ service.setHasCallback(sessionId, getCallingUid(), hasIt);
}
}
@Override
- public void startSession(IBinder activityToken, IBinder windowToken, IBinder appCallback,
+ public int startSession(IBinder activityToken, IBinder windowToken, IBinder appCallback,
AutofillId autofillId, Rect bounds, AutofillValue value, int userId,
boolean hasCallback, int flags, String packageName) {
// TODO(b/33197203): make sure it's called by resumed / focused activity
@@ -369,41 +369,73 @@ public final class AutofillManagerService extends SystemService {
synchronized (mLock) {
final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
- service.startSessionLocked(activityToken, windowToken, appCallback,
- autofillId, bounds, value, hasCallback, flags, packageName);
+ return service.startSessionLocked(activityToken, getCallingUid(), windowToken,
+ appCallback, autofillId, bounds, value, hasCallback, flags, packageName);
}
}
@Override
- public void updateSession(IBinder activityToken, AutofillId id, Rect bounds,
+ public boolean restoreSession(int sessionId, IBinder activityToken, IBinder appCallback)
+ throws RemoteException {
+ activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
+ appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
+
+ synchronized (mLock) {
+ final AutofillManagerServiceImpl service = mServicesCache.get(
+ UserHandle.getCallingUserId());
+ if (service != null) {
+ return service.restoreSession(sessionId, getCallingUid(), activityToken,
+ appCallback);
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void setWindow(int sessionId, IBinder windowToken) throws RemoteException {
+ windowToken = Preconditions.checkNotNull(windowToken, "windowToken");
+
+ synchronized (mLock) {
+ final AutofillManagerServiceImpl service = mServicesCache.get(
+ UserHandle.getCallingUserId());
+ if (service != null) {
+ service.setWindow(sessionId, getCallingUid(), windowToken);
+ }
+ }
+ }
+
+ @Override
+ public void updateSession(int sessionId, AutofillId id, Rect bounds,
AutofillValue value, int flags, int userId) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = mServicesCache.get(
UserHandle.getCallingUserId());
if (service != null) {
- service.updateSessionLocked(activityToken, id, bounds, value, flags);
+ service.updateSessionLocked(sessionId, getCallingUid(), id, bounds, value,
+ flags);
}
}
}
@Override
- public void finishSession(IBinder activityToken, int userId) {
+ public void finishSession(int sessionId, int userId) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = mServicesCache.get(
UserHandle.getCallingUserId());
if (service != null) {
- service.finishSessionLocked(activityToken);
+ service.finishSessionLocked(sessionId, getCallingUid());
}
}
}
@Override
- public void cancelSession(IBinder activityToken, int userId) {
+ public void cancelSession(int sessionId, int userId) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = mServicesCache.get(
UserHandle.getCallingUserId());
if (service != null) {
- service.cancelSessionLocked(activityToken);
+ service.cancelSessionLocked(sessionId, getCallingUid());
}
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index c8a5780fedf1..94d534a3d7fe 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -16,10 +16,11 @@
package com.android.server.autofill;
-import static android.service.autofill.AutofillService.EXTRA_ACTIVITY_TOKEN;
+import static android.service.autofill.AutofillService.EXTRA_SESSION_ID;
import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
+import static android.view.autofill.AutofillManager.NO_SESSION;
import static com.android.server.autofill.Helper.DEBUG;
import static com.android.server.autofill.Helper.VERBOSE;
@@ -48,11 +49,11 @@ import android.service.autofill.AutofillService;
import android.service.autofill.AutofillServiceInfo;
import android.service.autofill.IAutoFillService;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
import android.view.autofill.IAutoFillManagerClient;
@@ -65,6 +66,7 @@ import com.android.server.autofill.ui.AutoFillUI;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Random;
/**
* Bridge between the {@code system_server}'s {@link AutofillManagerService} and the
@@ -74,6 +76,7 @@ import java.util.ArrayList;
final class AutofillManagerServiceImpl {
private static final String TAG = "AutofillManagerServiceImpl";
+ private static final int MAX_SESSION_ID_CREATE_TRIES = 2048;
static final int MSG_SERVICE_SAVE = 1;
@@ -85,6 +88,8 @@ final class AutofillManagerServiceImpl {
private RemoteCallbackList<IAutoFillManagerClient> mClients;
private AutofillServiceInfo mInfo;
+ private static final Random sRandom = new Random();
+
private final LocalLog mRequestsHistory;
/**
* Whether service was disabled for user due to {@link UserManager} restrictions.
@@ -94,7 +99,7 @@ final class AutofillManagerServiceImpl {
private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
switch (msg.what) {
case MSG_SERVICE_SAVE:
- handleSessionSave((IBinder) msg.obj);
+ handleSessionSave(msg.arg1);
break;
default:
Slog.w(TAG, "invalid msg on handler: " + msg);
@@ -113,7 +118,7 @@ final class AutofillManagerServiceImpl {
// TODO(b/33197203): need to make sure service is bound while callback is pending and/or
// use WeakReference
@GuardedBy("mLock")
- private final ArrayMap<IBinder, Session> mSessions = new ArrayMap<>();
+ private final SparseArray<Session> mSessions = new SparseArray<>();
/**
* Receiver of assist data from the app's {@link Activity}.
@@ -137,12 +142,12 @@ final class AutofillManagerServiceImpl {
return;
}
- final IBinder activityToken = receiverExtras.getBinder(EXTRA_ACTIVITY_TOKEN);
+ final int sessionId = receiverExtras.getInt(EXTRA_SESSION_ID);
final Session session;
synchronized (mLock) {
- session = mSessions.get(activityToken);
+ session = mSessions.get(sessionId);
if (session == null) {
- Slog.w(TAG, "no server session for activityToken " + activityToken);
+ Slog.w(TAG, "no server session for " + sessionId);
return;
}
// TODO(b/33197203): since service is fetching the data (to use for save later),
@@ -244,13 +249,17 @@ final class AutofillManagerServiceImpl {
if (!isEnabled()) {
return;
}
- final Session session = mSessions.get(activityToken);
- if (session == null) {
- Slog.w(TAG, "requestSaveForUserLocked(): no session for " + activityToken);
- return;
+
+ final int numSessions = mSessions.size();
+ for (int i = 0; i < numSessions; i++) {
+ final Session session = mSessions.valueAt(i);
+ if (session.getActivityTokenLocked().equals(activityToken)) {
+ session.callSaveLocked();
+ return;
+ }
}
- session.callSaveLocked();
+ Slog.w(TAG, "requestSaveForUserLocked(): no session for " + activityToken);
}
boolean addClientLocked(IAutoFillManagerClient client) {
@@ -261,61 +270,59 @@ final class AutofillManagerServiceImpl {
return isEnabled();
}
- void setAuthenticationResultLocked(Bundle data, IBinder activityToken) {
+ void setAuthenticationResultLocked(Bundle data, int sessionId, int uid) {
if (!isEnabled()) {
return;
}
- final Session session = mSessions.get(activityToken);
- if (session != null) {
+ final Session session = mSessions.get(sessionId);
+ if (session != null && uid == session.uid) {
session.setAuthenticationResultLocked(data);
}
}
- void setHasCallback(IBinder activityToken, boolean hasIt) {
+ void setHasCallback(int sessionId, int uid, boolean hasIt) {
if (!isEnabled()) {
return;
}
- final Session session = mSessions.get(activityToken);
- if (session != null) {
+ final Session session = mSessions.get(sessionId);
+ if (session != null && uid == session.uid) {
session.setHasCallback(hasIt);
}
}
- void startSessionLocked(@NonNull IBinder activityToken, @Nullable IBinder windowToken,
+ int startSessionLocked(@NonNull IBinder activityToken, int uid, @Nullable IBinder windowToken,
@NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
@NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
int flags, @NonNull String packageName) {
if (!isEnabled()) {
- return;
+ return 0;
}
- final String historyItem = "s=" + mInfo.getServiceInfo().packageName
- + " u=" + mUserId + " a=" + activityToken
- + " i=" + autofillId + " b=" + virtualBounds + " hc=" + hasCallback
- + " f=" + flags;
- mRequestsHistory.log(historyItem);
-
- // TODO(b/33197203): Handle scenario when user forced autofill after app was already
- // autofilled.
- final Session session = mSessions.get(activityToken);
- if (session != null) {
- // Already started...
- return;
+ final Session newSession = createSessionByTokenLocked(activityToken, uid, windowToken,
+ appCallbackToken, hasCallback, flags, packageName);
+ if (newSession == null) {
+ return NO_SESSION;
}
- final Session newSession = createSessionByTokenLocked(activityToken,
- windowToken, appCallbackToken, hasCallback, flags, packageName);
+ final String historyItem =
+ "id=" + newSession.id + " uid=" + uid + " s=" + mInfo.getServiceInfo().packageName
+ + " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds + " hc=" +
+ hasCallback + " f=" + flags;
+ mRequestsHistory.log(historyItem);
+
newSession.updateLocked(autofillId, virtualBounds, value, FLAG_START_SESSION);
+
+ return newSession.id;
}
- void finishSessionLocked(IBinder activityToken) {
+ void finishSessionLocked(int sessionId, int uid) {
if (!isEnabled()) {
return;
}
- final Session session = mSessions.get(activityToken);
- if (session == null) {
- Slog.w(TAG, "finishSessionLocked(): no session for " + activityToken);
+ final Session session = mSessions.get(sessionId);
+ if (session == null || uid != session.uid) {
+ Slog.w(TAG, "finishSessionLocked(): no session for " + sessionId + "(" + uid + ")");
return;
}
@@ -328,26 +335,39 @@ final class AutofillManagerServiceImpl {
}
}
- void cancelSessionLocked(IBinder activityToken) {
+ void cancelSessionLocked(int sessionId, int uid) {
if (!isEnabled()) {
return;
}
- final Session session = mSessions.get(activityToken);
- if (session == null) {
- Slog.w(TAG, "cancelSessionLocked(): no session for " + activityToken);
+ final Session session = mSessions.get(sessionId);
+ if (session == null || uid != session.uid) {
+ Slog.w(TAG, "cancelSessionLocked(): no session for " + sessionId + "(" + uid + ")");
return;
}
session.removeSelfLocked();
}
- private Session createSessionByTokenLocked(@NonNull IBinder activityToken,
+ private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
@Nullable IBinder windowToken, @NonNull IBinder appCallbackToken, boolean hasCallback,
int flags, @NonNull String packageName) {
+ // use random ids so that one app cannot know that another app creates sessions
+ int sessionId;
+ int tries = 0;
+ do {
+ tries++;
+ if (tries > MAX_SESSION_ID_CREATE_TRIES) {
+ Log.w(TAG, "Cannot create session in " + MAX_SESSION_ID_CREATE_TRIES + " tries");
+ return null;
+ }
+
+ sessionId = sRandom.nextInt();
+ } while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0);
+
final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
- activityToken, windowToken, appCallbackToken, hasCallback, flags,
+ sessionId, uid, activityToken, windowToken, appCallbackToken, hasCallback, flags,
mInfo.getServiceInfo().getComponentName(), packageName);
- mSessions.put(activityToken, newSession);
+ mSessions.put(newSession.id, newSession);
/*
* TODO(b/33197203): apply security checks below:
@@ -358,7 +378,7 @@ final class AutofillManagerServiceImpl {
*/
try {
final Bundle receiverExtras = new Bundle();
- receiverExtras.putBinder(EXTRA_ACTIVITY_TOKEN, activityToken);
+ receiverExtras.putInt(EXTRA_SESSION_ID, sessionId);
final long identity = Binder.clearCallingIdentity();
try {
if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
@@ -374,12 +394,51 @@ final class AutofillManagerServiceImpl {
return newSession;
}
- void updateSessionLocked(IBinder activityToken, AutofillId autofillId, Rect virtualBounds,
+ /**
+ * Restores a session after an activity was temporarily destroyed.
+ *
+ * @param sessionId The id of the session to restore
+ * @param uid UID of the process that tries to restore the session
+ * @param activityToken The new instance of the activity
+ * @param appCallback The callbacks to the activity
+ */
+ boolean restoreSession(int sessionId, int uid, @NonNull IBinder activityToken,
+ @NonNull IBinder appCallback) {
+ final Session session = mSessions.get(sessionId);
+
+ if (session == null || uid != session.uid) {
+ return false;
+ } else {
+ session.switchActivity(activityToken, appCallback);
+ return true;
+ }
+ }
+
+ /**
+ * Set the window the UI should get attached to
+ *
+ * @param sessionId The id of the session to restore
+ * @param uid UID of the process that tries to restore the session
+ * @param windowToken The window the activity is now in
+ */
+ boolean setWindow(int sessionId, int uid, @NonNull IBinder windowToken) {
+ final Session session = mSessions.get(sessionId);
+
+ if (session == null || uid != session.uid) {
+ return false;
+ } else {
+ session.switchWindow(windowToken);
+ return true;
+ }
+ }
+
+ void updateSessionLocked(int sessionId, int uid, AutofillId autofillId, Rect virtualBounds,
AutofillValue value, int flags) {
- final Session session = mSessions.get(activityToken);
- if (session == null) {
+ final Session session = mSessions.get(sessionId);
+ if (session == null || session.uid != uid) {
if (VERBOSE) {
- Slog.v(TAG, "updateSessionLocked(): session gone for " + activityToken);
+ Slog.v(TAG, "updateSessionLocked(): session gone for " + sessionId + "(" + uid
+ + ")");
}
return;
}
@@ -387,15 +446,15 @@ final class AutofillManagerServiceImpl {
session.updateLocked(autofillId, virtualBounds, value, flags);
}
- void removeSessionLocked(IBinder activityToken) {
- mSessions.remove(activityToken);
+ void removeSessionLocked(int sessionId) {
+ mSessions.remove(sessionId);
}
- private void handleSessionSave(IBinder activityToken) {
+ private void handleSessionSave(int sessionId) {
synchronized (mLock) {
- final Session session = mSessions.get(activityToken);
+ final Session session = mSessions.get(sessionId);
if (session == null) {
- Slog.w(TAG, "handleSessionSave(): already gone: " + activityToken);
+ Slog.w(TAG, "handleSessionSave(): already gone: " + sessionId);
return;
}
@@ -408,8 +467,9 @@ final class AutofillManagerServiceImpl {
Slog.v(TAG, "destroyLocked()");
}
- for (Session session : mSessions.values()) {
- session.destroyLocked();
+ final int numSessions = mSessions.size();
+ for (int i = 0; i < numSessions; i++) {
+ mSessions.valueAt(i).destroyLocked();
}
mSessions.clear();
}
@@ -463,15 +523,16 @@ final class AutofillManagerServiceImpl {
}
void destroySessionsLocked() {
- for (Session session : mSessions.values()) {
- session.removeSelf();
+ while (mSessions.size() > 0) {
+ mSessions.valueAt(0).removeSelf();
}
}
void listSessionsLocked(ArrayList<String> output) {
- for (IBinder activityToken : mSessions.keySet()) {
+ final int numSessions = mSessions.size();
+ for (int i = 0; i < numSessions; i++) {
output.add((mInfo != null ? mInfo.getServiceInfo().getComponentName()
- : null) + ":" + activityToken);
+ : null) + ":" + mSessions.keyAt(i));
}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 9092bdb4e999..3ef9cd52762d 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -38,12 +38,10 @@ import android.content.Intent;
import android.content.IntentSender;
import android.graphics.Rect;
import android.metrics.LogMaker;
-import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.RemoteException;
-import android.provider.Settings;
import android.service.autofill.AutofillService;
import android.service.autofill.Dataset;
import android.service.autofill.FillResponse;
@@ -90,14 +88,24 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private static final String TAG = "AutofillSession";
private final AutofillManagerServiceImpl mService;
- private final IBinder mActivityToken;
- private final IBinder mWindowToken;
private final HandlerCaller mHandlerCaller;
private final Object mLock;
private final AutoFillUI mUi;
private final MetricsLogger mMetricsLogger = new MetricsLogger();
+ /** Id of the session */
+ public final int id;
+
+ /** uid the session is for */
+ public final int uid;
+
+ @GuardedBy("mLock")
+ @NonNull private IBinder mActivityToken;
+
+ @GuardedBy("mLock")
+ @NonNull private IBinder mWindowToken;
+
/** Package name of the app that is auto-filled */
@NonNull private final String mPackageName;
@@ -110,7 +118,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@GuardedBy("mLock")
@Nullable private AutofillId mCurrentViewId;
- private final IAutoFillManagerClient mClient;
+ @GuardedBy("mLock")
+ private IAutoFillManagerClient mClient;
@GuardedBy("mLock")
RemoteFillService mRemoteFillService;
@@ -156,9 +165,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
Session(@NonNull AutofillManagerServiceImpl service, @NonNull AutoFillUI ui,
@NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
- @NonNull Object lock, @NonNull IBinder activityToken,
+ @NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken,
@Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback,
int flags, @NonNull ComponentName componentName, @NonNull String packageName) {
+ id = sessionId;
+ this.uid = uid;
mService = service;
mLock = lock;
mUi = ui;
@@ -169,21 +180,43 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mHasCallback = hasCallback;
mPackageName = packageName;
mFlags = flags;
-
mClient = IAutoFillManagerClient.Stub.asInterface(client);
- try {
- client.linkToDeath(() -> {
- if (VERBOSE) {
- Slog.v(TAG, "app binder died");
- }
- removeSelf();
- }, 0);
- } catch (RemoteException e) {
- Slog.w(TAG, "linkToDeath() on mClient failed: " + e);
+ mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName);
+ }
+
+ /**
+ * Gets the currently registered activity token
+ *
+ * @return The activity token
+ */
+ public IBinder getActivityTokenLocked() {
+ return mActivityToken;
+ }
+
+ /**
+ * Sets new window for this session.
+ *
+ * @param newWindow The window the Ui should be attached to. Can be {@code null} if no
+ * further UI is needed.
+ */
+ void switchWindow(@NonNull IBinder newWindow) {
+ synchronized (mLock) {
+ mWindowToken = newWindow;
}
+ }
- mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName);
+ /**
+ * Sets new activity and client for this session.
+ *
+ * @param newActivity The token of the new activity
+ * @param newClient The client receiving autofill callbacks
+ */
+ void switchActivity(@NonNull IBinder newActivity, @NonNull IBinder newClient) {
+ synchronized (mLock) {
+ mActivityToken = newActivity;
+ mClient = IAutoFillManagerClient.Stub.asInterface(newClient);
+ }
}
// FillServiceCallbacks
@@ -301,7 +334,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@Override
public void save() {
mHandlerCaller.getHandler()
- .obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, mActivityToken)
+ .obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, id, 0)
.sendToTarget();
}
@@ -337,10 +370,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// AutoFillUiCallback
@Override
public void requestHideFillUi(AutofillId id) {
- try {
- mClient.requestHideFillUi(mWindowToken, id);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error requesting to hide fill UI", e);
+ synchronized (mLock) {
+ try {
+ mClient.requestHideFillUi(mWindowToken, id);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error requesting to hide fill UI", e);
+ }
}
}
@@ -398,12 +433,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return true;
}
- // TODO(b/33197203 , b/35707731): must iterate over all responses
- final FillResponse response = mResponses.get(0);
+ final FillResponse response = mResponses.get(mResponses.size() - 1);
final SaveInfo saveInfo = response.getSaveInfo();
if (DEBUG) {
- Slog.d(TAG, "showSaveLocked(): saveInfo=" + saveInfo);
+ Slog.d(TAG,
+ "showSaveLocked(): mResponses=" + mResponses + ", mViewStates=" + mViewStates);
}
/*
@@ -665,17 +700,19 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
private void notifyUnavailableToClient() {
- if (mCurrentViewId == null) {
- // TODO(b/33197203): temporary sanity check; should never happen
- Slog.w(TAG, "notifyUnavailable(): mCurrentViewId is null");
- return;
- }
- if (!mHasCallback) return;
- try {
- mClient.notifyNoFillUi(mWindowToken, mCurrentViewId);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
- + " id=" + mCurrentViewId, e);
+ synchronized (mLock) {
+ if (mCurrentViewId == null) {
+ // TODO(b/33197203): temporary sanity check; should never happen
+ Slog.w(TAG, "notifyUnavailable(): mCurrentViewId is null");
+ return;
+ }
+ if (!mHasCallback) return;
+ try {
+ mClient.notifyNoFillUi(mWindowToken, mCurrentViewId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
+ + " id=" + mCurrentViewId, e);
+ }
}
}
@@ -684,12 +721,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
Slog.d(TAG, "processResponseLocked(mCurrentViewId=" + mCurrentViewId + "):" + response);
}
- if (mCurrentViewId == null) {
- // TODO(b/33197203): temporary sanity check; should never happen
- Slog.w(TAG, "processResponseLocked(): mCurrentViewId is null");
- return;
- }
-
if (mResponses == null) {
mResponses = new ArrayList<>(4);
}
@@ -700,6 +731,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
setViewStatesLocked(response, ViewState.STATE_FILLABLE);
+ if (mCurrentViewId == null) {
+ return;
+ }
+
if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null
&& response.getDatasets().size() == 1) {
Slog.d(TAG, "autofilling manual request directly");
@@ -808,13 +843,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private void startAuthentication(IntentSender intent, Intent fillInIntent) {
try {
- mClient.authenticate(intent, fillInIntent);
+ synchronized (mLock) {
+ mClient.authenticate(intent, fillInIntent);
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Error launching auth intent", e);
}
}
void dumpLocked(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("id: "); pw.println(id);
+ pw.print(prefix); pw.print("uid: "); pw.println(uid);
pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags);
pw.print(prefix); pw.print("mResponses: "); pw.println(mResponses);
@@ -913,6 +952,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
Slog.v(TAG, "removeSelfLocked()");
}
destroyLocked();
- mService.removeSessionLocked(mActivityToken);
+ mService.removeSessionLocked(id);
}
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index d35cc95e6d26..f94d456cb47f 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -24,7 +24,7 @@ import android.content.Context;
import android.content.IntentSender;
import android.os.Handler;
import android.service.autofill.SaveInfo;
-import android.text.format.DateUtils;
+import android.util.ArraySet;
import android.util.Slog;
import android.view.Gravity;
import android.view.Window;
@@ -105,32 +105,45 @@ final class SaveUi {
final View view = inflater.inflate(R.layout.autofill_save, null);
final TextView titleView = (TextView) view.findViewById(R.id.autofill_save_title);
- final String type;
- switch(info.getType()) {
- case SaveInfo.SAVE_DATA_TYPE_PASSWORD:
- type = context.getString(R.string.autofill_save_type_password);
- break;
- case SaveInfo.SAVE_DATA_TYPE_ADDRESS:
- type = context.getString(R.string.autofill_save_type_address);
- break;
- case SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD:
- type = context.getString(R.string.autofill_save_type_credit_card);
+ final ArraySet<String> types = new ArraySet<>(3);
+ final int type = info.getType();
+
+ if ((type & SaveInfo.SAVE_DATA_TYPE_PASSWORD) != 0) {
+ types.add(context.getString(R.string.autofill_save_type_password));
+ }
+ if ((type & SaveInfo.SAVE_DATA_TYPE_ADDRESS) != 0) {
+ types.add(context.getString(R.string.autofill_save_type_address));
+ }
+ if ((type & SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD) != 0) {
+ types.add(context.getString(R.string.autofill_save_type_credit_card));
+ }
+ if ((type & SaveInfo.SAVE_DATA_TYPE_USERNAME) != 0) {
+ types.add(context.getString(R.string.autofill_save_type_username));
+ }
+ if ((type & SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS) != 0) {
+ types.add(context.getString(R.string.autofill_save_type_email_address));
+ }
+
+ final String title;
+ switch (types.size()) {
+ case 1:
+ title = context.getString(R.string.autofill_save_title_with_type,
+ types.valueAt(0), providerLabel);
break;
- case SaveInfo.SAVE_DATA_TYPE_USERNAME:
- type = context.getString(R.string.autofill_save_type_username);
+ case 2:
+ title = context.getString(R.string.autofill_save_title_with_2types,
+ types.valueAt(0), types.valueAt(1), providerLabel);
break;
- case SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS:
- type = context.getString(R.string.autofill_save_type_email_address);
+ case 3:
+ title = context.getString(R.string.autofill_save_title_with_3types,
+ types.valueAt(0), types.valueAt(1), types.valueAt(2), providerLabel);
break;
default:
- type = null;
+ // Use generic if more than 3 or invalid type (size 0).
+ title = context.getString(R.string.autofill_save_title, providerLabel);
}
- final String title = (type == null)
- ? context.getString(R.string.autofill_save_title, providerLabel)
- : context.getString(R.string.autofill_save_title_with_type, type, providerLabel);
-
titleView.setText(title);
final CharSequence subTitle = info.getDescription();
if (subTitle != null) {
@@ -139,6 +152,10 @@ final class SaveUi {
subTitleView.setVisibility(View.VISIBLE);
}
+ if (DEBUG) {
+ Slog.d(TAG, "Title: " + title + " SubTitle: " + subTitle);
+ }
+
final TextView noButton = view.findViewById(R.id.autofill_save_no);
if (info.getNegativeActionTitle() != null) {
noButton.setText(info.getNegativeActionTitle());
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 413746fab911..d647c635cbb2 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -3109,13 +3109,6 @@ public class BackupManagerService {
if (!mCancelAll && mStatus == BackupTransport.TRANSPORT_OK &&
mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
- CountDownLatch latch = new CountDownLatch(1);
- String[] fullBackups =
- mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
- PerformFullTransportBackupTask task =
- new PerformFullTransportBackupTask(/*fullBackupRestoreObserver*/ null,
- fullBackups, /*updateSchedule*/ false, /*runningJob*/ null, latch,
- mObserver, mMonitor, mUserInitiated);
// Acquiring wakelock for PerformFullTransportBackupTask before its start.
mWakelock.acquire();
(new Thread(mFullBackupTask, "full-transport-requested")).start();
diff --git a/services/core/java/com/android/server/AnimationThread.java b/services/core/java/com/android/server/AnimationThread.java
new file mode 100644
index 000000000000..08392b067a9a
--- /dev/null
+++ b/services/core/java/com/android/server/AnimationThread.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 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;
+
+import static android.os.Process.THREAD_PRIORITY_DISPLAY;
+
+import android.os.Handler;
+import android.os.Trace;
+
+/**
+ * Thread for handling all window animations, or anything that's directly impacting animations like
+ * starting windows or traversals.
+ */
+public final class AnimationThread extends ServiceThread {
+ private static AnimationThread sInstance;
+ private static Handler sHandler;
+
+ private AnimationThread() {
+ super("android.anim", THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
+ }
+
+ private static void ensureThreadLocked() {
+ if (sInstance == null) {
+ sInstance = new AnimationThread();
+ sInstance.start();
+ sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER);
+ sHandler = new Handler(sInstance.getLooper());
+ }
+ }
+
+ public static AnimationThread get() {
+ synchronized (AnimationThread.class) {
+ ensureThreadLocked();
+ return sInstance;
+ }
+ }
+
+ public static Handler getHandler() {
+ synchronized (AnimationThread.class) {
+ ensureThreadLocked();
+ return sHandler;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/DisplayThread.java b/services/core/java/com/android/server/DisplayThread.java
index 9ef02598c1d3..cad2a612a13d 100644
--- a/services/core/java/com/android/server/DisplayThread.java
+++ b/services/core/java/com/android/server/DisplayThread.java
@@ -17,6 +17,7 @@
package com.android.server;
import android.os.Handler;
+import android.os.Process;
import android.os.Trace;
/**
@@ -30,7 +31,9 @@ public final class DisplayThread extends ServiceThread {
private static Handler sHandler;
private DisplayThread() {
- super("android.display", android.os.Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
+ // DisplayThread runs important stuff, but these are not as important as things running in
+ // AnimationThread. Thus, set the priority to one lower.
+ super("android.display", Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);
}
private static void ensureThreadLocked() {
diff --git a/services/core/java/com/android/server/ThreadPriorityBooster.java b/services/core/java/com/android/server/ThreadPriorityBooster.java
index 17965d099af0..31726ad85a30 100644
--- a/services/core/java/com/android/server/ThreadPriorityBooster.java
+++ b/services/core/java/com/android/server/ThreadPriorityBooster.java
@@ -41,8 +41,8 @@ public class ThreadPriorityBooster {
final int tid = Process.myTid();
final int prevPriority = Process.getThreadPriority(tid);
PriorityState state = mThreadState.get();
+ state.prevPriority = prevPriority;
if (state.regionCounter == 0 && prevPriority > mBoostToPriority) {
- state.prevPriority = prevPriority;
Process.setThreadPriority(tid, mBoostToPriority);
}
state.regionCounter++;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index be5ff803ed56..35654d76dee5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -30,6 +30,7 @@ import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
@@ -2385,16 +2386,19 @@ public class ActivityManagerService extends IActivityManager.Stub
idleUids();
} break;
case VR_MODE_CHANGE_MSG: {
- if (mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
- synchronized (ActivityManagerService.this) {
- if (mVrController.shouldDisableNonVrUiLocked()) {
- // If we are in a VR mode where Picture-in-Picture mode is unsupported,
- // then remove the pinned stack.
- final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
- PINNED_STACK_ID);
- if (pinnedStack != null) {
- mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
- }
+ if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
+ return;
+ }
+ synchronized (ActivityManagerService.this) {
+ final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
+ mWindowManager.disableNonVrUi(disableNonVrUi);
+ if (disableNonVrUi) {
+ // If we are in a VR mode where Picture-in-Picture mode is unsupported,
+ // then remove the pinned stack.
+ final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
+ PINNED_STACK_ID);
+ if (pinnedStack != null) {
+ mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
}
}
}
@@ -13763,6 +13767,8 @@ public class ActivityManagerService extends IActivityManager.Stub
final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
final boolean supportsSplitScreenMultiWindow =
ActivityManager.supportsSplitScreenMultiWindow();
+ final boolean supportsMultiDisplay = mContext.getPackageManager()
+ .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
final boolean alwaysFinishActivities =
@@ -13800,6 +13806,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
mSupportsPictureInPicture = supportsPictureInPicture;
+ mSupportsMultiDisplay = supportsMultiDisplay;
mWindowManager.setForceResizableTasks(mForceResizableActivities);
mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
// This happens before any activities are started, so we can change global configuration
@@ -13828,8 +13835,6 @@ public class ActivityManagerService extends IActivityManager.Stub
com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
}
mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
- mSupportsMultiDisplay = res.getBoolean(
- com.android.internal.R.bool.config_supportsMultiDisplay);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 601141827f3c..04c2af5af339 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -247,8 +247,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
return runSupportsMultiwindow(pw);
case "supports-split-screen-multi-window":
return runSupportsSplitScreenMultiwindow(pw);
- case "supports-multi-display":
- return runSupportsMultiDisplay(pw);
case "update-appinfo":
return runUpdateApplicationInfo(pw);
case "no-home-screen":
@@ -2386,7 +2384,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
if (res == null) {
return -1;
}
- pw.println(res.getBoolean(com.android.internal.R.bool.config_supportsMultiWindow));
+ pw.println(ActivityManager.supportsMultiWindow());
return 0;
}
@@ -2395,17 +2393,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
if (res == null) {
return -1;
}
- pw.println(
- res.getBoolean(com.android.internal.R.bool.config_supportsSplitScreenMultiWindow));
- return 0;
- }
-
- int runSupportsMultiDisplay(PrintWriter pw) throws RemoteException {
- final Resources res = getResources(pw);
- if (res == null) {
- return -1;
- }
- pw.println(res.getBoolean(com.android.internal.R.bool.config_supportsMultiDisplay));
+ pw.println(ActivityManager.supportsSplitScreenMultiWindow());
return 0;
}
@@ -2638,8 +2626,6 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" Returns true if the device supports multiwindow.");
pw.println(" supports-split-screen-multi-window");
pw.println(" Returns true if the device supports split screen multiwindow.");
- pw.println(" supports-multi-display");
- pw.println(" Returns true if the device supports multi-display.");
pw.println(" suppress-resize-config-changes <true|false>");
pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 5edfb0651fe7..28817878373b 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -102,7 +102,7 @@ class ActivityMetricsLogger {
mLastLogTimeSecs = now;
ActivityStack stack = mSupervisor.getStack(DOCKED_STACK_ID);
- if (stack != null && stack.getStackVisibilityLocked(null) != STACK_INVISIBLE) {
+ if (stack != null && stack.shouldBeVisible(null) != STACK_INVISIBLE) {
mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
return;
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 6e7ad177fc07..2b953adfde18 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -505,7 +505,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
else TimeUtils.formatDuration(startTime, now, pw);
pw.println();
}
- final boolean waitingVisible = mStackSupervisor.mWaitingVisibleActivities.contains(this);
+ final boolean waitingVisible =
+ mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this);
if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
pw.print(" nowVisible="); pw.print(nowVisible);
@@ -1912,13 +1913,14 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
// If this activity was already idle, then we now need to make sure we perform
// the full stop of any activities that are waiting to do so. This is because
// we won't do that while they are still waiting for this one to become visible.
- final int size = mStackSupervisor.mWaitingVisibleActivities.size();
+ final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
- ActivityRecord r = mStackSupervisor.mWaitingVisibleActivities.get(i);
+ final ActivityRecord r =
+ mStackSupervisor.mActivitiesWaitingForVisibleActivity.get(i);
if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
}
- mStackSupervisor.mWaitingVisibleActivities.clear();
+ mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
mStackSupervisor.scheduleIdleLocked();
}
}
@@ -1959,7 +1961,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
// First find the real culprit... if this activity is waiting for
// another activity to start or has stopped, then the key dispatching
// timeout should not be caused by this.
- if (mStackSupervisor.mWaitingVisibleActivities.contains(this) || stopped) {
+ if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this) || stopped) {
final ActivityStack stack = mStackSupervisor.getFocusedStack();
// Try to use the one which is closest to top.
ActivityRecord r = stack.mResumedActivity;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index f13b11e65a88..51011b586743 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -116,7 +116,6 @@ import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.Watchdog;
@@ -313,6 +312,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
*/
boolean mConfigWillChange;
+ /**
+ * When set, will force the stack to report as invisible.
+ */
+ boolean mForceHidden = false;
+
// Whether or not this stack covers the entire screen; by default stacks are fullscreen
boolean mFullscreen = true;
// Current bounds of the stack or null if fullscreen.
@@ -1349,7 +1353,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
} else if (prev.app != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
+ " wasStopping=" + wasStopping + " visible=" + prev.visible);
- if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
+ if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {
if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
"Complete pause, no longer waiting: " + prev);
}
@@ -1560,13 +1564,20 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
return true;
}
+ /** Returns true if the stack is currently considered visible. */
+ boolean isVisible() {
+ return mWindowContainerController != null && mWindowContainerController.isVisible()
+ && !mForceHidden;
+ }
+
/**
- * Returns stack's visibility: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE} or
- * {@link #STACK_VISIBLE_ACTIVITY_BEHIND}.
+ * Returns what the stack visibility should be: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE}
+ * or {@link #STACK_VISIBLE_ACTIVITY_BEHIND}.
+ *
* @param starting The currently starting activity or null if there is none.
*/
- int getStackVisibilityLocked(ActivityRecord starting) {
- if (!isAttached()) {
+ int shouldBeVisible(ActivityRecord starting) {
+ if (!isAttached() || mForceHidden) {
return STACK_INVISIBLE;
}
@@ -1715,7 +1726,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
// If the top activity is not fullscreen, then we need to
// make sure any activities under it are now visible.
boolean aboveTop = top != null;
- final int stackVisibility = getStackVisibilityLocked(starting);
+ final int stackVisibility = shouldBeVisible(starting);
final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
boolean behindFullscreenActivity = stackInvisible;
@@ -2097,7 +2108,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
// activities as we need to display their starting window until they are done initializing.
boolean behindFullscreenActivity = false;
- if (getStackVisibilityLocked(null) == STACK_INVISIBLE) {
+ if (shouldBeVisible(null) == STACK_INVISIBLE) {
// The stack is not visible, so no activity in it should be displaying a starting
// window. Mark all activities below top and behind fullscreen.
aboveTop = false;
@@ -2262,7 +2273,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
- mStackSupervisor.mWaitingVisibleActivities.remove(next);
+ mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
@@ -2324,9 +2335,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
if (prev != null && prev != next) {
- if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
+ if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
&& next != null && !next.nowVisible) {
- mStackSupervisor.mWaitingVisibleActivities.add(prev);
+ mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
"Resuming top, waiting visible to hide: " + prev);
} else {
@@ -2342,13 +2353,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
prev.setVisibility(false);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
"Not waiting for visible to hide: " + prev + ", waitingVisible="
- + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
+ + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
+ ", nowVisible=" + next.nowVisible);
} else {
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
"Previous already visible but still waiting to hide: " + prev
+ ", waitingVisible="
- + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
+ + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
+ ", nowVisible=" + next.nowVisible);
}
}
@@ -3215,8 +3226,25 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
r.addResultLocked(null, resultWho, requestCode, resultCode, data);
}
+ /** Returns true if the task is one of the task finishing on-top of the top running task. */
+ boolean isATopFinishingTask(TaskRecord task) {
+ for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
+ final TaskRecord current = mTaskHistory.get(i);
+ final ActivityRecord r = current.topRunningActivityLocked();
+ if (r != null) {
+ // We got a top running activity, so there isn't a top finishing task...
+ return false;
+ }
+ if (current == task) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void adjustFocusedActivityStackLocked(ActivityRecord r, String reason) {
- if (!mStackSupervisor.isFocusedStack(this) || mResumedActivity != r) {
+ if (!mStackSupervisor.isFocusedStack(this) ||
+ ((mResumedActivity != r) && (mResumedActivity != null))) {
return;
}
@@ -3231,8 +3259,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
final TaskRecord task = r.getTask();
final boolean isAssistantOrOverAssistant = task.getStack().isAssistantStack() ||
task.isOverAssistantStack();
- if (r.frontOfTask && task == topTask() &&
- (task.isOverHomeStack() || isAssistantOrOverAssistant)) {
+ if (r.frontOfTask && isATopFinishingTask(task)
+ && (task.isOverHomeStack() || isAssistantOrOverAssistant)) {
// For non-fullscreen or assistant stack, we want to move the focus to the next
// visible stack to prevent the home screen from moving to the top and obscuring
// other visible stacks.
@@ -3617,8 +3645,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
mWindowManager.prepareAppTransition(transit, false);
r.setVisibility(false);
mWindowManager.executeAppTransition();
- if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
- mStackSupervisor.mWaitingVisibleActivities.add(r);
+ if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) {
+ mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(r);
}
}
@@ -3650,7 +3678,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
// make sure the record is cleaned out of other places.
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
- mStackSupervisor.mWaitingVisibleActivities.remove(r);
+ mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(r);
if (mResumedActivity == r) {
mResumedActivity = null;
}
@@ -3870,11 +3898,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
r.app = null;
}
- // Make sure this record is no longer in the pending finishes list.
- // This could happen, for example, if we are trimming activities
- // down to the max limit while they are still waiting to finish.
- mStackSupervisor.mFinishingActivities.remove(r);
- mStackSupervisor.mWaitingVisibleActivities.remove(r);
+ // Inform supervisor the activity has been removed.
+ mStackSupervisor.cleanupActivity(r);
+
// Remove any pending results.
if (r.finishing && r.pendingResults != null) {
@@ -4184,7 +4210,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
if (hasVisibleBehindActivity() &&
!mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
if (r == topRunningActivityLocked()
- && getStackVisibilityLocked(null) == STACK_VISIBLE) {
+ && shouldBeVisible(null) == STACK_VISIBLE) {
// Don't release the top activity if it has requested to run behind the next
// activity and the stack is currently visible.
return;
@@ -4253,8 +4279,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
"mStoppingActivities");
removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
"mGoingToSleepActivities");
- removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app,
- "mWaitingVisibleActivities");
+ removeHistoryRecordsForAppLocked(mStackSupervisor.mActivitiesWaitingForVisibleActivity, app,
+ "mActivitiesWaitingForVisibleActivity");
removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
"mFinishingActivities");
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 30e33c83e7be..c9bb9e547693 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -42,6 +42,7 @@ import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
@@ -153,6 +154,7 @@ import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.service.voice.IVoiceInteractionSession;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
@@ -164,17 +166,14 @@ import android.view.Display;
import android.view.InputEvent;
import android.view.Surface;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.ReferrerIntent;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.TransferPipe;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
import com.android.server.am.ActivityStack.ActivityState;
-import com.android.server.wm.StackWindowController;
import com.android.server.wm.WindowManagerService;
import java.io.FileDescriptor;
@@ -346,10 +345,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
/** List of activities that are waiting for a new activity to become visible before completing
* whatever operation they are supposed to do. */
- final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>();
+ // TODO: Remove mActivitiesWaitingForVisibleActivity list and just remove activity from
+ // mStoppingActivities when something else comes up.
+ final ArrayList<ActivityRecord> mActivitiesWaitingForVisibleActivity = new ArrayList<>();
- /** List of processes waiting to find out about the next visible activity. */
- final ArrayList<WaitResult> mWaitingActivityVisible = new ArrayList<>();
+ /** List of processes waiting to find out when a specific activity becomes visible. */
+ private final ArrayList<WaitInfo> mWaitingForActivityVisible = new ArrayList<>();
/** List of processes waiting to find out about the next launched activity. */
final ArrayList<WaitResult> mWaitingActivityLaunched = new ArrayList<>();
@@ -1003,7 +1004,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
final ActivityStack stack = stacks.get(stackNdx);
final ActivityRecord r = stack.mResumedActivity;
if (r != null) {
- if (!r.nowVisible || mWaitingVisibleActivities.contains(r)) {
+ if (!r.nowVisible || mActivitiesWaitingForVisibleActivity.contains(r)) {
return false;
}
foundResumed = true;
@@ -1083,22 +1084,41 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
}
+ void waitActivityVisible(ComponentName name, WaitResult result) {
+ final WaitInfo waitInfo = new WaitInfo(name, result);
+ mWaitingForActivityVisible.add(waitInfo);
+ }
+
+ void cleanupActivity(ActivityRecord r) {
+ // Make sure this record is no longer in the pending finishes list.
+ // This could happen, for example, if we are trimming activities
+ // down to the max limit while they are still waiting to finish.
+ mFinishingActivities.remove(r);
+ mActivitiesWaitingForVisibleActivity.remove(r);
+
+ for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) {
+ if (mWaitingForActivityVisible.get(i).matches(r)) {
+ mWaitingForActivityVisible.remove(i);
+ }
+ }
+ }
+
void reportActivityVisibleLocked(ActivityRecord r) {
sendWaitingVisibleReportLocked(r);
}
void sendWaitingVisibleReportLocked(ActivityRecord r) {
boolean changed = false;
- for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
- WaitResult w = mWaitingActivityVisible.get(i);
- if (w.who == null) {
+ for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) {
+ final WaitInfo w = mWaitingForActivityVisible.get(i);
+ if (w.matches(r)) {
+ final WaitResult result = w.getResult();
changed = true;
- w.timeout = false;
- if (r != null) {
- w.who = new ComponentName(r.info.packageName, r.info.name);
- }
- w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
- w.thisTime = w.totalTime;
+ result.timeout = false;
+ result.who = w.getComponent();
+ result.totalTime = SystemClock.uptimeMillis() - result.thisTime;
+ result.thisTime = result.totalTime;
+ mWaitingForActivityVisible.remove(w);
}
}
if (changed) {
@@ -2184,7 +2204,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
for (int j = stacks.size() - 1; j >= 0; --j) {
final ActivityStack stack = stacks.get(j);
if (stack != currentFocus && stack.isFocusable()
- && stack.getStackVisibilityLocked(null) != STACK_INVISIBLE) {
+ && stack.shouldBeVisible(null) != STACK_INVISIBLE) {
return stack;
}
}
@@ -2323,7 +2343,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
mWindowManager.deferSurfaceLayout();
try {
if (fromStackId == DOCKED_STACK_ID) {
-
// We are moving all tasks from the docked stack to the fullscreen stack,
// which is dismissing the docked stack, so resize all other stacks to
// fullscreen here already so we don't end up with resize trashing.
@@ -2342,13 +2361,19 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// resize when we remove task from it below and it is detached from the
// display because it no longer contains any tasks.
mAllowDockedStackResize = false;
+ } else if (fromStackId == PINNED_STACK_ID) {
+ if (onTop) {
+ // Log if we are expanding the PiP to fullscreen
+ MetricsLogger.action(mService.mContext,
+ ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN);
+ }
}
ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
final boolean isFullscreenStackVisible = fullscreenStack != null &&
- fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
+ fullscreenStack.shouldBeVisible(null) == STACK_VISIBLE;
// If we are moving from the pinned stack, then the animation takes care of updating
// the picture-in-picture mode.
- final boolean schedulePictureInPictureModeChange = (fromStackId != PINNED_STACK_ID);
+ final boolean schedulePictureInPictureModeChange = (fromStackId == PINNED_STACK_ID);
final ArrayList<TaskRecord> tasks = stack.getAllTasks();
final int size = tasks.size();
if (onTop) {
@@ -2361,8 +2386,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// pinned stack is recreated. See moveActivityToPinnedStackLocked().
task.setTaskToReturnTo(isFullscreenStackVisible && onTop ?
APPLICATION_ACTIVITY_TYPE : HOME_ACTIVITY_TYPE);
- MetricsLogger.action(mService.mContext,
- MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN);
}
// Defer resume until all the tasks have been moved to the fullscreen stack
task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
@@ -2517,27 +2540,24 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
final ArrayList<TaskRecord> tasks = stack.getAllTasks();
if (stack.getStackId() == PINNED_STACK_ID) {
- final ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
- if (fullscreenStack != null) {
- final boolean isFullscreenStackVisible =
- fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
- for (int i = 0; i < tasks.size(); i++) {
- // Insert the task either at the top of the fullscreen stack if it is hidden,
- // or to the bottom if it is currently visible
- final int insertPosition = isFullscreenStackVisible ? 0
- : fullscreenStack.getChildCount();
- final TaskRecord task = tasks.get(i);
- // Defer resume until we remove all the tasks
- task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, insertPosition,
- REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME, "removeStack");
- }
- ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- resumeFocusedStackTopActivityLocked();
- } else {
- // If there is no fullscreen stack, then create the stack and move all the tasks
- // onto the stack
- moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP);
- }
+ /**
+ * Workaround: Force-stop all the activities in the pinned stack before we reparent them
+ * to the fullscreen stack. This is to guarantee that when we are removing a stack,
+ * that the client receives onStop() before it is reparented. We do this by detaching
+ * the stack from the display so that it will be considered invisible when
+ * ensureActivitiesVisibleLocked() is called, and all of its activitys will be marked
+ * invisible as well and added to the stopping list. After which we process the
+ * stopping list by handling the idle.
+ */
+ final PinnedActivityStack pinnedStack = (PinnedActivityStack) stack;
+ pinnedStack.mForceHidden = true;
+ pinnedStack.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
+ pinnedStack.mForceHidden = false;
+ activityIdleInternalLocked(null, false /* fromTimeout */,
+ true /* processPausingActivites */, null /* configuration */);
+
+ // Move all the tasks to the bottom of the fullscreen stack
+ moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP);
} else {
for (int i = tasks.size() - 1; i >= 0; i--) {
removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
@@ -2915,6 +2935,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
resumeFocusedStackTopActivityLocked();
+ // TODO(b/36099777): Schedule the PiP mode change here immediately until we can defer all
+ // callbacks until after the bounds animation
+ scheduleUpdatePictureInPictureModeIfNeeded(r.getTask(), destBounds, true /* immediate */);
+
stack.animateResizePinnedStack(sourceBounds, destBounds, -1 /* animationDuration */);
mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName);
}
@@ -3421,13 +3445,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
final boolean nowVisible = allResumedActivitiesVisible();
for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord s = mStoppingActivities.get(activityNdx);
- // TODO: Remove mWaitingVisibleActivities list and just remove activity from
- // mStoppingActivities when something else comes up.
- boolean waitingVisible = mWaitingVisibleActivities.contains(s);
+ boolean waitingVisible = mActivitiesWaitingForVisibleActivity.contains(s);
if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
+ " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
if (waitingVisible && nowVisible) {
- mWaitingVisibleActivities.remove(s);
+ mActivitiesWaitingForVisibleActivity.remove(s);
waitingVisible = false;
if (s.finishing) {
// If this activity is finishing, it is sitting on top of
@@ -3520,6 +3542,13 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
}
}
+ if (!mWaitingForActivityVisible.isEmpty()) {
+ pw.print(prefix); pw.println("mWaitingForActivityVisible=");
+ for (int i = 0; i < mWaitingForActivityVisible.size(); ++i) {
+ pw.print(prefix); pw.print(prefix); mWaitingForActivityVisible.get(i).dump(pw, prefix);
+ }
+ }
+
pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
mKeyguardController.dump(pw, prefix);
}
@@ -3554,7 +3583,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
ActivityStack stack = stacks.get(stackNdx);
if (!dumpVisibleStacksOnly ||
- stack.getStackVisibilityLocked(null) == STACK_VISIBLE) {
+ stack.shouldBeVisible(null) == STACK_VISIBLE) {
activities.addAll(stack.getDumpActivitiesLocked(name));
}
}
@@ -3642,9 +3671,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
false, dumpPackage, true, " Activities waiting to finish:", null);
printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
false, dumpPackage, true, " Activities waiting to stop:", null);
- printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
- false, dumpPackage, true, " Activities waiting for another to become visible:",
- null);
+ printed |= dumpHistoryList(fd, pw, mActivitiesWaitingForVisibleActivity, " ", "Wait",
+ false, !dumpAll, false, dumpPackage, true,
+ " Activities waiting for another to become visible:", null);
printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
false, dumpPackage, true, " Activities waiting to sleep:", null);
printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
@@ -3861,7 +3890,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
info.displayId = DEFAULT_DISPLAY;
info.stackId = stack.mStackId;
info.userId = stack.mCurrentUser;
- info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
+ info.visible = stack.shouldBeVisible(null) == STACK_VISIBLE;
info.position = display != null
? display.mStacks.indexOf(stack)
: 0;
@@ -4980,7 +5009,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
for (int j = display.mStacks.size() - 1; j >= 0; j--) {
final ActivityStack stack = display.mStacks.get(j);
// Get top activity from a visible stack and add it to the list.
- if (stack.getStackVisibilityLocked(null /* starting */)
+ if (stack.shouldBeVisible(null /* starting */)
== ActivityStack.STACK_VISIBLE) {
final ActivityRecord top = stack.topActivity();
if (top != null) {
@@ -4995,4 +5024,38 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
return topActivityTokens;
}
+
+ /**
+ * Internal container to store a match qualifier alongside a WaitResult.
+ */
+ static class WaitInfo {
+ private final ComponentName mTargetComponent;
+ private final WaitResult mResult;
+
+ public WaitInfo(ComponentName targetComponent, WaitResult result) {
+ this.mTargetComponent = targetComponent;
+ this.mResult = result;
+ }
+
+ public boolean matches(ActivityRecord record) {
+ return mTargetComponent == null ||
+ (TextUtils.equals(mTargetComponent.getPackageName(), record.info.packageName)
+ && TextUtils.equals(mTargetComponent.getClassName(), record.info.name));
+ }
+
+ public WaitResult getResult() {
+ return mResult;
+ }
+
+ public ComponentName getComponent() {
+ return mTargetComponent;
+ }
+
+ public void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "WaitInfo:");
+ pw.println(prefix + " mTargetComponent=" + mTargetComponent);
+ pw.println(prefix + " mResult=");
+ mResult.dump(pw, prefix);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index bb5f5884773e..59f6098684eb 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -74,7 +74,6 @@ import static com.android.server.am.ActivityManagerService.ANIMATE;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
@@ -118,14 +117,11 @@ import android.os.UserManager;
import android.service.voice.IVoiceInteractionSession;
import android.util.EventLog;
import android.util.Slog;
-import android.view.Display;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
-import com.android.server.LocalServices;
import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
import com.android.server.pm.InstantAppResolver;
-import com.android.server.vr.VrManagerInternal;
import com.android.server.wm.WindowManagerService;
import java.util.ArrayList;
@@ -152,7 +148,6 @@ class ActivityStarter {
// Share state variable among methods when starting an activity.
private ActivityRecord mStartActivity;
- private ActivityRecord mReusedActivity;
private Intent mIntent;
private int mCallingUid;
private ActivityOptions mOptions;
@@ -520,7 +515,7 @@ class ActivityStarter {
doPendingActivityLaunchesLocked(false);
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
- options, inTask);
+ options, inTask, outActivity);
}
/**
@@ -562,31 +557,17 @@ class ActivityStarter {
startedActivityStackId = targetStack.mStackId;
}
- // If we launched the activity from a no display activity that was launched from the home
- // screen, we also need to start recents to un-minimize the docked stack, since the
- // noDisplay activity will be finished shortly after.
- // Note that some apps have trampoline activities without noDisplay being set. In that case,
- // we have another heuristic in DockedStackDividerController.notifyAppTransitionStarting
- // that tries to detect that case.
- // TODO: We should prevent noDisplay activities from affecting task/stack ordering and
- // visibility instead of using this flag.
- final boolean noDisplayActivityOverHome = sourceRecord != null
- && sourceRecord.noDisplay
- && sourceRecord.getTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE;
- if (startedActivityStackId == DOCKED_STACK_ID
- && (prevFocusedStackId == HOME_STACK_ID || noDisplayActivityOverHome)) {
+ if (startedActivityStackId == DOCKED_STACK_ID) {
final ActivityStack homeStack = mSupervisor.getStack(HOME_STACK_ID);
- final ActivityRecord topActivityHomeStack = homeStack != null
- ? homeStack.topRunningActivityLocked() : null;
- if (topActivityHomeStack == null
- || topActivityHomeStack.mActivityType != RECENTS_ACTIVITY_TYPE) {
+ final boolean homeStackVisible = homeStack != null && homeStack.isVisible();
+ if (homeStackVisible) {
// We launch an activity while being in home stack, which means either launcher or
// recents into docked stack. We don't want the launched activity to be alone in a
// docked stack, so we want to immediately launch recents too.
if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
mWindowManager.showRecentApps(true /* fromHome */);
- return;
}
+ return;
}
if (startedActivityStackId == PINNED_STACK_ID
@@ -821,15 +802,19 @@ class ActivityStarter {
}
}
if (res == START_TASK_TO_FRONT) {
- ActivityRecord r = stack.topRunningActivityLocked();
+ final ActivityRecord r = outRecord[0];
+
+ // ActivityRecord may represent a different activity, but it should not be in
+ // the resumed state.
if (r.nowVisible && r.state == RESUMED) {
outResult.timeout = false;
- outResult.who = new ComponentName(r.info.packageName, r.info.name);
+ outResult.who = r.realActivity;
outResult.totalTime = 0;
outResult.thisTime = 0;
} else {
outResult.thisTime = SystemClock.uptimeMillis();
- mSupervisor.mWaitingActivityVisible.add(outResult);
+ mSupervisor.waitActivityVisible(r.realActivity, outResult);
+ // Note: the timeout variable is not currently not ever set.
do {
try {
mService.wait();
@@ -840,9 +825,7 @@ class ActivityStarter {
}
}
- final ActivityRecord launchedActivity = mReusedActivity != null
- ? mReusedActivity : outRecord[0];
- mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);
+ mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, outRecord[0]);
return res;
}
}
@@ -954,12 +937,13 @@ class ActivityStarter {
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
+ int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
+ ActivityRecord[] outActivity) {
int result = START_CANCELED;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
- startFlags, doResume, options, inTask);
+ startFlags, doResume, options, inTask, outActivity);
} finally {
// If we are not able to proceed, disassociate the activity from the task. Leaving an
// activity in an incomplete state can lead to issues, such as performing operations
@@ -979,7 +963,8 @@ class ActivityStarter {
// Note: This method should only be called from {@link startActivity}.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
+ int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
+ ActivityRecord[] outActivity) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
@@ -990,16 +975,16 @@ class ActivityStarter {
mIntent.setFlags(mLaunchFlags);
- mReusedActivity = getReusableIntentActivity();
+ ActivityRecord reusedActivity = getReusableIntentActivity();
final int preferredLaunchStackId =
(mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
- if (mReusedActivity != null) {
+ if (reusedActivity != null) {
// When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
// still needs to be a lock task mode violation since the task gets cleared out and
// the device would otherwise leave the locked task.
- if (mSupervisor.isLockTaskModeViolation(mReusedActivity.getTask(),
+ if (mSupervisor.isLockTaskModeViolation(reusedActivity.getTask(),
(mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
mSupervisor.showLockTaskToast();
@@ -1008,12 +993,12 @@ class ActivityStarter {
}
if (mStartActivity.getTask() == null) {
- mStartActivity.setTask(mReusedActivity.getTask());
+ mStartActivity.setTask(reusedActivity.getTask());
}
- if (mReusedActivity.getTask().intent == null) {
+ if (reusedActivity.getTask().intent == null) {
// This task was started because of movement of the activity based on affinity...
// Now that we are actually launching it, we can assign the base intent.
- mReusedActivity.getTask().setIntent(mStartActivity);
+ reusedActivity.getTask().setIntent(mStartActivity);
}
// This code path leads to delivering a new intent, we want to make sure we schedule it
@@ -1022,7 +1007,7 @@ class ActivityStarter {
if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| isDocumentLaunchesIntoExisting(mLaunchFlags)
|| mLaunchSingleInstance || mLaunchSingleTask) {
- final TaskRecord task = mReusedActivity.getTask();
+ final TaskRecord task = reusedActivity.getTask();
// In this situation we want to remove all activities from the task up to the one
// being started. In most cases this means we are resetting the task to its initial
@@ -1030,12 +1015,12 @@ class ActivityStarter {
final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
mLaunchFlags);
- // The above code can remove {@code mReusedActivity} from the task, leading to the
+ // The above code can remove {@code reusedActivity} from the task, leading to the
// the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
// task reference is needed in the call below to
// {@link setTargetStackAndMoveToFrontIfNeeded}.
- if (mReusedActivity.getTask() == null) {
- mReusedActivity.setTask(task);
+ if (reusedActivity.getTask() == null) {
+ reusedActivity.setTask(task);
}
if (top != null) {
@@ -1052,7 +1037,10 @@ class ActivityStarter {
sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
- mReusedActivity = setTargetStackAndMoveToFrontIfNeeded(mReusedActivity);
+ reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
+ if (outActivity.length > 0) {
+ outActivity[0] = reusedActivity;
+ }
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do anything
@@ -1061,7 +1049,7 @@ class ActivityStarter {
resumeTargetStackIfNeeded();
return START_RETURN_INTENT_TO_CALLER;
}
- setTaskFromIntentActivity(mReusedActivity);
+ setTaskFromIntentActivity(reusedActivity);
if (!mAddingToTask && mReuseTask == null) {
// We didn't do anything... but it was needed (a.k.a., client don't use that
@@ -1469,17 +1457,11 @@ class ActivityStarter {
}
/**
- * Returns the ID of the display to use for a new activity. If the source activity has
- * a explicit display ID set, use that to launch the activity. If not and the device is in VR
- * mode, then return the Vr mode's virtual display ID.
+ * Returns the ID of the display to use for a new activity. If the device is in VR mode,
+ * then return the Vr mode's virtual display ID. If not, if the source activity has
+ * a explicit display ID set, use that to launch the activity.
*/
private int getSourceDisplayId(ActivityRecord sourceRecord, ActivityRecord startingActivity) {
- int displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
- // If the activity has a displayId set explicitly, launch it on the same displayId.
- if (displayId != INVALID_DISPLAY) {
- return displayId;
- }
-
// Check if the Activity is a VR activity. If so, the activity should be launched in
// main display.
if (startingActivity != null && startingActivity.requestedVrComponent != null) {
@@ -1487,7 +1469,7 @@ class ActivityStarter {
}
// Get the virtual display id from ActivityManagerService.
- displayId = mService.mVrCompatibilityDisplayId;
+ int displayId = mService.mVrCompatibilityDisplayId;
if (displayId != INVALID_DISPLAY) {
if (DEBUG_STACK) {
Slog.d(TAG, "getSourceDisplayId :" + displayId);
@@ -1495,6 +1477,12 @@ class ActivityStarter {
mUsingVrCompatibilityDisplay = true;
return displayId;
}
+
+ displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
+ // If the activity has a displayId set explicitly, launch it on the same displayId.
+ if (displayId != INVALID_DISPLAY) {
+ return displayId;
+ }
return DEFAULT_DISPLAY;
}
@@ -1963,7 +1951,7 @@ class ActivityStarter {
final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
try {
startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
- null);
+ null, null /*outRecords*/);
} catch (Exception e) {
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
pal.sendErrorResult(e.getMessage());
@@ -2150,7 +2138,7 @@ class ActivityStarter {
// activity into parent's stack, because we can't find a better place.
final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
if (dockedStack != null
- && dockedStack.getStackVisibilityLocked(r) == STACK_INVISIBLE) {
+ && dockedStack.shouldBeVisible(r) == STACK_INVISIBLE) {
// There is a docked stack, but it isn't visible, so we can't launch into that.
return null;
} else {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index d83676b58552..208295847e24 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -63,6 +63,7 @@ import android.view.DisplayInfo;
import android.view.Surface;
import android.view.WindowManagerInternal;
+import com.android.server.AnimationThread;
import com.android.server.DisplayThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -257,13 +258,13 @@ public final class DisplayManagerService extends SystemService {
}
public void setupSchedulerPolicies() {
- /*
- * android.display is critical to user experience and we should
- * make sure it is not in the default foregroup groups, add it to
- * top-app to make sure it uses all the cores and scheduling
- * settings for top-app when it runs.
- */
- Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(), Process.THREAD_GROUP_TOP_APP);
+ // android.display and android.anim is critical to user experience and we should make sure
+ // it is not in the default foregroup groups, add it to top-app to make sure it uses all the
+ // cores and scheduling settings for top-app when it runs.
+ Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(),
+ Process.THREAD_GROUP_TOP_APP);
+ Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(),
+ Process.THREAD_GROUP_TOP_APP);
}
@Override
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 2b85570d66cf..85f7056ba1ad 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +16,12 @@
package com.android.server.fingerprint;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.MANAGE_FINGERPRINT;
+import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
+import static android.Manifest.permission.USE_FINGERPRINT;
+
import android.Manifest;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
@@ -30,8 +36,14 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback;
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
+import android.hardware.fingerprint.IFingerprintService;
import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
+import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.os.Binder;
import android.os.Bundle;
import android.os.DeadObjectException;
@@ -42,12 +54,12 @@ import android.os.IHwBinder;
import android.os.IRemoteCallback;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
-import android.security.KeyStore;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
+import android.security.KeyStore;
import android.service.fingerprint.FingerprintActionStatsProto;
import android.service.fingerprint.FingerprintServiceDumpProto;
import android.service.fingerprint.FingerprintUserStatsProto;
@@ -64,19 +76,6 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.IFingerprintService;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-
-import static android.Manifest.permission.INTERACT_ACROSS_USERS;
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
-import static android.Manifest.permission.MANAGE_FINGERPRINT;
-import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
-import static android.Manifest.permission.USE_FINGERPRINT;
-
import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -121,7 +120,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
private static final int MAX_FAILED_ATTEMPTS = 5;
private static final long CANCEL_TIMEOUT_LIMIT = 3000; // max wait for onCancel() from HAL,in ms
private final String mKeyguardPackage;
- private int mCurrentUserId = UserHandle.USER_CURRENT;
+ private int mCurrentUserId = UserHandle.USER_NULL;
private final FingerprintUtils mFingerprintUtils = FingerprintUtils.getInstance();
private Context mContext;
private long mHalDeviceId;
@@ -208,10 +207,6 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
public void serviceDied(long cookie) {
Slog.v(TAG, "fingerprint HAL died");
MetricsLogger.count(mContext, "fingerprintd_died", 1);
- synchronized (this) {
- mDaemon = null;
- }
- mCurrentUserId = UserHandle.USER_CURRENT;
handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /*vendorCode */);
}
@@ -300,6 +295,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
synchronized (this) {
mDaemon = null;
mHalDeviceId = 0;
+ mCurrentUserId = UserHandle.USER_NULL;
}
}
}
@@ -538,15 +534,16 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
final long token = Binder.clearCallingIdentity();
try {
// Allow current user or profiles of the current user...
- for (int profileId : um.getEnabledProfileIds(mCurrentUserId)) {
+ for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) {
if (profileId == userId) {
return true;
}
}
- return false;
} finally {
Binder.restoreCallingIdentity(token);
}
+
+ return false;
}
private boolean isForegroundActivity(int uid, int pid) {
@@ -573,12 +570,12 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
* @return true if caller can use fingerprint API
*/
private boolean canUseFingerprint(String opPackageName, boolean requireForeground, int uid,
- int pid) {
+ int pid, int userId) {
checkPermission(USE_FINGERPRINT);
if (isKeyguard(opPackageName)) {
return true; // Keyguard is always allowed
}
- if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) {
+ if (!isCurrentUserOrProfile(userId)) {
Slog.w(TAG,"Rejecting " + opPackageName + " ; not a current user or profile");
return false;
}
@@ -635,7 +632,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
} catch (RemoteException re) {
// If the remote is dead, stop notifying it
mClientActiveCallbacks.remove(callbacks.get(i));
- }
+ }
}
}
@@ -909,7 +906,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
@Override
public void run() {
if (!canUseFingerprint(opPackageName, true /* foregroundOnly */,
- callingUid, pid)) {
+ callingUid, pid, callingUserId)) {
if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
return;
}
@@ -936,10 +933,12 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
public void cancelAuthentication(final IBinder token, final String opPackageName) {
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
+ final int callingUserId = UserHandle.getCallingUserId();
mHandler.post(new Runnable() {
@Override
public void run() {
- if (!canUseFingerprint(opPackageName, true /* foregroundOnly */, uid, pid)) {
+ if (!canUseFingerprint(opPackageName, true /* foregroundOnly */, uid, pid,
+ callingUserId)) {
if (DEBUG) Slog.v(TAG, "cancelAuthentication(): reject " + opPackageName);
} else {
ClientMonitor client = mCurrentClient;
@@ -982,7 +981,6 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
startRemove(token, fingerId, groupId, userId, receiver, restricted);
}
});
-
}
public void enumerate(final IBinder token, final int userId,
@@ -995,17 +993,23 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
startEnumerate(token, userId, receiver, restricted);
}
});
-
}
@Override // Binder call
public boolean isHardwareDetected(long deviceId, String opPackageName) {
if (!canUseFingerprint(opPackageName, false /* foregroundOnly */,
- Binder.getCallingUid(), Binder.getCallingPid())) {
+ Binder.getCallingUid(), Binder.getCallingPid(),
+ UserHandle.getCallingUserId())) {
return false;
}
- IBiometricsFingerprint daemon = getFingerprintDaemon();
- return daemon != null && mHalDeviceId != 0;
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ IBiometricsFingerprint daemon = getFingerprintDaemon();
+ return daemon != null && mHalDeviceId != 0;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override // Binder call
@@ -1026,10 +1030,8 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
@Override // Binder call
public List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName) {
if (!canUseFingerprint(opPackageName, false /* foregroundOnly */,
- Binder.getCallingUid(), Binder.getCallingPid())) {
- return Collections.emptyList();
- }
- if (!isCurrentUserOrProfile(userId)) {
+ Binder.getCallingUid(), Binder.getCallingPid(),
+ UserHandle.getCallingUserId())) {
return Collections.emptyList();
}
@@ -1039,13 +1041,11 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
@Override // Binder call
public boolean hasEnrolledFingerprints(int userId, String opPackageName) {
if (!canUseFingerprint(opPackageName, false /* foregroundOnly */,
- Binder.getCallingUid(), Binder.getCallingPid())) {
+ Binder.getCallingUid(), Binder.getCallingPid(),
+ UserHandle.getCallingUserId())) {
return false;
}
- if (!isCurrentUserOrProfile(userId)) {
- return false;
- }
return FingerprintService.this.hasEnrolledFingerprints(userId);
}
@@ -1085,6 +1085,7 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
Binder.restoreCallingIdentity(ident);
}
}
+
@Override // Binder call
public void resetTimeout(byte [] token) {
checkPermission(RESET_FINGERPRINT_LOCKOUT);
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index b63b05f1f59b..b789d5cd602e 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -152,7 +152,8 @@ public class RankingHelper implements RankingConfig {
if (type != XmlPullParser.START_TAG) return;
String tag = parser.getName();
if (!TAG_RANKING.equals(tag)) return;
- mRecords.clear();
+ // Clobber groups and channels with the xml, but don't delete other data that wasn't present
+ // at the time of serialization.
mRestoredWithoutUids.clear();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
diff --git a/services/core/java/com/android/server/os/SchedulingPolicyService.java b/services/core/java/com/android/server/os/SchedulingPolicyService.java
index 5d72d5056715..a8bb80905cd2 100644
--- a/services/core/java/com/android/server/os/SchedulingPolicyService.java
+++ b/services/core/java/com/android/server/os/SchedulingPolicyService.java
@@ -48,7 +48,7 @@ public class SchedulingPolicyService extends ISchedulingPolicyService.Stub {
// Once we've verified that the caller uid is permitted, we can trust the pid but
// we can't trust the tid. No need to explicitly check for pid == 0 || tid == 0,
// since if not the case then the getThreadGroupLeader() test will also fail.
- if (!isPermittedCallingUid() || prio < PRIORITY_MIN ||
+ if (!isPermitted() || prio < PRIORITY_MIN ||
prio > PRIORITY_MAX || Process.getThreadGroupLeader(tid) != pid) {
return PackageManager.PERMISSION_DENIED;
}
@@ -65,9 +65,13 @@ public class SchedulingPolicyService extends ISchedulingPolicyService.Stub {
return PackageManager.PERMISSION_GRANTED;
}
- private boolean isPermittedCallingUid() {
- final int callingUid = Binder.getCallingUid();
- switch (callingUid) {
+ private boolean isPermitted() {
+ // schedulerservice hidl
+ if (Binder.getCallingPid() == Process.myPid()) {
+ return true;
+ }
+
+ switch (Binder.getCallingUid()) {
case Process.AUDIOSERVER_UID: // fastcapture, fastmixer
case Process.CAMERASERVER_UID: // camera high frame rate recording
return true;
diff --git a/services/core/java/com/android/server/vr/CompatibilityDisplay.java b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
index ae1d50ff1f71..ee615fd6fde4 100644
--- a/services/core/java/com/android/server/vr/CompatibilityDisplay.java
+++ b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
@@ -8,7 +8,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.graphics.ImageFormat;
+import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.ImageReader;
@@ -279,7 +279,7 @@ class CompatibilityDisplay {
*/
private void startImageReader() {
if (mImageReader == null) {
- mImageReader = ImageReader.newInstance(WIDTH, HEIGHT, ImageFormat.RAW_PRIVATE,
+ mImageReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888,
2 /* maxImages */);
}
synchronized (mVdLock) {
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java
index 56311a367577..37479c89fd35 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdater.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java
@@ -315,15 +315,6 @@ class WebViewUpdater {
}
}
- // Could not find any installed and enabled package either, use the most stable and
- // default-available provider.
- // TODO(gsennton) remove this when we have a functional WebView stub.
- for (ProviderAndPackageInfo providerAndPackage : providers) {
- if (providerAndPackage.provider.availableByDefault) {
- return providerAndPackage.packageInfo;
- }
- }
-
// This should never happen during normal operation (only with modified system images).
mAnyWebViewInstalled = false;
throw new WebViewPackageMissingException("Could not find a loadable WebView package");
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index efc92cf02dde..7ed3eac10d11 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -50,7 +50,7 @@ class AlertWindowNotification {
private String mNotificationTag;
private final NotificationManager mNotificationManager;
private final String mPackageName;
- private boolean mCancelled;
+ private boolean mPosted;
private IconUtilities mIconUtilities;
AlertWindowNotification(WindowManagerService service, String packageName) {
@@ -61,7 +61,9 @@ class AlertWindowNotification {
mNotificationTag = CHANNEL_PREFIX + mPackageName;
mRequestCode = sNextRequestCode++;
mIconUtilities = new IconUtilities(mService.mContext);
+ }
+ void post() {
// We can't create/post the notification while the window manager lock is held since it will
// end up calling into activity manager. So, we post a message to do it later.
mService.mH.post(this::onPostNotification);
@@ -76,16 +78,21 @@ class AlertWindowNotification {
/** Don't call with the window manager lock held! */
private void onCancelNotification() {
+ if (!mPosted) {
+ // Notification isn't currently posted...
+ return;
+ }
+ mPosted = false;
mNotificationManager.cancel(mNotificationTag, NOTIFICATION_ID);
- mCancelled = true;
}
/** Don't call with the window manager lock held! */
private void onPostNotification() {
- if (mCancelled) {
- // Notification was cancelled, so nothing more to do...
+ if (mPosted) {
+ // Notification already posted...
return;
}
+ mPosted = true;
final Context context = mService.mContext;
final PackageManager pm = context.getPackageManager();
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 4b4be40880ee..a39131cbaf03 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -554,7 +554,7 @@ public class AppWindowContainerController
// want to process the message ASAP, before any other queued
// messages.
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
- mHandler.postAtFrontOfQueue(mAddStartingWindow);
+ mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
}
private boolean createSnapshot() {
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 7b8057cafbb4..2811145bcf5f 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -170,8 +170,8 @@ public class BoundsAnimationController {
// If we are animating to a new fullscreen state (either to/from fullscreen), then
// notify the target of the change with the new frozen task bounds
- if (mAnimatingToNewFullscreenState) {
- mTarget.updatePictureInPictureMode(mMoveToFullScreen ? null : mTo);
+ if (mAnimatingToNewFullscreenState && mMoveToFullScreen) {
+ mTarget.updatePictureInPictureMode(null);
}
// Immediately update the task bounds if they have to become larger, but preserve
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 30e0dedd7c99..6a7123c030fc 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -81,6 +81,7 @@ public class Session extends IWindowSession.Stub
private final Set<WindowSurfaceController> mAlertWindowSurfaces = new HashSet<>();
final boolean mCanAddInternalSystemWindow;
private AlertWindowNotification mAlertWindowNotification;
+ private boolean mShowingAlertWindowNotificationAllowed;
private boolean mClientDead = false;
private float mLastReportedAnimatorScale;
private String mPackageName;
@@ -95,6 +96,7 @@ public class Session extends IWindowSession.Stub
mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission(
INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
+ mShowingAlertWindowNotificationAllowed = mService.mShowAlertWindowNotifications;
StringBuilder sb = new StringBuilder();
sb.append("Session{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
@@ -591,6 +593,9 @@ public class Session extends IWindowSession.Stub
cancelAlertWindowNotification();
} else if (mAlertWindowNotification == null){
mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName);
+ if (mShowingAlertWindowNotificationAllowed) {
+ mAlertWindowNotification.post();
+ }
}
}
}
@@ -612,6 +617,17 @@ public class Session extends IWindowSession.Stub
}
}
+ void setShowingAlertWindowNotificationAllowed(boolean allowed) {
+ mShowingAlertWindowNotificationAllowed = allowed;
+ if (mAlertWindowNotification != null) {
+ if (allowed) {
+ mAlertWindowNotification.post();
+ } else {
+ mAlertWindowNotification.cancel();
+ }
+ }
+ }
+
private void killSessionLocked() {
if (mNumWindow > 0 || !mClientDead) {
return;
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 635527e68ffe..5d0384e34e93 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -94,6 +94,12 @@ public class StackWindowController
}
}
+ public boolean isVisible() {
+ synchronized (mWindowMap) {
+ return mContainer != null && mContainer.isVisible();
+ }
+ }
+
public void reparent(int displayId, Rect outStackBounds) {
synchronized (mWindowMap) {
if (mContainer == null) {
@@ -363,7 +369,7 @@ public class StackWindowController
}
/** Calls directly into activity manager so window manager lock shouldn't held. */
- public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
+ void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
if (mListener != null) {
mListener.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
}
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 53c24e13e859..0c68e2ca6d77 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -262,7 +262,8 @@ class TaskPositioner implements DimLayer.DimLayerUser {
mService.mInputManager.registerInputChannel(mServerChannel, null);
mInputEventReceiver = new WindowPositionerEventReceiver(
- mClientChannel, mService.mH.getLooper(), mService.mChoreographer);
+ mClientChannel, mService.mAnimationHandler.getLooper(),
+ mService.mAnimator.getChoreographer());
mDragApplicationHandle = new InputApplicationHandle(null);
mDragApplicationHandle.name = TAG;
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 57eaa2b2ad8d..1367a06eb110 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -25,7 +25,6 @@ import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_C
import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
import android.content.Context;
-import android.os.Handler;
import android.os.Trace;
import android.util.Slog;
import android.util.SparseArray;
@@ -35,7 +34,7 @@ import android.view.SurfaceControl;
import android.view.WindowManagerPolicy;
import com.android.internal.view.SurfaceFlingerVsyncChoreographer;
-import com.android.server.DisplayThread;
+import com.android.server.AnimationThread;
import java.io.PrintWriter;
@@ -87,20 +86,25 @@ public class WindowAnimator {
private final Runnable mAnimationTick;
private final SurfaceFlingerVsyncChoreographer mSfChoreographer;
+ private Choreographer mChoreographer;
+ private boolean mAnimationScheduled;
+
+
WindowAnimator(final WindowManagerService service) {
mService = service;
mContext = service.mContext;
mPolicy = service.mPolicy;
mWindowPlacerLocked = service.mWindowPlacerLocked;
- final Handler handler = DisplayThread.getHandler();
+ AnimationThread.getHandler().runWithScissors(
+ () -> mChoreographer = Choreographer.getInstance(), 0 /* timeout */);
// TODO: Multi-display: If displays have different vsync tick, have a separate tick per
// display.
- mSfChoreographer = new SurfaceFlingerVsyncChoreographer(handler,
- mService.getDefaultDisplayContentLocked().getDisplay());
+ mSfChoreographer = new SurfaceFlingerVsyncChoreographer(AnimationThread.getHandler(),
+ mService.getDefaultDisplayContentLocked().getDisplay(), mChoreographer);
mAnimationTick = () -> {
synchronized (mService.mWindowMap) {
- mService.mAnimationScheduled = false;
+ mAnimationScheduled = false;
animateLocked(mCurrentFrameTime);
}
};
@@ -366,6 +370,13 @@ public class WindowAnimator {
mRemoveReplacedWindows = true;
}
+ void scheduleAnimation() {
+ if (!mAnimationScheduled) {
+ mAnimationScheduled = true;
+ mChoreographer.postFrameCallback(mAnimationFrameCallback);
+ }
+ }
+
private class DisplayContentsAnimator {
ScreenRotationAnimation mScreenRotationAnimation = null;
}
@@ -374,6 +385,14 @@ public class WindowAnimator {
return mAnimating;
}
+ boolean isAnimationScheduled() {
+ return mAnimationScheduled;
+ }
+
+ Choreographer getChoreographer() {
+ return mChoreographer;
+ }
+
void setAnimating(boolean animating) {
mAnimating = animating;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1be051270e16..0f4707e56164 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -31,6 +31,7 @@ import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.os.Process.myPid;
+import static android.os.Process.myTid;
import static android.os.UserHandle.USER_NULL;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.DOCKED_INVALID;
@@ -147,6 +148,7 @@ import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StrictMode;
@@ -169,7 +171,6 @@ import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.TypedValue;
import android.view.AppTransitionAnimationSpec;
-import android.view.Choreographer;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Gravity;
@@ -218,6 +219,7 @@ import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.WindowManagerPolicyThread;
+import com.android.server.AnimationThread;
import com.android.server.DisplayThread;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
@@ -402,6 +404,9 @@ public class WindowManagerService extends IWindowManager.Stub
final DisplaySettings mDisplaySettings;
+ /** If the system should display notifications for apps displaying an alert window. */
+ boolean mShowAlertWindowNotifications = true;
+
/**
* All currently active sessions with clients.
*/
@@ -601,7 +606,12 @@ public class WindowManagerService extends IWindowManager.Stub
final H mH = new H();
- final Choreographer mChoreographer = Choreographer.getInstance();
+ /**
+ * Handler for things to run that have direct impact on an animation, i.e. animation tick,
+ * layout, starting window creation, whereas {@link H} runs things that are still important, but
+ * not as critical.
+ */
+ final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper());
WindowState mCurrentFocus = null;
WindowState mLastFocus = null;
@@ -708,8 +718,6 @@ public class WindowManagerService extends IWindowManager.Stub
// For frozen screen animations.
private int mExitAnimId, mEnterAnimId;
- boolean mAnimationScheduled;
-
/** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
* is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
int mTransactionSequence;
@@ -4645,7 +4653,6 @@ public class WindowManagerService extends IWindowManager.Stub
final class H extends android.os.Handler {
public static final int REPORT_FOCUS_CHANGE = 2;
public static final int REPORT_LOSING_FOCUS = 3;
- public static final int DO_TRAVERSAL = 4;
public static final int WINDOW_FREEZE_TIMEOUT = 11;
public static final int APP_TRANSITION_TIMEOUT = 13;
@@ -4775,12 +4782,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
} break;
- case DO_TRAVERSAL: {
- synchronized(mWindowMap) {
- mWindowPlacerLocked.performSurfacePlacement();
- }
- } break;
-
case WINDOW_FREEZE_TIMEOUT: {
// TODO(multidisplay): Can non-default displays rotate?
synchronized (mWindowMap) {
@@ -4849,7 +4850,7 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mWindowMap) {
// Since we're holding both mWindowMap and mAnimator we don't need to
// hold mAnimator.mLayoutToAnim.
- if (mAnimator.isAnimating() || mAnimationScheduled) {
+ if (mAnimator.isAnimating() || mAnimator.isAnimationScheduled()) {
// If we are animating, don't do the gc now but
// delay a bit so we don't interrupt the animation.
sendEmptyMessageDelayed(H.FORCE_GC, 2000);
@@ -5744,10 +5745,7 @@ public class WindowManagerService extends IWindowManager.Stub
/** Note that Locked in this case is on mLayoutToAnim */
void scheduleAnimationLocked() {
- if (!mAnimationScheduled) {
- mAnimationScheduled = true;
- mChoreographer.postFrameCallback(mAnimator.mAnimationFrameCallback);
- }
+ mAnimator.scheduleAnimation();
}
// TODO: Move to DisplayContent
@@ -7370,4 +7368,21 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
+
+ /** Called to inform window manager if non-Vr UI shoul be disabled or not. */
+ public void disableNonVrUi(boolean disable) {
+ synchronized (mWindowMap) {
+ // Allow alert window notifications to be shown if non-vr UI is enabled.
+ final boolean showAlertWindowNotifications = !disable;
+ if (showAlertWindowNotifications == mShowAlertWindowNotifications) {
+ return;
+ }
+ mShowAlertWindowNotifications = showAlertWindowNotifications;
+
+ for (int i = mSessions.size() - 1; i >= 0; --i) {
+ final Session s = mSessions.valueAt(i);
+ s.setShowingAlertWindowNotificationAllowed(mShowAlertWindowNotifications);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index ee2d5de710c1..ddd1ca5c1aec 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -30,7 +30,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACT
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
@@ -97,9 +96,16 @@ class WindowSurfacePlacer {
private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
private final SparseIntArray mTempTransitionReasons = new SparseIntArray();
+ private final Runnable mPerformSurfacePlacement;
+
public WindowSurfacePlacer(WindowManagerService service) {
mService = service;
mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
+ mPerformSurfacePlacement = () -> {
+ synchronized (mService.mWindowMap) {
+ performSurfacePlacement();
+ }
+ };
}
/**
@@ -131,7 +137,7 @@ class WindowSurfacePlacer {
do {
mTraversalScheduled = false;
performSurfacePlacementLoop();
- mService.mH.removeMessages(DO_TRAVERSAL);
+ mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
loopCount--;
} while (mTraversalScheduled && loopCount > 0);
mService.mRoot.mWallpaperActionPending = false;
@@ -735,7 +741,7 @@ class WindowSurfacePlacer {
void requestTraversal() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
- mService.mH.sendEmptyMessage(DO_TRAVERSAL);
+ mService.mAnimationHandler.post(mPerformSurfacePlacement);
}
}
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index b5ed26630b23..23637de70f9c 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -64,6 +64,7 @@ LOCAL_SHARED_LIBRARIES += \
libinput \
libinputflinger \
libinputservice \
+ libschedulerservicehidl \
libsensorservice \
libsensorservicehidl \
libskia \
@@ -89,6 +90,7 @@ LOCAL_SHARED_LIBRARIES += \
android.hardware.tv.input@1.0 \
android.hardware.vibrator@1.0 \
android.hardware.vr@1.0 \
+ android.frameworks.schedulerservice@1.0 \
android.frameworks.sensorservice@1.0 \
LOCAL_STATIC_LIBRARIES += libscrypt_static
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index 8ad88eddd73b..4a08ce4aebb7 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -19,6 +19,7 @@
#include <hidl/HidlTransportSupport.h>
+#include <schedulerservice/SchedulingPolicyService.h>
#include <sensorservice/SensorService.h>
#include <sensorservicehidl/SensorManager.h>
@@ -39,17 +40,23 @@ static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jo
}
static void android_server_SystemServer_startHidlServices(JNIEnv* /* env */, jobject /* clazz */) {
+ using ::android::frameworks::schedulerservice::V1_0::ISchedulingPolicyService;
+ using ::android::frameworks::schedulerservice::V1_0::implementation::SchedulingPolicyService;
using ::android::frameworks::sensorservice::V1_0::ISensorManager;
using ::android::frameworks::sensorservice::V1_0::implementation::SensorManager;
using ::android::hardware::configureRpcThreadpool;
+ status_t err;
+
configureRpcThreadpool(1, false /* callerWillJoin */);
+
sp<ISensorManager> sensorService = new SensorManager();
- status_t err = sensorService->registerAsService();
- if (err != OK) {
- ALOGE("Cannot register ::android::frameworks::sensorservice::V1_0::"
- "implementation::SensorManager: %d", err);
- }
+ err = sensorService->registerAsService();
+ ALOGE_IF(err != OK, "Cannot register %s: %d", ISensorManager::descriptor, err);
+
+ sp<ISchedulingPolicyService> schedulingService = new SchedulingPolicyService();
+ err = schedulingService->registerAsService();
+ ALOGE_IF(err != OK, "Cannot register %s: %d", ISchedulingPolicyService::descriptor, err);
}
/*
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index ad593be199b7..885eb2ea235a 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -490,6 +490,19 @@ public class RankingHelperTest {
}
@Test
+ public void testLoadingOldChannelsDoesNotDeleteNewlyCreatedChannels() throws Exception {
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
+ NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
+ mHelper.createNotificationChannel(PKG, UID,
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
+
+ loadStreamXml(baos);
+
+ // Should still have the newly created channel that wasn't in the xml.
+ assertTrue(mHelper.getNotificationChannel(PKG, UID, "bananas", false) != null);
+ }
+
+ @Test
public void testCreateChannel_blocked() throws Exception {
mHelper.setImportance(PKG, UID, NotificationManager.IMPORTANCE_NONE);
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index 925f41490e4c..9c8007a9d489 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -1219,14 +1219,11 @@ public class WebViewUpdateServiceTest {
runWebViewBootPreparationOnMainSync();
- checkPreparationPhasesForPackage(testPackageName, 1 /* first preparation phase */);
- // TODO(gsennton) change this logic to use the code below when we have created a functional
- // stub.
- //Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
- // Matchers.anyObject());
- //WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
- //assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
- //assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage());
+ Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
+ Matchers.anyObject());
+ WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
+ assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
+ assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
index 25004de60676..3c8bf206b8a6 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -98,11 +98,11 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
createAppWindowController();
controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
- waitUntilHandlerIdle();
+ waitUntilHandlersIdle();
final AppWindowToken atoken = controller.getAppWindowToken();
assertHasStartingWindow(atoken);
controller.removeStartingWindow();
- waitUntilHandlerIdle();
+ waitUntilHandlersIdle();
assertNoStartingWindow(atoken);
}
@@ -114,11 +114,11 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
createAppWindowController();
controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
- waitUntilHandlerIdle();
+ waitUntilHandlersIdle();
controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
true, true, false);
- waitUntilHandlerIdle();
+ waitUntilHandlersIdle();
assertNoStartingWindow(controller1.getAppWindowToken());
assertHasStartingWindow(controller2.getAppWindowToken());
}
@@ -138,7 +138,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
});
controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
- waitUntilHandlerIdle();
+ waitUntilHandlersIdle();
assertNoStartingWindow(controller1.getAppWindowToken());
assertHasStartingWindow(controller2.getAppWindowToken());
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index eaf4ac4baf4f..218af7356e30 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -167,8 +167,9 @@ class WindowTestsBase {
/**
* Waits until the main handler for WM has processed all messages.
*/
- void waitUntilHandlerIdle() {
+ void waitUntilHandlersIdle() {
sWm.mH.runWithScissors(() -> { }, 0);
+ sWm.mAnimationHandler.runWithScissors(() -> { }, 0);
}
private static WindowToken createWindowToken(DisplayContent dc, int stackId, int type) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index bb8363316dd8..0b4a3e8cac90 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -771,6 +771,13 @@ public class CarrierConfigManager {
public static final String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
/**
+ * Determines whether the Enhanced 4G LTE toggle will be shown in the settings. When this
+ * option is {@code true}, the toggle will be hidden regardless of whether the device and
+ * carrier supports 4G LTE or not.
+ */
+ public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
+
+ /**
* Determine whether IMS apn can be shown.
*/
public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
@@ -1529,6 +1536,7 @@ public class CarrierConfigManager {
sDefaults.putInt(KEY_IMS_CONFERENCE_SIZE_LIMIT_INT, 5);
sDefaults.putBoolean(KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, true);
sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
+ sDefaults.putBoolean(KEY_HIDE_ENHANCED_4G_LTE_BOOL, false);
sDefaults.putBoolean(KEY_HIDE_IMS_APN_BOOL, false);
sDefaults.putBoolean(KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, false);
sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, false);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8357a2b535a4..1fd1929dbe01 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3106,30 +3106,6 @@ public class TelephonyManager {
}
/**
- * Send the special dialer code. The IPC caller must be the current default dialer.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- *
- * @param inputCode The special dialer code to send which follows the format of *#*#<code>#*#*
- * @return true if sent sucessfully, false otherwise
- * @deprecated use {@link #sendDialerSpecialCode(String)} ()} instead.
- */
- public boolean sendDialerCode(String inputCode) {
- try {
- final ITelephony telephony = getITelephony();
- if (telephony == null) {
- Log.e(TAG, "Telephony service unavailable");
- return false;
- }
- return telephony.sendDialerCode(mContext.getOpPackageName(), inputCode);
- } catch (RemoteException | NullPointerException ex) {
- // This could happen before phone restarts due to crashing
- return false;
- }
- }
-
- /**
* Send the special dialer code. The IPC caller must be the current default dialer or has
* carrier privileges.
* @see #hasCarrierPrivileges
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index cd15c444d8bd..db7e417cbcb5 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -530,9 +530,6 @@ interface ITelephony {
in String number, in int port, in String text, in PendingIntent sentIntent);
// Send the special dialer code. The IPC caller must be the current default dialer.
- boolean sendDialerCode(String callingPackageName, String inputCode);
-
- // Send the special dialer code. The IPC caller must be the current default dialer.
void sendDialerSpecialCode(String callingPackageName, String inputCode);
/**
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index a33fd0673d98..407eb5266785 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -2151,7 +2151,7 @@ int Link(const std::vector<StringPiece>& args) {
}
AxisConfigFilter filter;
- if (configs.empty()) {
+ if (!configs.empty()) {
for (const std::string& config_arg : configs) {
for (const StringPiece& config_str : util::Tokenize(config_arg, ',')) {
ConfigDescription config;