Merge "[Ongoing Call] Use the notification's key to identify when to remove the ongoing call chip, rather than the notification's template." into sc-dev
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
index cfcb4e7..80317e4 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7351002"
+ build_id: "7396576"
target: "CtsShim"
source_file: "aosp_arm64/CtsShimPriv.apk"
}
@@ -9,4 +9,5 @@
version_group: ""
git_project: "platform/frameworks/base"
git_branch: "sc-dev"
+ transform: TRANSFORM_NONE
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
index 0948e47..3605b6d 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7351002"
+ build_id: "7396576"
target: "CtsShim"
source_file: "aosp_arm64/CtsShim.apk"
}
@@ -9,4 +9,5 @@
version_group: ""
git_project: "platform/frameworks/base"
git_branch: "sc-dev"
+ transform: TRANSFORM_NONE
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
index db64475..025ec3a 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7351002"
+ build_id: "7396576"
target: "CtsShim"
source_file: "aosp_x86_64/CtsShimPriv.apk"
}
@@ -9,4 +9,5 @@
version_group: ""
git_project: "platform/frameworks/base"
git_branch: "sc-dev"
+ transform: TRANSFORM_NONE
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
index 80812df..e19235a 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "7351002"
+ build_id: "7396576"
target: "CtsShim"
source_file: "aosp_x86_64/CtsShim.apk"
}
@@ -9,4 +9,5 @@
version_group: ""
git_project: "platform/frameworks/base"
git_branch: "sc-dev"
+ transform: TRANSFORM_NONE
}
diff --git a/core/api/current.txt b/core/api/current.txt
index 4c61afe..1de47b5 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -246,7 +246,6 @@
public static final class R.attr {
ctor public R.attr();
- field public static final int __removed3;
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -308,7 +307,7 @@
field public static final int allowAudioPlaybackCapture = 16844289; // 0x1010601
field public static final int allowBackup = 16843392; // 0x1010280
field public static final int allowClearUserData = 16842757; // 0x1010005
- field public static final int allowClickWhenDisabled;
+ field public static final int allowClickWhenDisabled = 16844312; // 0x1010618
field public static final int allowEmbedded = 16843765; // 0x10103f5
field public static final int allowNativeHeapPointerTagging = 16844306; // 0x1010612
field public static final int allowParallelSyncs = 16843570; // 0x1010332
@@ -339,8 +338,8 @@
field public static final int apiKey = 16843281; // 0x1010211
field public static final int appCategory = 16844101; // 0x1010545
field public static final int appComponentFactory = 16844154; // 0x101057a
- field public static final int attributionTags;
- field public static final int attributionsAreUserVisible;
+ field public static final int attributionTags = 16844354; // 0x1010642
+ field public static final int attributionsAreUserVisible = 16844363; // 0x101064b
field public static final int author = 16843444; // 0x10102b4
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
@@ -406,7 +405,7 @@
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
field public static final int canControlMagnification = 16844039; // 0x1010507
- field public static final int canPauseRecording;
+ field public static final int canPauseRecording = 16844314; // 0x101061a
field public static final int canPerformGestures = 16844045; // 0x101050d
field public static final int canRecord = 16844060; // 0x101051c
field @Deprecated public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
@@ -448,7 +447,7 @@
field public static final int clickable = 16842981; // 0x10100e5
field public static final int clipChildren = 16842986; // 0x10100ea
field public static final int clipOrientation = 16843274; // 0x101020a
- field public static final int clipToOutline;
+ field public static final int clipToOutline = 16844328; // 0x1010628
field public static final int clipToPadding = 16842987; // 0x10100eb
field public static final int closeIcon = 16843905; // 0x1010481
field @Deprecated public static final int codes = 16843330; // 0x1010242
@@ -518,7 +517,7 @@
field public static final int dashGap = 16843175; // 0x10101a7
field public static final int dashWidth = 16843174; // 0x10101a6
field public static final int data = 16842798; // 0x101002e
- field public static final int dataExtractionRules;
+ field public static final int dataExtractionRules = 16844350; // 0x101063e
field public static final int datePickerDialogTheme = 16843948; // 0x10104ac
field public static final int datePickerMode = 16843955; // 0x10104b3
field public static final int datePickerStyle = 16843612; // 0x101035c
@@ -540,8 +539,8 @@
field public static final int detailSocialSummary = 16843428; // 0x10102a4
field public static final int detailsElementBackground = 16843598; // 0x101034e
field public static final int dial = 16843010; // 0x1010102
- field public static final int dialTint;
- field public static final int dialTintMode;
+ field public static final int dialTint = 16844342; // 0x1010636
+ field public static final int dialTintMode = 16844343; // 0x1010637
field public static final int dialogCornerRadius = 16844145; // 0x1010571
field public static final int dialogIcon = 16843252; // 0x10101f4
field public static final int dialogLayout = 16843255; // 0x10101f7
@@ -595,7 +594,7 @@
field public static final int editTextStyle = 16842862; // 0x101006e
field @Deprecated public static final int editable = 16843115; // 0x101016b
field public static final int editorExtras = 16843300; // 0x1010224
- field public static final int effectColor;
+ field public static final int effectColor = 16844361; // 0x1010649
field public static final int elegantTextHeight = 16843869; // 0x101045d
field public static final int elevation = 16843840; // 0x1010440
field public static final int ellipsize = 16842923; // 0x10100ab
@@ -675,7 +674,7 @@
field @Deprecated public static final int fontProviderCerts = 16844125; // 0x101055d
field @Deprecated public static final int fontProviderPackage = 16844119; // 0x1010557
field @Deprecated public static final int fontProviderQuery = 16844113; // 0x1010551
- field public static final int fontProviderSystemFontFamily;
+ field public static final int fontProviderSystemFontFamily = 16844322; // 0x1010622
field public static final int fontStyle = 16844095; // 0x101053f
field public static final int fontVariationSettings = 16844144; // 0x1010570
field public static final int fontWeight = 16844083; // 0x1010533
@@ -739,14 +738,14 @@
field public static final int groupIndicator = 16843019; // 0x101010b
field public static final int gwpAsanMode = 16844310; // 0x1010616
field public static final int hand_hour = 16843011; // 0x1010103
- field public static final int hand_hourTint;
- field public static final int hand_hourTintMode;
+ field public static final int hand_hourTint = 16844344; // 0x1010638
+ field public static final int hand_hourTintMode = 16844345; // 0x1010639
field public static final int hand_minute = 16843012; // 0x1010104
- field public static final int hand_minuteTint;
- field public static final int hand_minuteTintMode;
- field public static final int hand_second;
- field public static final int hand_secondTint;
- field public static final int hand_secondTintMode;
+ field public static final int hand_minuteTint = 16844346; // 0x101063a
+ field public static final int hand_minuteTintMode = 16844347; // 0x101063b
+ field public static final int hand_second = 16844323; // 0x1010623
+ field public static final int hand_secondTint = 16844348; // 0x101063c
+ field public static final int hand_secondTintMode = 16844349; // 0x101063d
field public static final int handle = 16843354; // 0x101025a
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
@@ -830,7 +829,7 @@
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interactiveUiTimeout = 16844181; // 0x1010595
field public static final int interpolator = 16843073; // 0x1010141
- field public static final int isAccessibilityTool;
+ field public static final int isAccessibilityTool = 16844353; // 0x1010641
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
field public static final int isAsciiCapable = 16843753; // 0x10103e9
field public static final int isAuxiliary = 16843647; // 0x101037f
@@ -872,8 +871,8 @@
field public static final int keyboardNavigationCluster = 16844096; // 0x1010540
field public static final int keycode = 16842949; // 0x10100c5
field public static final int killAfterRestore = 16843420; // 0x101029c
- field public static final int knownCerts;
- field public static final int lStar;
+ field public static final int knownCerts = 16844330; // 0x101062a
+ field public static final int lStar = 16844359; // 0x1010647
field public static final int label = 16842753; // 0x1010001
field public static final int labelFor = 16843718; // 0x10103c6
field @Deprecated public static final int labelTextSize = 16843317; // 0x1010235
@@ -983,8 +982,8 @@
field public static final int maxLines = 16843091; // 0x1010153
field public static final int maxLongVersionCode = 16844163; // 0x1010583
field public static final int maxRecents = 16843846; // 0x1010446
- field public static final int maxResizeHeight;
- field public static final int maxResizeWidth;
+ field public static final int maxResizeHeight = 16844339; // 0x1010633
+ field public static final int maxResizeWidth = 16844338; // 0x1010632
field public static final int maxRows = 16843059; // 0x1010133
field public static final int maxSdkVersion = 16843377; // 0x1010271
field public static final int maxWidth = 16843039; // 0x101011f
@@ -993,7 +992,7 @@
field public static final int measureWithLargestChild = 16843476; // 0x10102d4
field public static final int mediaRouteButtonStyle = 16843693; // 0x10103ad
field public static final int mediaRouteTypes = 16843694; // 0x10103ae
- field public static final int memtagMode;
+ field public static final int memtagMode = 16844324; // 0x1010624
field public static final int menuCategory = 16843230; // 0x10101de
field public static final int mimeGroup = 16844309; // 0x1010615
field public static final int mimeType = 16842790; // 0x1010026
@@ -1017,7 +1016,7 @@
field public static final int multiArch = 16843918; // 0x101048e
field public static final int multiprocess = 16842771; // 0x1010013
field public static final int name = 16842755; // 0x1010003
- field public static final int nativeHeapZeroInitialized;
+ field public static final int nativeHeapZeroInitialized = 16844325; // 0x1010625
field public static final int navigationBarColor = 16843858; // 0x1010452
field public static final int navigationBarDividerColor = 16844141; // 0x101056d
field public static final int navigationContentDescription = 16843969; // 0x10104c1
@@ -1087,13 +1086,13 @@
field public static final int panelTextAppearance = 16842850; // 0x1010062
field public static final int parentActivityName = 16843687; // 0x10103a7
field @Deprecated public static final int password = 16843100; // 0x101015c
- field public static final int passwordsActivity;
+ field public static final int passwordsActivity = 16844351; // 0x101063f
field public static final int path = 16842794; // 0x101002a
- field public static final int pathAdvancedPattern;
+ field public static final int pathAdvancedPattern = 16844320; // 0x1010620
field public static final int pathData = 16843781; // 0x1010405
field public static final int pathPattern = 16842796; // 0x101002c
field public static final int pathPrefix = 16842795; // 0x101002b
- field public static final int pathSuffix;
+ field public static final int pathSuffix = 16844318; // 0x101061e
field public static final int patternPathData = 16843978; // 0x10104ca
field public static final int permission = 16842758; // 0x1010006
field public static final int permissionFlags = 16843719; // 0x10103c7
@@ -1130,7 +1129,7 @@
field public static final int presentationTheme = 16843712; // 0x10103c0
field public static final int preserveLegacyExternalStorage = 16844308; // 0x1010614
field public static final int previewImage = 16843482; // 0x10102da
- field public static final int previewLayout;
+ field public static final int previewLayout = 16844327; // 0x1010627
field public static final int primaryContentAlpha = 16844114; // 0x1010552
field public static final int priority = 16842780; // 0x101001c
field public static final int privateImeOptions = 16843299; // 0x1010223
@@ -1187,8 +1186,8 @@
field public static final int reqNavigation = 16843306; // 0x101022a
field public static final int reqTouchScreen = 16843303; // 0x1010227
field public static final int requestLegacyExternalStorage = 16844291; // 0x1010603
- field public static final int requestRawExternalStorageAccess;
- field public static final int requireDeviceScreenOn;
+ field public static final int requestRawExternalStorageAccess = 16844357; // 0x1010645
+ field public static final int requireDeviceScreenOn = 16844317; // 0x101061d
field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
field public static final int required = 16843406; // 0x101028e
field public static final int requiredAccountType = 16843734; // 0x10103d6
@@ -1213,7 +1212,7 @@
field public static final int right = 16843183; // 0x10101af
field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
field public static final int ringtoneType = 16843257; // 0x10101f9
- field public static final int rollbackDataPolicy;
+ field public static final int rollbackDataPolicy = 16844311; // 0x1010617
field public static final int rotation = 16843558; // 0x1010326
field public static final int rotationAnimation = 16844090; // 0x101053a
field public static final int rotationX = 16843559; // 0x1010327
@@ -1274,7 +1273,7 @@
field public static final int segmentedButtonStyle = 16843568; // 0x1010330
field public static final int selectAllOnFocus = 16843102; // 0x101015e
field public static final int selectable = 16843238; // 0x10101e6
- field public static final int selectableAsDefault;
+ field public static final int selectableAsDefault = 16844352; // 0x1010640
field public static final int selectableItemBackground = 16843534; // 0x101030e
field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c
field @Deprecated public static final int selectedDateVerticalBar = 16843591; // 0x1010347
@@ -1302,7 +1301,7 @@
field public static final int showDefault = 16843258; // 0x10101fa
field public static final int showDividers = 16843561; // 0x1010329
field public static final int showForAllUsers = 16844015; // 0x10104ef
- field public static final int showInInputMethodPicker;
+ field public static final int showInInputMethodPicker = 16844360; // 0x1010648
field public static final int showMetadataInPreview = 16844079; // 0x101052f
field @Deprecated public static final int showOnLockScreen = 16843721; // 0x10103c9
field public static final int showSilent = 16843259; // 0x10101fb
@@ -1325,17 +1324,17 @@
field public static final int spinnerMode = 16843505; // 0x10102f1
field public static final int spinnerStyle = 16842881; // 0x1010081
field public static final int spinnersShown = 16843595; // 0x101034b
- field public static final int splashScreenTheme;
+ field public static final int splashScreenTheme = 16844337; // 0x1010631
field public static final int splitMotionEvents = 16843503; // 0x10102ef
field public static final int splitName = 16844105; // 0x1010549
field public static final int splitTrack = 16843852; // 0x101044c
field public static final int spotShadowAlpha = 16843967; // 0x10104bf
field public static final int src = 16843033; // 0x1010119
field public static final int ssp = 16843747; // 0x10103e3
- field public static final int sspAdvancedPattern;
+ field public static final int sspAdvancedPattern = 16844321; // 0x1010621
field public static final int sspPattern = 16843749; // 0x10103e5
field public static final int sspPrefix = 16843748; // 0x10103e4
- field public static final int sspSuffix;
+ field public static final int sspSuffix = 16844319; // 0x101061f
field public static final int stackFromBottom = 16843005; // 0x10100fd
field public static final int stackViewStyle = 16843838; // 0x101043e
field public static final int starStyle = 16842882; // 0x1010082
@@ -1408,7 +1407,7 @@
field public static final int supportsRtl = 16843695; // 0x10103af
field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
field public static final int supportsUploading = 16843419; // 0x101029b
- field public static final int suppressesSpellChecker;
+ field public static final int suppressesSpellChecker = 16844355; // 0x1010643
field public static final int switchMinWidth = 16843632; // 0x1010370
field public static final int switchPadding = 16843633; // 0x1010371
field public static final int switchPreferenceStyle = 16843629; // 0x101036d
@@ -1423,8 +1422,8 @@
field public static final int tabWidgetStyle = 16842883; // 0x1010083
field public static final int tag = 16842961; // 0x10100d1
field public static final int targetActivity = 16843266; // 0x1010202
- field public static final int targetCellHeight;
- field public static final int targetCellWidth;
+ field public static final int targetCellHeight = 16844341; // 0x1010635
+ field public static final int targetCellWidth = 16844340; // 0x1010634
field public static final int targetClass = 16842799; // 0x101002f
field @Deprecated public static final int targetDescriptions = 16843680; // 0x10103a0
field public static final int targetId = 16843740; // 0x10103dc
@@ -1594,7 +1593,7 @@
field public static final int useLevel = 16843167; // 0x101019f
field public static final int userVisible = 16843409; // 0x1010291
field public static final int usesCleartextTraffic = 16844012; // 0x10104ec
- field public static final int usesPermissionFlags;
+ field public static final int usesPermissionFlags = 16844356; // 0x1010644
field public static final int value = 16842788; // 0x1010024
field public static final int valueFrom = 16843486; // 0x10102de
field public static final int valueTo = 16843487; // 0x10102df
@@ -1649,10 +1648,10 @@
field public static final int windowAllowReturnTransitionOverlap = 16843835; // 0x101043b
field public static final int windowAnimationStyle = 16842926; // 0x10100ae
field public static final int windowBackground = 16842836; // 0x1010054
- field public static final int windowBackgroundBlurRadius;
+ field public static final int windowBackgroundBlurRadius = 16844331; // 0x101062b
field public static final int windowBackgroundFallback = 16844035; // 0x1010503
- field public static final int windowBlurBehindEnabled;
- field public static final int windowBlurBehindRadius;
+ field public static final int windowBlurBehindEnabled = 16844316; // 0x101061c
+ field public static final int windowBlurBehindRadius = 16844315; // 0x101061b
field public static final int windowClipToOutline = 16843947; // 0x10104ab
field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
field public static final int windowContentOverlay = 16842841; // 0x1010059
@@ -1671,7 +1670,7 @@
field public static final int windowHideAnimation = 16842935; // 0x10100b7
field public static final int windowIsFloating = 16842839; // 0x1010057
field public static final int windowIsTranslucent = 16842840; // 0x1010058
- field public static final int windowLayoutAffinity;
+ field public static final int windowLayoutAffinity = 16844313; // 0x1010619
field public static final int windowLayoutInDisplayCutoutMode = 16844166; // 0x1010586
field public static final int windowLightNavigationBar = 16844140; // 0x101056c
field public static final int windowLightStatusBar = 16844000; // 0x10104e0
@@ -1690,11 +1689,11 @@
field public static final int windowShowAnimation = 16842934; // 0x10100b6
field public static final int windowShowWallpaper = 16843410; // 0x1010292
field public static final int windowSoftInputMode = 16843307; // 0x101022b
- field public static final int windowSplashScreenAnimatedIcon;
- field public static final int windowSplashScreenAnimationDuration;
- field public static final int windowSplashScreenBackground;
- field public static final int windowSplashScreenBrandingImage;
- field public static final int windowSplashScreenIconBackgroundColor;
+ field public static final int windowSplashScreenAnimatedIcon = 16844333; // 0x101062d
+ field public static final int windowSplashScreenAnimationDuration = 16844334; // 0x101062e
+ field public static final int windowSplashScreenBackground = 16844332; // 0x101062c
+ field public static final int windowSplashScreenBrandingImage = 16844335; // 0x101062f
+ field public static final int windowSplashScreenIconBackgroundColor = 16844336; // 0x1010630
field @Deprecated public static final int windowSplashscreenContent = 16844132; // 0x1010564
field @Deprecated public static final int windowSwipeToDismiss = 16843763; // 0x10103f3
field public static final int windowTitleBackgroundStyle = 16842844; // 0x101005c
@@ -1742,71 +1741,71 @@
field @Deprecated public static final int secondary_text_dark_nodisable = 17170438; // 0x1060006
field @Deprecated public static final int secondary_text_light = 17170439; // 0x1060007
field @Deprecated public static final int secondary_text_light_nodisable = 17170440; // 0x1060008
- field public static final int system_accent1_0;
- field public static final int system_accent1_10;
- field public static final int system_accent1_100;
- field public static final int system_accent1_1000;
- field public static final int system_accent1_200;
- field public static final int system_accent1_300;
- field public static final int system_accent1_400;
- field public static final int system_accent1_50;
- field public static final int system_accent1_500;
- field public static final int system_accent1_600;
- field public static final int system_accent1_700;
- field public static final int system_accent1_800;
- field public static final int system_accent1_900;
- field public static final int system_accent2_0;
- field public static final int system_accent2_10;
- field public static final int system_accent2_100;
- field public static final int system_accent2_1000;
- field public static final int system_accent2_200;
- field public static final int system_accent2_300;
- field public static final int system_accent2_400;
- field public static final int system_accent2_50;
- field public static final int system_accent2_500;
- field public static final int system_accent2_600;
- field public static final int system_accent2_700;
- field public static final int system_accent2_800;
- field public static final int system_accent2_900;
- field public static final int system_accent3_0;
- field public static final int system_accent3_10;
- field public static final int system_accent3_100;
- field public static final int system_accent3_1000;
- field public static final int system_accent3_200;
- field public static final int system_accent3_300;
- field public static final int system_accent3_400;
- field public static final int system_accent3_50;
- field public static final int system_accent3_500;
- field public static final int system_accent3_600;
- field public static final int system_accent3_700;
- field public static final int system_accent3_800;
- field public static final int system_accent3_900;
- field public static final int system_neutral1_0;
- field public static final int system_neutral1_10;
- field public static final int system_neutral1_100;
- field public static final int system_neutral1_1000;
- field public static final int system_neutral1_200;
- field public static final int system_neutral1_300;
- field public static final int system_neutral1_400;
- field public static final int system_neutral1_50;
- field public static final int system_neutral1_500;
- field public static final int system_neutral1_600;
- field public static final int system_neutral1_700;
- field public static final int system_neutral1_800;
- field public static final int system_neutral1_900;
- field public static final int system_neutral2_0;
- field public static final int system_neutral2_10;
- field public static final int system_neutral2_100;
- field public static final int system_neutral2_1000;
- field public static final int system_neutral2_200;
- field public static final int system_neutral2_300;
- field public static final int system_neutral2_400;
- field public static final int system_neutral2_50;
- field public static final int system_neutral2_500;
- field public static final int system_neutral2_600;
- field public static final int system_neutral2_700;
- field public static final int system_neutral2_800;
- field public static final int system_neutral2_900;
+ field public static final int system_accent1_0 = 17170487; // 0x1060037
+ field public static final int system_accent1_10 = 17170488; // 0x1060038
+ field public static final int system_accent1_100 = 17170490; // 0x106003a
+ field public static final int system_accent1_1000 = 17170499; // 0x1060043
+ field public static final int system_accent1_200 = 17170491; // 0x106003b
+ field public static final int system_accent1_300 = 17170492; // 0x106003c
+ field public static final int system_accent1_400 = 17170493; // 0x106003d
+ field public static final int system_accent1_50 = 17170489; // 0x1060039
+ field public static final int system_accent1_500 = 17170494; // 0x106003e
+ field public static final int system_accent1_600 = 17170495; // 0x106003f
+ field public static final int system_accent1_700 = 17170496; // 0x1060040
+ field public static final int system_accent1_800 = 17170497; // 0x1060041
+ field public static final int system_accent1_900 = 17170498; // 0x1060042
+ field public static final int system_accent2_0 = 17170500; // 0x1060044
+ field public static final int system_accent2_10 = 17170501; // 0x1060045
+ field public static final int system_accent2_100 = 17170503; // 0x1060047
+ field public static final int system_accent2_1000 = 17170512; // 0x1060050
+ field public static final int system_accent2_200 = 17170504; // 0x1060048
+ field public static final int system_accent2_300 = 17170505; // 0x1060049
+ field public static final int system_accent2_400 = 17170506; // 0x106004a
+ field public static final int system_accent2_50 = 17170502; // 0x1060046
+ field public static final int system_accent2_500 = 17170507; // 0x106004b
+ field public static final int system_accent2_600 = 17170508; // 0x106004c
+ field public static final int system_accent2_700 = 17170509; // 0x106004d
+ field public static final int system_accent2_800 = 17170510; // 0x106004e
+ field public static final int system_accent2_900 = 17170511; // 0x106004f
+ field public static final int system_accent3_0 = 17170513; // 0x1060051
+ field public static final int system_accent3_10 = 17170514; // 0x1060052
+ field public static final int system_accent3_100 = 17170516; // 0x1060054
+ field public static final int system_accent3_1000 = 17170525; // 0x106005d
+ field public static final int system_accent3_200 = 17170517; // 0x1060055
+ field public static final int system_accent3_300 = 17170518; // 0x1060056
+ field public static final int system_accent3_400 = 17170519; // 0x1060057
+ field public static final int system_accent3_50 = 17170515; // 0x1060053
+ field public static final int system_accent3_500 = 17170520; // 0x1060058
+ field public static final int system_accent3_600 = 17170521; // 0x1060059
+ field public static final int system_accent3_700 = 17170522; // 0x106005a
+ field public static final int system_accent3_800 = 17170523; // 0x106005b
+ field public static final int system_accent3_900 = 17170524; // 0x106005c
+ field public static final int system_neutral1_0 = 17170461; // 0x106001d
+ field public static final int system_neutral1_10 = 17170462; // 0x106001e
+ field public static final int system_neutral1_100 = 17170464; // 0x1060020
+ field public static final int system_neutral1_1000 = 17170473; // 0x1060029
+ field public static final int system_neutral1_200 = 17170465; // 0x1060021
+ field public static final int system_neutral1_300 = 17170466; // 0x1060022
+ field public static final int system_neutral1_400 = 17170467; // 0x1060023
+ field public static final int system_neutral1_50 = 17170463; // 0x106001f
+ field public static final int system_neutral1_500 = 17170468; // 0x1060024
+ field public static final int system_neutral1_600 = 17170469; // 0x1060025
+ field public static final int system_neutral1_700 = 17170470; // 0x1060026
+ field public static final int system_neutral1_800 = 17170471; // 0x1060027
+ field public static final int system_neutral1_900 = 17170472; // 0x1060028
+ field public static final int system_neutral2_0 = 17170474; // 0x106002a
+ field public static final int system_neutral2_10 = 17170475; // 0x106002b
+ field public static final int system_neutral2_100 = 17170477; // 0x106002d
+ field public static final int system_neutral2_1000 = 17170486; // 0x1060036
+ field public static final int system_neutral2_200 = 17170478; // 0x106002e
+ field public static final int system_neutral2_300 = 17170479; // 0x106002f
+ field public static final int system_neutral2_400 = 17170480; // 0x1060030
+ field public static final int system_neutral2_50 = 17170476; // 0x106002c
+ field public static final int system_neutral2_500 = 17170481; // 0x1060031
+ field public static final int system_neutral2_600 = 17170482; // 0x1060032
+ field public static final int system_neutral2_700 = 17170483; // 0x1060033
+ field public static final int system_neutral2_800 = 17170484; // 0x1060034
+ field public static final int system_neutral2_900 = 17170485; // 0x1060035
field public static final int tab_indicator_text = 17170441; // 0x1060009
field @Deprecated public static final int tertiary_text_dark = 17170448; // 0x1060010
field @Deprecated public static final int tertiary_text_light = 17170449; // 0x1060011
@@ -1822,8 +1821,8 @@
field public static final int dialog_min_width_minor = 17104900; // 0x1050004
field public static final int notification_large_icon_height = 17104902; // 0x1050006
field public static final int notification_large_icon_width = 17104901; // 0x1050005
- field public static final int system_app_widget_background_radius;
- field public static final int system_app_widget_inner_radius;
+ field public static final int system_app_widget_background_radius = 17104904; // 0x1050008
+ field public static final int system_app_widget_inner_radius = 17104905; // 0x1050009
field public static final int thumbnail_height = 17104897; // 0x1050001
field public static final int thumbnail_width = 17104898; // 0x1050002
}
@@ -30797,7 +30796,7 @@
field public static final int P = 28; // 0x1c
field public static final int Q = 29; // 0x1d
field public static final int R = 30; // 0x1e
- field public static final int S = 10000; // 0x2710
+ field public static final int S = 31; // 0x1f
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/core/api/removed.txt b/core/api/removed.txt
index 57e1598..bf86422 100644
--- a/core/api/removed.txt
+++ b/core/api/removed.txt
@@ -1,12 +1,4 @@
// Signature format: 2.0
-package android {
-
- public static final class R.dimen {
- field public static final int __removed_system_app_widget_internal_padding;
- }
-
-}
-
package android.app {
public class Notification implements android.os.Parcelable {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 7072bbe..2d73aa67 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -317,10 +317,10 @@
public static final class R.attr {
field public static final int allowClearUserDataOnFailedRestore = 16844288; // 0x1010600
- field public static final int hotwordDetectionService;
+ field public static final int hotwordDetectionService = 16844326; // 0x1010626
field public static final int isVrOnly = 16844152; // 0x1010578
field public static final int minExtensionVersion = 16844305; // 0x1010611
- field public static final int playHomeTransitionSound;
+ field public static final int playHomeTransitionSound = 16844358; // 0x1010646
field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
field public static final int requiredSystemPropertyValue = 16844134; // 0x1010566
field public static final int sdkVersion = 16844304; // 0x1010610
@@ -353,8 +353,8 @@
}
public static final class R.string {
- field public static final int config_customMediaKeyDispatcher;
- field public static final int config_customMediaSessionPolicyProvider;
+ field public static final int config_customMediaKeyDispatcher = 17039404; // 0x104002c
+ field public static final int config_customMediaSessionPolicyProvider = 17039405; // 0x104002d
field public static final int config_defaultAssistant = 17039393; // 0x1040021
field public static final int config_defaultBrowser = 17039394; // 0x1040022
field public static final int config_defaultCallRedirection = 17039397; // 0x1040025
@@ -367,24 +367,24 @@
field public static final int config_helpIntentNameKey = 17039390; // 0x104001e
field public static final int config_helpPackageNameKey = 17039387; // 0x104001b
field public static final int config_helpPackageNameValue = 17039388; // 0x104001c
- field public static final int config_systemActivityRecognizer;
- field public static final int config_systemAmbientAudioIntelligence;
- field public static final int config_systemAudioIntelligence;
- field public static final int config_systemAutomotiveCluster;
- field public static final int config_systemAutomotiveProjection;
- field public static final int config_systemCompanionDeviceProvider;
- field public static final int config_systemContacts;
+ field public static final int config_systemActivityRecognizer = 17039416; // 0x1040038
+ field public static final int config_systemAmbientAudioIntelligence = 17039411; // 0x1040033
+ field public static final int config_systemAudioIntelligence = 17039412; // 0x1040034
+ field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028
+ field public static final int config_systemAutomotiveProjection = 17039401; // 0x1040029
+ field public static final int config_systemCompanionDeviceProvider = 17039417; // 0x1040039
+ field public static final int config_systemContacts = 17039403; // 0x104002b
field public static final int config_systemGallery = 17039399; // 0x1040027
- field public static final int config_systemNotificationIntelligence;
- field public static final int config_systemShell;
- field public static final int config_systemSpeechRecognizer;
- field public static final int config_systemTelevisionNotificationHandler;
- field public static final int config_systemTextIntelligence;
- field public static final int config_systemUi;
- field public static final int config_systemUiIntelligence;
- field public static final int config_systemVisualIntelligence;
- field public static final int config_systemWellbeing;
- field public static final int config_systemWifiCoexManager;
+ field public static final int config_systemNotificationIntelligence = 17039413; // 0x1040035
+ field public static final int config_systemShell = 17039402; // 0x104002a
+ field public static final int config_systemSpeechRecognizer = 17039406; // 0x104002e
+ field public static final int config_systemTelevisionNotificationHandler = 17039409; // 0x1040031
+ field public static final int config_systemTextIntelligence = 17039414; // 0x1040036
+ field public static final int config_systemUi = 17039418; // 0x104003a
+ field public static final int config_systemUiIntelligence = 17039410; // 0x1040032
+ field public static final int config_systemVisualIntelligence = 17039415; // 0x1040037
+ field public static final int config_systemWellbeing = 17039408; // 0x1040030
+ field public static final int config_systemWifiCoexManager = 17039407; // 0x104002f
}
public static final class R.style {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 2f795f0..d31679e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -51,7 +51,7 @@
}
public static final class R.attr {
- field public static final int requestForegroundServiceExemption;
+ field public static final int requestForegroundServiceExemption = 16844362; // 0x101064a
}
public static final class R.bool {
@@ -63,8 +63,8 @@
public static final class R.string {
field public static final int config_defaultAssistant = 17039393; // 0x1040021
field public static final int config_defaultDialer = 17039395; // 0x1040023
- field public static final int config_systemAutomotiveCluster;
- field public static final int config_systemAutomotiveProjection;
+ field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028
+ field public static final int config_systemAutomotiveProjection = 17039401; // 0x1040029
field public static final int config_systemGallery = 17039399; // 0x1040027
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 6d2d023..91e2d88 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -779,6 +779,9 @@
/** @hide requestType for assist context: generate full AssistStructure for autofill. */
public static final int ASSIST_CONTEXT_AUTOFILL = 2;
+ /** @hide requestType for assist context: generate AssistContent but not AssistStructure. */
+ public static final int ASSIST_CONTEXT_CONTENT = 3;
+
/** @hide Flag for registerUidObserver: report changes in process state. */
public static final int UID_OBSERVER_PROCSTATE = 1<<0;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7149096..02ab314 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3843,6 +3843,8 @@
// - it does not call onProvideAssistData()
// - it needs an IAutoFillCallback
boolean forAutofill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTOFILL;
+ // When only the AssistContent is requested, omit the AsssistStructure
+ boolean requestedOnlyContent = cmd.requestType == ActivityManager.ASSIST_CONTEXT_CONTENT;
// TODO: decide if lastSessionId logic applies to autofill sessions
if (mLastSessionId != cmd.sessionId) {
@@ -3869,8 +3871,11 @@
r.activity.onProvideAssistData(data);
referrer = r.activity.onProvideReferrer();
}
- if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutofill) {
- structure = new AssistStructure(r.activity, forAutofill, cmd.flags);
+ if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutofill
+ || requestedOnlyContent) {
+ if (!requestedOnlyContent) {
+ structure = new AssistStructure(r.activity, forAutofill, cmd.flags);
+ }
Intent activityIntent = r.activity.getIntent();
boolean notSecure = r.window == null ||
(r.window.getAttributes().flags
@@ -3892,18 +3897,21 @@
r.activity.onProvideAssistContent(content);
}
}
-
- }
- if (structure == null) {
- structure = new AssistStructure();
}
- // TODO: decide if lastSessionId logic applies to autofill sessions
+ if (!requestedOnlyContent) {
+ if (structure == null) {
+ structure = new AssistStructure();
+ }
- structure.setAcquisitionStartTime(startTime);
- structure.setAcquisitionEndTime(SystemClock.uptimeMillis());
+ // TODO: decide if lastSessionId logic applies to autofill sessions
- mLastAssistStructures.add(new WeakReference<>(structure));
+ structure.setAcquisitionStartTime(startTime);
+ structure.setAcquisitionEndTime(SystemClock.uptimeMillis());
+
+ mLastAssistStructures.add(new WeakReference<>(structure));
+ }
+
IActivityTaskManager mgr = ActivityTaskManager.getService();
try {
mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 02520af..1415212 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2784,16 +2784,6 @@
private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>();
/**
- * Optimization: we need to propagate to IPCs whether the current thread is collecting
- * app ops but using only the thread local above is too slow as it requires a map lookup
- * on every IPC. We add this static var that is lockless and stores an OR-ed mask of the
- * thread id's currently collecting ops, thus reducing the map lookup to a simple bit
- * operation except the extremely unlikely case when threads with overlapping id bits
- * execute op collecting ops.
- */
- private static volatile long sThreadsListeningForOpNotedInBinderTransaction = 0L;
-
- /**
* If a thread is currently executing a two-way binder transaction, this stores the
* ops that were noted blaming any app (the caller, the caller of the caller, etc).
*
@@ -8903,7 +8893,6 @@
* @hide
*/
public static void startNotedAppOpsCollection(int callingUid) {
- sThreadsListeningForOpNotedInBinderTransaction |= Thread.currentThread().getId();
sBinderThreadCallingUid.set(callingUid);
}
@@ -8918,7 +8907,6 @@
*/
public static void finishNotedAppOpsCollection() {
sBinderThreadCallingUid.remove();
- sThreadsListeningForOpNotedInBinderTransaction &= ~Thread.currentThread().getId();
sAppOpsNotedInThisBinderTransaction.remove();
}
@@ -9263,9 +9251,7 @@
* @return whether we are in a binder transaction and collecting appops.
*/
private static boolean isListeningForOpNotedInBinderTransaction() {
- return (sThreadsListeningForOpNotedInBinderTransaction
- & Thread.currentThread().getId()) != 0
- && sBinderThreadCallingUid.get() != null;
+ return sBinderThreadCallingUid.get() != null;
}
/**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 60fe2ef..30ddd20 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -9804,10 +9804,6 @@
* <p>Apps sending bubbles may set this flag so that the bubble is posted <b>without</b>
* the associated notification in the notification shade.</p>
*
- * <p>Apps sending bubbles can only apply this flag when the app is in the foreground,
- * otherwise the flag is not respected. The app is considered foreground if it is visible
- * and on the screen, note that a foreground service does not qualify.</p>
- *
* <p>Generally this flag should only be set by the app if the user has performed an
* action to request or create a bubble, or if the user has seen the content in the
* notification and the notification is no longer relevant. </p>
@@ -9958,10 +9954,6 @@
* <p>Apps sending bubbles may set this flag so that the bubble is posted <b>without</b>
* the associated notification in the notification shade.</p>
*
- * <p>Apps sending bubbles can only apply this flag when the app is in the foreground,
- * otherwise the flag is not respected. The app is considered foreground if it is visible
- * and on the screen, note that a foreground service does not qualify.</p>
- *
* <p>Generally the app should only set this flag if the user has performed an
* action to request or create a bubble, or if the user has seen the content in the
* notification and the notification is no longer relevant. </p>
@@ -10159,6 +10151,8 @@
* {@link Activity#isLaunchedFromBubble()} will return with {@code true}.
* </p>
*
+ * Note that the pending intent used here requires PendingIntent.FLAG_MUTABLE.
+ *
* @throws NullPointerException if intent is null.
* @throws NullPointerException if icon is null.
*/
@@ -10347,11 +10341,6 @@
* Sets whether the bubble will be posted <b>without</b> the associated notification in
* the notification shade.
*
- * <p>This flag has no effect if the app posting the bubble is not in the foreground.
- * The app is considered foreground if it is visible and on the screen, note that
- * a foreground service does not qualify.
- * </p>
- *
* <p>Generally, this flag should only be set if the user has performed an action to
* request or create a bubble, or if the user has seen the content in the notification
* and the notification is no longer relevant.</p>
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 0662f16..8dfb787 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -846,6 +846,14 @@
return 0;
}
+ private static int[] convertIntegerToIntList(List<Integer> integerList) {
+ int[] integerArray = new int[integerList.size()];
+ for (int i = 0; i < integerList.size(); i++) {
+ integerArray[i] = integerList.get(i);
+ }
+ return integerArray;
+ }
+
@Override
public void writeToParcel(Parcel dest, int flags) {
if (dest == null) {
@@ -861,7 +869,9 @@
dest.writeTypedList(mSurfaces);
dest.writeString(mPhysicalCameraId);
dest.writeInt(mIsMultiResolution ? 1 : 0);
- dest.writeList(mSensorPixelModesUsed);
+ // writeList doesn't seem to work well with Integer list.
+ dest.writeIntArray(convertIntegerToIntList(mSensorPixelModesUsed));
+ //dest.writeArray(mSensorPixelModesUsed.toArray());
}
/**
diff --git a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
index d2cb5bf..f18360ff 100644
--- a/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
+++ b/core/java/android/hardware/fingerprint/IUdfpsOverlayController.aidl
@@ -35,6 +35,10 @@
// Hides the overlay.
void hideUdfpsOverlay(int sensorId);
+ // Good image captured. Turn off HBM. Success/Reject comes after, which is when hideUdfpsOverlay
+ // will be called.
+ void onAcquiredGood(int sensorId);
+
// Notifies of enrollment progress changes.
void onEnrollmentProgress(int sensorId, int remaining);
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index fd446cd..249154a 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -514,6 +514,10 @@
return mSubscriberIdMatchRule;
}
+ public int getMeteredness() {
+ return mMetered;
+ }
+
/**
* Test if given {@link NetworkIdentity} matches this template.
*/
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 900659b..a5b7e99 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1086,7 +1086,7 @@
/**
* S.
*/
- public static final int S = CUR_DEVELOPMENT;
+ public static final int S = 31;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 781800d..a0cbbfe 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -182,6 +182,11 @@
* @return The desired effect.
*/
public static VibrationEffect createOneShot(long milliseconds, int amplitude) {
+ if (amplitude == 0) {
+ throw new IllegalArgumentException(
+ "amplitude must either be DEFAULT_AMPLITUDE, "
+ + "or between 1 and 255 inclusive (amplitude=" + amplitude + ")");
+ }
return createWaveform(new long[]{milliseconds}, new int[]{amplitude}, -1 /* repeat */);
}
@@ -581,22 +586,16 @@
public void validate() {
int segmentCount = mSegments.size();
boolean hasNonZeroDuration = false;
- boolean hasNonZeroAmplitude = false;
for (int i = 0; i < segmentCount; i++) {
VibrationEffectSegment segment = mSegments.get(i);
segment.validate();
// A segment with unknown duration = -1 still counts as a non-zero duration.
hasNonZeroDuration |= segment.getDuration() != 0;
- hasNonZeroAmplitude |= segment.hasNonZeroAmplitude();
}
if (!hasNonZeroDuration) {
throw new IllegalArgumentException("at least one timing must be non-zero"
+ " (segments=" + mSegments + ")");
}
- if (!hasNonZeroAmplitude) {
- throw new IllegalArgumentException("at least one amplitude must be non-zero"
- + " (segments=" + mSegments + ")");
- }
if (mRepeatIndex != -1) {
Preconditions.checkArgumentInRange(mRepeatIndex, 0, segmentCount - 1,
"repeat index must be within the bounds of the segments (segments.length="
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index 0b99b85..8854e27 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -17,6 +17,7 @@
package android.permission;
import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
+import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED;
import static android.permission.PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED;
import static android.permission.PermissionControllerManager.COUNT_WHEN_SYSTEM;
@@ -510,7 +511,7 @@
String callerPackageName, AdminPermissionControlParams params,
AndroidFuture callback) {
checkStringNotEmpty(callerPackageName);
- if (params.getGrantState() == PERMISSION_GRANT_STATE_DENIED) {
+ if (params.getGrantState() == PERMISSION_GRANT_STATE_GRANTED) {
enforceSomePermissionsGrantedToCaller(
Manifest.permission.GRANT_RUNTIME_PERMISSIONS);
}
@@ -542,6 +543,9 @@
public void updateUserSensitiveForApp(int uid, @NonNull AndroidFuture callback) {
Preconditions.checkNotNull(callback, "callback cannot be null");
+ enforceSomePermissionsGrantedToCaller(
+ Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
+
try {
onUpdateUserSensitivePermissionFlags(uid, () -> callback.complete(null));
} catch (Exception e) {
@@ -608,9 +612,7 @@
try {
Objects.requireNonNull(permissionGroupName);
Objects.requireNonNull(callback);
- PermissionControllerService
- .this
- .onGetGroupOfPlatformPermission(
+ PermissionControllerService.this.onGetGroupOfPlatformPermission(
permissionGroupName, callback::complete);
} catch (Throwable t) {
callback.completeExceptionally(t);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 13e5cda..cb87653 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6661,6 +6661,20 @@
public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category.";
/**
+ * Whether or not compress blocks should be released on install.
+ * <p>The setting only determines if the platform will attempt to release
+ * compress blocks; it does not guarantee that the files will have their
+ * compress blocks released. Compression is currently only supported on
+ * some f2fs filesystems.
+ * <p>
+ * Type: int (0 for false, 1 for true)
+ *
+ * @hide
+ */
+ public static final String RELEASE_COMPRESS_BLOCKS_ON_INSTALL =
+ "release_compress_blocks_on_install";
+
+ /**
* List of input methods that are currently enabled. This is a string
* containing the IDs of all enabled input methods, each ID separated
* by ':'.
@@ -11060,7 +11074,7 @@
* @hide
*/
@UnsupportedAppUsage
- @Readable(maxTargetSdk = Build.VERSION_CODES.R)
+ @Readable
public static final String MOBILE_DATA = "mobile_data";
/**
diff --git a/core/java/android/service/smartspace/SmartspaceService.java b/core/java/android/service/smartspace/SmartspaceService.java
index 09b7310..7dd85cc 100644
--- a/core/java/android/service/smartspace/SmartspaceService.java
+++ b/core/java/android/service/smartspace/SmartspaceService.java
@@ -122,14 +122,18 @@
@Override
public void onCreate() {
super.onCreate();
- Log.d(TAG, "onCreate mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) {
+ Log.d(TAG, "onCreate mSessionCallbacks: " + mSessionCallbacks);
+ }
mHandler = new Handler(Looper.getMainLooper(), null, true);
}
@Override
@NonNull
public final IBinder onBind(@NonNull Intent intent) {
- Log.d(TAG, "onBind mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) {
+ Log.d(TAG, "onBind mSessionCallbacks: " + mSessionCallbacks);
+ }
if (SERVICE_INTERFACE.equals(intent.getAction())) {
return mInterface.asBinder();
}
@@ -140,7 +144,9 @@
private void doCreateSmartspaceSession(@NonNull SmartspaceConfig config,
@NonNull SmartspaceSessionId sessionId) {
- Log.d(TAG, "doCreateSmartspaceSession mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) {
+ Log.d(TAG, "doCreateSmartspaceSession mSessionCallbacks: " + mSessionCallbacks);
+ }
mSessionCallbacks.put(sessionId, new ArrayList<>());
onCreateSmartspaceSession(config, sessionId);
}
@@ -166,7 +172,9 @@
private void doRegisterSmartspaceUpdates(@NonNull SmartspaceSessionId sessionId,
@NonNull ISmartspaceCallback callback) {
- Log.d(TAG, "doRegisterSmartspaceUpdates mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) {
+ Log.d(TAG, "doRegisterSmartspaceUpdates mSessionCallbacks: " + mSessionCallbacks);
+ }
final ArrayList<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId);
if (callbacks == null) {
Slog.e(TAG, "Failed to register for updates for unknown session: " + sessionId);
@@ -184,7 +192,9 @@
private void doUnregisterSmartspaceUpdates(@NonNull SmartspaceSessionId sessionId,
@NonNull ISmartspaceCallback callback) {
- Log.d(TAG, "doUnregisterSmartspaceUpdates mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) {
+ Log.d(TAG, "doUnregisterSmartspaceUpdates mSessionCallbacks: " + mSessionCallbacks);
+ }
final ArrayList<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId);
if (callbacks == null) {
Slog.e(TAG, "Failed to unregister for updates for unknown session: " + sessionId);
@@ -198,7 +208,9 @@
}
private void doRequestPredictionUpdate(@NonNull SmartspaceSessionId sessionId) {
- Log.d(TAG, "doRequestPredictionUpdate mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) {
+ Log.d(TAG, "doRequestPredictionUpdate mSessionCallbacks: " + mSessionCallbacks);
+ }
// Just an optimization, if there are no callbacks, then don't bother notifying the service
final ArrayList<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId);
if (callbacks != null && !callbacks.isEmpty()) {
@@ -246,7 +258,9 @@
*/
public final void updateSmartspaceTargets(@NonNull SmartspaceSessionId sessionId,
@NonNull List<SmartspaceTarget> targets) {
- Log.d(TAG, "updateSmartspaceTargets mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) {
+ Log.d(TAG, "updateSmartspaceTargets mSessionCallbacks: " + mSessionCallbacks);
+ }
List<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId);
if (callbacks != null) {
for (CallbackWrapper callback : callbacks) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index afd6878..67cf85c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2783,7 +2783,7 @@
& WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED) != 0;
final boolean dragResizing = freeformResizing || dockedResizing;
if (mSurfaceControl.isValid()) {
- updateOpacity(params, dragResizing);
+ updateOpacity(mWindowAttributes, dragResizing);
}
if (DEBUG_LAYOUT) Log.v(mTag, "relayout: frame=" + frame.toShortString()
@@ -7749,9 +7749,10 @@
return relayoutResult;
}
- private void updateOpacity(@Nullable WindowManager.LayoutParams params, boolean dragResizing) {
+ private void updateOpacity(WindowManager.LayoutParams params, boolean dragResizing) {
boolean opaque = false;
- if (params != null && !PixelFormat.formatHasAlpha(params.format)
+
+ if (!PixelFormat.formatHasAlpha(params.format)
// Don't make surface with surfaceInsets opaque as they display a
// translucent shadow.
&& params.surfaceInsets.left == 0
diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java
index ea3f1b1..40ada0b 100644
--- a/core/java/com/android/internal/app/AbstractResolverComparator.java
+++ b/core/java/com/android/internal/app/AbstractResolverComparator.java
@@ -64,6 +64,7 @@
private static final int WATCHDOG_TIMEOUT_MILLIS = 500;
private final Comparator<ResolveInfo> mAzComparator;
+ private ChooserActivityLogger mChooserActivityLogger;
protected final Handler mHandler = new Handler(Looper.getMainLooper()) {
public void handleMessage(Message msg) {
@@ -85,6 +86,9 @@
}
mHandler.removeMessages(RANKER_SERVICE_RESULT);
afterCompute();
+ if (mChooserActivityLogger != null) {
+ mChooserActivityLogger.logSharesheetAppShareRankingTimeout();
+ }
break;
default:
@@ -131,6 +135,14 @@
mAfterCompute = afterCompute;
}
+ void setChooserActivityLogger(ChooserActivityLogger chooserActivityLogger) {
+ mChooserActivityLogger = chooserActivityLogger;
+ }
+
+ ChooserActivityLogger getChooserActivityLogger() {
+ return mChooserActivityLogger;
+ }
+
protected final void afterCompute() {
final AfterCompute afterCompute = mAfterCompute;
if (afterCompute != null) {
diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
index b76ef0f..bc9eff0 100644
--- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
@@ -61,17 +61,19 @@
private ResolverRankerServiceResolverComparator mResolverRankerService;
AppPredictionServiceResolverComparator(
- Context context,
- Intent intent,
- String referrerPackage,
- AppPredictor appPredictor,
- UserHandle user) {
+ Context context,
+ Intent intent,
+ String referrerPackage,
+ AppPredictor appPredictor,
+ UserHandle user,
+ ChooserActivityLogger chooserActivityLogger) {
super(context, intent);
mContext = context;
mIntent = intent;
mAppPredictor = appPredictor;
mUser = user;
mReferrerPackage = referrerPackage;
+ setChooserActivityLogger(chooserActivityLogger);
}
@Override
@@ -116,8 +118,9 @@
// APS for chooser is disabled. Fallback to resolver.
mResolverRankerService =
new ResolverRankerServiceResolverComparator(
- mContext, mIntent, mReferrerPackage,
- () -> mHandler.sendEmptyMessage(RANKER_SERVICE_RESULT));
+ mContext, mIntent, mReferrerPackage,
+ () -> mHandler.sendEmptyMessage(RANKER_SERVICE_RESULT),
+ getChooserActivityLogger());
mResolverRankerService.compute(targets);
} else {
Log.i(TAG, "AppPredictionService response received");
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 28c2774..08db74f 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2591,7 +2591,8 @@
boolean filterLastUsed, ResolverListController resolverListController) {
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
filterLastUsed, resolverListController, this,
- this, context.getPackageManager());
+ this, context.getPackageManager(),
+ getChooserActivityLogger());
}
@VisibleForTesting
@@ -2600,11 +2601,11 @@
AbstractResolverComparator resolverComparator;
if (appPredictor != null) {
resolverComparator = new AppPredictionServiceResolverComparator(this, getTargetIntent(),
- getReferrerPackageName(), appPredictor, userHandle);
+ getReferrerPackageName(), appPredictor, userHandle, getChooserActivityLogger());
} else {
resolverComparator =
new ResolverRankerServiceResolverComparator(this, getTargetIntent(),
- getReferrerPackageName(), null);
+ getReferrerPackageName(), null, getChooserActivityLogger());
}
return new ChooserListController(
diff --git a/core/java/com/android/internal/app/ChooserActivityLogger.java b/core/java/com/android/internal/app/ChooserActivityLogger.java
index 47d8334..3217307 100644
--- a/core/java/com/android/internal/app/ChooserActivityLogger.java
+++ b/core/java/com/android/internal/app/ChooserActivityLogger.java
@@ -75,6 +75,20 @@
}
/**
+ * Logs a UiEventReported event for the system sharesheet app share ranking timing out.
+ */
+ default void logSharesheetAppShareRankingTimeout() {
+ log(SharesheetStandardEvent.SHARESHEET_APP_SHARE_RANKING_TIMEOUT, getInstanceId());
+ }
+
+ /**
+ * Logs a UiEventReported event for the system sharesheet when direct share row is empty.
+ */
+ default void logSharesheetEmptyDirectShareRow() {
+ log(SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW, getInstanceId());
+ }
+
+ /**
* Logs a UiEventReported event for a given share activity
* @param event
* @param instanceId
@@ -168,7 +182,11 @@
@UiEvent(doc = "Sharesheet direct targets is fully populated.")
SHARESHEET_DIRECT_LOAD_COMPLETE(323),
@UiEvent(doc = "Sharesheet direct targets timed out.")
- SHARESHEET_DIRECT_LOAD_TIMEOUT(324);
+ SHARESHEET_DIRECT_LOAD_TIMEOUT(324),
+ @UiEvent(doc = "Sharesheet app share ranking timed out.")
+ SHARESHEET_APP_SHARE_RANKING_TIMEOUT(831),
+ @UiEvent(doc = "Sharesheet empty direct share row.")
+ SHARESHEET_EMPTY_DIRECT_SHARE_ROW(828);
private final int mId;
SharesheetStandardEvent(int id) {
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index cc2b12a..87737ca 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -79,6 +79,7 @@
private final ChooserListCommunicator mChooserListCommunicator;
private final SelectableTargetInfo.SelectableTargetInfoCommunicator
mSelectableTargetInfoCommunicator;
+ private final ChooserActivityLogger mChooserActivityLogger;
private int mNumShortcutResults = 0;
private Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
@@ -104,7 +105,8 @@
boolean filterLastUsed, ResolverListController resolverListController,
ChooserListCommunicator chooserListCommunicator,
SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoCommunicator,
- PackageManager packageManager) {
+ PackageManager packageManager,
+ ChooserActivityLogger chooserActivityLogger) {
// Don't send the initial intents through the shared ResolverActivity path,
// we want to separate them into a different section.
super(context, payloadIntents, null, rList, filterLastUsed,
@@ -115,6 +117,7 @@
mChooserListCommunicator = chooserListCommunicator;
createPlaceHolders();
mSelectableTargetInfoCommunicator = selectableTargetInfoCommunicator;
+ mChooserActivityLogger = chooserActivityLogger;
if (initialIntents != null) {
for (int i = 0; i < initialIntents.length; i++) {
@@ -590,6 +593,7 @@
mServiceTargets.removeIf(o -> o instanceof ChooserActivity.PlaceHolderTargetInfo);
if (mServiceTargets.isEmpty()) {
mServiceTargets.add(new ChooserActivity.EmptyTargetInfo());
+ mChooserActivityLogger.logSharesheetEmptyDirectShareRow();
}
notifyDataSetChanged();
}
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 2b59907..10ac1bc 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -70,7 +70,7 @@
UserHandle userHandle) {
this(context, pm, targetIntent, referrerPackage, launchedFromUid, userHandle,
new ResolverRankerServiceResolverComparator(
- context, targetIntent, referrerPackage, null));
+ context, targetIntent, referrerPackage, null, null));
}
public ResolverListController(
diff --git a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
index 2869450..cb946c0 100644
--- a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
@@ -85,7 +85,8 @@
private CountDownLatch mConnectSignal;
public ResolverRankerServiceResolverComparator(Context context, Intent intent,
- String referrerPackage, AfterCompute afterCompute) {
+ String referrerPackage, AfterCompute afterCompute,
+ ChooserActivityLogger chooserActivityLogger) {
super(context, intent);
mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
mReferrerPackage = referrerPackage;
@@ -97,6 +98,7 @@
mAction = intent.getAction();
mRankerServiceName = new ComponentName(mContext, this.getClass());
setCallBack(afterCompute);
+ setChooserActivityLogger(chooserActivityLogger);
}
@Override
diff --git a/core/java/com/android/internal/content/F2fsUtils.java b/core/java/com/android/internal/content/F2fsUtils.java
new file mode 100644
index 0000000..27f1b30
--- /dev/null
+++ b/core/java/com/android/internal/content/F2fsUtils.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2021 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.internal.content;
+
+import android.annotation.NonNull;
+import android.content.ContentResolver;
+import android.os.Environment;
+import android.os.incremental.IncrementalManager;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility methods to work with the f2fs file system.
+ */
+public final class F2fsUtils {
+ private static final String TAG = "F2fsUtils";
+ private static final boolean DEBUG_F2FS = false;
+
+ /** Directory containing kernel features */
+ private static final File sKernelFeatures =
+ new File("/sys/fs/f2fs/features");
+ /** File containing features enabled on "/data" */
+ private static final File sUserDataFeatures =
+ new File("/dev/sys/fs/by-name/userdata/features");
+ private static final File sDataDirectory = Environment.getDataDirectory();
+ /** Name of the compression feature */
+ private static final String COMPRESSION_FEATURE = "compression";
+
+ private static final boolean sKernelCompressionAvailable;
+ private static final boolean sUserDataCompressionAvailable;
+
+ static {
+ sKernelCompressionAvailable = isCompressionEnabledInKernel();
+ if (!sKernelCompressionAvailable) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "f2fs compression DISABLED; feature not part of the kernel");
+ }
+ }
+ sUserDataCompressionAvailable = isCompressionEnabledOnUserData();
+ if (!sUserDataCompressionAvailable) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "f2fs compression DISABLED; feature not enabled on filesystem");
+ }
+ }
+ }
+
+ /**
+ * Releases compressed blocks from eligible installation artifacts.
+ * <p>
+ * Modern f2fs implementations starting in {@code S} support compression
+ * natively within the file system. The data blocks of specific installation
+ * artifacts [eg. .apk, .so, ...] can be compressed at the file system level,
+ * making them look and act like any other uncompressed file, but consuming
+ * a fraction of the space.
+ * <p>
+ * However, the unused space is not free'd automatically. Instead, we must
+ * manually tell the file system to release the extra blocks [the delta between
+ * the compressed and uncompressed block counts] back to the free pool.
+ * <p>
+ * Because of how compression works within the file system, once the blocks
+ * have been released, the file becomes read-only and cannot be modified until
+ * the free'd blocks have again been reserved from the free pool.
+ */
+ public static void releaseCompressedBlocks(ContentResolver resolver, File file) {
+ if (!sKernelCompressionAvailable || !sUserDataCompressionAvailable) {
+ return;
+ }
+
+ // NOTE: Retrieving this setting means we need to delay releasing cblocks
+ // of any APKs installed during the PackageManagerService constructor. Instead
+ // of being able to release them in the constructor, they can only be released
+ // immediately prior to the system being available. When we no longer need to
+ // read this setting, move cblock release back to the package manager constructor.
+ final boolean releaseCompressBlocks =
+ Secure.getInt(resolver, Secure.RELEASE_COMPRESS_BLOCKS_ON_INSTALL, 1) != 0;
+ if (!releaseCompressBlocks) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "SKIP; release compress blocks not enabled");
+ }
+ return;
+ }
+ if (!isCompressionAllowed(file)) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "SKIP; compression not allowed");
+ }
+ return;
+ }
+ final File[] files = getFilesToRelease(file);
+ if (files == null || files.length == 0) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "SKIP; no files to compress");
+ }
+ return;
+ }
+ for (int i = files.length - 1; i >= 0; --i) {
+ final long releasedBlocks = nativeReleaseCompressedBlocks(files[i].getAbsolutePath());
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "RELEASED " + releasedBlocks + " blocks"
+ + " from \"" + files[i] + "\"");
+ }
+ }
+ }
+
+ /**
+ * Returns {@code true} if compression is allowed on the file system containing
+ * the given file.
+ * <p>
+ * NOTE: The return value does not mean if the given file, or any other file
+ * on the same file system, is actually compressed. It merely determines whether
+ * not files <em>may</em> be compressed.
+ */
+ private static boolean isCompressionAllowed(@NonNull File file) {
+ final String filePath;
+ try {
+ filePath = file.getCanonicalPath();
+ } catch (IOException e) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "f2fs compression DISABLED; could not determine path");
+ }
+ return false;
+ }
+ if (IncrementalManager.isIncrementalPath(filePath)) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "f2fs compression DISABLED; file on incremental fs");
+ }
+ return false;
+ }
+ if (!isChild(sDataDirectory, filePath)) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "f2fs compression DISABLED; file not on /data");
+ }
+ return false;
+ }
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "f2fs compression ENABLED");
+ }
+ return true;
+ }
+
+ /**
+ * Returns {@code true} if the given child is a descendant of the base.
+ */
+ private static boolean isChild(@NonNull File base, @NonNull String childPath) {
+ try {
+ base = base.getCanonicalFile();
+
+ File parentFile = new File(childPath).getCanonicalFile();
+ while (parentFile != null) {
+ if (base.equals(parentFile)) {
+ return true;
+ }
+ parentFile = parentFile.getParentFile();
+ }
+ return false;
+ } catch (IOException ignore) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether or not the compression feature is enabled in the kernel.
+ * <p>
+ * NOTE: This doesn't mean compression is enabled on a particular file system
+ * or any files have been compressed. Only that the functionality is enabled
+ * on the device.
+ */
+ private static boolean isCompressionEnabledInKernel() {
+ final File[] features = sKernelFeatures.listFiles();
+ if (features == null || features.length == 0) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "ERROR; no kernel features");
+ }
+ return false;
+ }
+ for (int i = features.length - 1; i >= 0; --i) {
+ final File feature = features[i];
+ if (COMPRESSION_FEATURE.equals(features[i].getName())) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "FOUND kernel compression feature");
+ }
+ return true;
+ }
+ }
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "ERROR; kernel compression feature not found");
+ }
+ return false;
+ }
+
+ /**
+ * Returns whether or not the compression feature is enabled on user data [ie. "/data"].
+ * <p>
+ * NOTE: This doesn't mean any files have been compressed. Only that the functionality
+ * is enabled on the file system.
+ */
+ private static boolean isCompressionEnabledOnUserData() {
+ if (!sUserDataFeatures.exists()
+ || !sUserDataFeatures.isFile()
+ || !sUserDataFeatures.canRead()) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "ERROR; filesystem features not available");
+ }
+ return false;
+ }
+ final List<String> configLines;
+ try {
+ configLines = Files.readAllLines(sUserDataFeatures.toPath());
+ } catch (IOException ignore) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "ERROR; couldn't read filesystem features");
+ }
+ return false;
+ }
+ if (configLines == null
+ || configLines.size() > 1
+ || TextUtils.isEmpty(configLines.get(0))) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "ERROR; no filesystem features");
+ }
+ return false;
+ }
+ final String[] features = configLines.get(0).split(",");
+ for (int i = features.length - 1; i >= 0; --i) {
+ if (COMPRESSION_FEATURE.equals(features[i].trim())) {
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "FOUND filesystem compression feature");
+ }
+ return true;
+ }
+ }
+ if (DEBUG_F2FS) {
+ Slog.d(TAG, "ERROR; filesystem compression feature not found");
+ }
+ return false;
+ }
+
+ /**
+ * Returns all files contained within the directory at any depth from the given path.
+ */
+ private static List<File> getFilesRecursive(@NonNull File path) {
+ final File[] allFiles = path.listFiles();
+ if (allFiles == null) {
+ return null;
+ }
+ final ArrayList<File> files = new ArrayList<>();
+ for (File f : allFiles) {
+ if (f.isDirectory()) {
+ files.addAll(getFilesRecursive(f));
+ } else if (f.isFile()) {
+ files.add(f);
+ }
+ }
+ return files;
+ }
+
+ /**
+ * Returns all files contained within the directory at any depth from the given path.
+ */
+ private static File[] getFilesToRelease(@NonNull File codePath) {
+ final List<File> files = getFilesRecursive(codePath);
+ if (files == null) {
+ if (codePath.isFile()) {
+ return new File[] { codePath };
+ }
+ return null;
+ }
+ if (files.size() == 0) {
+ return null;
+ }
+ return files.toArray(new File[files.size()]);
+ }
+
+ private static native long nativeReleaseCompressedBlocks(String path);
+
+}
diff --git a/core/java/com/android/internal/content/OWNERS b/core/java/com/android/internal/content/OWNERS
new file mode 100644
index 0000000..c42bee6
--- /dev/null
+++ b/core/java/com/android/internal/content/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 36137
+include /core/java/android/content/pm/OWNERS
+
+per-file ReferrerIntent.aidl = file:/services/core/java/com/android/server/am/OWNERS
+per-file ReferrerIntent.java = file:/services/core/java/com/android/server/am/OWNERS
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 1468633..4502a33 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -84,6 +84,7 @@
android: {
srcs: [
"AndroidRuntime.cpp",
+ "com_android_internal_content_F2fsUtils.cpp",
"com_android_internal_content_NativeLibraryHelper.cpp",
"com_google_android_gles_jni_EGLImpl.cpp",
"com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7e8fc7e..dca5d96 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -190,6 +190,7 @@
extern int register_android_content_res_Configuration(JNIEnv* env);
extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
extern int register_android_security_Scrypt(JNIEnv *env);
+extern int register_com_android_internal_content_F2fsUtils(JNIEnv* env);
extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
extern int register_com_android_internal_content_om_OverlayConfig(JNIEnv *env);
extern int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv* env);
@@ -1621,6 +1622,7 @@
REG_JNI(register_android_animation_PropertyValuesHolder),
REG_JNI(register_android_security_Scrypt),
+ REG_JNI(register_com_android_internal_content_F2fsUtils),
REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
REG_JNI(register_com_android_internal_os_DmabufInfoReader),
REG_JNI(register_com_android_internal_os_FuseAppLoop),
diff --git a/core/jni/com_android_internal_content_F2fsUtils.cpp b/core/jni/com_android_internal_content_F2fsUtils.cpp
new file mode 100644
index 0000000..8b9d59c
--- /dev/null
+++ b/core/jni/com_android_internal_content_F2fsUtils.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_TAG "F2fsUtils"
+
+#include "core_jni_helpers.h"
+
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni_macros.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <linux/f2fs.h>
+#include <linux/fs.h>
+
+#include <android-base/unique_fd.h>
+
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+#include <array>
+
+using namespace std::literals;
+
+namespace android {
+
+static jlong com_android_internal_content_F2fsUtils_nativeReleaseCompressedBlocks(JNIEnv *env,
+ jclass clazz,
+ jstring path) {
+ unsigned long long blkcnt;
+ int ret;
+ ScopedUtfChars filePath(env, path);
+
+ android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY | O_CLOEXEC, 0));
+ if (fd < 0) {
+ ALOGW("Failed to open file: %s (%d)\n", filePath.c_str(), errno);
+ return 0;
+ }
+
+ long flags = 0;
+ ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
+ if (ret < 0) {
+ ALOGW("Failed to get flags for file: %s (%d)\n", filePath.c_str(), errno);
+ return 0;
+ }
+ if ((flags & FS_COMPR_FL) == 0) {
+ return 0;
+ }
+
+ ret = ioctl(fd, F2FS_IOC_RELEASE_COMPRESS_BLOCKS, &blkcnt);
+ if (ret < 0) {
+ return -errno;
+ }
+ return blkcnt;
+}
+
+static const std::array gMethods = {
+ MAKE_JNI_NATIVE_METHOD(
+ "nativeReleaseCompressedBlocks", "(Ljava/lang/String;)J",
+ com_android_internal_content_F2fsUtils_nativeReleaseCompressedBlocks),
+};
+
+int register_com_android_internal_content_F2fsUtils(JNIEnv *env) {
+ return RegisterMethodsOrDie(env, "com/android/internal/content/F2fsUtils", gMethods.data(),
+ gMethods.size());
+}
+
+}; // namespace android
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1ddff32..e5f4588 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1792,6 +1792,9 @@
<!-- Boolean indicating if placing the phone face down will result in a screen off. -->
<bool name="config_flipToScreenOffEnabled">true</bool>
+ <!-- Integer to set a max latency the accelerometer will batch sensor requests with. -->
+ <integer name="config_flipToScreenOffMaxLatencyMicros">2000000</integer>
+
<!-- Boolean indicating if current platform supports bluetooth SCO for off call
use cases -->
<bool name="config_bluetooth_sco_off_call">true</bool>
@@ -1968,6 +1971,9 @@
<string name="config_systemActivityRecognizer" translatable="false"></string>
<!-- The name of the package that will hold the system ui role -->
<string name="config_systemUi" translatable="false">com.android.systemui</string>
+ <!-- The name of the package that will hold the television remote service role.
+ TODO(b/189347385) make this a @SystemAPI -->
+ <string name="config_systemTelevisionRemoteService" translatable="false">@string/config_tvRemoteServicePackage</string>
<!-- The name of the package that will be allowed to change its components' label/icon. -->
<string name="config_overrideComponentUiPackage" translatable="false">com.android.stk</string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index d334306..ea93520 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -939,4 +939,8 @@
<!-- System-provided padding for inner views on app widgets. The resolved value of this resource may change at runtime. @removed -->
<dimen name="__removed_system_app_widget_internal_padding">16dp</dimen>
+ <!-- The width/height of the icon view on staring surface. -->
+ <dimen name="starting_surface_icon_size">160dp</dimen>
+ <!-- The default width/height of the icon on the spec of adaptive icon drawable. -->
+ <dimen name="starting_surface_default_icon_size">108dp</dimen>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index ef5cfe3..2403a60 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3027,222 +3027,178 @@
<public type="bool" name="config_assistantOnTopOfDream" id="0x01110005" />
<!-- @hide @TestApi -->
<public type="bool" name="config_remoteInsetsControllerControlsSystemBars" id="0x01110006" />
- <!-- ===============================================================
+
+ <!-- ===============================================================
Resources added in version S of the platform
-
- NOTE: add <public> elements within a <staging-public-group> like so:
-
- <staging-public-group type="attr" first-id="0x01010531">
- <public name="exampleAttr1" />
- <public name="exampleAttr2" />
- </staging-public-group>
-
- To add a new public-group block, choose an id value that is 1 greater
- than the last of that item above. For example, the last "attr" id
- value above is 0x01010530, so the public-group of attrs below has
- the id value of 0x01010531.
=============================================================== -->
- <eat-comment />
+ <eat-comment />
- <staging-public-group type="attr" first-id="0x01010617">
- <public name="rollbackDataPolicy" />
- <public name="allowClickWhenDisabled" />
- <public name="windowLayoutAffinity" />
- <public name="canPauseRecording" />
- <public name="windowBlurBehindRadius"/>
- <public name="windowBlurBehindEnabled"/>
- <public name="requireDeviceScreenOn" />
- <public name="pathSuffix" />
- <public name="sspSuffix" />
- <public name="pathAdvancedPattern" />
- <public name="sspAdvancedPattern" />
- <public name="fontProviderSystemFontFamily" />
- <public name="hand_second" />
- <public name="memtagMode" />
- <public name="nativeHeapZeroInitialized" />
+ <public type="attr" name="rollbackDataPolicy" id="0x01010617" />
+ <public type="attr" name="allowClickWhenDisabled" id="0x01010618" />
+ <public type="attr" name="windowLayoutAffinity" id="0x01010619" />
+ <public type="attr" name="canPauseRecording" id="0x0101061a" />
+ <public type="attr" name="windowBlurBehindRadius" id="0x0101061b" />
+ <public type="attr" name="windowBlurBehindEnabled" id="0x0101061c" />
+ <public type="attr" name="requireDeviceScreenOn" id="0x0101061d" />
+ <public type="attr" name="pathSuffix" id="0x0101061e" />
+ <public type="attr" name="sspSuffix" id="0x0101061f" />
+ <public type="attr" name="pathAdvancedPattern" id="0x01010620" />
+ <public type="attr" name="sspAdvancedPattern" id="0x01010621" />
+ <public type="attr" name="fontProviderSystemFontFamily" id="0x01010622" />
+ <public type="attr" name="hand_second" id="0x01010623" />
+ <public type="attr" name="memtagMode" id="0x01010624" />
+ <public type="attr" name="nativeHeapZeroInitialized" id="0x01010625" />
<!-- @hide @SystemApi -->
- <public name="hotwordDetectionService" />
- <public name="previewLayout" />
- <public name="clipToOutline" />
- <public name="__removed3" />
- <public name="knownCerts" />
- <public name="windowBackgroundBlurRadius"/>
- <public name="windowSplashScreenBackground"/>
- <public name="windowSplashScreenAnimatedIcon"/>
- <public name="windowSplashScreenAnimationDuration"/>
- <public name="windowSplashScreenBrandingImage"/>
- <public name="windowSplashScreenIconBackgroundColor"/>
- <public name="splashScreenTheme" />
- <public name="maxResizeWidth" />
- <public name="maxResizeHeight" />
- <public name="targetCellWidth" />
- <public name="targetCellHeight" />
- <public name="dialTint"/>
- <public name="dialTintMode"/>
- <public name="hand_hourTint"/>
- <public name="hand_hourTintMode"/>
- <public name="hand_minuteTint"/>
- <public name="hand_minuteTintMode"/>
- <public name="hand_secondTint"/>
- <public name="hand_secondTintMode"/>
- <public name="dataExtractionRules"/>
- <public name="passwordsActivity"/>
- <public name="selectableAsDefault"/>
- <public name="isAccessibilityTool"/>
- <public name="attributionTags"/>
- <public name="suppressesSpellChecker" />
- <public name="usesPermissionFlags" />
- <public name="requestRawExternalStorageAccess" />
+ <public type="attr" name="hotwordDetectionService" id="0x01010626" />
+ <public type="attr" name="previewLayout" id="0x01010627" />
+ <public type="attr" name="clipToOutline" id="0x01010628" />
+ <!-- <public type="attr" name="__removed3" id="0x01010629" /> -->
+ <public type="attr" name="knownCerts" id="0x0101062a" />
+ <public type="attr" name="windowBackgroundBlurRadius" id="0x0101062b" />
+ <public type="attr" name="windowSplashScreenBackground" id="0x0101062c" />
+ <public type="attr" name="windowSplashScreenAnimatedIcon" id="0x0101062d" />
+ <public type="attr" name="windowSplashScreenAnimationDuration" id="0x0101062e" />
+ <public type="attr" name="windowSplashScreenBrandingImage" id="0x0101062f" />
+ <public type="attr" name="windowSplashScreenIconBackgroundColor" id="0x01010630" />
+ <public type="attr" name="splashScreenTheme" id="0x01010631" />
+ <public type="attr" name="maxResizeWidth" id="0x01010632" />
+ <public type="attr" name="maxResizeHeight" id="0x01010633" />
+ <public type="attr" name="targetCellWidth" id="0x01010634" />
+ <public type="attr" name="targetCellHeight" id="0x01010635" />
+ <public type="attr" name="dialTint" id="0x01010636" />
+ <public type="attr" name="dialTintMode" id="0x01010637" />
+ <public type="attr" name="hand_hourTint" id="0x01010638" />
+ <public type="attr" name="hand_hourTintMode" id="0x01010639" />
+ <public type="attr" name="hand_minuteTint" id="0x0101063a" />
+ <public type="attr" name="hand_minuteTintMode" id="0x0101063b" />
+ <public type="attr" name="hand_secondTint" id="0x0101063c" />
+ <public type="attr" name="hand_secondTintMode" id="0x0101063d" />
+ <public type="attr" name="dataExtractionRules" id="0x0101063e" />
+ <public type="attr" name="passwordsActivity" id="0x0101063f" />
+ <public type="attr" name="selectableAsDefault" id="0x01010640" />
+ <public type="attr" name="isAccessibilityTool" id="0x01010641" />
+ <public type="attr" name="attributionTags" id="0x01010642" />
+ <public type="attr" name="suppressesSpellChecker" id="0x01010643" />
+ <public type="attr" name="usesPermissionFlags" id="0x01010644" />
+ <public type="attr" name="requestRawExternalStorageAccess" id="0x01010645" />
<!-- @hide @SystemApi -->
- <public name="playHomeTransitionSound" />
- <public name="lStar" />
- <public name="showInInputMethodPicker" />
- <public name="effectColor" />
+ <public type="attr" name="playHomeTransitionSound" id="0x01010646" />
+ <public type="attr" name="lStar" id="0x01010647" />
+ <public type="attr" name="showInInputMethodPicker" id="0x01010648" />
+ <public type="attr" name="effectColor" id="0x01010649" />
<!-- @hide @TestApi -->
- <public name="requestForegroundServiceExemption" />
- <public name="attributionsAreUserVisible" />
- </staging-public-group>
+ <public type="attr" name="requestForegroundServiceExemption" id="0x0101064a" />
+ <public type="attr" name="attributionsAreUserVisible" id="0x0101064b" />
- <staging-public-group type="drawable" first-id="0x010800b5">
- <!-- drawable definitions go here -->
- </staging-public-group>
+ <public type="color" name="system_neutral1_0" id="0x0106001d" />
+ <public type="color" name="system_neutral1_10" id="0x0106001e" />
+ <public type="color" name="system_neutral1_50" id="0x0106001f" />
+ <public type="color" name="system_neutral1_100" id="0x01060020" />
+ <public type="color" name="system_neutral1_200" id="0x01060021" />
+ <public type="color" name="system_neutral1_300" id="0x01060022" />
+ <public type="color" name="system_neutral1_400" id="0x01060023" />
+ <public type="color" name="system_neutral1_500" id="0x01060024" />
+ <public type="color" name="system_neutral1_600" id="0x01060025" />
+ <public type="color" name="system_neutral1_700" id="0x01060026" />
+ <public type="color" name="system_neutral1_800" id="0x01060027" />
+ <public type="color" name="system_neutral1_900" id="0x01060028" />
+ <public type="color" name="system_neutral1_1000" id="0x01060029" />
+ <public type="color" name="system_neutral2_0" id="0x0106002a" />
+ <public type="color" name="system_neutral2_10" id="0x0106002b" />
+ <public type="color" name="system_neutral2_50" id="0x0106002c" />
+ <public type="color" name="system_neutral2_100" id="0x0106002d" />
+ <public type="color" name="system_neutral2_200" id="0x0106002e" />
+ <public type="color" name="system_neutral2_300" id="0x0106002f" />
+ <public type="color" name="system_neutral2_400" id="0x01060030" />
+ <public type="color" name="system_neutral2_500" id="0x01060031" />
+ <public type="color" name="system_neutral2_600" id="0x01060032" />
+ <public type="color" name="system_neutral2_700" id="0x01060033" />
+ <public type="color" name="system_neutral2_800" id="0x01060034" />
+ <public type="color" name="system_neutral2_900" id="0x01060035" />
+ <public type="color" name="system_neutral2_1000" id="0x01060036" />
+ <public type="color" name="system_accent1_0" id="0x01060037" />
+ <public type="color" name="system_accent1_10" id="0x01060038" />
+ <public type="color" name="system_accent1_50" id="0x01060039" />
+ <public type="color" name="system_accent1_100" id="0x0106003a" />
+ <public type="color" name="system_accent1_200" id="0x0106003b" />
+ <public type="color" name="system_accent1_300" id="0x0106003c" />
+ <public type="color" name="system_accent1_400" id="0x0106003d" />
+ <public type="color" name="system_accent1_500" id="0x0106003e" />
+ <public type="color" name="system_accent1_600" id="0x0106003f" />
+ <public type="color" name="system_accent1_700" id="0x01060040" />
+ <public type="color" name="system_accent1_800" id="0x01060041" />
+ <public type="color" name="system_accent1_900" id="0x01060042" />
+ <public type="color" name="system_accent1_1000" id="0x01060043" />
+ <public type="color" name="system_accent2_0" id="0x01060044" />
+ <public type="color" name="system_accent2_10" id="0x01060045" />
+ <public type="color" name="system_accent2_50" id="0x01060046" />
+ <public type="color" name="system_accent2_100" id="0x01060047" />
+ <public type="color" name="system_accent2_200" id="0x01060048" />
+ <public type="color" name="system_accent2_300" id="0x01060049" />
+ <public type="color" name="system_accent2_400" id="0x0106004a" />
+ <public type="color" name="system_accent2_500" id="0x0106004b" />
+ <public type="color" name="system_accent2_600" id="0x0106004c" />
+ <public type="color" name="system_accent2_700" id="0x0106004d" />
+ <public type="color" name="system_accent2_800" id="0x0106004e" />
+ <public type="color" name="system_accent2_900" id="0x0106004f" />
+ <public type="color" name="system_accent2_1000" id="0x01060050" />
+ <public type="color" name="system_accent3_0" id="0x01060051" />
+ <public type="color" name="system_accent3_10" id="0x01060052" />
+ <public type="color" name="system_accent3_50" id="0x01060053" />
+ <public type="color" name="system_accent3_100" id="0x01060054" />
+ <public type="color" name="system_accent3_200" id="0x01060055" />
+ <public type="color" name="system_accent3_300" id="0x01060056" />
+ <public type="color" name="system_accent3_400" id="0x01060057" />
+ <public type="color" name="system_accent3_500" id="0x01060058" />
+ <public type="color" name="system_accent3_600" id="0x01060059" />
+ <public type="color" name="system_accent3_700" id="0x0106005a" />
+ <public type="color" name="system_accent3_800" id="0x0106005b" />
+ <public type="color" name="system_accent3_900" id="0x0106005c" />
+ <public type="color" name="system_accent3_1000" id="0x0106005d" />
- <staging-public-group type="color" first-id="0x0106001d">
- <!-- color definitions go here -->
+ <public type="dimen" name="system_app_widget_background_radius" id="0x01050008" />
+ <public type="dimen" name="system_app_widget_inner_radius" id="0x01050009" />
- <!-- Material design dynamic system palette:-->
- <!-- Neutral colors for background and text -->
- <public name="system_neutral1_0" />
- <public name="system_neutral1_10" />
- <public name="system_neutral1_50" />
- <public name="system_neutral1_100" />
- <public name="system_neutral1_200" />
- <public name="system_neutral1_300" />
- <public name="system_neutral1_400" />
- <public name="system_neutral1_500" />
- <public name="system_neutral1_600" />
- <public name="system_neutral1_700" />
- <public name="system_neutral1_800" />
- <public name="system_neutral1_900" />
- <public name="system_neutral1_1000" />
- <public name="system_neutral2_0" />
- <public name="system_neutral2_10" />
- <public name="system_neutral2_50" />
- <public name="system_neutral2_100" />
- <public name="system_neutral2_200" />
- <public name="system_neutral2_300" />
- <public name="system_neutral2_400" />
- <public name="system_neutral2_500" />
- <public name="system_neutral2_600" />
- <public name="system_neutral2_700" />
- <public name="system_neutral2_800" />
- <public name="system_neutral2_900" />
- <public name="system_neutral2_1000" />
- <!-- Accent colors, for buttons and UI decorations -->
- <public name="system_accent1_0" />
- <public name="system_accent1_10" />
- <public name="system_accent1_50" />
- <public name="system_accent1_100" />
- <public name="system_accent1_200" />
- <public name="system_accent1_300" />
- <public name="system_accent1_400" />
- <public name="system_accent1_500" />
- <public name="system_accent1_600" />
- <public name="system_accent1_700" />
- <public name="system_accent1_800" />
- <public name="system_accent1_900" />
- <public name="system_accent1_1000" />
- <public name="system_accent2_0" />
- <public name="system_accent2_10" />
- <public name="system_accent2_50" />
- <public name="system_accent2_100" />
- <public name="system_accent2_200" />
- <public name="system_accent2_300" />
- <public name="system_accent2_400" />
- <public name="system_accent2_500" />
- <public name="system_accent2_600" />
- <public name="system_accent2_700" />
- <public name="system_accent2_800" />
- <public name="system_accent2_900" />
- <public name="system_accent2_1000" />
- <public name="system_accent3_0" />
- <public name="system_accent3_10" />
- <public name="system_accent3_50" />
- <public name="system_accent3_100" />
- <public name="system_accent3_200" />
- <public name="system_accent3_300" />
- <public name="system_accent3_400" />
- <public name="system_accent3_500" />
- <public name="system_accent3_600" />
- <public name="system_accent3_700" />
- <public name="system_accent3_800" />
- <public name="system_accent3_900" />
- <public name="system_accent3_1000" />
- </staging-public-group>
-
- <staging-public-group type="dimen" first-id="0x01050008">
- <!-- dimension definitions go here -->
-
- <!-- System-provided dimensions for app widgets. -->
- <public name="system_app_widget_background_radius" />
- <public name="system_app_widget_inner_radius" />
- <public name="__removed_system_app_widget_internal_padding" />
- </staging-public-group>
-
- <staging-public-group type="bool" first-id="0x01110007">
- <!-- boolean definitions go here -->
- </staging-public-group>
-
- <staging-public-group type="style" first-id="0x010302e5">
- <!-- style definitions go here -->
- </staging-public-group>
-
- <staging-public-group type="string" first-id="0x01040028">
<!-- @hide @SystemApi @TestApi -->
- <public name="config_systemAutomotiveCluster" />
+ <public type="string" name="config_systemAutomotiveCluster" id="0x01040028" />
<!-- @hide @SystemApi @TestApi -->
- <public name="config_systemAutomotiveProjection" />
+ <public type="string" name="config_systemAutomotiveProjection" id="0x01040029" />
<!-- @hide @SystemApi -->
- <public name="config_systemShell" />
+ <public type="string" name="config_systemShell" id="0x0104002a" />
<!-- @hide @SystemApi -->
- <public name="config_systemContacts" />
+ <public type="string" name="config_systemContacts" id="0x0104002b" />
<!-- @hide @SystemApi -->
- <public name="config_customMediaKeyDispatcher" />
+ <public type="string" name="config_customMediaKeyDispatcher" id="0x0104002c" />
<!-- @hide @SystemApi -->
- <public name="config_customMediaSessionPolicyProvider" />
+ <public type="string" name="config_customMediaSessionPolicyProvider" id="0x0104002d" />
<!-- @hide @SystemApi -->
- <public name="config_systemSpeechRecognizer" />
+ <public type="string" name="config_systemSpeechRecognizer" id="0x0104002e" />
<!-- @hide @SystemApi -->
- <public name="config_systemWifiCoexManager" />
+ <public type="string" name="config_systemWifiCoexManager" id="0x0104002f" />
<!-- @hide @SystemApi -->
- <public name="config_systemWellbeing" />
+ <public type="string" name="config_systemWellbeing" id="0x01040030" />
<!-- @hide @SystemApi -->
- <public name="config_systemTelevisionNotificationHandler" />
+ <public type="string" name="config_systemTelevisionNotificationHandler" id="0x01040031" />
<!-- @hide @SystemApi -->
- <public name="config_systemUiIntelligence" />
+ <public type="string" name="config_systemUiIntelligence" id="0x01040032" />
<!-- @hide @SystemApi -->
- <public name="config_systemAmbientAudioIntelligence" />
+ <public type="string" name="config_systemAmbientAudioIntelligence" id="0x01040033" />
<!-- @hide @SystemApi -->
- <public name="config_systemAudioIntelligence" />
+ <public type="string" name="config_systemAudioIntelligence" id="0x01040034" />
<!-- @hide @SystemApi -->
- <public name="config_systemNotificationIntelligence" />
+ <public type="string" name="config_systemNotificationIntelligence" id="0x01040035" />
<!-- @hide @SystemApi -->
- <public name="config_systemTextIntelligence" />
+ <public type="string" name="config_systemTextIntelligence" id="0x01040036" />
<!-- @hide @SystemApi -->
- <public name="config_systemVisualIntelligence" />
+ <public type="string" name="config_systemVisualIntelligence" id="0x01040037" />
<!-- @hide @SystemApi -->
- <public name="config_systemActivityRecognizer" />
+ <public type="string" name="config_systemActivityRecognizer" id="0x01040038" />
<!-- @hide @SystemApi -->
- <public name="config_systemCompanionDeviceProvider"/>
+ <public type="string" name="config_systemCompanionDeviceProvider" id="0x01040039" />
<!-- @hide @SystemApi -->
- <public name="config_systemUi" />
+ <public type="string" name="config_systemUi" id="0x0104003a" />
<!-- @hide For use by platform and tools only. Developers should not specify this value. -->
- <public name="config_defaultRingtoneVibrationSound"/>
- </staging-public-group>
-
- <staging-public-group type="id" first-id="0x01020055">
- <!-- id definitions go here -->
- </staging-public-group>
+ <public type="string" name="config_defaultRingtoneVibrationSound" id="0x0104003b" />
<!-- ===============================================================
DO NOT ADD UN-GROUPED ITEMS HERE
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4da5859..374cea7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -276,6 +276,7 @@
<java-symbol type="bool" name="config_avoidGfxAccel" />
<java-symbol type="bool" name="config_bluetooth_address_validation" />
<java-symbol type="bool" name="config_flipToScreenOffEnabled" />
+ <java-symbol type="integer" name="config_flipToScreenOffMaxLatencyMicros" />
<java-symbol type="bool" name="config_bluetooth_sco_off_call" />
<java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" />
<java-symbol type="bool" name="config_bluetooth_hfp_inband_ringing_support" />
@@ -4388,4 +4389,7 @@
<java-symbol type="bool" name="config_supportsMicToggle" />
<java-symbol type="bool" name="config_supportsCamToggle" />
+
+ <java-symbol type="dimen" name="starting_surface_icon_size" />
+ <java-symbol type="dimen" name="starting_surface_default_icon_size" />
</resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 97acd5b..9d0a42d8 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -232,6 +232,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -261,6 +264,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -307,6 +313,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -355,6 +364,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -402,6 +414,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -464,6 +479,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -503,6 +521,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -548,6 +569,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -594,6 +618,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -656,6 +683,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -703,6 +733,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -748,6 +781,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -795,6 +831,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -841,6 +880,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -887,6 +929,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -933,6 +978,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -979,6 +1027,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1029,6 +1080,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1076,6 +1130,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1120,6 +1177,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1318,6 +1378,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1348,6 +1411,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1393,6 +1459,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1439,6 +1508,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1487,6 +1559,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1534,6 +1609,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1598,6 +1676,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1636,6 +1717,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1684,6 +1768,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1733,6 +1820,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1781,6 +1871,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1811,6 +1904,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1842,6 +1938,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1892,6 +1991,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1940,6 +2042,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -1987,6 +2092,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2033,6 +2141,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2079,6 +2190,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2123,6 +2237,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2285,6 +2402,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -2330,6 +2450,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2385,6 +2508,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2433,6 +2559,9 @@
<item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
<item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
<item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
+ <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
+ <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
+ <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
<item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
diff --git a/core/tests/coretests/src/android/os/VibrationEffectTest.java b/core/tests/coretests/src/android/os/VibrationEffectTest.java
index 009665f..6cbfffc 100644
--- a/core/tests/coretests/src/android/os/VibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/VibrationEffectTest.java
@@ -102,7 +102,9 @@
assertThrows(IllegalArgumentException.class,
() -> VibrationEffect.createOneShot(1, -2).validate());
assertThrows(IllegalArgumentException.class,
- () -> VibrationEffect.createOneShot(1, 256).validate());
+ () -> VibrationEffect.createOneShot(1, 0).validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> VibrationEffect.createOneShot(-1, 255).validate());
}
@Test
@@ -117,6 +119,7 @@
@Test
public void testValidateWaveform() {
VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1).validate();
+ VibrationEffect.createWaveform(new long[]{10, 10}, new int[] {0, 0}, -1).validate();
VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, 0).validate();
VibrationEffect.startWaveform()
.addStep(/* amplitude= */ 1, /* duration= */ 10)
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 19c2763..6e34a33 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -1857,6 +1857,57 @@
}
@Test
+ public void testEmptyDirectRowLogging() throws InterruptedException {
+ Intent sendIntent = createSendTextIntent();
+ // We need app targets for direct targets to get displayed
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+ when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
+ Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+
+ // Start activity
+ final ChooserWrapperActivity activity = mActivityRule
+ .launchActivity(Intent.createChooser(sendIntent, null));
+
+ // Thread.sleep shouldn't be a thing in an integration test but it's
+ // necessary here because of the way the code is structured
+ Thread.sleep(3000);
+
+ assertThat("Chooser should have 2 app targets",
+ activity.getAdapter().getCount(), is(2));
+ assertThat("Chooser should have no direct targets",
+ activity.getAdapter().getSelectableServiceTargetCount(), is(0));
+
+ ChooserActivityLoggerFake logger =
+ (ChooserActivityLoggerFake) activity.getChooserActivityLogger();
+ assertThat(logger.numCalls(), is(6));
+ // first one should be SHARESHEET_TRIGGERED uievent
+ assertThat(logger.get(0).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
+ assertThat(logger.get(0).event.getId(),
+ is(ChooserActivityLogger.SharesheetStandardEvent.SHARESHEET_TRIGGERED.getId()));
+ // second one should be SHARESHEET_STARTED event
+ assertThat(logger.get(1).atomId, is(FrameworkStatsLog.SHARESHEET_STARTED));
+ assertThat(logger.get(1).intent, is(Intent.ACTION_SEND));
+ assertThat(logger.get(1).mimeType, is("text/plain"));
+ assertThat(logger.get(1).packageName, is("com.android.frameworks.coretests"));
+ assertThat(logger.get(1).appProvidedApp, is(0));
+ assertThat(logger.get(1).appProvidedDirect, is(0));
+ assertThat(logger.get(1).isWorkprofile, is(false));
+ assertThat(logger.get(1).previewType, is(3));
+ // third one should be SHARESHEET_APP_LOAD_COMPLETE uievent
+ assertThat(logger.get(2).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
+ assertThat(logger.get(2).event.getId(),
+ is(ChooserActivityLogger
+ .SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE.getId()));
+ // fourth and fifth are just artifacts of test set-up
+ // sixth one should be ranking atom with SHARESHEET_EMPTY_DIRECT_SHARE_ROW event
+ assertThat(logger.get(5).atomId, is(FrameworkStatsLog.UI_EVENT_REPORTED));
+ assertThat(logger.get(5).event.getId(),
+ is(ChooserActivityLogger
+ .SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW.getId()));
+ }
+
+ @Test
public void testCopyTextToClipboardLogging() throws Exception {
Intent sendIntent = createSendTextIntent();
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index 16a2fbd..9fcab09 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -68,7 +68,8 @@
: sOverrides.packageManager;
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
filterLastUsed, resolverListController,
- this, this, packageManager);
+ this, this, packageManager,
+ getChooserActivityLogger());
}
ChooserListAdapter getAdapter() {
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 8d4739d..99d7167 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -153,7 +153,6 @@
<permission name="android.permission.PACKAGE_USAGE_STATS" />
<permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
<permission name="android.permission.MODIFY_AUDIO_ROUTING" />
- <permission name="android.permission.GET_RUNTIME_PERMISSION_GROUP_MAPPING" />
</privapp-permissions>
<privapp-permissions package="com.android.phone">
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index ce8ce51..3caff35 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -180,11 +180,6 @@
individual_bubble_size + some padding. -->
<dimen name="bubble_stack_user_education_side_inset">72dp</dimen>
- <!-- The width/height of the icon view on staring surface. -->
- <dimen name="starting_surface_icon_size">160dp</dimen>
- <!-- The default width/height of the icon on the spec of adaptive icon drawable. -->
- <dimen name="default_icon_size">108dp</dimen>
-
<!-- The width/height of the size compat restart button. -->
<dimen name="size_compat_button_size">48dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 536165b..7e48a7e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -938,6 +938,8 @@
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
if (mShowingManage) {
showManageMenu(false /* show */);
+ } else if (mStackEduView != null && mStackEduView.getVisibility() == VISIBLE) {
+ mStackEduView.hide(false);
} else if (mBubbleData.isExpanded()) {
mBubbleData.setExpanded(false);
}
@@ -1152,6 +1154,7 @@
mStackEduView = new StackEducationView(mContext);
addView(mStackEduView);
}
+ mBubbleContainer.bringToFront();
return mStackEduView.show(mPositioner.getDefaultStartPosition());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 093c272..1d37a12 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -124,9 +124,9 @@
private void updateDensity() {
mIconSize = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.starting_surface_icon_size);
+ com.android.internal.R.dimen.starting_surface_icon_size);
mDefaultIconSize = mContext.getResources().getDimensionPixelSize(
- com.android.wm.shell.R.dimen.default_icon_size);
+ com.android.internal.R.dimen.starting_surface_default_icon_size);
mBrandingImageWidth = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.starting_surface_brand_image_width);
mBrandingImageHeight = mContext.getResources().getDimensionPixelSize(
@@ -135,7 +135,7 @@
com.android.wm.shell.R.dimen.starting_surface_exit_animation_window_shift_length);
}
- private int getSystemBGColor() {
+ private static int getSystemBGColor() {
final Context systemContext = ActivityThread.currentApplication();
if (systemContext == null) {
Slog.e(TAG, "System context does not exist!");
@@ -145,17 +145,18 @@
return res.getColor(com.android.wm.shell.R.color.splash_window_background_default);
}
- private Drawable createDefaultBackgroundDrawable() {
+ private static Drawable createDefaultBackgroundDrawable() {
return new ColorDrawable(getSystemBGColor());
}
- private @ColorInt int peekWindowBGColor(Context context) {
+ /** Extract the window background color from {@code attrs}. */
+ public static int peekWindowBGColor(Context context, SplashScreenWindowAttrs attrs) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "peekWindowBGColor");
final Drawable themeBGDrawable;
- if (mTmpAttrs.mWindowBgColor != 0) {
- themeBGDrawable = new ColorDrawable(mTmpAttrs.mWindowBgColor);
- } else if (mTmpAttrs.mWindowBgResId != 0) {
- themeBGDrawable = context.getDrawable(mTmpAttrs.mWindowBgResId);
+ if (attrs.mWindowBgColor != 0) {
+ themeBGDrawable = new ColorDrawable(attrs.mWindowBgColor);
+ } else if (attrs.mWindowBgResId != 0) {
+ themeBGDrawable = context.getDrawable(attrs.mWindowBgResId);
} else {
themeBGDrawable = createDefaultBackgroundDrawable();
Slog.w(TAG, "Window background does not exist, using " + themeBGDrawable);
@@ -165,7 +166,7 @@
return estimatedWindowBGColor;
}
- private int estimateWindowBGColor(Drawable themeBGDrawable) {
+ private static int estimateWindowBGColor(Drawable themeBGDrawable) {
final DrawableColorTester themeBGTester =
new DrawableColorTester(themeBGDrawable, true /* filterTransparent */);
if (themeBGTester.nonTransparentRatio() == 0) {
@@ -183,7 +184,7 @@
getWindowAttrs(context, mTmpAttrs);
final StartingWindowViewBuilder builder = new StartingWindowViewBuilder();
- final int themeBGColor = peekWindowBGColor(context);
+ final int themeBGColor = peekWindowBGColor(context, this.mTmpAttrs);
// TODO (b/173975965) Tracking the performance on improved splash screen.
return builder
.setContext(context)
@@ -193,7 +194,11 @@
.build();
}
- private static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) {
+ /**
+ * Get the {@link SplashScreenWindowAttrs} from {@code context} and fill them into
+ * {@code attrs}.
+ */
+ public static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) {
final TypedArray typedArray = context.obtainStyledAttributes(
com.android.internal.R.styleable.Window);
attrs.mWindowBgResId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0);
@@ -216,7 +221,8 @@
}
}
- private static class SplashScreenWindowAttrs {
+ /** The configuration of the splash screen window. */
+ public static class SplashScreenWindowAttrs {
private int mWindowBgResId = 0;
private int mWindowBgColor = Color.TRANSPARENT;
private Drawable mReplaceIcon = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index bdc8ff1..ff91d82 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -29,6 +29,7 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
@@ -215,6 +216,7 @@
WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
params.setFitInsetsSides(0);
params.setFitInsetsTypes(0);
+ params.format = PixelFormat.TRANSLUCENT;
int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
| WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
diff --git a/libs/androidfw/TEST_MAPPING b/libs/androidfw/TEST_MAPPING
index 8a5c06d..9ebc996 100644
--- a/libs/androidfw/TEST_MAPPING
+++ b/libs/androidfw/TEST_MAPPING
@@ -2,9 +2,6 @@
"presubmit": [
{
"name": "CtsResourcesLoaderTests"
- },
- {
- "name": "ResourcesHardeningTest"
}
]
-}
\ No newline at end of file
+}
diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk
index ca69a28..bb6dfa3 100644
--- a/packages/CtsShim/apk/arm/CtsShim.apk
+++ b/packages/CtsShim/apk/arm/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk
index d7cfb96..2835d57 100644
--- a/packages/CtsShim/apk/arm/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk
index ca69a28..bb6dfa3 100644
--- a/packages/CtsShim/apk/x86/CtsShim.apk
+++ b/packages/CtsShim/apk/x86/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk
index 84c3401..2e1a789 100644
--- a/packages/CtsShim/apk/x86/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk
Binary files differ
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/dimens.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/dimens.xml
index f0cdaf6..626fd3a 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/dimens.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/dimens.xml
@@ -16,10 +16,12 @@
-->
<resources>
<!-- Collapsing toolbar layout dimensions -->
- <dimen name="toolbar_one_line_height">226dp</dimen>
- <dimen name="toolbar_two_lines_height">270dp</dimen>
- <dimen name="toolbar_three_lines_height">314dp</dimen>
+ <dimen name="toolbar_one_line_height">216dp</dimen>
+ <dimen name="toolbar_two_lines_height">260dp</dimen>
+ <dimen name="toolbar_three_lines_height">304dp</dimen>
<dimen name="scrim_visible_height_trigger">174dp</dimen>
+ <dimen name="scrim_visible_height_trigger_two_lines">218dp</dimen>
+ <dimen name="scrim_visible_height_trigger_three_lines">262dp</dimen>
<dimen name="expanded_title_margin_start">24dp</dimen>
<dimen name="expanded_title_margin_end">24dp</dimen>
</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java
index b3053ac..0e7e595 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java
@@ -26,12 +26,9 @@
import com.google.android.material.appbar.CollapsingToolbarLayout;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
/**
- * A customized version of CollapsingToolbarLayout that can apply different font size based on
- * the line count of its title.
+ * A customized version of CollapsingToolbarLayout that can apply different font size based on the
+ * line count of its title.
*/
public class AdjustableToolbarLayout extends CollapsingToolbarLayout {
@@ -59,43 +56,25 @@
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
v.removeOnLayoutChangeListener(this);
- final int count = getLineCountWithReflection();
+ final int count = getLineCount();
if (count > TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
+ setScrimVisibleHeightTrigger(
+ getResources().getDimensionPixelSize(
+ R.dimen.scrim_visible_height_trigger_three_lines));
setLayoutParams(lp);
} else if (count == TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
+ setScrimVisibleHeightTrigger(
+ getResources().getDimensionPixelSize(
+ R.dimen.scrim_visible_height_trigger_two_lines));
setLayoutParams(lp);
}
}
});
}
-
- /**
- * Returns a number of title line count for CollapsingToolbarLayout so that facilitates the
- * determination to apply what kind of font size. Since the title of CollapsingToolbarLayout is
- * drawn in a canvas and the text process is wrapped in a CollapsingTextHelper, the way we used
- * here is to get the line count from the CollapsingTextHelper via Java Reflection.
- */
- private int getLineCountWithReflection() {
- try {
- final Field textHelperField =
- this.getClass().getSuperclass().getDeclaredField("collapsingTextHelper");
- textHelperField.setAccessible(true);
- final Object textHelperObj = textHelperField.get(this);
-
- final Field layoutField = textHelperObj.getClass().getDeclaredField("textLayout");
- layoutField.setAccessible(true);
- final Object layoutObj = layoutField.get(textHelperObj);
-
- final Method method = layoutObj.getClass().getDeclaredMethod("getLineCount");
- return (int) method.invoke(layoutObj);
- } catch (Exception e) {
- return 0;
- }
- }
}
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
index 010b9ba..2d214fe 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml
@@ -48,7 +48,6 @@
android:layout_width="@dimen/settingslib_restricted_icon_size"
android:layout_height="@dimen/settingslib_restricted_icon_size"
android:tint="?android:attr/colorAccent"
- android:theme="@android:style/Theme.Material"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/settingslib_restricted_icon_margin_end"
android:src="@*android:drawable/ic_info"
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 2dbfef0..83a6973 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -139,6 +139,17 @@
}
/**
+ * @return EnforcedAdmin if we have been passed the restriction in the xml.
+ */
+ public EnforcedAdmin checkRestrictionEnforced() {
+ if (mAttrUserRestriction == null) {
+ return null;
+ }
+ return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(mContext,
+ mAttrUserRestriction, UserHandle.myUserId());
+ }
+
+ /**
* Disable this preference based on the enforce admin.
*
* @param admin details of the admin who enforced the restriction. If it is
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java
index 6d7f8df..a537394 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminController.java
@@ -16,6 +16,7 @@
package com.android.settingslib.enterprise;
+import android.annotation.UserIdInt;
import android.content.Context;
import androidx.annotation.Nullable;
@@ -28,10 +29,15 @@
public interface ActionDisabledByAdminController {
/**
+ * Sets the {@link ActionDisabledLearnMoreButtonLauncher}.
+ */
+ void initialize(ActionDisabledLearnMoreButtonLauncher launcher);
+
+ /**
* Handles the adding and setting up of the learn more button. If button is not needed, then
* this method can be left empty.
*/
- void setupLearnMoreButton(Context context, Object alertDialogBuilder);
+ void setupLearnMoreButton(Context context);
/**
* Returns the admin support dialog's title resource id.
@@ -41,11 +47,11 @@
/**
* Returns the admin support dialog's content string.
*/
- CharSequence getAdminSupportContentString(
- Context context, @Nullable CharSequence supportMessage);
+ CharSequence getAdminSupportContentString(Context context,
+ @Nullable CharSequence supportMessage);
/**
* Updates the enforced admin
*/
- void updateEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin, int adminUserId);
+ void updateEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin, @UserIdInt int adminUserId);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
index 7eecd19..da42e33 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
@@ -19,29 +19,30 @@
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
import android.app.admin.DevicePolicyManager;
+import android.content.Context;
/**
* A factory that returns the relevant instance of {@link ActionDisabledByAdminController}.
*/
-public class ActionDisabledByAdminControllerFactory {
+public final class ActionDisabledByAdminControllerFactory {
/**
* Returns the relevant instance of {@link ActionDisabledByAdminController}.
*/
- public static ActionDisabledByAdminController createInstance(
- DevicePolicyManager dpm,
- ActionDisabledLearnMoreButtonLauncher helper,
- DeviceAdminStringProvider deviceAdminStringProvider) {
- if (isFinancedDevice(dpm)) {
- return new FinancedDeviceActionDisabledByAdminController(
- helper, deviceAdminStringProvider);
- }
- return new ManagedDeviceActionDisabledByAdminController(
- helper, deviceAdminStringProvider);
+ public static ActionDisabledByAdminController createInstance(Context context,
+ DeviceAdminStringProvider stringProvider) {
+ return isFinancedDevice(context)
+ ? new FinancedDeviceActionDisabledByAdminController(stringProvider)
+ : new ManagedDeviceActionDisabledByAdminController(stringProvider);
}
- private static boolean isFinancedDevice(DevicePolicyManager dpm) {
+ private static boolean isFinancedDevice(Context context) {
+ DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
return dpm.isDeviceManaged() && dpm.getDeviceOwnerType(
dpm.getDeviceOwnerComponentOnAnyUser()) == DEVICE_OWNER_TYPE_FINANCED;
}
+
+ private ActionDisabledByAdminControllerFactory() {
+ throw new UnsupportedOperationException("provides only static methods");
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java
index 65b91f1..78a42be 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java
@@ -16,29 +16,100 @@
package com.android.settingslib.enterprise;
-import android.content.Context;
+import static java.util.Objects.requireNonNull;
-import com.android.settingslib.RestrictedLockUtils;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
/**
- * Helper interface meant to set up the "Learn more" button in the action disabled dialog.
+ * Helper class meant to set up the "Learn more" button in the action disabled dialog.
*/
-public interface ActionDisabledLearnMoreButtonLauncher {
+public abstract class ActionDisabledLearnMoreButtonLauncher {
/**
* Sets up a "learn more" button which shows a screen with device policy settings
*/
- void setupLearnMoreButtonToShowAdminPolicies(
- Context context,
- Object alertDialogBuilder,
- int enforcementAdminUserId,
- RestrictedLockUtils.EnforcedAdmin enforcedAdmin);
+ public final void setupLearnMoreButtonToShowAdminPolicies(Context context,
+ int enforcementAdminUserId, EnforcedAdmin enforcedAdmin) {
+ requireNonNull(context, "context cannot be null");
+ requireNonNull(enforcedAdmin, "enforcedAdmin cannot be null");
+
+ // The "Learn more" button appears only if the restriction is enforced by an admin in the
+ // same profile group. Otherwise the admin package and its policies are not accessible to
+ // the current user.
+ if (isSameProfileGroup(context, enforcementAdminUserId)) {
+ setLearnMoreButton(() -> showAdminPolicies(context, enforcedAdmin));
+ }
+ }
/**
* Sets up a "learn more" button which launches a help page
*/
- void setupLearnMoreButtonToLaunchHelpPage(
- Context context,
- Object alertDialogBuilder,
- String url);
+ public final void setupLearnMoreButtonToLaunchHelpPage(Context context, String url) {
+ requireNonNull(context, "context cannot be null");
+ requireNonNull(url, "url cannot be null");
+
+ setLearnMoreButton(() -> showHelpPage(context, url));
+ }
+
+ /**
+ * Sets the "learning more" button.
+ *
+ * @param action action to be run when the button is tapped.
+ */
+ public abstract void setLearnMoreButton(Runnable action);
+
+ /**
+ * Launches the settings page with info about the given admin.
+ */
+ protected abstract void launchShowAdminPolicies(Context context, UserHandle user,
+ ComponentName admin);
+
+ /**
+ * Launches the settings page that shows all admins.
+ */
+ protected abstract void launchShowAdminSettings(Context context);
+
+ /**
+ * Callback to finish the activity associated with the launcher.
+ */
+ protected void finishSelf() {
+ }
+
+ @VisibleForTesting
+ protected boolean isSameProfileGroup(Context context, int enforcementAdminUserId) {
+ UserManager um = context.getSystemService(UserManager.class);
+
+ return um.isSameProfileGroup(enforcementAdminUserId, um.getUserHandle());
+ }
+
+ /**
+ * Shows the help page using the given {@code url}.
+ */
+ @VisibleForTesting
+ public void showHelpPage(Context context, String url) {
+ context.startActivityAsUser(createLearnMoreIntent(url), UserHandle.of(context.getUserId()));
+ finishSelf();
+ }
+
+ private void showAdminPolicies(Context context, EnforcedAdmin enforcedAdmin) {
+ if (enforcedAdmin.component != null) {
+ launchShowAdminPolicies(context, enforcedAdmin.user, enforcedAdmin.component);
+ } else {
+ launchShowAdminSettings(context);
+ }
+ finishSelf();
+ }
+
+ private static Intent createLearnMoreIntent(String url) {
+ return new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/BaseActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/BaseActionDisabledByAdminController.java
new file mode 100644
index 0000000..dd71557
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/BaseActionDisabledByAdminController.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 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.settingslib.enterprise;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.UserIdInt;
+
+import com.android.internal.util.Preconditions;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+/**
+ * Base class for {@link ActionDisabledByAdminController} implementations.
+ */
+abstract class BaseActionDisabledByAdminController
+ implements ActionDisabledByAdminController {
+
+ protected @UserIdInt int mEnforcementAdminUserId;
+ protected EnforcedAdmin mEnforcedAdmin;
+ protected ActionDisabledLearnMoreButtonLauncher mLauncher;
+ protected final DeviceAdminStringProvider mStringProvider;
+
+ BaseActionDisabledByAdminController(DeviceAdminStringProvider stringProvider) {
+ mStringProvider = stringProvider;
+ }
+
+ @Override
+ public final void initialize(ActionDisabledLearnMoreButtonLauncher launcher) {
+ mLauncher = requireNonNull(launcher, "launcher cannot be null");
+ }
+
+ @Override
+ public final void updateEnforcedAdmin(EnforcedAdmin admin, int adminUserId) {
+ assertInitialized();
+ mEnforcementAdminUserId = adminUserId;
+ mEnforcedAdmin = requireNonNull(admin, "admin cannot be null");
+ }
+
+ protected final void assertInitialized() {
+ Preconditions.checkState(mLauncher != null, "must call initialize() first");
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminController.java
index cd816e88..2ed0dc4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminController.java
@@ -16,52 +16,31 @@
package com.android.settingslib.enterprise;
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.UserIdInt;
import android.content.Context;
import androidx.annotation.Nullable;
-import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
/**
* An {@link ActionDisabledByAdminController} to be used with financed devices.
*/
-public class FinancedDeviceActionDisabledByAdminController
- implements ActionDisabledByAdminController {
+final class FinancedDeviceActionDisabledByAdminController
+ extends BaseActionDisabledByAdminController {
- private @UserIdInt int mEnforcementAdminUserId;
- private EnforcedAdmin mEnforcedAdmin;
- private final ActionDisabledLearnMoreButtonLauncher mHelper;
- private final DeviceAdminStringProvider mDeviceAdminStringProvider;
-
- FinancedDeviceActionDisabledByAdminController(
- ActionDisabledLearnMoreButtonLauncher helper,
- DeviceAdminStringProvider deviceAdminStringProvider) {
- mHelper = requireNonNull(helper, "helper cannot be null");
- mDeviceAdminStringProvider = requireNonNull(deviceAdminStringProvider,
- "deviceAdminStringProvider cannot be null");
+ FinancedDeviceActionDisabledByAdminController(DeviceAdminStringProvider stringProvider) {
+ super(stringProvider);
}
@Override
- public void updateEnforcedAdmin(EnforcedAdmin admin, int adminUserId) {
- mEnforcementAdminUserId = adminUserId;
- mEnforcedAdmin = requireNonNull(admin, "admin cannot be null");
- }
+ public void setupLearnMoreButton(Context context) {
+ assertInitialized();
- @Override
- public void setupLearnMoreButton(Context context, Object alertDialogBuilder) {
- mHelper.setupLearnMoreButtonToShowAdminPolicies(
- context,
- alertDialogBuilder,
- mEnforcementAdminUserId,
+ mLauncher.setupLearnMoreButtonToShowAdminPolicies(context, mEnforcementAdminUserId,
mEnforcedAdmin);
}
@Override
public String getAdminSupportTitle(@Nullable String restriction) {
- return mDeviceAdminStringProvider.getDisabledByPolicyTitleForFinancedDevice();
+ return mStringProvider.getDisabledByPolicyTitleForFinancedDevice();
}
@Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java
index 70e19f9..df6bab7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java
@@ -16,55 +16,39 @@
package com.android.settingslib.enterprise;
-import static java.util.Objects.requireNonNull;
-
-import android.annotation.UserIdInt;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserManager;
import android.text.TextUtils;
-import com.android.settingslib.RestrictedLockUtils;
+import androidx.annotation.Nullable;
+
/**
* An {@link ActionDisabledByAdminController} to be used with managed devices.
*/
-class ManagedDeviceActionDisabledByAdminController implements
- ActionDisabledByAdminController {
- private @UserIdInt int mEnforcementAdminUserId;
- private RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
- private final ActionDisabledLearnMoreButtonLauncher mHelper;
- private final DeviceAdminStringProvider mStringProvider;
+final class ManagedDeviceActionDisabledByAdminController
+ extends BaseActionDisabledByAdminController {
- ManagedDeviceActionDisabledByAdminController(
- ActionDisabledLearnMoreButtonLauncher helper,
- DeviceAdminStringProvider stringProvider) {
- mHelper = requireNonNull(helper);
- mStringProvider = requireNonNull(stringProvider);
+ ManagedDeviceActionDisabledByAdminController(DeviceAdminStringProvider stringProvider) {
+ super(stringProvider);
}
@Override
- public void updateEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin, int adminUserId) {
- mEnforcementAdminUserId = adminUserId;
- mEnforcedAdmin = requireNonNull(admin, "admin cannot be null");
- }
+ public void setupLearnMoreButton(Context context) {
+ assertInitialized();
- @Override
- public void setupLearnMoreButton(Context context, Object alertDialogBuilder) {
String url = mStringProvider.getLearnMoreHelpPageUrl();
if (TextUtils.isEmpty(url)) {
- mHelper.setupLearnMoreButtonToShowAdminPolicies(
- context,
- alertDialogBuilder,
- mEnforcementAdminUserId,
+ mLauncher.setupLearnMoreButtonToShowAdminPolicies(context, mEnforcementAdminUserId,
mEnforcedAdmin);
} else {
- mHelper.setupLearnMoreButtonToLaunchHelpPage(context, alertDialogBuilder, url);
+ mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url);
}
}
@Override
- public String getAdminSupportTitle(String restriction) {
+ public String getAdminSupportTitle(@Nullable String restriction) {
if (restriction == null) {
return mStringProvider.getDefaultDisabledByPolicyTitle();
}
@@ -88,9 +72,8 @@
@Override
public CharSequence getAdminSupportContentString(Context context, CharSequence supportMessage) {
- if (supportMessage != null) {
- return supportMessage;
- }
- return mStringProvider.getDefaultDisabledByPolicyContent();
+ return supportMessage != null
+ ? supportMessage
+ : mStringProvider.getDefaultDisabledByPolicyContent();
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
index b1234f2..51e533a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
@@ -73,6 +73,7 @@
private static NetworkTemplate getMobileTemplateForSubId(
TelephonyManager telephonyManager, int subId) {
- return NetworkTemplate.buildTemplateMobileAll(telephonyManager.getSubscriberId(subId));
+ return NetworkTemplate.buildTemplateCarrierMetered(
+ telephonyManager.getSubscriberId(subId));
}
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/NetworkPolicyEditorTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/NetworkPolicyEditorTest.java
index 37f2600..7e389a1 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/NetworkPolicyEditorTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/NetworkPolicyEditorTest.java
@@ -44,7 +44,7 @@
@Before
public void setUp() {
- mNetworkTemplate = NetworkTemplate.buildTemplateMobileAll("123456789123456");
+ mNetworkTemplate = NetworkTemplate.buildTemplateCarrierMetered("123456789123456");
NetworkPolicyManager policyManager = NetworkPolicyManager.from(InstrumentationRegistry
.getContext());
mNetworkPolicyEditor = new NetworkPolicyEditor(policyManager);
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index 63cfe59..2d1a516 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -45,6 +45,7 @@
"SettingsLib-robo-testutils",
"androidx.test.core",
"androidx.core_core",
+ "testng", // TODO: remove once JUnit on Android provides assertThrows
],
java_resource_dirs: ["config"],
instrumentation_for: "SettingsLibShell",
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerTestUtils.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerTestUtils.java
index 4b51790..e57335f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerTestUtils.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerTestUtils.java
@@ -16,51 +16,81 @@
package com.android.settingslib.enterprise;
-import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
-import android.app.Activity;
+import android.content.ComponentName;
import android.content.Context;
+import android.os.UserHandle;
+import android.util.DebugUtils;
-import androidx.appcompat.app.AlertDialog;
-
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
/**
* Utils related to the action disabled by admin dialogs.
*/
-class ActionDisabledByAdminControllerTestUtils {
- static final int LEARN_MORE_ACTION_NONE = 0;
- static final int LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES = 1;
- static final int LEARN_MORE_ACTION_LAUNCH_HELP_PAGE = 2;
+// NOTE: must be public because of DebugUtils.constantToString() call
+public final class ActionDisabledByAdminControllerTestUtils {
+
+ static final int ENFORCEMENT_ADMIN_USER_ID = 123;
+ static final UserHandle ENFORCEMENT_ADMIN_USER = UserHandle.of(ENFORCEMENT_ADMIN_USER_ID);
+
+ static final String SUPPORT_MESSAGE = "support message";
+
+ static final ComponentName ADMIN_COMPONENT =
+ new ComponentName("some.package.name", "some.package.name.SomeClass");
+ static final EnforcedAdmin ENFORCED_ADMIN = new EnforcedAdmin(
+ ADMIN_COMPONENT, UserHandle.of(ENFORCEMENT_ADMIN_USER_ID));
+ static final EnforcedAdmin ENFORCED_ADMIN_WITHOUT_COMPONENT = new EnforcedAdmin(
+ /* component= */ null, UserHandle.of(ENFORCEMENT_ADMIN_USER_ID));
+
+ static final String URL = "https://testexample.com";
+
+ // NOTE: fields below must be public because of DebugUtils.constantToString() call
+ public static final int LEARN_MORE_ACTION_NONE = 0;
+ public static final int LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES = 1;
+ public static final int LEARN_MORE_ACTION_SHOW_ADMIN_SETTINGS = 2;
+ public static final int LEARN_MORE_ACTION_LAUNCH_HELP_PAGE = 3;
private int mLearnMoreButtonAction = LEARN_MORE_ACTION_NONE;
ActionDisabledLearnMoreButtonLauncher createLearnMoreButtonLauncher() {
return new ActionDisabledLearnMoreButtonLauncher() {
+
@Override
- public void setupLearnMoreButtonToShowAdminPolicies(Context context,
- Object alertDialogBuilder, int enforcementAdminUserId,
- RestrictedLockUtils.EnforcedAdmin enforcedAdmin) {
+ public void setLearnMoreButton(Runnable action) {
+ action.run();
+ }
+
+ @Override
+ protected void launchShowAdminPolicies(Context context, UserHandle user,
+ ComponentName admin) {
mLearnMoreButtonAction = LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES;
}
@Override
- public void setupLearnMoreButtonToLaunchHelpPage(Context context,
- Object alertDialogBuilder, String url) {
+ protected void launchShowAdminSettings(Context context) {
+ mLearnMoreButtonAction = LEARN_MORE_ACTION_SHOW_ADMIN_SETTINGS;
+ }
+
+ @Override
+ public void showHelpPage(Context context, String url) {
mLearnMoreButtonAction = LEARN_MORE_ACTION_LAUNCH_HELP_PAGE;
}
+
+ @Override
+ protected boolean isSameProfileGroup(Context context, int enforcementAdminUserId) {
+ return true;
+ }
};
}
void assertLearnMoreAction(int learnMoreActionShowAdminPolicies) {
- assertThat(learnMoreActionShowAdminPolicies).isEqualTo(mLearnMoreButtonAction);
+ assertWithMessage("action").that(actionToString(mLearnMoreButtonAction))
+ .isEqualTo(actionToString(learnMoreActionShowAdminPolicies));
}
- AlertDialog createAlertDialog(ActionDisabledByAdminController mController, Activity activity) {
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- mController.setupLearnMoreButton(activity, builder);
- AlertDialog alertDialog = builder.create();
- alertDialog.show();
- return alertDialog;
+ private static String actionToString(int action) {
+ return DebugUtils.constantToString(ActionDisabledByAdminControllerTestUtils.class,
+ "LEARN_MORE_ACTION_", action);
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java
new file mode 100644
index 0000000..7014da0
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2021 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.settingslib.enterprise;
+
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ADMIN_COMPONENT;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCED_ADMIN;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCED_ADMIN_WITHOUT_COMPONENT;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCEMENT_ADMIN_USER;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCEMENT_ADMIN_USER_ID;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.URL;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertThrows;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)// NOTE: this test doesn't need RoboElectric...
+public final class ActionDisabledLearnMoreButtonLauncherTest {
+
+ private static final int CONTEXT_USER_ID = -ENFORCEMENT_ADMIN_USER_ID;
+ private static final UserHandle CONTEXT_USER = UserHandle.of(CONTEXT_USER_ID);
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Mock
+ private Context mContext;
+
+ @Mock
+ private UserManager mUserManager;
+
+ @Spy
+ private ActionDisabledLearnMoreButtonLauncher mLauncher;
+
+ @Captor
+ private ArgumentCaptor<Runnable> mLearnMoreActionCaptor;
+
+ @Captor
+ private ArgumentCaptor<Intent> mIntentCaptor;
+
+ @Before
+ public void setUp() {
+ when(mContext.getUserId()).thenReturn(CONTEXT_USER_ID);
+ when(mUserManager.getUserHandle()).thenReturn(CONTEXT_USER_ID);
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ }
+
+ @Test
+ public void testSetupLearnMoreButtonToShowAdminPolicies_nullContext() {
+ assertThrows(NullPointerException.class,
+ () -> mLauncher.setupLearnMoreButtonToShowAdminPolicies(/* context= */ null,
+ ENFORCEMENT_ADMIN_USER_ID, ENFORCED_ADMIN));
+ }
+
+ @Test
+ public void testSetupLearnMoreButtonToShowAdminPolicies_nullEnforcedAdmin() {
+ assertThrows(NullPointerException.class,
+ () -> mLauncher.setupLearnMoreButtonToShowAdminPolicies(/* context= */ null,
+ ENFORCEMENT_ADMIN_USER_ID, /* enforcedAdmin= */ null));
+ }
+
+ @Test
+ public void testSetupLearnMoreButtonToShowAdminPolicies_differentProfileGroup() {
+ mockDifferentProfileGroup();
+
+ mLauncher.setupLearnMoreButtonToShowAdminPolicies(mContext, ENFORCEMENT_ADMIN_USER_ID,
+ ENFORCED_ADMIN);
+
+ verify(mLauncher, never()).setLearnMoreButton(any());
+ }
+
+ @Test
+ public void testSetupLearnMoreButtonToShowAdminPolicies_sameProfileGroup_noComponent() {
+ mockSameProfileGroup();
+
+ mLauncher.setupLearnMoreButtonToShowAdminPolicies(mContext, ENFORCEMENT_ADMIN_USER_ID,
+ ENFORCED_ADMIN_WITHOUT_COMPONENT);
+ tapLearnMore();
+
+ verify(mLauncher, never()).launchShowAdminPolicies(any(), any(), any());
+ verify(mLauncher).launchShowAdminSettings(mContext);
+ verifyFinishSelf();
+ }
+
+ @Test
+ public void testSetupLearnMoreButtonToShowAdminPolicies_sameProfileGroup_withComponent() {
+ mockSameProfileGroup();
+
+ mLauncher.setupLearnMoreButtonToShowAdminPolicies(mContext, ENFORCEMENT_ADMIN_USER_ID,
+ ENFORCED_ADMIN);
+ tapLearnMore();
+
+ verify(mLauncher).launchShowAdminPolicies(mContext, ENFORCEMENT_ADMIN_USER,
+ ADMIN_COMPONENT);
+ verify(mLauncher, never()).launchShowAdminSettings(any());
+ verifyFinishSelf();
+ }
+
+ @Test
+ public void testSetupLearnMoreButtonToLaunchHelpPage_nullContext() {
+ assertThrows(NullPointerException.class,
+ () -> mLauncher.setupLearnMoreButtonToLaunchHelpPage(/* context= */ null, URL));
+ }
+
+ @Test
+ public void testSetupLearnMoreButtonToLaunchHelpPage_nullUrl() {
+ assertThrows(NullPointerException.class,
+ () -> mLauncher.setupLearnMoreButtonToLaunchHelpPage(mContext, /* url= */ null));
+ }
+
+ @Test
+ public void testSetupLearnMoreButtonToLaunchHelpPage() {
+ mLauncher.setupLearnMoreButtonToLaunchHelpPage(mContext, URL);
+ tapLearnMore();
+
+ verify(mContext).startActivityAsUser(mIntentCaptor.capture(), eq(CONTEXT_USER));
+ Intent intent = mIntentCaptor.getValue();
+ assertWithMessage("wrong url on intent %s", intent).that(intent.getData())
+ .isEqualTo(Uri.parse(URL));
+ verifyFinishSelf();
+ }
+
+ private void mockDifferentProfileGroup() {
+ // No need to mock anything - isSameProfileGroup() will return false by default
+ }
+
+ private void mockSameProfileGroup() {
+ when(mUserManager.isSameProfileGroup(ENFORCEMENT_ADMIN_USER_ID, CONTEXT_USER_ID))
+ .thenReturn(true);
+ }
+
+ private void tapLearnMore() {
+ verify(mLauncher).setLearnMoreButton(mLearnMoreActionCaptor.capture());
+ mLearnMoreActionCaptor.getValue().run();
+ }
+
+ private void verifyFinishSelf() {
+ verify(mLauncher).finishSelf();
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java
index 8c07d75..be3e9fc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FakeDeviceAdminStringProvider.java
@@ -30,6 +30,8 @@
static final String DEFAULT_DISABLED_BY_POLICY_CONTENT = "default_disabled_by_policy_content";
static final String DEFAULT_DISABLED_BY_POLICY_TITLE_FINANCED_DEVICE =
"default_disabled_by_policy_title_financed_device";
+ static final DeviceAdminStringProvider DEFAULT_DEVICE_ADMIN_STRING_PROVIDER =
+ new FakeDeviceAdminStringProvider(/* url = */ null);
private final String mUrl;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminControllerTest.java
index 2fe2262..7b08fee 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminControllerTest.java
@@ -16,22 +16,21 @@
package com.android.settingslib.enterprise;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCED_ADMIN;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCEMENT_ADMIN_USER_ID;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.SUPPORT_MESSAGE;
+import static com.android.settingslib.enterprise.FakeDeviceAdminStringProvider.DEFAULT_DEVICE_ADMIN_STRING_PROVIDER;
import static com.android.settingslib.enterprise.FakeDeviceAdminStringProvider.DEFAULT_DISABLED_BY_POLICY_TITLE_FINANCED_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
-import android.app.Dialog;
-import android.content.ComponentName;
import android.content.Context;
-import android.os.UserHandle;
-import androidx.appcompat.app.AlertDialog;
import androidx.test.core.app.ApplicationProvider;
import com.android.settingslib.R;
-import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
import org.junit.Test;
@@ -41,73 +40,46 @@
@RunWith(RobolectricTestRunner.class)
public class FinancedDeviceActionDisabledByAdminControllerTest {
- private static final int ENFORCEMENT_ADMIN_USER_ID = 123;
- private static final ComponentName ADMIN_COMPONENT =
- new ComponentName("some.package.name", "some.package.name.SomeClass");
- private static final String SUPPORT_MESSAGE = "support message";
- private static final DeviceAdminStringProvider DEVICE_ADMIN_STRING_PROVIDER =
- new FakeDeviceAdminStringProvider(/* url = */ null);
- private static final RestrictedLockUtils.EnforcedAdmin ENFORCED_ADMIN =
- new RestrictedLockUtils.EnforcedAdmin(
- ADMIN_COMPONENT, UserHandle.of(ENFORCEMENT_ADMIN_USER_ID));
private final Context mContext = ApplicationProvider.getApplicationContext();
private final Activity mActivity = ActivityController.of(new Activity()).get();
private final ActionDisabledByAdminControllerTestUtils mTestUtils =
new ActionDisabledByAdminControllerTestUtils();
- private final ActionDisabledLearnMoreButtonLauncher mLauncher =
- mTestUtils.createLearnMoreButtonLauncher();
+ private final FinancedDeviceActionDisabledByAdminController mController =
+ new FinancedDeviceActionDisabledByAdminController(
+ DEFAULT_DEVICE_ADMIN_STRING_PROVIDER);
@Before
public void setUp() {
mActivity.setTheme(R.style.Theme_AppCompat_DayNight);
+
+ mController.initialize(mTestUtils.createLearnMoreButtonLauncher());
+ mController.updateEnforcedAdmin(ENFORCED_ADMIN, ENFORCEMENT_ADMIN_USER_ID);
+
}
@Test
public void setupLearnMoreButton_negativeButtonSet() {
- FinancedDeviceActionDisabledByAdminController mController = createController(mLauncher);
- AlertDialog alertDialog = mTestUtils.createAlertDialog(mController, mActivity);
-
- alertDialog.getButton(Dialog.BUTTON_NEUTRAL).performClick();
+ mController.setupLearnMoreButton(mContext);
mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES);
}
@Test
public void getAdminSupportTitleResource_works() {
- FinancedDeviceActionDisabledByAdminController mController = createController();
-
assertThat(mController.getAdminSupportTitle(null))
.isEqualTo(DEFAULT_DISABLED_BY_POLICY_TITLE_FINANCED_DEVICE);
}
@Test
public void getAdminSupportContentString_withSupportMessage_returnsSupportMessage() {
- FinancedDeviceActionDisabledByAdminController mController = createController();
-
assertThat(mController.getAdminSupportContentString(mContext, SUPPORT_MESSAGE))
.isEqualTo(SUPPORT_MESSAGE);
}
@Test
public void getAdminSupportContentString_noSupportMessage_returnsNull() {
- FinancedDeviceActionDisabledByAdminController mController = createController();
-
assertThat(mController.getAdminSupportContentString(mContext, /* supportMessage= */ null))
.isNull();
}
-
- private FinancedDeviceActionDisabledByAdminController createController() {
- return createController(mLauncher);
- }
-
- private FinancedDeviceActionDisabledByAdminController createController(
- ActionDisabledLearnMoreButtonLauncher buttonHelper) {
- FinancedDeviceActionDisabledByAdminController controller =
- new FinancedDeviceActionDisabledByAdminController(
- buttonHelper,
- DEVICE_ADMIN_STRING_PROVIDER);
- controller.updateEnforcedAdmin(ENFORCED_ADMIN, ENFORCEMENT_ADMIN_USER_ID);
- return controller;
- }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
index eb1dc96..19f6aa1 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
@@ -16,8 +16,12 @@
package com.android.settingslib.enterprise;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCED_ADMIN;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCEMENT_ADMIN_USER_ID;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.LEARN_MORE_ACTION_LAUNCH_HELP_PAGE;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.SUPPORT_MESSAGE;
+import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.URL;
import static com.android.settingslib.enterprise.FakeDeviceAdminStringProvider.DEFAULT_DISABLED_BY_POLICY_CONTENT;
import static com.android.settingslib.enterprise.FakeDeviceAdminStringProvider.DEFAULT_DISABLED_BY_POLICY_TITLE;
import static com.android.settingslib.enterprise.FakeDeviceAdminStringProvider.DISALLOW_ADJUST_VOLUME_TITLE;
@@ -25,15 +29,12 @@
import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
-import android.app.Dialog;
-import android.content.ComponentName;
-import android.os.UserHandle;
+import android.content.Context;
import android.os.UserManager;
-import androidx.appcompat.app.AlertDialog;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settingslib.R;
-import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
import org.junit.Test;
@@ -43,23 +44,15 @@
@RunWith(RobolectricTestRunner.class)
public class ManagedDeviceActionDisabledByAdminControllerTest {
- private static final int ENFORCEMENT_ADMIN_USER_ID = 123;
- private static final ComponentName ADMIN_COMPONENT =
- new ComponentName("some.package.name", "some.package.name.SomeClass");
- private static final String SUPPORT_MESSAGE = "support message";
+
private static final String RESTRICTION = UserManager.DISALLOW_ADJUST_VOLUME;
- private static final String URL = "https://testexample.com";
private static final String EMPTY_URL = "";
- private static final RestrictedLockUtils.EnforcedAdmin ENFORCED_ADMIN =
- new RestrictedLockUtils.EnforcedAdmin(
- ADMIN_COMPONENT, UserHandle.of(ENFORCEMENT_ADMIN_USER_ID));
private static final String SUPPORT_TITLE_FOR_RESTRICTION = DISALLOW_ADJUST_VOLUME_TITLE;
+ private final Context mContext = ApplicationProvider.getApplicationContext();
private final Activity mActivity = ActivityController.of(new Activity()).get();
private final ActionDisabledByAdminControllerTestUtils mTestUtils =
new ActionDisabledByAdminControllerTestUtils();
- private final ActionDisabledLearnMoreButtonLauncher mLauncher =
- mTestUtils.createLearnMoreButtonLauncher();
@Before
public void setUp() {
@@ -68,68 +61,63 @@
@Test
public void setupLearnMoreButton_validUrl_negativeButtonSet() {
- ManagedDeviceActionDisabledByAdminController mController =
- createController(mLauncher, URL);
- AlertDialog alertDialog = mTestUtils.createAlertDialog(mController, mActivity);
+ ManagedDeviceActionDisabledByAdminController controller = createController(URL);
- alertDialog.getButton(Dialog.BUTTON_NEUTRAL).performClick();
+ controller.setupLearnMoreButton(mContext);
mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_LAUNCH_HELP_PAGE);
}
@Test
public void setupLearnMoreButton_noUrl_negativeButtonSet() {
- ManagedDeviceActionDisabledByAdminController mController =
- createController(mLauncher, EMPTY_URL);
- AlertDialog alertDialog = mTestUtils.createAlertDialog(mController, mActivity);
+ ManagedDeviceActionDisabledByAdminController controller = createController(EMPTY_URL);
- alertDialog.getButton(Dialog.BUTTON_NEUTRAL).performClick();
+ controller.setupLearnMoreButton(mContext);
mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES);
}
@Test
public void getAdminSupportTitleResource_noRestriction_works() {
- ManagedDeviceActionDisabledByAdminController mController = createController();
+ ManagedDeviceActionDisabledByAdminController controller = createController();
- assertThat(mController.getAdminSupportTitle(null))
+ assertThat(controller.getAdminSupportTitle(null))
.isEqualTo(DEFAULT_DISABLED_BY_POLICY_TITLE);
}
@Test
public void getAdminSupportTitleResource_withRestriction_works() {
- ManagedDeviceActionDisabledByAdminController mController = createController();
+ ManagedDeviceActionDisabledByAdminController controller = createController();
- assertThat(mController.getAdminSupportTitle(RESTRICTION))
+ assertThat(controller.getAdminSupportTitle(RESTRICTION))
.isEqualTo(SUPPORT_TITLE_FOR_RESTRICTION);
}
@Test
public void getAdminSupportContentString_withSupportMessage_returnsSupportMessage() {
- ManagedDeviceActionDisabledByAdminController mController = createController();
+ ManagedDeviceActionDisabledByAdminController controller = createController();
- assertThat(mController.getAdminSupportContentString(mActivity, SUPPORT_MESSAGE))
+ assertThat(controller.getAdminSupportContentString(mActivity, SUPPORT_MESSAGE))
.isEqualTo(SUPPORT_MESSAGE);
}
@Test
public void getAdminSupportContentString_noSupportMessage_returnsDefault() {
- ManagedDeviceActionDisabledByAdminController mController = createController();
+ ManagedDeviceActionDisabledByAdminController controller = createController();
- assertThat(mController.getAdminSupportContentString(mActivity, /* supportMessage= */ null))
+ assertThat(controller.getAdminSupportContentString(mActivity, /* supportMessage= */ null))
.isEqualTo(DEFAULT_DISABLED_BY_POLICY_CONTENT);
}
private ManagedDeviceActionDisabledByAdminController createController() {
- return createController(mLauncher, /* url= */ null);
+ return createController(/* url= */ null);
}
- private ManagedDeviceActionDisabledByAdminController createController(
- ActionDisabledLearnMoreButtonLauncher buttonHelper, String url) {
+ private ManagedDeviceActionDisabledByAdminController createController(String url) {
ManagedDeviceActionDisabledByAdminController controller =
new ManagedDeviceActionDisabledByAdminController(
- buttonHelper,
new FakeDeviceAdminStringProvider(url));
+ controller.initialize(mTestUtils.createLearnMoreButtonLauncher());
controller.updateEnforcedAdmin(ENFORCED_ADMIN, ENFORCEMENT_ADMIN_USER_ID);
return controller;
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index 27d877d..9be783d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -87,8 +87,8 @@
ShadowSubscriptionManager.setDefaultDataSubscriptionId(mDefaultSubscriptionId);
doReturn(SUB_ID).when(mTelephonyManager).getSubscriberId();
- mNetworkTemplate = NetworkTemplate.buildTemplateMobileAll(SUB_ID);
- mNetworkTemplate2 = NetworkTemplate.buildTemplateMobileAll(SUB_ID_2);
+ mNetworkTemplate = NetworkTemplate.buildTemplateCarrierMetered(SUB_ID);
+ mNetworkTemplate2 = NetworkTemplate.buildTemplateCarrierMetered(SUB_ID_2);
mWifiNetworkTemplate = NetworkTemplate.buildTemplateWifi(
NetworkTemplate.WIFI_NETWORKID_ALL, null);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
index 877eb61..e8d5844 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
@@ -62,7 +62,7 @@
when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
.thenReturn(mNetworkPolicyManager);
when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
- mNetworkTemplate = NetworkTemplate.buildTemplateMobileAll(SUB_ID);
+ mNetworkTemplate = NetworkTemplate.buildTemplateCarrierMetered(SUB_ID);
}
@Test
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index 1b15d20..761b1f4 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -36,6 +36,7 @@
static_libs: [
"PluginCoreLib",
+ "WindowManager-Shell",
],
manifest: "AndroidManifest.xml",
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index 4f179c4..d185ba36 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -5,13 +5,18 @@
import android.animation.ValueAnimator
import android.app.ActivityManager
import android.app.ActivityTaskManager
+import android.app.AppGlobals
import android.app.PendingIntent
import android.content.Context
import android.graphics.Matrix
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.graphics.RectF
+import android.graphics.drawable.GradientDrawable
import android.os.Looper
import android.os.RemoteException
+import android.os.UserHandle
import android.util.Log
import android.util.MathUtils
import android.view.IRemoteAnimationFinishedCallback
@@ -26,6 +31,8 @@
import android.view.animation.PathInterpolator
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.ScreenDecorationsUtils
+import com.android.wm.shell.startingsurface.SplashscreenContentDrawer
+import com.android.wm.shell.startingsurface.SplashscreenContentDrawer.SplashScreenWindowAttrs
import kotlin.math.roundToInt
/**
@@ -40,9 +47,9 @@
companion object {
const val ANIMATION_DURATION = 500L
- const val ANIMATION_DURATION_FADE_OUT_CONTENT = 183L
- const val ANIMATION_DURATION_FADE_IN_WINDOW = 217L
- const val ANIMATION_DELAY_FADE_IN_WINDOW = 167L
+ private const val ANIMATION_DURATION_FADE_OUT_CONTENT = 150L
+ private const val ANIMATION_DURATION_FADE_IN_WINDOW = 183L
+ private const val ANIMATION_DELAY_FADE_IN_WINDOW = ANIMATION_DURATION_FADE_OUT_CONTENT
private const val ANIMATION_DURATION_NAV_FADE_IN = 266L
private const val ANIMATION_DURATION_NAV_FADE_OUT = 133L
private const val ANIMATION_DELAY_NAV_FADE_IN =
@@ -54,6 +61,8 @@
private val NAV_FADE_IN_INTERPOLATOR = PathInterpolator(0f, 0f, 0f, 1f)
private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f)
+ private val SRC_MODE = PorterDuffXfermode(PorterDuff.Mode.SRC)
+
/**
* Given the [linearProgress] of a launch animation, return the linear progress of the
* sub-animation starting [delay] ms after the launch animation and that lasts [duration].
@@ -68,6 +77,8 @@
}
}
+ private val packageManager = AppGlobals.getPackageManager()
+
/** The interpolator used for the width, height, Y position and corner radius. */
private val animationInterpolator = AnimationUtils.loadInterpolator(context,
R.interpolator.launch_animation_interpolator_y)
@@ -76,6 +87,8 @@
private val animationInterpolatorX = AnimationUtils.loadInterpolator(context,
R.interpolator.launch_animation_interpolator_x)
+ private val cornerRadii = FloatArray(8)
+
/**
* Start an intent and animate the opening window. The intent will be started by running
* [intentStarter], which should use the provided [RemoteAnimationAdapter] and return the launch
@@ -288,10 +301,7 @@
var right: Int,
var topCornerRadius: Float = 0f,
- var bottomCornerRadius: Float = 0f,
-
- var contentAlpha: Float = 1f,
- var backgroundAlpha: Float = 1f
+ var bottomCornerRadius: Float = 0f
) {
private val startTop = top
private val startBottom = bottom
@@ -331,6 +341,9 @@
val centerY: Float
get() = top + height / 2f
+
+ /** Whether the expanded view should be visible or hidden. */
+ var visible: Boolean = true
}
@VisibleForTesting
@@ -452,22 +465,39 @@
0f
}
+ // We add an extra layer with the same color as the app splash screen background color,
+ // which is usually the same color of the app background. We first fade in this layer
+ // to hide the expanding view, then we fade it out with SRC mode to draw a hole in the
+ // launch container and reveal the opening window.
+ val windowBackgroundColor = extractSplashScreenBackgroundColor(window)
+ val windowBackgroundLayer = GradientDrawable().apply {
+ setColor(windowBackgroundColor)
+ alpha = 0
+ }
+
// Update state.
val animator = ValueAnimator.ofFloat(0f, 1f)
this.animator = animator
animator.duration = ANIMATION_DURATION
animator.interpolator = Interpolators.LINEAR
+ val launchContainerOverlay = launchContainer.overlay
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
Log.d(TAG, "Animation started")
controller.onLaunchAnimationStart(isExpandingFullyAbove)
+
+ // Add the drawable to the launch container overlay. Overlays always draw
+ // drawables after views, so we know that it will be drawn above any view added
+ // by the controller.
+ launchContainerOverlay.add(windowBackgroundLayer)
}
override fun onAnimationEnd(animation: Animator?) {
Log.d(TAG, "Animation ended")
iCallback?.invoke()
controller.onLaunchAnimationEnd(isExpandingFullyAbove)
+ launchContainerOverlay.remove(windowBackgroundLayer)
}
})
@@ -491,24 +521,61 @@
state.bottomCornerRadius =
MathUtils.lerp(startBottomCornerRadius, endRadius, progress)
- val contentAlphaProgress = getProgress(linearProgress, 0,
- ANIMATION_DURATION_FADE_OUT_CONTENT)
- state.contentAlpha =
- 1 - CONTENT_FADE_OUT_INTERPOLATOR.getInterpolation(contentAlphaProgress)
-
- val backgroundAlphaProgress = getProgress(linearProgress,
- ANIMATION_DELAY_FADE_IN_WINDOW, ANIMATION_DURATION_FADE_IN_WINDOW)
- state.backgroundAlpha =
- 1 - WINDOW_FADE_IN_INTERPOLATOR.getInterpolation(backgroundAlphaProgress)
+ // The expanding view can/should be hidden once it is completely coverred by the
+ // windowBackgroundLayer.
+ state.visible =
+ getProgress(linearProgress, 0, ANIMATION_DURATION_FADE_OUT_CONTENT) < 1
applyStateToWindow(window, state)
+ applyStateToWindowBackgroundLayer(windowBackgroundLayer, state, linearProgress)
navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }
+
+ // If we started expanding the view, we make it 1 pixel smaller on all sides to
+ // avoid artefacts on the corners caused by anti-aliasing of the view background and
+ // the window background layer.
+ if (state.top != startTop && state.left != startLeft &&
+ state.bottom != startBottom && state.right != startRight) {
+ state.top += 1
+ state.left += 1
+ state.right -= 1
+ state.bottom -= 1
+ }
controller.onLaunchAnimationProgress(state, progress, linearProgress)
}
animator.start()
}
+ /** Extract the background color of the app splash screen. */
+ private fun extractSplashScreenBackgroundColor(window: RemoteAnimationTarget): Int {
+ val taskInfo = window.taskInfo
+ val windowPackage = taskInfo.topActivity.packageName
+ val userId = taskInfo.userId
+ val windowContext = context.createPackageContextAsUser(
+ windowPackage, Context.CONTEXT_RESTRICTED, UserHandle.of(userId))
+ val activityInfo = taskInfo.topActivityInfo
+ val splashScreenThemeName = packageManager.getSplashScreenTheme(windowPackage, userId)
+ val splashScreenThemeId = if (splashScreenThemeName != null) {
+ windowContext.resources.getIdentifier(splashScreenThemeName, null, null)
+ } else {
+ 0
+ }
+
+ val themeResId = when {
+ splashScreenThemeId != 0 -> splashScreenThemeId
+ activityInfo.themeResource != 0 -> activityInfo.themeResource
+ else -> com.android.internal.R.style.Theme_DeviceDefault_DayNight
+ }
+
+ if (themeResId != windowContext.themeResId) {
+ windowContext.setTheme(themeResId)
+ }
+
+ val windowAttrs = SplashScreenWindowAttrs()
+ SplashscreenContentDrawer.getWindowAttrs(windowContext, windowAttrs)
+ return SplashscreenContentDrawer.peekWindowBGColor(windowContext, windowAttrs)
+ }
+
private fun applyStateToWindow(window: RemoteAnimationTarget, state: State) {
val screenBounds = window.screenSpaceBounds
val centerX = (screenBounds.left + screenBounds.right) / 2f
@@ -563,6 +630,41 @@
transactionApplier.scheduleApply(params)
}
+ private fun applyStateToWindowBackgroundLayer(
+ drawable: GradientDrawable,
+ state: State,
+ linearProgress: Float
+ ) {
+ // Update position.
+ drawable.setBounds(state.left, state.top, state.right, state.bottom)
+
+ // Update radius.
+ cornerRadii[0] = state.topCornerRadius
+ cornerRadii[1] = state.topCornerRadius
+ cornerRadii[2] = state.topCornerRadius
+ cornerRadii[3] = state.topCornerRadius
+ cornerRadii[4] = state.bottomCornerRadius
+ cornerRadii[5] = state.bottomCornerRadius
+ cornerRadii[6] = state.bottomCornerRadius
+ cornerRadii[7] = state.bottomCornerRadius
+ drawable.cornerRadii = cornerRadii
+
+ // We first fade in the background layer to hide the expanding view, then fade it out
+ // with SRC mode to draw a hole punch in the status bar and reveal the opening window.
+ val fadeInProgress = getProgress(linearProgress, 0, ANIMATION_DURATION_FADE_OUT_CONTENT)
+ if (fadeInProgress < 1) {
+ val alpha = CONTENT_FADE_OUT_INTERPOLATOR.getInterpolation(fadeInProgress)
+ drawable.alpha = (alpha * 0xFF).roundToInt()
+ drawable.setXfermode(null)
+ } else {
+ val fadeOutProgress = getProgress(linearProgress,
+ ANIMATION_DELAY_FADE_IN_WINDOW, ANIMATION_DURATION_FADE_IN_WINDOW)
+ val alpha = 1 - WINDOW_FADE_IN_INTERPOLATOR.getInterpolation(fadeOutProgress)
+ drawable.alpha = (alpha * 0xFF).roundToInt()
+ drawable.setXfermode(SRC_MODE)
+ }
+ }
+
private fun applyStateToNavigationBar(
navigationBar: RemoteAnimationTarget,
state: State,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index ce9feed..4b655a1 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -4,8 +4,6 @@
import android.graphics.ColorFilter
import android.graphics.Matrix
import android.graphics.PixelFormat
-import android.graphics.PorterDuff
-import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
@@ -111,9 +109,7 @@
}
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
- backgroundView = FrameLayout(launchContainer.context).apply {
- forceHasOverlappingRendering(false)
- }
+ backgroundView = FrameLayout(launchContainer.context)
launchContainerOverlay.add(backgroundView)
// We wrap the ghosted view background and use it to draw the expandable background. Its
@@ -125,9 +121,7 @@
// Create a ghost of the view that will be moving and fading out. This allows to fade out
// the content before fading out the background.
- ghostView = GhostView.addGhost(ghostedView, launchContainer).apply {
- setLayerType(View.LAYER_TYPE_HARDWARE, null)
- }
+ ghostView = GhostView.addGhost(ghostedView, launchContainer)
val matrix = ghostView?.animationMatrix ?: Matrix.IDENTITY_MATRIX
matrix.getValues(initialGhostViewMatrixValues)
@@ -139,7 +133,18 @@
linearProgress: Float
) {
val ghostView = this.ghostView!!
- ghostView.alpha = state.contentAlpha
+ val backgroundView = this.backgroundView!!
+
+ if (!state.visible) {
+ if (ghostView.visibility == View.VISIBLE) {
+ // Making the ghost view invisible will make the ghosted view visible, so order is
+ // important here.
+ ghostView.visibility = View.INVISIBLE
+ ghostedView.visibility = View.INVISIBLE
+ backgroundView.visibility = View.INVISIBLE
+ }
+ return
+ }
val scale = min(state.widthRatio, state.heightRatio)
ghostViewMatrix.setValues(initialGhostViewMatrixValues)
@@ -150,14 +155,12 @@
)
ghostView.animationMatrix = ghostViewMatrix
- val backgroundView = this.backgroundView!!
backgroundView.top = state.top
backgroundView.bottom = state.bottom
backgroundView.left = state.left
backgroundView.right = state.right
val backgroundDrawable = backgroundDrawable!!
- backgroundDrawable.alpha = (0xFF * state.backgroundAlpha).toInt()
backgroundDrawable.wrapped?.let {
setBackgroundCornerRadius(it, state.topCornerRadius, state.bottomCornerRadius)
}
@@ -168,6 +171,7 @@
GhostView.removeGhost(ghostedView)
launchContainerOverlay.remove(backgroundView)
+ ghostedView.visibility = View.VISIBLE
ghostedView.invalidate()
}
@@ -203,10 +207,6 @@
}
private class WrappedDrawable(val wrapped: Drawable?) : Drawable() {
- companion object {
- private val SRC_MODE = PorterDuffXfermode(PorterDuff.Mode.SRC)
- }
-
private var currentAlpha = 0xFF
private var previousBounds = Rect()
@@ -220,7 +220,6 @@
wrapped.alpha = currentAlpha
wrapped.bounds = bounds
- setXfermode(wrapped, SRC_MODE)
applyBackgroundRadii()
wrapped.draw(canvas)
@@ -230,7 +229,6 @@
// background.
wrapped.alpha = 0
wrapped.bounds = previousBounds
- setXfermode(wrapped, null)
restoreBackgroundRadii()
}
@@ -257,27 +255,6 @@
wrapped?.colorFilter = filter
}
- private fun setXfermode(background: Drawable, mode: PorterDuffXfermode?) {
- if (background is InsetDrawable) {
- background.drawable?.let { setXfermode(it, mode) }
- return
- }
-
- if (background !is LayerDrawable) {
- background.setXfermode(mode)
- return
- }
-
- // We set the xfermode on the first layer that is not a mask. Most of the time it will
- // be the "background layer".
- for (i in 0 until background.numberOfLayers) {
- if (background.getId(i) != android.R.id.mask) {
- background.getDrawable(i).setXfermode(mode)
- break
- }
- }
- }
-
fun setBackgroundRadius(topCornerRadius: Float, bottomCornerRadius: Float) {
updateRadii(cornerRadii, topCornerRadius, bottomCornerRadius)
invalidateSelf()
diff --git a/packages/SystemUI/docs/qs-tiles.md b/packages/SystemUI/docs/qs-tiles.md
index 5216209..89c28a0 100644
--- a/packages/SystemUI/docs/qs-tiles.md
+++ b/packages/SystemUI/docs/qs-tiles.md
@@ -305,6 +305,7 @@
* Inject a `Provider` for the tile created before.
* Add a case to the `switch` with a unique String spec for the chosen tile.
5. In [SystemUI/res/values/config.xml](/packages/SystemUI/res/values/config.xml), modify `quick_settings_tiles_stock` and add the spec defined in the previous step. If necessary, add it also to `quick_settings_tiles_default`. The first one contains a list of all the tiles that SystemUI knows how to create (to show to the user in the customization screen). The second one contains only the default tiles that the user will experience on a fresh boot or after they reset their tiles.
+6. In [SystemUI/res/values/tiles_states_strings.xml](/packages/SystemUI/res/values/tiles_states_strings.xml), add a new array for your tile. The name has to be `tile_states_<spec>`. Use a good description to help the translators.
#### Abstract methods in QSTileImpl
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index f1c1477..77018d7 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -166,11 +166,13 @@
public boolean handlesLongClick = true;
public boolean showRippleEffect = true;
public Drawable sideViewCustomDrawable;
+ public String spec;
public boolean copyTo(State other) {
if (other == null) throw new IllegalArgumentException();
if (!other.getClass().equals(getClass())) throw new IllegalArgumentException();
- final boolean changed = !Objects.equals(other.icon, icon)
+ final boolean changed = !Objects.equals(other.spec, spec)
+ || !Objects.equals(other.icon, icon)
|| !Objects.equals(other.iconSupplier, iconSupplier)
|| !Objects.equals(other.label, label)
|| !Objects.equals(other.secondaryLabel, secondaryLabel)
@@ -188,6 +190,7 @@
|| !Objects.equals(other.handlesLongClick, handlesLongClick)
|| !Objects.equals(other.showRippleEffect, showRippleEffect)
|| !Objects.equals(other.sideViewCustomDrawable, sideViewCustomDrawable);
+ other.spec = spec;
other.icon = icon;
other.iconSupplier = iconSupplier;
other.label = label;
@@ -216,6 +219,7 @@
// This string may be used for CTS testing of tiles, so removing elements is discouraged.
protected StringBuilder toStringBuilder() {
final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
+ sb.append("spec=").append(spec);
sb.append(",icon=").append(icon);
sb.append(",iconSupplier=").append(iconSupplier);
sb.append(",label=").append(label);
diff --git a/packages/SystemUI/res/drawable/screenshot_edit_background.xml b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
new file mode 100644
index 0000000..5c3c12c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<!-- Long screenshot edit FAB background -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:color="?android:textColorPrimary">
+ <item android:id="@android:id/background">
+ <shape android:shape="rectangle">
+ <solid android:color="?androidprv:attr/colorAccentSecondary"/>
+ <corners android:radius="16dp"/>
+ </shape>
+ </item>
+ <item android:id="@android:id/mask">
+ <shape android:shape="rectangle">
+ <solid android:color="?android:textColorPrimary"/>
+ <corners android:radius="16dp"/>
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/screenshot_save_background.xml b/packages/SystemUI/res/drawable/screenshot_save_background.xml
new file mode 100644
index 0000000..cfd2dc2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/screenshot_save_background.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<!-- Long screenshot save button background -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:color="?android:textColorPrimary">
+ <item android:id="@android:id/background">
+ <shape android:shape="rectangle">
+ <solid android:color="?androidprv:attr/colorAccentSecondary"/>
+ <corners android:radius="20dp"/>
+ </shape>
+ </item>
+ <item android:id="@android:id/mask">
+ <shape android:shape="rectangle">
+ <solid android:color="?android:textColorPrimary"/>
+ <corners android:radius="20dp"/>
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/accessibility_floating_menu_item.xml b/packages/SystemUI/res/layout/accessibility_floating_menu_item.xml
index f7357b2..2067f85 100644
--- a/packages/SystemUI/res/layout/accessibility_floating_menu_item.xml
+++ b/packages/SystemUI/res/layout/accessibility_floating_menu_item.xml
@@ -19,8 +19,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="@dimen/accessibility_floating_menu_padding"
- android:paddingEnd="@dimen/accessibility_floating_menu_padding"
+ android:paddingStart="@dimen/accessibility_floating_menu_small_padding"
+ android:paddingEnd="@dimen/accessibility_floating_menu_small_padding"
android:orientation="vertical"
android:gravity="center">
@@ -29,9 +29,4 @@
android:layout_width="@dimen/accessibility_floating_menu_small_width_height"
android:layout_height="@dimen/accessibility_floating_menu_small_width_height"/>
- <View
- android:id="@+id/transparent_divider"
- android:layout_width="match_parent"
- android:layout_height="@dimen/accessibility_floating_menu_padding"/>
-
</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index de33846..8e30aec 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -28,11 +28,11 @@
android:id="@+id/save"
style="@android:style/Widget.DeviceDefault.Button.Colored"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="40dp"
android:text="@string/save"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
+ android:background="@drawable/screenshot_save_background"
android:textColor="?android:textColorSecondary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
@@ -114,7 +114,7 @@
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
style="@android:style/Widget.DeviceDefault.Button.Colored"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
+ android:background="@drawable/screenshot_edit_background"
android:src="@drawable/ic_screenshot_edit"
android:contentDescription="@string/screenshot_edit_label"
android:tint="?android:textColorSecondary"
diff --git a/packages/SystemUI/res/layout/privacy_dialog.xml b/packages/SystemUI/res/layout/privacy_dialog.xml
index 720ae8db..459fb66 100644
--- a/packages/SystemUI/res/layout/privacy_dialog.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog.xml
@@ -24,8 +24,6 @@
android:layout_marginEnd="@dimen/ongoing_appops_dialog_side_margins"
android:layout_marginTop="8dp"
android:orientation="vertical"
- android:paddingLeft="@dimen/ongoing_appops_dialog_side_padding"
- android:paddingRight="@dimen/ongoing_appops_dialog_side_padding"
android:paddingBottom="12dp"
android:paddingTop="8dp"
android:background="@drawable/qs_dialog_bg"
diff --git a/packages/SystemUI/res/layout/privacy_dialog_item.xml b/packages/SystemUI/res/layout/privacy_dialog_item.xml
index b91fb29c..7c8945e 100644
--- a/packages/SystemUI/res/layout/privacy_dialog_item.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog_item.xml
@@ -23,6 +23,9 @@
android:orientation="horizontal"
android:layout_marginTop="4dp"
android:importantForAccessibility="yes"
+ android:background="?android:attr/selectableItemBackground"
+ android:paddingLeft="@dimen/ongoing_appops_dialog_side_padding"
+ android:paddingRight="@dimen/ongoing_appops_dialog_side_padding"
android:focusable="true"
>
<!-- 4dp marginTop makes 20dp minimum between icons -->
diff --git a/packages/SystemUI/res/layout/qs_paged_page.xml b/packages/SystemUI/res/layout/qs_paged_page.xml
index a4f0a0c8..98804fc 100644
--- a/packages/SystemUI/res/layout/qs_paged_page.xml
+++ b/packages/SystemUI/res/layout/qs_paged_page.xml
@@ -18,4 +18,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tile_page"
android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent"
+ android:paddingStart="@dimen/notification_side_paddings"
+ android:paddingEnd="@dimen/notification_side_paddings"
+ android:clipChildren="false"
+ android:clipToPadding="false" />
diff --git a/packages/SystemUI/res/layout/qs_tile_side_icon.xml b/packages/SystemUI/res/layout/qs_tile_side_icon.xml
index 1ae0a1c..f1b7259 100644
--- a/packages/SystemUI/res/layout/qs_tile_side_icon.xml
+++ b/packages/SystemUI/res/layout/qs_tile_side_icon.xml
@@ -23,7 +23,7 @@
<ImageView
android:id="@+id/customDrawable"
android:layout_width="wrap_content"
- android:layout_height="@dimen/qs_icon_size"
+ android:layout_height="@dimen/qs_side_view_size"
android:layout_marginEnd="@dimen/qs_drawable_end_margin"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
@@ -39,4 +39,4 @@
android:visibility="gone"
android:importantForAccessibility="no"
/>
-</FrameLayout>
\ No newline at end of file
+</FrameLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ab606ba..0be648f 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -561,6 +561,7 @@
<dimen name="qs_tile_icon_background_stroke_width">-1dp</dimen>
<dimen name="qs_tile_background_size">56dp</dimen>
<dimen name="qs_icon_size">20dp</dimen>
+ <dimen name="qs_side_view_size">28dp</dimen>
<dimen name="qs_label_container_margin">10dp</dimen>
<dimen name="qs_quick_tile_size">60dp</dimen>
<dimen name="qs_tile_padding">12dp</dimen>
@@ -1467,16 +1468,17 @@
<dimen name="medium_content_padding_above_name">4dp</dimen>
<!-- Accessibility floating menu -->
- <dimen name="accessibility_floating_menu_elevation">5dp</dimen>
+ <dimen name="accessibility_floating_menu_elevation">3dp</dimen>
<dimen name="accessibility_floating_menu_stroke_width">1dp</dimen>
<dimen name="accessibility_floating_menu_stroke_inset">-2dp</dimen>
<dimen name="accessibility_floating_menu_margin">16dp</dimen>
- <dimen name="accessibility_floating_menu_padding">6dp</dimen>
+ <dimen name="accessibility_floating_menu_small_padding">6dp</dimen>
<dimen name="accessibility_floating_menu_small_width_height">36dp</dimen>
<dimen name="accessibility_floating_menu_small_single_radius">25dp</dimen>
<dimen name="accessibility_floating_menu_small_multiple_radius">20dp</dimen>
+ <dimen name="accessibility_floating_menu_large_padding">8dp</dimen>
<dimen name="accessibility_floating_menu_large_width_height">56dp</dimen>
- <dimen name="accessibility_floating_menu_large_single_radius">33dp</dimen>
+ <dimen name="accessibility_floating_menu_large_single_radius">35dp</dimen>
<dimen name="accessibility_floating_menu_large_multiple_radius">35dp</dimen>
<dimen name="accessibility_floating_tooltip_arrow_width">8dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index aadcaba..4651168 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -199,11 +199,11 @@
<item name="android:textSize">@dimen/qs_tile_text_size</item>
<item name="android:letterSpacing">0.01</item>
<item name="android:lineHeight">20sp</item>
- <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
</style>
<style name="TextAppearance.QS.TileLabel.Secondary">
- <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
</style>
<style name="TextAppearance.QS.UserSwitcher">
@@ -223,7 +223,7 @@
</style>
<style name="TextAppearance.QS.Status">
- <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">14sp</item>
<item name="android:letterSpacing">0.01</item>
@@ -231,20 +231,19 @@
</style>
<style name="TextAppearance.QS.SecurityFooter" parent="@style/TextAppearance.QS.Status">
- <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
- <style name="TextAppearance.QS.Status.Carriers">
- <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- </style>
+ <style name="TextAppearance.QS.Status.Carriers" />
<style name="TextAppearance.QS.Status.Carriers.NoCarrierText">
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
<style name="TextAppearance.QS.Status.Build">
- <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
@@ -643,7 +642,7 @@
<item name="android:tint">?android:attr/textColorPrimary</item>
<item name="android:stateListAnimator">@anim/media_button_state_list_animator</item>
<item name="android:padding">12dp</item>
- <item name="android:scaleType">fitCenter</item>
+ <item name="android:scaleType">centerInside</item>
</style>
<style name="MediaPlayer.OutlineButton">
@@ -663,7 +662,8 @@
<style name="MediaPlayer.AppIcon">
<item name="android:background">@drawable/qs_media_icon_background</item>
- <item name="android:backgroundTint">?android:attr/textColorPrimary</item>
+ <item name="android:backgroundTint">@color/media_player_solid_button_bg</item>
+ <item name="android:padding">4dp</item>
</style>
<style name="MediaPlayer.Album">
diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml
new file mode 100644
index 0000000..5ac7c1d
--- /dev/null
+++ b/packages/SystemUI/res/values/tiles_states_strings.xml
@@ -0,0 +1,284 @@
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+
+<!-- This resources set the default subtitle for tiles. This way, each tile can be translated
+ separately.
+ The indices in the array correspond to the state values in QSTile:
+ * STATE_UNAVAILABLE
+ * STATE_INACTIVE
+ * STATE_ACTIVE
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as if
+ they could appear.
+-->
+<resources>
+ <!-- Default names for tiles states: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_default">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for internet tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_internet">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for wifi tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_wifi">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for cell (data) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear.[CHAR LIMIT=32] -->
+ <string-array name="tile_states_cell">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for battery (saver) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_battery">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for dnd (Do not disturb) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_dnd">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for flashlight tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_flashlight">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for rotation (lock) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_rotation">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for bt (bluetooth) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_bt">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for airplane tile: unavailable, off, on [CHAR LIMIT=32] -->
+ <string-array name="tile_states_airplane">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for location tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_location">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for hotspot tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_hotspot">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for (color) inversion tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_inversion">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for (data) saver tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_saver">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for dark (mode) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_dark">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for work (mode) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_work">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for cast tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_cast">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for night (light) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_night">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for screenrecord tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_screenrecord">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for reverse (charging) tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_reverse">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for reduce_brightness tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_reduce_brightness">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for cameratoggle tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear.[CHAR LIMIT=32] -->
+ <string-array name="tile_states_cameratoggle">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for mictoggle tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_mictoggle">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for (home) controls tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_controls">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for (quick access) wallet tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_wallet">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+
+ <!-- State names for alarm tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_alarm">
+ <item>@string/tile_unavailable</item>
+ <item>@string/switch_bar_off</item>
+ <item>@string/switch_bar_on</item>
+ </string-array>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 3e084b7..fbea1e9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -305,10 +305,6 @@
// know that it should re-position our SmartSpace.
if (mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
mKeyguardUnlockAnimationController.updateLockscreenSmartSpacePosition();
- } else {
- // Otherwise, reset Y translation in case it's still offset from a previous shared
- // element transition.
- ((View) mSmartspaceView).setTranslationY(0f);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 89ca507..e8cc5c8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -89,7 +89,6 @@
// element transition.
if (keyguardStateController.isShowing()) {
mView.setChildrenAlphaExcludingClockView(1f);
- mKeyguardClockSwitchController.setChildrenAlphaExcludingSmartspace(1f);
}
}
});
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index eff412e..423bd56 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -21,7 +21,6 @@
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
-import android.view.Surface;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -30,44 +29,25 @@
*/
public class LockIconView extends ImageView {
@NonNull private final RectF mSensorRect;
- @NonNull private final Context mContext;
-
@NonNull private PointF mLockIconCenter = new PointF(0f, 0f);
private int mRadius;
public LockIconView(Context context, AttributeSet attrs) {
super(context, attrs);
- mContext = context;
mSensorRect = new RectF();
}
void setLocation(@NonNull PointF center, int radius) {
mLockIconCenter = center;
mRadius = radius;
- }
- // The "h" and "w" are the display's height and width relative to its current rotation.
- private void updateSensorRect(int h, int w) {
- // mSensorProps coordinates assume portrait mode.
+ // mSensorProps coordinates assume portrait mode which is OK b/c the keyguard is always in
+ // portrait.
mSensorRect.set(mLockIconCenter.x - mRadius,
mLockIconCenter.y - mRadius,
mLockIconCenter.x + mRadius,
mLockIconCenter.y + mRadius);
- // Transform mSensorRect if the device is in landscape mode.
- switch (mContext.getDisplay().getRotation()) {
- case Surface.ROTATION_90:
- mSensorRect.set(mSensorRect.top, h - mSensorRect.right, mSensorRect.bottom,
- h - mSensorRect.left);
- break;
- case Surface.ROTATION_270:
- mSensorRect.set(w - mSensorRect.bottom, mSensorRect.left, w - mSensorRect.top,
- mSensorRect.right);
- break;
- default:
- // Do nothing to stay in portrait mode.
- }
-
setX(mSensorRect.left);
setY(mSensorRect.top);
setLayoutParams(new FrameLayout.LayoutParams(
@@ -76,18 +56,6 @@
}
@Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- // Always re-compute the layout regardless of whether "changed" is true. It is usually false
- // when the device goes from landscape to seascape and vice versa, but mSensorRect and
- // its dependencies need to be recalculated to stay at the same physical location on the
- // screen.
- final int w = getLayoutParams().width;
- final int h = getLayoutParams().height;
- updateSensorRect(h, w);
- }
-
- @Override
public boolean hasOverlappingRendering() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index 964b135..2e6c9e4 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -18,6 +18,7 @@
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import android.annotation.NonNull;
import android.annotation.UiContext;
@@ -36,6 +37,7 @@
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
+import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -106,16 +108,41 @@
R.string.magnification_mode_switch_click_label));
info.addAction(clickAction);
info.setClickable(true);
+ info.addAction(new AccessibilityAction(R.id.accessibility_action_move_up,
+ mContext.getString(R.string.accessibility_control_move_up)));
+ info.addAction(new AccessibilityAction(R.id.accessibility_action_move_down,
+ mContext.getString(R.string.accessibility_control_move_down)));
+ info.addAction(new AccessibilityAction(R.id.accessibility_action_move_left,
+ mContext.getString(R.string.accessibility_control_move_left)));
+ info.addAction(new AccessibilityAction(R.id.accessibility_action_move_right,
+ mContext.getString(R.string.accessibility_control_move_right)));
}
@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
- if (action == AccessibilityAction.ACTION_CLICK.getId()) {
- handleSingleTap();
+ if (performA11yAction(action)) {
return true;
}
return super.performAccessibilityAction(host, action, args);
}
+
+ private boolean performA11yAction(int action) {
+ final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
+ if (action == AccessibilityAction.ACTION_CLICK.getId()) {
+ handleSingleTap();
+ } else if (action == R.id.accessibility_action_move_up) {
+ moveButton(0, -windowBounds.height());
+ } else if (action == R.id.accessibility_action_move_down) {
+ moveButton(0, windowBounds.height());
+ } else if (action == R.id.accessibility_action_move_left) {
+ moveButton(-windowBounds.width(), 0);
+ } else if (action == R.id.accessibility_action_move_right) {
+ moveButton(windowBounds.width(), 0);
+ } else {
+ return false;
+ }
+ return true;
+ }
});
mWindowInsetChangeRunnable = this::onWindowInsetChanged;
mImageView.setOnApplyWindowInsetsListener((v, insets) -> {
@@ -362,21 +389,21 @@
PixelFormat.TRANSPARENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.accessibilityTitle = getAccessibilityWindowTitle(context);
+ params.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
return params;
}
private Rect getDraggableWindowBounds() {
final int layoutMargin = mContext.getResources().getDimensionPixelSize(
R.dimen.magnification_switch_button_margin);
- final Rect boundRect = new Rect(mWindowManager.getCurrentWindowMetrics().getBounds());
- final Insets systemBars =
- mWindowManager.getCurrentWindowMetrics().getWindowInsets()
- .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
- final Rect insets = new Rect(layoutMargin,
- systemBars.top + layoutMargin,
- mParams.width + layoutMargin,
- mParams.height + layoutMargin + systemBars.bottom);
- boundRect.inset(insets);
+ final WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();
+ final Insets windowInsets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
+ WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
+ final Rect boundRect = new Rect(windowMetrics.getBounds());
+ boundRect.offsetTo(0, 0);
+ boundRect.inset(0, 0, mParams.width, mParams.height);
+ boundRect.inset(windowInsets);
+ boundRect.inset(layoutMargin, layoutMargin);
return boundRect;
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
index e85bd88..259a9f7 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -18,6 +18,8 @@
import static android.util.MathUtils.constrain;
import static android.util.MathUtils.sq;
+import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.navigationBars;
import static java.util.Objects.requireNonNull;
@@ -29,6 +31,7 @@
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -42,7 +45,9 @@
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
+import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.animation.Animation;
@@ -90,6 +95,7 @@
private boolean mIsShowing;
private boolean mIsDownInEnlargedTouchArea;
private boolean mIsDragging = false;
+ private boolean mImeVisibility;
@Alignment
private int mAlignment = Alignment.RIGHT;
@SizeType
@@ -369,6 +375,8 @@
mIsShowing = true;
mWindowManager.addView(this, mCurrentLayoutParams);
+
+ setOnApplyWindowInsetsListener((view, insets) -> onWindowInsetsApplied(insets));
setSystemGestureExclusion();
}
@@ -379,6 +387,8 @@
mIsShowing = false;
mWindowManager.removeView(this);
+
+ setOnApplyWindowInsetsListener(null);
setSystemGestureExclusion();
}
@@ -409,11 +419,13 @@
mSizeType = newSizeType;
- updateIconSizeWith(newSizeType);
+ updateItemViewWith(newSizeType);
updateRadiusWith(newSizeType, mRadiusType, mTargets.size());
// When the icon sized changed, the menu size and location will be impacted.
updateLocationWith(mAlignment, mPercentageY);
+ updateScrollModeWith(hasExceededMaxLayoutHeight());
+ updateOffsetWith(mShapeType, mAlignment);
setSystemGestureExclusion();
fadeOut();
@@ -565,6 +577,16 @@
return mListView.dispatchTouchEvent(event);
}
+ private WindowInsets onWindowInsetsApplied(WindowInsets insets) {
+ final boolean currentImeVisibility = insets.isVisible(ime());
+ if (currentImeVisibility != mImeVisibility) {
+ mImeVisibility = currentImeVisibility;
+ updateLocationWith(mAlignment, mPercentageY);
+ }
+
+ return insets;
+ }
+
private boolean isMovingTowardsScreenEdge(@Alignment int side, int currentRawX, int downX) {
return (side == Alignment.RIGHT && currentRawX > downX)
|| (side == Alignment.LEFT && downX > currentRawX);
@@ -601,24 +623,35 @@
mScreenHeight = dm.heightPixels;
mMargin =
res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_margin);
- mPadding =
- res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_padding);
mInset =
res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_stroke_inset);
mSquareScaledTouchSlop =
sq(ViewConfiguration.get(getContext()).getScaledTouchSlop());
+
+ updateItemViewDimensionsWith(mSizeType);
}
- private void updateIconSizeWith(@SizeType int sizeType) {
+ private void updateItemViewDimensionsWith(@SizeType int sizeType) {
final Resources res = getResources();
+ final int paddingResId =
+ sizeType == SizeType.SMALL
+ ? R.dimen.accessibility_floating_menu_small_padding
+ : R.dimen.accessibility_floating_menu_large_padding;
+ mPadding = res.getDimensionPixelSize(paddingResId);
+
final int iconResId =
sizeType == SizeType.SMALL
? R.dimen.accessibility_floating_menu_small_width_height
: R.dimen.accessibility_floating_menu_large_width_height;
mIconWidth = res.getDimensionPixelSize(iconResId);
mIconHeight = mIconWidth;
+ }
+ private void updateItemViewWith(@SizeType int sizeType) {
+ updateItemViewDimensionsWith(sizeType);
+
+ mAdapter.setItemPadding(mPadding);
mAdapter.setIconWidthHeight(mIconWidth);
mAdapter.notifyDataSetChanged();
}
@@ -630,7 +663,6 @@
final LayoutParams layoutParams =
new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.setMargins(mMargin, mMargin, mMargin, mMargin);
mListView.setLayoutParams(layoutParams);
final InstantInsetLayerDrawable layerDrawable =
new InstantInsetLayerDrawable(new Drawable[]{background});
@@ -645,6 +677,10 @@
}
private void updateListView() {
+ final LayoutParams layoutParams = (FrameLayout.LayoutParams) mListView.getLayoutParams();
+ layoutParams.setMargins(mMargin, mMargin, mMargin, mMargin);
+ mListView.setLayoutParams(layoutParams);
+
final int elevation =
getResources().getDimensionPixelSize(R.dimen.accessibility_floating_menu_elevation);
mListView.setElevation(elevation);
@@ -658,6 +694,7 @@
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
+ params.receiveInsetsIgnoringZOrder = true;
params.windowAnimations = android.R.style.Animation_Translucent;
params.gravity = Gravity.START | Gravity.TOP;
params.x = getMaxWindowX();
@@ -676,11 +713,13 @@
updateDimensions();
updateListView();
- updateIconSizeWith(mSizeType);
+ updateItemViewWith(mSizeType);
updateColor();
updateStrokeWith(newConfig.uiMode, mAlignment);
updateLocationWith(mAlignment, mPercentageY);
+ updateRadiusWith(mSizeType, mRadiusType, mTargets.size());
updateScrollModeWith(hasExceededMaxLayoutHeight());
+ setSystemGestureExclusion();
mLastConfiguration.setTo(newConfig);
}
@@ -728,10 +767,30 @@
*/
private void updateLocationWith(@Alignment int side, float percentageCurrentY) {
mCurrentLayoutParams.x = (side == Alignment.RIGHT) ? getMaxWindowX() : getMinWindowX();
- mCurrentLayoutParams.y = (int) (percentageCurrentY * getMaxWindowY());
+ final int currentLayoutY = (int) (percentageCurrentY * getMaxWindowY());
+ mCurrentLayoutParams.y = Math.max(MIN_WINDOW_Y, currentLayoutY - getInterval());
mWindowManager.updateViewLayout(this, mCurrentLayoutParams);
}
+ /**
+ * Gets the moving interval to not overlap between the keyboard and menu view.
+ *
+ * @return the moving interval if they overlap each other, otherwise 0.
+ */
+ private int getInterval() {
+ if (!mImeVisibility) {
+ return 0;
+ }
+
+ final WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();
+ final Insets imeInsets = windowMetrics.getWindowInsets().getInsets(
+ ime() | navigationBars());
+ final int imeY = mScreenHeight - imeInsets.bottom;
+ final int layoutBottomY = mCurrentLayoutParams.y + getWindowHeight();
+
+ return layoutBottomY > imeY ? (layoutBottomY - imeY) : 0;
+ }
+
private void updateOffsetWith(@ShapeType int shapeType, @Alignment int side) {
final float halfWidth = getLayoutWidth() / 2.0f;
final float offset = (shapeType == ShapeType.OVAL) ? 0 : halfWidth;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
index 76106e7..63cfd51 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
@@ -16,8 +16,6 @@
package com.android.systemui.accessibility.floatingmenu;
-import static android.view.View.GONE;
-
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -43,6 +41,7 @@
*/
public class AccessibilityTargetAdapter extends Adapter<ViewHolder> {
private int mIconWidthHeight;
+ private int mItemPadding;
private final List<AccessibilityTarget> mTargets;
@IntDef({
@@ -84,6 +83,7 @@
final AccessibilityTarget target = mTargets.get(position);
holder.mIconView.setBackground(target.getIcon());
holder.updateIconWidthHeight(mIconWidthHeight);
+ holder.updateItemPadding(mItemPadding, getItemCount());
holder.itemView.setOnClickListener((v) -> target.onSelected());
holder.itemView.setStateDescription(target.getStateDescription());
holder.itemView.setContentDescription(target.getLabel());
@@ -120,14 +120,16 @@
mIconWidthHeight = iconWidthHeight;
}
+ public void setItemPadding(int itemPadding) {
+ mItemPadding = itemPadding;
+ }
+
static class ViewHolder extends RecyclerView.ViewHolder {
final View mIconView;
- final View mDivider;
ViewHolder(View itemView) {
super(itemView);
mIconView = itemView.findViewById(R.id.icon_view);
- mDivider = itemView.findViewById(R.id.transparent_divider);
}
void updateIconWidthHeight(int newValue) {
@@ -139,21 +141,31 @@
layoutParams.height = newValue;
mIconView.setLayoutParams(layoutParams);
}
+
+ void updateItemPadding(int padding, int size) {
+ itemView.setPaddingRelative(padding, padding, padding, padding);
+ }
}
static class TopViewHolder extends ViewHolder {
TopViewHolder(View itemView) {
super(itemView);
- final int padding = itemView.getPaddingStart();
- itemView.setPaddingRelative(padding, padding, padding, 0);
+ }
+
+ @Override
+ void updateItemPadding(int padding, int size) {
+ final int paddingBottom = size <= 2 ? padding : 0;
+ itemView.setPaddingRelative(padding, padding, padding, paddingBottom);
}
}
static class BottomViewHolder extends ViewHolder {
BottomViewHolder(View itemView) {
super(itemView);
- mDivider.setVisibility(GONE);
- final int padding = itemView.getPaddingStart();
+ }
+
+ @Override
+ void updateItemPadding(int padding, int size) {
itemView.setPaddingRelative(padding, 0, padding, padding);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
index 3085854..61fc7ed 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
@@ -214,6 +214,8 @@
final GradientDrawable gradientDrawable = (GradientDrawable) mTextView.getBackground();
gradientDrawable.setCornerRadius(mTextViewCornerRadius);
+ gradientDrawable.setColor(Utils.getColorAttrDefaultColor(getContext(),
+ com.android.internal.R.attr.colorAccentPrimary));
}
private void updateArrowWith(Rect anchorViewLocation) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 1ac1df1..29cd76d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -596,10 +596,6 @@
Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this);
}
- private void setText(TextView view, CharSequence charSequence) {
- view.setText(charSequence);
- }
-
// Remove all pending icon and text animations
private void removePendingAnimations() {
mHandler.removeCallbacks(mResetHelpRunnable);
@@ -688,7 +684,7 @@
*/
@VisibleForTesting
void onAttachedToWindowInternal() {
- setText(mTitleView, mPromptInfo.getTitle());
+ mTitleView.setText(mPromptInfo.getTitle());
if (isDeviceCredentialAllowed()) {
final CharSequence credentialButtonText;
@@ -718,7 +714,7 @@
mUseCredentialButton.setText(credentialButtonText);
mUseCredentialButton.setVisibility(View.VISIBLE);
} else {
- setText(mNegativeButton, mPromptInfo.getNegativeButtonText());
+ mNegativeButton.setText(mPromptInfo.getNegativeButtonText());
}
setTextOrHide(mSubtitleView, mPromptInfo.getSubtitle());
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 6f1a387..9ec7bd0c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -575,7 +575,7 @@
if (mBiometricView != null) {
mBiometricView.restoreState(savedState);
}
- wm.addView(this, getLayoutParams(mWindowToken));
+ wm.addView(this, getLayoutParams(mWindowToken, mConfig.mPromptInfo.getTitle()));
}
@Override
@@ -728,11 +728,9 @@
}
}
- /**
- * @param windowToken token for the window
- * @return
- */
- public static WindowManager.LayoutParams getLayoutParams(IBinder windowToken) {
+ @VisibleForTesting
+ static WindowManager.LayoutParams getLayoutParams(IBinder windowToken,
+ CharSequence title) {
final int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
| WindowManager.LayoutParams.FLAG_SECURE;
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -744,15 +742,11 @@
lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~WindowInsets.Type.ime());
lp.setTitle("BiometricPrompt");
+ lp.accessibilityTitle = title;
lp.token = windowToken;
return lp;
}
- private boolean hasFaceAndFingerprintSensors() {
- final int[] ids = findFaceAndFingerprintSensors();
- return ids[0] >= 0 && ids[1] >= 0;
- }
-
// returns [face, fingerprint] sensor ids (id is -1 if not present)
private int[] findFaceAndFingerprintSensors() {
int faceSensorId = -1;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 5c360a6..3726ae1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -123,6 +123,11 @@
private int mActivePointerId = -1;
// The timestamp of the most recent touch log.
private long mTouchLogTime;
+ // Sensor has a good capture for this touch. Do not need to illuminate for this particular
+ // touch event anymore. In other words, do not illuminate until user lifts and touches the
+ // sensor area again.
+ // TODO: We should probably try to make touch/illumination things more of a FSM
+ private boolean mGoodCaptureReceived;
@Nullable private UdfpsView mView;
// The current request from FingerprintService. Null if no current request.
@@ -225,48 +230,69 @@
@Override
public void showUdfpsOverlay(int sensorId, int reason,
@NonNull IUdfpsOverlayControllerCallback callback) {
- final UdfpsEnrollHelper enrollHelper;
- if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
- || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) {
- enrollHelper = new UdfpsEnrollHelper(mContext, reason);
- } else {
- enrollHelper = null;
- }
-
- mServerRequest = new ServerRequest(reason, callback, enrollHelper);
- updateOverlay();
+ mFgExecutor.execute(() -> {
+ final UdfpsEnrollHelper enrollHelper;
+ if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
+ || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) {
+ enrollHelper = new UdfpsEnrollHelper(mContext, reason);
+ } else {
+ enrollHelper = null;
+ }
+ mServerRequest = new ServerRequest(reason, callback, enrollHelper);
+ updateOverlay();
+ });
}
@Override
public void hideUdfpsOverlay(int sensorId) {
- mServerRequest = null;
- updateOverlay();
+ mFgExecutor.execute(() -> {
+ mServerRequest = null;
+ updateOverlay();
+ });
+ }
+
+ @Override
+ public void onAcquiredGood(int sensorId) {
+ mFgExecutor.execute(() -> {
+ if (mView == null) {
+ Log.e(TAG, "Null view when onAcquiredGood for sensorId: " + sensorId);
+ return;
+ }
+ mGoodCaptureReceived = true;
+ mView.stopIllumination();
+ });
}
@Override
public void onEnrollmentProgress(int sensorId, int remaining) {
- if (mServerRequest == null) {
- Log.e(TAG, "onEnrollProgress received but serverRequest is null");
- return;
- }
- mServerRequest.onEnrollmentProgress(remaining);
+ mFgExecutor.execute(() -> {
+ if (mServerRequest == null) {
+ Log.e(TAG, "onEnrollProgress received but serverRequest is null");
+ return;
+ }
+ mServerRequest.onEnrollmentProgress(remaining);
+ });
}
@Override
public void onEnrollmentHelp(int sensorId) {
- if (mServerRequest == null) {
- Log.e(TAG, "onEnrollmentHelp received but serverRequest is null");
- return;
- }
- mServerRequest.onEnrollmentHelp();
+ mFgExecutor.execute(() -> {
+ if (mServerRequest == null) {
+ Log.e(TAG, "onEnrollmentHelp received but serverRequest is null");
+ return;
+ }
+ mServerRequest.onEnrollmentHelp();
+ });
}
@Override
public void setDebugMessage(int sensorId, String message) {
- if (mView == null) {
- return;
- }
- mView.setDebugMessage(message);
+ mFgExecutor.execute(() -> {
+ if (mView == null) {
+ return;
+ }
+ mView.setDebugMessage(message);
+ });
}
}
@@ -333,7 +359,7 @@
private boolean onTouch(View view, MotionEvent event, boolean fromUdfpsView) {
UdfpsView udfpsView = (UdfpsView) view;
- final boolean isFingerDown = udfpsView.isIlluminationRequested();
+ final boolean isIlluminationRequested = udfpsView.isIlluminationRequested();
boolean handled = false;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_OUTSIDE:
@@ -388,7 +414,8 @@
"minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b",
minor, major, v, exceedsVelocityThreshold);
final long sinceLastLog = SystemClock.elapsedRealtime() - mTouchLogTime;
- if (!isFingerDown && !exceedsVelocityThreshold) {
+ if (!isIlluminationRequested && !mGoodCaptureReceived &&
+ !exceedsVelocityThreshold) {
onFingerDown((int) x, (int) y, minor, major);
Log.v(TAG, "onTouch | finger down: " + touchInfo);
mTouchLogTime = SystemClock.elapsedRealtime();
@@ -423,7 +450,7 @@
Log.v(TAG, "onTouch | finger move: " + touchInfo);
mTouchLogTime = SystemClock.elapsedRealtime();
}
- } else if (isFingerDown) {
+ } else {
Log.v(TAG, "onTouch | finger outside");
onFingerUp();
}
@@ -438,10 +465,8 @@
mVelocityTracker.recycle();
mVelocityTracker = null;
}
- if (isFingerDown) {
- Log.v(TAG, "onTouch | finger up");
- onFingerUp();
- }
+ Log.v(TAG, "onTouch | finger up");
+ onFingerUp();
mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
break;
@@ -795,13 +820,16 @@
// This method can be called from the UI thread.
private void onFingerUp() {
mActivePointerId = -1;
+ mGoodCaptureReceived = false;
mMainHandler.removeCallbacks(mAcquiredVibration);
if (mView == null) {
Log.w(TAG, "Null view in onFingerUp");
return;
}
mFingerprintManager.onPointerUp(mSensorProps.sensorId);
- mView.stopIllumination();
+ if (mView.isIlluminationRequested()) {
+ mView.stopIllumination();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 2b4c1ab..9a32412 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -108,6 +108,7 @@
mStatusBarStateController.addCallback(mStateListener);
mUdfpsRequested = false;
+
mStatusBarState = mStatusBarStateController.getState();
mQsExpanded = mKeyguardViewManager.isQsExpanded();
mInputBouncerHiddenAmount = KeyguardBouncer.EXPANSION_HIDDEN;
@@ -125,7 +126,7 @@
mFaceDetectRunning = false;
mStatusBarStateController.removeCallback(mStateListener);
- mKeyguardViewManager.setAlternateAuthInterceptor(null);
+ mKeyguardViewManager.removeAlternateAuthInterceptor(mAlternateAuthInterceptor);
mTransitioningFromHome = false;
mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
index 076c7cb..4d4e4dd 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
@@ -29,7 +29,6 @@
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.os.UserManager;
-import android.util.DisplayMetrics;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -50,17 +49,6 @@
@IntDef({CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD})
@interface CredentialType {}
-
- static float dpToPixels(Context context, float dp) {
- return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
- / DisplayMetrics.DENSITY_DEFAULT);
- }
-
- static float pixelsToDp(Context context, float pixels) {
- return pixels / ((float) context.getResources().getDisplayMetrics().densityDpi
- / DisplayMetrics.DENSITY_DEFAULT);
- }
-
static void notifyAccessibilityContentChanged(AccessibilityManager am, ViewGroup view) {
if (!am.isEnabled()) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
index f01ac68..508262d 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
@@ -28,6 +28,9 @@
import android.view.Gravity;
import android.view.WindowManager;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
/**
* A WirelessChargingAnimation is a view containing view + animation for wireless charging.
* @hide
@@ -54,9 +57,10 @@
* @hide
*/
public WirelessChargingAnimation(@NonNull Context context, @Nullable Looper looper,
- int transmittingBatteryLevel, int batteryLevel, Callback callback, boolean isDozing) {
+ int transmittingBatteryLevel, int batteryLevel, Callback callback, boolean isDozing,
+ UiEventLogger uiEventLogger) {
mCurrentWirelessChargingView = new WirelessChargingView(context, looper,
- transmittingBatteryLevel, batteryLevel, callback, isDozing);
+ transmittingBatteryLevel, batteryLevel, callback, isDozing, uiEventLogger);
}
/**
@@ -66,9 +70,9 @@
*/
public static WirelessChargingAnimation makeWirelessChargingAnimation(@NonNull Context context,
@Nullable Looper looper, int transmittingBatteryLevel, int batteryLevel,
- Callback callback, boolean isDozing) {
+ Callback callback, boolean isDozing, UiEventLogger uiEventLogger) {
return new WirelessChargingAnimation(context, looper, transmittingBatteryLevel,
- batteryLevel, callback, isDozing);
+ batteryLevel, callback, isDozing, uiEventLogger);
}
/**
@@ -95,6 +99,7 @@
private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
private final Handler mHandler;
+ private final UiEventLogger mUiEventLogger;
private int mGravity;
private WirelessChargingLayout mView;
@@ -104,11 +109,12 @@
public WirelessChargingView(Context context, @Nullable Looper looper,
int transmittingBatteryLevel, int batteryLevel, Callback callback,
- boolean isDozing) {
+ boolean isDozing, UiEventLogger uiEventLogger) {
mCallback = callback;
mNextView = new WirelessChargingLayout(context, transmittingBatteryLevel, batteryLevel,
isDozing);
mGravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER;
+ mUiEventLogger = uiEventLogger;
final WindowManager.LayoutParams params = mParams;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
@@ -195,6 +201,7 @@
mCallback.onAnimationStarting();
}
mWM.addView(mView, mParams);
+ mUiEventLogger.log(WirelessChargingRippleEvent.WIRELESS_RIPPLE_PLAYED);
} catch (WindowManager.BadTokenException e) {
Slog.d(TAG, "Unable to add wireless charging view. " + e);
}
@@ -215,5 +222,19 @@
mView = null;
}
}
+
+ enum WirelessChargingRippleEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Wireless charging ripple effect played")
+ WIRELESS_RIPPLE_PLAYED(830);
+
+ private final int mInt;
+ WirelessChargingRippleEvent(int id) {
+ mInt = id;
+ }
+
+ @Override public int getId() {
+ return mInt;
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 06fbf73..8a47a36 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -102,6 +102,10 @@
override fun onReleased() {
removeDetailTask()
}
+
+ override fun onBackPressedOnTaskRoot(taskId: Int) {
+ dismiss()
+ }
}
init {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 55feea9..d698142 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -315,8 +315,7 @@
appIconView.clearColorFilter();
if (data.getAppIcon() != null && !data.getResumption()) {
appIconView.setImageIcon(data.getAppIcon());
- int color = Utils.getColorAttrDefaultColor(mContext,
- com.android.internal.R.attr.colorAccentTertiary);
+ int color = mContext.getColor(android.R.color.system_accent2_900);
appIconView.setColorFilter(color);
} else {
appIconView.setColorFilter(getGrayscaleFilter());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index e0c8af6..ce1066e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -80,8 +80,22 @@
@Override
public void setPageMargin(int marginPixels) {
- if (marginPixels != getPageMargin()) {
- super.setPageMargin(marginPixels);
+ // Using page margins creates some rounding issues that interfere with the correct position
+ // in the onPageChangedListener and therefore present bad positions to the PageIndicator.
+ // Instead, we use negative margins in the container and positive padding in the pages,
+ // matching the margin set from QSContainerImpl (note that new pages will always be inflated
+ // with the correct value.
+ // QSContainerImpl resources are set onAttachedView, so this view will always have the right
+ // values when attached.
+ MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
+ lp.setMarginStart(-marginPixels);
+ lp.setMarginEnd(-marginPixels);
+ setLayoutParams(lp);
+
+ int nPages = mPages.size();
+ for (int i = 0; i < nPages; i++) {
+ View v = mPages.get(i);
+ v.setPadding(marginPixels, v.getPaddingTop(), marginPixels, v.getPaddingBottom());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index cd97f97..edfbed0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -295,7 +295,7 @@
qsPanelController.setContentMargins(mContentPadding, mContentPadding);
// Set it as double the side margin (to simulate end margin of current page +
// start margin of next page).
- qsPanelController.setPageMargin(2 * mSideMargins);
+ qsPanelController.setPageMargin(mSideMargins);
} else if (view == mHeader) {
// No content padding for the header.
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 47d80bb..a938821 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -181,14 +181,15 @@
mStatusBarStateController = statusBarStateController;
mActivityStarter = activityStarter;
- mState = newTileState();
- mTmpState = newTileState();
+ resetStates();
mUiHandler.post(() -> mLifecycle.setCurrentState(CREATED));
}
protected final void resetStates() {
mState = newTileState();
mTmpState = newTileState();
+ mState.spec = mTileSpec;
+ mTmpState.spec = mTileSpec;
}
@NonNull
@@ -225,6 +226,8 @@
public void setTileSpec(String tileSpec) {
mTileSpec = tileSpec;
+ mState.spec = tileSpec;
+ mTmpState.spec = tileSpec;
}
public QSHost getHost() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index cd76b4d..8aed0a8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -38,6 +38,7 @@
import android.widget.LinearLayout
import android.widget.Switch
import android.widget.TextView
+import androidx.annotation.VisibleForTesting
import com.android.settingslib.Utils
import com.android.systemui.FontSizeUtils
import com.android.systemui.R
@@ -62,6 +63,8 @@
private const val SECONDARY_LABEL_NAME = "secondaryLabel"
private const val CHEVRON_NAME = "chevron"
const val UNAVAILABLE_ALPHA = 0.3f
+ @VisibleForTesting
+ internal const val TILE_STATE_RES_PREFIX = "tile_states_"
}
override var heightOverride: Int = HeightOverrideable.NO_OVERRIDE
@@ -484,16 +487,18 @@
}
private fun getStateText(state: QSTile.State): String {
- return if (state.disabledByPolicy) {
- context.getString(R.string.tile_disabled)
- } else if (state.state == Tile.STATE_UNAVAILABLE) {
- context.getString(R.string.tile_unavailable)
- } else if (state is BooleanState) {
- if (state.state == Tile.STATE_INACTIVE) {
- context.getString(R.string.switch_bar_off)
- } else {
- context.getString(R.string.switch_bar_on)
+ if (state.disabledByPolicy) {
+ return context.getString(R.string.tile_disabled)
+ }
+
+ return if (state.state == Tile.STATE_UNAVAILABLE || state is BooleanState) {
+ val resName = "$TILE_STATE_RES_PREFIX${state.spec}"
+ var arrayResId = resources.getIdentifier(resName, "array", context.packageName)
+ if (arrayResId == 0) {
+ arrayResId = R.array.tile_states_default
}
+ val array = resources.getStringArray(arrayResId)
+ array[state.state]
} else {
""
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index 74d3425..7cb1421 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -45,7 +45,6 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QSIconView;
-import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.SignalState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.AlphaControlledSignalTileView;
@@ -72,7 +71,6 @@
protected final NetworkController mController;
private final DataUsageController mDataController;
- private final QSTile.SignalState mStateBeforeClick = newTileState();
// The last updated tile state, 0: mobile, 1: wifi, 2: ethernet.
private int mLastTileState = -1;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index efac141..41a3020 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -94,6 +94,7 @@
mWifiController = accessPointController;
mDetailAdapter = (WifiDetailAdapter) createDetailAdapter();
mController.observe(getLifecycle(), mSignalCallback);
+ mStateBeforeClick.spec = "wifi";
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index 7ca8277..060d7b1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -33,7 +33,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.policy.CallbackController;
-import java.util.ArrayList;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject;
@@ -58,7 +58,8 @@
"com.android.systemui.screenrecord.UPDATE_STATE";
protected static final String EXTRA_STATE = "extra_state";
- private ArrayList<RecordingStateChangeCallback> mListeners = new ArrayList<>();
+ private CopyOnWriteArrayList<RecordingStateChangeCallback> mListeners =
+ new CopyOnWriteArrayList<>();
@VisibleForTesting
protected final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
index 05afc57f..22bbb81b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
@@ -25,6 +25,8 @@
import android.view.View
import android.view.WindowManager
import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
import com.android.settingslib.Utils
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.FeatureFlags
@@ -55,7 +57,8 @@
featureFlags: FeatureFlags,
private val context: Context,
private val windowManager: WindowManager,
- private val systemClock: SystemClock
+ private val systemClock: SystemClock,
+ private val uiEventLogger: UiEventLogger
) {
private var pluggedIn: Boolean? = null
private val rippleEnabled: Boolean = featureFlags.isChargingRippleEnabled &&
@@ -164,6 +167,7 @@
}
})
windowManager.addView(rippleView, windowLayoutParams)
+ uiEventLogger.log(WiredChargingRippleEvent.CHARGING_RIPPLE_PLAYED)
}
private fun layoutRipple() {
@@ -203,4 +207,11 @@
pw.println("Usage: adb shell cmd statusbar charging-ripple")
}
}
+
+ enum class WiredChargingRippleEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Wired charging ripple effect played")
+ CHARGING_RIPPLE_PLAYED(829);
+
+ override fun getId() = _id
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index 33aa7c7..8479b30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -315,7 +315,11 @@
) : AnimatorListenerAdapter() {
override fun onAnimationEnd(p0: Animator?) {
chipAnimationController.onChipAnimationEnd(animationState)
- animationState = endState
+ animationState = if (endState == SHOWING_PERSISTENT_DOT && !hasPersistentDot) {
+ IDLE
+ } else {
+ endState
+ }
}
override fun onAnimationStart(p0: Animator?) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index c6753b3..d68271a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -73,7 +73,6 @@
import com.android.internal.widget.CallLayout;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.plugins.FalsingManager;
@@ -2020,6 +2019,14 @@
if (params == null) {
return;
}
+
+ if (!params.getVisible()) {
+ if (getVisibility() == View.VISIBLE) {
+ setVisibility(View.INVISIBLE);
+ }
+ return;
+ }
+
float zProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
params.getProgress(0, 50));
float translationZ = MathUtils.lerp(params.getStartTranslationZ(),
@@ -2077,10 +2084,6 @@
contentView = mGuts;
}
if (expandAnimationRunning) {
- contentView.animate()
- .alpha(0f)
- .setDuration(ActivityLaunchAnimator.ANIMATION_DURATION_FADE_OUT_CONTENT)
- .setInterpolator(ActivityLaunchAnimator.CONTENT_FADE_OUT_INTERPOLATOR);
setAboveShelf(true);
mExpandAnimationRunning = true;
getViewState().cancelAnimations(this);
@@ -2088,6 +2091,7 @@
} else {
mExpandAnimationRunning = false;
setAboveShelf(isAboveShelf());
+ setVisibility(View.VISIBLE);
if (mGuts != null) {
mGuts.setAlpha(1.0f);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index f6ab409..4b1f679 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -20,7 +20,6 @@
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
@@ -30,8 +29,6 @@
import com.android.internal.util.ArrayUtils;
import com.android.systemui.R;
-import com.android.systemui.animation.ActivityLaunchAnimator;
-import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
/**
@@ -281,11 +278,6 @@
public void setExpandAnimationParams(ExpandAnimationParameters params) {
mActualHeight = params.getHeight();
mActualWidth = params.getWidth();
- float alphaProgress = Interpolators.ALPHA_IN.getInterpolation(
- params.getProgress(
- ActivityLaunchAnimator.ANIMATION_DELAY_FADE_IN_WINDOW /* delay */,
- ActivityLaunchAnimator.ANIMATION_DURATION_FADE_IN_WINDOW /* duration */));
- mBackground.setAlpha((int) (mDrawableAlpha * (1.0f - alphaProgress)));
invalidate();
}
@@ -294,8 +286,6 @@
if (mBackground instanceof LayerDrawable) {
GradientDrawable gradientDrawable =
(GradientDrawable) ((LayerDrawable) mBackground).getDrawable(0);
- gradientDrawable.setXfermode(
- running ? new PorterDuffXfermode(PorterDuff.Mode.SRC) : null);
// Speed optimization: disable AA if transfer mode is not SRC_OVER. AA is not easy to
// spot during animation anyways.
gradientDrawable.setAntiAlias(!running);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 82e670b..64f228f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -43,6 +43,7 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
@@ -129,7 +130,12 @@
public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
private static final String TAG = "StackScroller";
- private static final boolean DEBUG = false;
+
+ // Usage:
+ // adb shell setprop persist.debug.nssl true && adb reboot
+ private static final boolean DEBUG = SystemProperties.getBoolean("persist.debug.nssl",
+ false /* default */);
+
private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f;
private static final float RUBBER_BAND_FACTOR_ON_PANEL_EXPAND = 0.21f;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 86465b6..b60ef1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -382,13 +382,15 @@
final boolean isHunGoingToShade = ambientState.isShadeExpanded()
&& view == ambientState.getTrackedHeadsUpRow();
- if (!isHunGoingToShade) {
- if (ambientState.isExpansionChanging() && !ambientState.isOnKeyguard()) {
- viewState.alpha = Interpolators.getNotificationScrimAlpha(
- ambientState.getExpansionFraction(), true /* notification */);
- } else {
- viewState.alpha = 1f - ambientState.getHideAmount();
- }
+ if (isHunGoingToShade) {
+ // Keep 100% opacity for heads up notification going to shade.
+ } else if (ambientState.isOnKeyguard()) {
+ // Adjust alpha for wakeup to lockscreen.
+ viewState.alpha = 1f - ambientState.getHideAmount();
+ } else if (ambientState.isExpansionChanging()) {
+ // Adjust alpha for shade open & close.
+ viewState.alpha = Interpolators.getNotificationScrimAlpha(
+ ambientState.getExpansionFraction(), true /* notification */);
}
if (view.mustStayOnScreen() && viewState.yTranslation >= 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index eb46fe3..a7b802a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -75,6 +75,7 @@
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardStatusViewController;
@@ -906,8 +907,7 @@
R.dimen.pulse_expansion_max_top_overshoot);
mScrimCornerRadius = mResources.getDimensionPixelSize(
R.dimen.notification_scrim_corner_radius);
- mScreenCornerRadius = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.rounded_corner_radius);
+ mScreenCornerRadius = (int) ScreenDecorationsUtils.getWindowCornerRadius(mResources);
mNotificationScrimPadding = mResources.getDimensionPixelSize(
R.dimen.notification_side_paddings);
mLockscreenNotificationQSPadding = mResources.getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 2eece18..8e8dcbd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -2587,7 +2587,7 @@
public void onAnimationEnded() {
mNotificationShadeWindowController.setRequestTopUi(false, TAG);
}
- }, false).show(animationDelay);
+ }, false, sUiEventLogger).show(animationDelay);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 91d1bd7..c0957c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -35,6 +35,7 @@
import android.view.ViewRootImpl;
import android.view.WindowManagerGlobal;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -63,6 +64,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;
@@ -268,10 +270,23 @@
registerListeners();
}
- public void setAlternateAuthInterceptor(@Nullable AlternateAuthInterceptor authInterceptor) {
- final boolean newlyNull = authInterceptor == null && mAlternateAuthInterceptor != null;
+ /**
+ * Sets the given alt auth interceptor to null if it's the current auth interceptor. Else,
+ * does nothing.
+ */
+ public void removeAlternateAuthInterceptor(@NonNull AlternateAuthInterceptor authInterceptor) {
+ if (Objects.equals(mAlternateAuthInterceptor, authInterceptor)) {
+ mAlternateAuthInterceptor = null;
+ resetAlternateAuth(true);
+ }
+ }
+
+ /**
+ * Sets a new alt auth interceptor.
+ */
+ public void setAlternateAuthInterceptor(@NonNull AlternateAuthInterceptor authInterceptor) {
mAlternateAuthInterceptor = authInterceptor;
- resetAlternateAuth(newlyNull);
+ resetAlternateAuth(false);
}
private void registerListeners() {
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index b1241b1..941cd77 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -68,7 +68,9 @@
super.onCreate(icicle);
- if (SystemProperties.getInt("service.adb.tcp.port", 0) == 0) {
+ // Emulator does not support reseating the usb cable to reshow the dialog.
+ boolean isEmulator = SystemProperties.get("ro.boot.qemu").equals("1");
+ if (SystemProperties.getInt("service.adb.tcp.port", 0) == 0 && !isEmulator) {
mDisconnectedReceiver = new UsbDisconnectedReceiver(this);
IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE);
mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index 936ec80..49604ff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -22,6 +22,7 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;
+import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK;
@@ -69,6 +70,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
@@ -88,8 +90,9 @@
import java.util.List;
@SmallTest
+@FlakyTest(bugId = 188890599)
@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class MagnificationModeSwitchTest extends SysuiTestCase {
private static final float FADE_IN_ALPHA = 1f;
@@ -223,7 +226,7 @@
}
@Test
- public void onApplyWindowInsetsWithWindowInsetsChange_buttonIsShowing_draggableBoundsChanged() {
+ public void onSystemBarsInsetsChanged_buttonIsShowing_draggableBoundsChanged() {
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
final Rect oldDraggableBounds = new Rect(mMagnificationModeSwitch.mDraggableWindowBounds);
@@ -236,6 +239,19 @@
}
@Test
+ public void onDisplayCutoutInsetsChanged_buttonIsShowing_draggableBoundsChanged() {
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+ final Rect oldDraggableBounds = new Rect(mMagnificationModeSwitch.mDraggableWindowBounds);
+
+ mWindowManager.setWindowInsets(new WindowInsets.Builder()
+ .setInsetsIgnoringVisibility(displayCutout(), Insets.of(20, 30, 20, 30))
+ .build());
+ mSpyImageView.onApplyWindowInsets(WindowInsets.CONSUMED);
+
+ assertNotEquals(oldDraggableBounds, mMagnificationModeSwitch.mDraggableWindowBounds);
+ }
+
+ @Test
public void onDraggingGestureFinish_buttonIsShowing_stickToRightEdge() {
final int windowHalfWidth =
mWindowManager.getCurrentWindowMetrics().getBounds().width() / 2;
@@ -378,10 +394,26 @@
hasItems(new AccessibilityNodeInfo.AccessibilityAction(
ACTION_CLICK.getId(), mContext.getResources().getString(
R.string.magnification_mode_switch_click_label))));
+ assertThat(nodeInfo.getActionList(),
+ hasItems(new AccessibilityNodeInfo.AccessibilityAction(
+ R.id.accessibility_action_move_up, mContext.getResources().getString(
+ R.string.accessibility_control_move_up))));
+ assertThat(nodeInfo.getActionList(),
+ hasItems(new AccessibilityNodeInfo.AccessibilityAction(
+ R.id.accessibility_action_move_down, mContext.getResources().getString(
+ R.string.accessibility_control_move_down))));
+ assertThat(nodeInfo.getActionList(),
+ hasItems(new AccessibilityNodeInfo.AccessibilityAction(
+ R.id.accessibility_action_move_left, mContext.getResources().getString(
+ R.string.accessibility_control_move_left))));
+ assertThat(nodeInfo.getActionList(),
+ hasItems(new AccessibilityNodeInfo.AccessibilityAction(
+ R.id.accessibility_action_move_right, mContext.getResources().getString(
+ R.string.accessibility_control_move_right))));
}
@Test
- public void performA11yActions_showWindowModeButton_verifyTapAction() {
+ public void performClickA11yActions_showWindowModeButton_verifyTapAction() {
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
resetAndStubMockImageViewAndAnimator();
@@ -392,6 +424,16 @@
}
@Test
+ public void performMoveLeftA11yAction_showButtonAtRightEdge_moveToLeftEdge() {
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+ mSpyImageView.performAccessibilityAction(
+ R.id.accessibility_action_move_left, null);
+
+ assertLayoutPosition(/* toLeftScreenEdge= */true);
+ }
+
+ @Test
public void showButton_showFadeOutAnimation_fadeOutAnimationCanceled() {
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
assertShowFadingAnimation(FADE_OUT_ALPHA);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
index 0de257a..448211e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
@@ -18,6 +18,8 @@
import static android.view.View.OVER_SCROLL_ALWAYS;
import static android.view.View.OVER_SCROLL_NEVER;
+import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.navigationBars;
import static com.google.common.truth.Truth.assertThat;
@@ -31,9 +33,11 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
@@ -43,7 +47,9 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewPropertyAnimator;
+import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.NonNull;
@@ -79,12 +85,17 @@
@Mock
private ViewPropertyAnimator mAnimator;
+ @Mock
+ private WindowMetrics mWindowMetrics;
+
private MotionEvent mInterceptMotionEvent;
private RecyclerView mListView;
private Rect mAvailableBounds = new Rect(100, 200, 300, 400);
+ private int mScreenHeight;
+ private int mMenuWindowHeight;
private int mMenuHalfWidth;
private int mMenuHalfHeight;
private int mScreenHalfWidth;
@@ -111,18 +122,19 @@
final int margin =
res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_margin);
final int padding =
- res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_padding);
+ res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_small_padding);
final int iconWidthHeight =
res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_small_width_height);
final int menuWidth = padding * 2 + iconWidthHeight;
final int menuHeight = (padding + iconWidthHeight) * mTargets.size() + padding;
final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
- final int screenHeight = mContext.getResources().getDisplayMetrics().heightPixels;
+ mScreenHeight = mContext.getResources().getDisplayMetrics().heightPixels;
mMenuHalfWidth = menuWidth / 2;
mMenuHalfHeight = menuHeight / 2;
mScreenHalfWidth = screenWidth / 2;
- mScreenHalfHeight = screenHeight / 2;
+ mScreenHalfHeight = mScreenHeight / 2;
mMaxWindowX = screenWidth - margin - menuWidth;
+ mMenuWindowHeight = menuHeight + margin * 2;
}
@Test
@@ -464,12 +476,80 @@
assertThat(mListView.getOverScrollMode()).isEqualTo(OVER_SCROLL_NEVER);
}
+ @Test
+ public void showMenuView_insetsListener_overlapWithIme_menuViewShifted() {
+ final int offset = 200;
+
+ showMenuWithLatestStatus();
+ final WindowInsets imeInset = fakeImeInsetWith(offset);
+ when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics);
+ when(mWindowMetrics.getWindowInsets()).thenReturn(imeInset);
+ final int expectedLayoutY = mMenuView.mCurrentLayoutParams.y - offset;
+ mMenuView.dispatchApplyWindowInsets(imeInset);
+
+ assertThat(mMenuView.mCurrentLayoutParams.y).isEqualTo(expectedLayoutY);
+ }
+
+ @Test
+ public void hideIme_onMenuViewShifted_menuViewMovedBack() {
+ final int offset = 200;
+ showMenuWithLatestStatus();
+ final WindowInsets imeInset = fakeImeInsetWith(offset);
+ when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics);
+ when(mWindowMetrics.getWindowInsets()).thenReturn(imeInset);
+ final int expectedLayoutY = mMenuView.mCurrentLayoutParams.y;
+ mMenuView.dispatchApplyWindowInsets(imeInset);
+
+ mMenuView.dispatchApplyWindowInsets(
+ new WindowInsets.Builder().setVisible(ime(), false).build());
+
+ assertThat(mMenuView.mCurrentLayoutParams.y).isEqualTo(expectedLayoutY);
+ }
+
+ @Test
+ public void showMenuAndIme_withHigherIme_alignScreenTopEdge() {
+ final int offset = 99999;
+
+ showMenuWithLatestStatus();
+ final WindowInsets imeInset = fakeImeInsetWith(offset);
+ when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics);
+ when(mWindowMetrics.getWindowInsets()).thenReturn(imeInset);
+ mMenuView.dispatchApplyWindowInsets(imeInset);
+
+ assertThat(mMenuView.mCurrentLayoutParams.y).isEqualTo(0);
+ }
+
@After
public void tearDown() {
mInterceptMotionEvent = null;
mMotionEventHelper.recycleEvents();
}
+ private void showMenuWithLatestStatus() {
+ mMenuView.show();
+ mMenuView.onTargetsChanged(mTargets);
+ mMenuView.setSizeType(0);
+ mMenuView.setShapeType(0);
+ }
+
+ /**
+ * Based on the current menu status, fake the ime inset component {@link WindowInsets} used
+ * for testing.
+ *
+ * @param offset is used for the y-axis position of ime higher than the y-axis position of menu.
+ * @return the ime inset
+ */
+ private WindowInsets fakeImeInsetWith(int offset) {
+ // Ensure the keyboard has overlapped on the menu view.
+ final int fakeImeHeight =
+ mScreenHeight - (mMenuView.mCurrentLayoutParams.y + mMenuWindowHeight) + offset;
+
+ return new WindowInsets.Builder()
+ .setVisible(ime() | navigationBars(), true)
+ .setInsets(ime() | navigationBars(), Insets.of(0, 0, 0, fakeImeHeight))
+ .build();
+ }
+
private class TestAccessibilityFloatingMenu extends AccessibilityFloatingMenuView {
TestAccessibilityFloatingMenu(Context context, RecyclerView listView) {
super(context, listView);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index 9a0ed98..d499011 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -2,6 +2,9 @@
import android.app.ActivityManager
import android.app.WindowConfiguration
+import android.content.ComponentName
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
import android.graphics.Point
import android.graphics.Rect
import android.os.Looper
@@ -167,10 +170,16 @@
private fun fakeWindow(): RemoteAnimationTarget {
val bounds = Rect(10 /* left */, 20 /* top */, 30 /* right */, 40 /* bottom */)
+ val taskInfo = ActivityManager.RunningTaskInfo()
+ taskInfo.topActivity = ComponentName("com.android.systemui", "FakeActivity")
+ taskInfo.topActivityInfo = ActivityInfo().apply {
+ applicationInfo = ApplicationInfo()
+ }
+
return RemoteAnimationTarget(
0, RemoteAnimationTarget.MODE_OPENING, SurfaceControl(), false, Rect(), Rect(), 0,
Point(), Rect(), bounds, WindowConfiguration(), false, SurfaceControl(), Rect(),
- ActivityManager.RunningTaskInfo()
+ taskInfo
)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
index f41c100..0b399cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
@@ -224,7 +224,7 @@
public void testLayoutParams_hasSecureWindowFlag() {
final IBinder windowToken = mock(IBinder.class);
final WindowManager.LayoutParams layoutParams =
- AuthContainerView.getLayoutParams(windowToken);
+ AuthContainerView.getLayoutParams(windowToken, "");
assertTrue((layoutParams.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0);
}
@@ -232,7 +232,7 @@
public void testLayoutParams_excludesImeInsets() {
final IBinder windowToken = mock(IBinder.class);
final WindowManager.LayoutParams layoutParams =
- AuthContainerView.getLayoutParams(windowToken);
+ AuthContainerView.getLayoutParams(windowToken, "");
assertTrue((layoutParams.getFitInsetsTypes() & WindowInsets.Type.ime()) == 0);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 46c1848..9322aa9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -275,6 +275,7 @@
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
+ when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
// WHEN it is cancelled
mUdfpsController.onCancelUdfps();
// THEN the illumination is hidden
@@ -289,6 +290,7 @@
mScreenObserver.onScreenTurnedOn();
mFgExecutor.runAllReady();
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
+ when(mUdfpsView.isIlluminationRequested()).thenReturn(true);
// WHEN it times out
mFgExecutor.advanceClockToNext();
mFgExecutor.runAllReady();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index a7c63c1..5923de6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -254,15 +254,15 @@
@Test
public void testOnDetachedStateReset() {
- // GIVEN view is attached, alt auth is force being shown
+ // GIVEN view is attached
mController.onViewAttached();
- captureStatusBarStateListeners();
+ captureAltAuthInterceptor();
// WHEN view is detached
mController.onViewDetached();
- // THEN set alternate auth interceptor to null
- verify(mStatusBarKeyguardViewManager).setAlternateAuthInterceptor(null);
+ // THEN remove alternate auth interceptor
+ verify(mStatusBarKeyguardViewManager).removeAlternateAuthInterceptor(mAltAuthInterceptor);
}
private void sendStatusBarStateChanged(int statusBarState) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
index 126dca5..a2b5013 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
@@ -23,6 +23,7 @@
import android.testing.TestableLooper
import android.text.TextUtils
import android.view.View
+import android.widget.TextView
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -52,6 +53,7 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
+ context.ensureTestableResources()
tileView = FakeTileView(context, iconView, false)
customDrawableView = tileView.requireViewById(R.id.customDrawable)
@@ -117,7 +119,7 @@
}
@Test
- fun testSecondaryLabelDescription_unavailable() {
+ fun testSecondaryLabelDescription_unavailable_default() {
val state = QSTile.State()
state.state = Tile.STATE_UNAVAILABLE
state.secondaryLabel = ""
@@ -130,7 +132,7 @@
}
@Test
- fun testSecondaryLabelDescription_booleanInactive() {
+ fun testSecondaryLabelDescription_booleanInactive_default() {
val state = QSTile.BooleanState()
state.state = Tile.STATE_INACTIVE
state.secondaryLabel = ""
@@ -143,7 +145,7 @@
}
@Test
- fun testSecondaryLabelDescription_booleanActive() {
+ fun testSecondaryLabelDescription_booleanActive_default() {
val state = QSTile.BooleanState()
state.state = Tile.STATE_ACTIVE
state.secondaryLabel = ""
@@ -220,6 +222,41 @@
assertThat(chevronView.visibility).isEqualTo(View.GONE)
}
+ @Test
+ fun testUseStateStringsForKnownSpec_Boolean() {
+ val state = QSTile.BooleanState()
+ val spec = "internet"
+ state.spec = spec
+
+ val unavailableString = "${spec}_unavailable"
+ val offString = "${spec}_off"
+ val onString = "${spec}_on"
+
+ context.orCreateTestableResources.addOverride(R.array.tile_states_internet, arrayOf(
+ unavailableString,
+ offString,
+ onString
+ ))
+
+ // State UNAVAILABLE
+ state.secondaryLabel = ""
+ state.state = Tile.STATE_UNAVAILABLE
+ tileView.changeState(state)
+ assertThat((tileView.secondaryLabel as TextView).text).isEqualTo(unavailableString)
+
+ // State INACTIVE
+ state.secondaryLabel = ""
+ state.state = Tile.STATE_INACTIVE
+ tileView.changeState(state)
+ assertThat((tileView.secondaryLabel as TextView).text).isEqualTo(offString)
+
+ // State ACTIVE
+ state.secondaryLabel = ""
+ state.state = Tile.STATE_ACTIVE
+ tileView.changeState(state)
+ assertThat((tileView.secondaryLabel as TextView).text).isEqualTo(onString)
+ }
+
class FakeTileView(
context: Context,
icon: QSIconView,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
new file mode 100644
index 0000000..19ffa49
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tileimpl
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class TilesStatesTextTest : SysuiTestCase() {
+
+ @Test
+ fun testStockTilesHaveStatesArray() {
+ val tiles = mContext.getString(R.string.quick_settings_tiles_stock).split(",")
+ tiles.forEach { spec ->
+ val resName = "${QSTileViewImpl.TILE_STATE_RES_PREFIX}$spec"
+ val resId = mContext.resources.getIdentifier(resName, "array", mContext.packageName)
+
+ assertNotEquals("Missing resource for $resName", 0, resId)
+
+ val array = mContext.resources.getStringArray(resId)
+
+ assertEquals("Array for $spec is of wrong size", 3, array.size)
+ }
+ }
+
+ @Test
+ fun testDefaultArray() {
+ val array = mContext.resources.getStringArray(R.array.tile_states_default)
+
+ assertThat(array.size).isEqualTo(3)
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
index 03744b78..85ec3fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
@@ -20,6 +20,7 @@
import android.view.View
import android.view.WindowManager
import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.FeatureFlags
import com.android.systemui.statusbar.commandline.CommandRegistry
@@ -50,6 +51,7 @@
@Mock private lateinit var configurationController: ConfigurationController
@Mock private lateinit var rippleView: ChargingRippleView
@Mock private lateinit var windowManager: WindowManager
+ @Mock private lateinit var uiEventLogger: UiEventLogger
private val systemClock = FakeSystemClock()
@Before
@@ -58,7 +60,7 @@
`when`(featureFlags.isChargingRippleEnabled).thenReturn(true)
controller = WiredChargingRippleController(
commandRegistry, batteryController, configurationController,
- featureFlags, context, windowManager, systemClock)
+ featureFlags, context, windowManager, systemClock, uiEventLogger)
controller.rippleView = rippleView // Replace the real ripple view with a mock instance
}
@@ -87,6 +89,10 @@
// Verify ripple removed
runnableCaptor.value.run()
verify(windowManager).removeView(rippleView)
+
+ // Verify event logged
+ verify(uiEventLogger).log(
+ WiredChargingRippleController.WiredChargingRippleEvent.CHARGING_RIPPLE_PLAYED)
}
@Test
diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java
index 70a54cf..98ad81d 100644
--- a/services/core/java/com/android/server/am/AssistDataRequester.java
+++ b/services/core/java/com/android/server/am/AssistDataRequester.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.app.ActivityManager.ASSIST_CONTEXT_CONTENT;
import static android.app.ActivityManager.ASSIST_CONTEXT_FULL;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_NONE;
@@ -143,45 +144,47 @@
* Request that autofill data be loaded asynchronously. The resulting data will be provided
* through the {@link AssistDataRequesterCallbacks}.
*
- * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String,
- * boolean)}.
+ * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, boolean, int,
+ * String, boolean)}.
*/
public void requestAutofillData(List<IBinder> activityTokens, int callingUid,
String callingPackage) {
requestData(activityTokens, true /* requestAutofillData */,
true /* fetchData */, false /* fetchScreenshot */,
- true /* allowFetchData */, false /* allowFetchScreenshot */,
- false /* ignoreTopActivityCheck */, callingUid, callingPackage);
+ true /* fetchStructure */, true /* allowFetchData */,
+ false /* allowFetchScreenshot */, false /* ignoreTopActivityCheck */, callingUid,
+ callingPackage);
}
/**
* Request that assist data be loaded asynchronously. The resulting data will be provided
* through the {@link AssistDataRequesterCallbacks}.
*
- * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String,
- * boolean)}.
+ * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, boolean, int,
+ * String, boolean)}.
*/
public void requestAssistData(List<IBinder> activityTokens, final boolean fetchData,
final boolean fetchScreenshot, boolean allowFetchData, boolean allowFetchScreenshot,
int callingUid, String callingPackage) {
- requestAssistData(activityTokens, fetchData, fetchScreenshot, allowFetchData,
- allowFetchScreenshot, false /* ignoreTopActivityCheck */, callingUid,
- callingPackage);
+ requestAssistData(activityTokens, fetchData, fetchScreenshot, true /* fetchStructure */,
+ allowFetchData, allowFetchScreenshot, false /* ignoreTopActivityCheck */,
+ callingUid, callingPackage);
}
/**
* Request that assist data be loaded asynchronously. The resulting data will be provided
* through the {@link AssistDataRequesterCallbacks}.
*
- * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, int, String,
- * boolean)}.
+ * See {@link #requestData(List, boolean, boolean, boolean, boolean, boolean, boolean, int,
+ * String, boolean)}.
*/
public void requestAssistData(List<IBinder> activityTokens, final boolean fetchData,
- final boolean fetchScreenshot, boolean allowFetchData, boolean allowFetchScreenshot,
- boolean ignoreTopActivityCheck, int callingUid, String callingPackage) {
+ final boolean fetchScreenshot, final boolean fetchStructure, boolean allowFetchData,
+ boolean allowFetchScreenshot, boolean ignoreTopActivityCheck, int callingUid,
+ String callingPackage) {
requestData(activityTokens, false /* requestAutofillData */, fetchData, fetchScreenshot,
- allowFetchData, allowFetchScreenshot, ignoreTopActivityCheck, callingUid,
- callingPackage);
+ fetchStructure, allowFetchData, allowFetchScreenshot, ignoreTopActivityCheck,
+ callingUid, callingPackage);
}
/**
@@ -197,6 +200,8 @@
* @param fetchScreenshot whether or not to fetch the screenshot, only applies if fetchData is
* true, the caller is allowed to fetch the assist data, and the current activity allows
* assist data to be fetched from it
+ * @param fetchStructure whether or not to fetch the AssistStructure along with the
+ * AssistContent
* @param allowFetchData to be joined with other checks, determines whether or not the requester
* is allowed to fetch the assist data
* @param allowFetchScreenshot to be joined with other checks, determines whether or not the
@@ -205,9 +210,9 @@
* making the request. Used when passing an activity from Recents.
*/
private void requestData(List<IBinder> activityTokens, final boolean requestAutofillData,
- final boolean fetchData, final boolean fetchScreenshot, boolean allowFetchData,
- boolean allowFetchScreenshot, boolean ignoreTopActivityCheck, int callingUid,
- String callingPackage) {
+ final boolean fetchData, final boolean fetchScreenshot, final boolean fetchStructure,
+ boolean allowFetchData, boolean allowFetchScreenshot, boolean ignoreTopActivityCheck,
+ int callingUid, String callingPackage) {
// TODO(b/34090158): Known issue, if the assist data is not allowed on the current activity,
// then no assist data is requested for any of the other activities
@@ -246,13 +251,18 @@
Bundle receiverExtras = new Bundle();
receiverExtras.putInt(KEY_RECEIVER_EXTRA_INDEX, i);
receiverExtras.putInt(KEY_RECEIVER_EXTRA_COUNT, numActivities);
- boolean result = requestAutofillData
- ? mActivityTaskManager.requestAutofillData(this,
- receiverExtras, topActivity, 0 /* flags */)
- : mActivityTaskManager.requestAssistContextExtras(
- ASSIST_CONTEXT_FULL, this, receiverExtras, topActivity,
+ boolean result;
+ if (requestAutofillData) {
+ result = mActivityTaskManager.requestAutofillData(this, receiverExtras,
+ topActivity, 0 /* flags */);
+ } else {
+ int requestType = fetchStructure ? ASSIST_CONTEXT_FULL :
+ ASSIST_CONTEXT_CONTENT;
+ result = mActivityTaskManager.requestAssistContextExtras(
+ requestType, this, receiverExtras, topActivity,
/* checkActivityIsTop= */ (i == 0)
&& !ignoreTopActivityCheck, /* newSessionId= */ i == 0);
+ }
if (result) {
mPendingDataCount++;
} else if (i == 0) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java
index f0e4597..879c8a0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java
@@ -113,6 +113,19 @@
}
}
+ public static void onAcquiredGood(int sensorId,
+ @Nullable IUdfpsOverlayController udfpsOverlayController) {
+ if (udfpsOverlayController == null) {
+ return;
+ }
+
+ try {
+ udfpsOverlayController.onAcquiredGood(sensorId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when sending onAcquiredGood", e);
+ }
+ }
+
public static void onEnrollmentProgress(int sensorId, int remaining,
@Nullable IUdfpsOverlayController udfpsOverlayController) {
if (udfpsOverlayController == null) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 4584267..a5326b3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricFingerprintConstants;
+import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.fingerprint.ISession;
@@ -81,6 +82,17 @@
}
@Override
+ public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
+ // For UDFPS, notify SysUI that the illumination can be turned off.
+ // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE
+ if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
+ UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController);
+ }
+
+ super.onAcquired(acquiredInfo, vendorCode);
+ }
+
+ @Override
public void onError(int errorCode, int vendorCode) {
super.onError(errorCode, vendorCode);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index ed886fe..125cfd2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricFingerprintConstants;
+import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.fingerprint.ISession;
@@ -85,14 +86,19 @@
}
}
-
@Override
- public void onAcquired(int acquiredInfo, int vendorCode) {
- super.onAcquired(acquiredInfo, vendorCode);
+ public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
+ // For UDFPS, notify SysUI that the illumination can be turned off.
+ // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE
+ if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD) {
+ UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController);
+ }
if (UdfpsHelper.isValidAcquisitionMessage(getContext(), acquiredInfo, vendorCode)) {
UdfpsHelper.onEnrollmentHelp(getSensorId(), mUdfpsOverlayController);
}
+
+ super.onAcquired(acquiredInfo, vendorCode);
}
@Override
diff --git a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
index a34d722..70a222f 100644
--- a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
@@ -35,17 +35,17 @@
private final Context mContext;
- private TelephonyManager mTelephonyManager;
+ TelephonyManager mTelephonyManager;
- private boolean mIsInEmergencyCall;
- private long mEmergencyCallEndRealtimeMs = Long.MIN_VALUE;
+ boolean mIsInEmergencyCall;
+ long mEmergencyCallEndRealtimeMs = Long.MIN_VALUE;
public SystemEmergencyHelper(Context context) {
mContext = context;
}
/** Called when system is ready. */
- public void onSystemReady() {
+ public synchronized void onSystemReady() {
if (mTelephonyManager != null) {
return;
}
@@ -64,14 +64,20 @@
return;
}
- mIsInEmergencyCall = mTelephonyManager.isEmergencyNumber(
- intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
+ synchronized (SystemEmergencyHelper.this) {
+ mIsInEmergencyCall = mTelephonyManager.isEmergencyNumber(
+ intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
+ }
}
}, new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL));
}
@Override
- public boolean isInEmergency(long extensionTimeMs) {
+ public synchronized boolean isInEmergency(long extensionTimeMs) {
+ if (mTelephonyManager == null) {
+ return false;
+ }
+
boolean isInExtensionTime = mEmergencyCallEndRealtimeMs != Long.MIN_VALUE
&& (SystemClock.elapsedRealtime() - mEmergencyCallEndRealtimeMs) < extensionTimeMs;
@@ -84,12 +90,16 @@
private class EmergencyCallTelephonyCallback extends TelephonyCallback implements
TelephonyCallback.CallStateListener{
+ EmergencyCallTelephonyCallback() {}
+
@Override
public void onCallStateChanged(int state) {
if (state == TelephonyManager.CALL_STATE_IDLE) {
- if (mIsInEmergencyCall) {
- mEmergencyCallEndRealtimeMs = SystemClock.elapsedRealtime();
- mIsInEmergencyCall = false;
+ synchronized (SystemEmergencyHelper.this) {
+ if (mIsInEmergencyCall) {
+ mEmergencyCallEndRealtimeMs = SystemClock.elapsedRealtime();
+ mIsInEmergencyCall = false;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 6d7f792..4f8b87b 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -1527,16 +1527,16 @@
throw new IllegalArgumentException(mName + " provider is not a test provider");
}
+ String locationProvider = location.getProvider();
+ if (!TextUtils.isEmpty(locationProvider) && !mName.equals(locationProvider)) {
+ // The location has an explicit provider that is different from the mock
+ // provider name. The caller may be trying to fool us via b/33091107.
+ EventLog.writeEvent(0x534e4554, "33091107", Binder.getCallingUid(),
+ mName + "!=" + locationProvider);
+ }
+
final long identity = Binder.clearCallingIdentity();
try {
- String locationProvider = location.getProvider();
- if (!TextUtils.isEmpty(locationProvider) && !mName.equals(locationProvider)) {
- // The location has an explicit provider that is different from the mock
- // provider name. The caller may be trying to fool us via b/33091107.
- EventLog.writeEvent(0x534e4554, "33091107", Binder.getCallingUid(),
- mName + "!=" + locationProvider);
- }
-
mProvider.setMockProviderLocation(location);
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 5b03989..0bec09c 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -105,6 +105,7 @@
import android.security.keystore2.AndroidKeyStoreProvider;
import android.service.gatekeeper.GateKeeperResponse;
import android.service.gatekeeper.IGateKeeperService;
+import android.system.keystore2.Domain;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -254,8 +255,7 @@
* The UIDs that are used for system credential storage in keystore.
*/
private static final int[] SYSTEM_CREDENTIAL_UIDS = {
- Process.WIFI_UID, Process.VPN_UID,
- Process.ROOT_UID, Process.SYSTEM_UID };
+ Process.VPN_UID, Process.ROOT_UID, Process.SYSTEM_UID};
// This class manages life cycle events for encrypted users on File Based Encryption (FBE)
// devices. The most basic of these is to show/hide notifications about missing features until
@@ -2123,9 +2123,14 @@
// Clear all the users credentials could have been installed in for this user.
for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
for (int uid : SYSTEM_CREDENTIAL_UIDS) {
- mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
+ AndroidKeyStoreMaintenance.clearNamespace(Domain.APP,
+ UserHandle.getUid(profileId, uid));
}
}
+ if (mUserManager.getUserInfo(userId).isPrimary()) {
+ AndroidKeyStoreMaintenance.clearNamespace(Domain.SELINUX,
+ KeyProperties.NAMESPACE_WIFI);
+ }
} finally {
if (managedUserId != -1 && managedUserDecryptedPassword != null) {
if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 8c1fd36..cfd5750 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -99,8 +99,12 @@
import static android.net.NetworkPolicyManager.uidPoliciesToString;
import static android.net.NetworkPolicyManager.uidRulesToString;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
+import static android.net.NetworkStats.METERED_ALL;
+import static android.net.NetworkStats.METERED_YES;
+import static android.net.NetworkTemplate.MATCH_CARRIER;
import static android.net.NetworkTemplate.MATCH_MOBILE;
import static android.net.NetworkTemplate.MATCH_WIFI;
+import static android.net.NetworkTemplate.buildTemplateCarrierMetered;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
@@ -349,7 +353,8 @@
private static final int VERSION_SWITCH_UID = 10;
private static final int VERSION_ADDED_CYCLE = 11;
private static final int VERSION_ADDED_NETWORK_TYPES = 12;
- private static final int VERSION_LATEST = VERSION_ADDED_NETWORK_TYPES;
+ private static final int VERSION_SUPPORTED_CARRIER_USAGE = 13;
+ private static final int VERSION_LATEST = VERSION_SUPPORTED_CARRIER_USAGE;
@VisibleForTesting
public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
@@ -374,7 +379,9 @@
private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
+ private static final String ATTR_SUBSCRIBER_ID_MATCH_RULE = "subscriberIdMatchRule";
private static final String ATTR_NETWORK_ID = "networkId";
+ private static final String ATTR_TEMPLATE_METERED = "templateMetered";
@Deprecated private static final String ATTR_CYCLE_DAY = "cycleDay";
@Deprecated private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
private static final String ATTR_CYCLE_START = "cycleStart";
@@ -1451,7 +1458,7 @@
*/
@GuardedBy("mNetworkPoliciesSecondLock")
private int findRelevantSubIdNL(NetworkTemplate template) {
- // Mobile template is relevant when any active subscriber matches
+ // Carrier template is relevant when any active subscriber matches
for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
final int subId = mSubIdToSubscriberId.keyAt(i);
final String subscriberId = mSubIdToSubscriberId.valueAt(i);
@@ -1530,6 +1537,7 @@
}
case TYPE_LIMIT: {
switch (policy.template.getMatchRule()) {
+ case MATCH_CARRIER:
case MATCH_MOBILE:
title = res.getText(R.string.data_usage_mobile_limit_title);
break;
@@ -1558,6 +1566,7 @@
}
case TYPE_LIMIT_SNOOZED: {
switch (policy.template.getMatchRule()) {
+ case MATCH_CARRIER:
case MATCH_MOBILE:
title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
break;
@@ -1655,7 +1664,7 @@
synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) {
- ensureActiveMobilePolicyAL();
+ ensureActiveCarrierPolicyAL();
normalizePoliciesNL();
updateNetworkEnabledNL();
updateNetworkRulesNL();
@@ -1680,17 +1689,17 @@
}
/**
- * Update mobile policies with data cycle information from {@link CarrierConfigManager}
+ * Update carrier policies with data cycle information from {@link CarrierConfigManager}
* if necessary.
*
* @param subId that has its associated NetworkPolicy updated if necessary
* @return if any policies were updated
*/
@GuardedBy("mNetworkPoliciesSecondLock")
- private boolean maybeUpdateMobilePolicyCycleAL(int subId, String subscriberId) {
- if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleAL()");
+ private boolean maybeUpdateCarrierPolicyCycleAL(int subId, String subscriberId) {
+ if (LOGV) Slog.v(TAG, "maybeUpdateCarrierPolicyCycleAL()");
- // find and update the mobile NetworkPolicy for this subscriber id
+ // find and update the carrier NetworkPolicy for this subscriber id
boolean policyUpdated = false;
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true,
@@ -1699,21 +1708,21 @@
final NetworkTemplate template = mNetworkPolicy.keyAt(i);
if (template.matches(probeIdent)) {
final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
- policyUpdated |= updateDefaultMobilePolicyAL(subId, policy);
+ policyUpdated |= updateDefaultCarrierPolicyAL(subId, policy);
}
}
return policyUpdated;
}
/**
- * Returns the cycle day that should be used for a mobile NetworkPolicy.
+ * Returns the cycle day that should be used for a carrier NetworkPolicy.
*
* It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable
* to do so, it returns the fallback value.
*
* @param config The CarrierConfig to read the value from.
* @param fallbackCycleDay to return if the CarrierConfig can't be read.
- * @return cycleDay to use in the mobile NetworkPolicy.
+ * @return cycleDay to use in the carrier NetworkPolicy.
*/
@VisibleForTesting
int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
@@ -1738,14 +1747,14 @@
}
/**
- * Returns the warning bytes that should be used for a mobile NetworkPolicy.
+ * Returns the warning bytes that should be used for a carrier NetworkPolicy.
*
* It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
* to do so, it returns the fallback value.
*
* @param config The CarrierConfig to read the value from.
* @param fallbackWarningBytes to return if the CarrierConfig can't be read.
- * @return warningBytes to use in the mobile NetworkPolicy.
+ * @return warningBytes to use in the carrier NetworkPolicy.
*/
@VisibleForTesting
long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
@@ -1771,14 +1780,14 @@
}
/**
- * Returns the limit bytes that should be used for a mobile NetworkPolicy.
+ * Returns the limit bytes that should be used for a carrier NetworkPolicy.
*
* It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
* to do so, it returns the fallback value.
*
* @param config The CarrierConfig to read the value from.
* @param fallbackLimitBytes to return if the CarrierConfig can't be read.
- * @return limitBytes to use in the mobile NetworkPolicy.
+ * @return limitBytes to use in the carrier NetworkPolicy.
*/
@VisibleForTesting
long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
@@ -1824,8 +1833,8 @@
synchronized (mNetworkPoliciesSecondLock) {
final String subscriberId = mSubIdToSubscriberId.get(subId, null);
if (subscriberId != null) {
- ensureActiveMobilePolicyAL(subId, subscriberId);
- maybeUpdateMobilePolicyCycleAL(subId, subscriberId);
+ ensureActiveCarrierPolicyAL(subId, subscriberId);
+ maybeUpdateCarrierPolicyCycleAL(subId, subscriberId);
} else {
Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
}
@@ -1911,10 +1920,12 @@
// TODO: reach into ConnectivityManager to proactively disable bringing
// up this network, since we know that traffic will be blocked.
- if (template.getMatchRule() == MATCH_MOBILE) {
- // If mobile data usage hits the limit or if the user resumes the data, we need to
+ if (template.getMatchRule() == MATCH_MOBILE
+ || template.getMatchRule() == MATCH_CARRIER) {
+ // If carrier data usage hits the limit or if the user resumes the data, we need to
// notify telephony.
+ // TODO: It needs to check if it matches the merged WIFI and notify to wifi module.
final IntArray matchingSubIds = new IntArray();
synchronized (mNetworkPoliciesSecondLock) {
for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
@@ -2174,7 +2185,7 @@
.truncatedTo(ChronoUnit.DAYS)
.toInstant().toEpochMilli();
final long totalBytes = getTotalBytes(
- NetworkTemplate.buildTemplateMobileAll(snapshot.getSubscriberId()),
+ buildTemplateCarrierMetered(snapshot.getSubscriberId()),
start, startOfDay);
final long remainingBytes = limitBytes - totalBytes;
// Number of remaining days including current day
@@ -2200,31 +2211,31 @@
/**
* Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
- * have at least a default mobile policy defined.
+ * have at least a default carrier policy defined.
*/
@GuardedBy("mNetworkPoliciesSecondLock")
- private void ensureActiveMobilePolicyAL() {
- if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyAL()");
+ private void ensureActiveCarrierPolicyAL() {
+ if (LOGV) Slog.v(TAG, "ensureActiveCarrierPolicyAL()");
if (mSuppressDefaultPolicy) return;
for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
final int subId = mSubIdToSubscriberId.keyAt(i);
final String subscriberId = mSubIdToSubscriberId.valueAt(i);
- ensureActiveMobilePolicyAL(subId, subscriberId);
+ ensureActiveCarrierPolicyAL(subId, subscriberId);
}
}
/**
* Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
- * have at least a default mobile policy defined.
+ * have at least a default carrier policy defined.
*
* @param subId to build a default policy for
* @param subscriberId that we check for an existing policy
- * @return true if a mobile network policy was added, or false one already existed.
+ * @return true if a carrier network policy was added, or false one already existed.
*/
@GuardedBy("mNetworkPoliciesSecondLock")
- private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) {
+ private boolean ensureActiveCarrierPolicyAL(int subId, String subscriberId) {
// Poke around to see if we already have a policy
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true,
@@ -2243,7 +2254,7 @@
Slog.i(TAG, "No policy for subscriber "
+ NetworkIdentityUtils.scrubSubscriberId(subscriberId)
+ "; generating default policy");
- final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId);
+ final NetworkPolicy policy = buildDefaultCarrierPolicy(subId, subscriberId);
addNetworkPolicyAL(policy);
return true;
}
@@ -2263,8 +2274,8 @@
}
@VisibleForTesting
- NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) {
- final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
+ NetworkPolicy buildDefaultCarrierPolicy(int subId, String subscriberId) {
+ final NetworkTemplate template = buildTemplateCarrierMetered(subscriberId);
final RecurrenceRule cycleRule = NetworkPolicy
.buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault());
final NetworkPolicy policy = new NetworkPolicy(template, cycleRule,
@@ -2272,7 +2283,7 @@
SNOOZE_NEVER, SNOOZE_NEVER, true, true);
synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) {
- updateDefaultMobilePolicyAL(subId, policy);
+ updateDefaultCarrierPolicyAL(subId, policy);
}
}
return policy;
@@ -2286,7 +2297,7 @@
* @return if the policy was modified
*/
@GuardedBy("mNetworkPoliciesSecondLock")
- private boolean updateDefaultMobilePolicyAL(int subId, NetworkPolicy policy) {
+ private boolean updateDefaultCarrierPolicyAL(int subId, NetworkPolicy policy) {
if (!policy.inferred) {
if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy);
return false;
@@ -2372,14 +2383,33 @@
mLoadedRestrictBackground = (version >= VERSION_ADDED_RESTRICT_BACKGROUND)
&& readBooleanAttribute(in, ATTR_RESTRICT_BACKGROUND);
} else if (TAG_NETWORK_POLICY.equals(tag)) {
- final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
+ int templateType = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
final String networkId;
+ final int subscriberIdMatchRule;
+ final int templateMeteredness;
if (version >= VERSION_ADDED_NETWORK_ID) {
networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
} else {
networkId = null;
}
+
+ if (version >= VERSION_SUPPORTED_CARRIER_USAGE) {
+ subscriberIdMatchRule = readIntAttribute(in,
+ ATTR_SUBSCRIBER_ID_MATCH_RULE);
+ templateMeteredness = readIntAttribute(in, ATTR_TEMPLATE_METERED);
+
+ } else {
+ subscriberIdMatchRule = NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT;
+ if (templateType == MATCH_MOBILE) {
+ Log.d(TAG, "Update template match rule from mobile to carrier and"
+ + " force to metered");
+ templateType = MATCH_CARRIER;
+ templateMeteredness = METERED_YES;
+ } else {
+ templateMeteredness = METERED_ALL;
+ }
+ }
final RecurrenceRule cycleRule;
if (version >= VERSION_ADDED_CYCLE) {
final String start = readStringAttribute(in, ATTR_CYCLE_START);
@@ -2413,7 +2443,7 @@
if (version >= VERSION_ADDED_METERED) {
metered = readBooleanAttribute(in, ATTR_METERED);
} else {
- switch (networkTemplate) {
+ switch (templateType) {
case MATCH_MOBILE:
metered = true;
break;
@@ -2433,9 +2463,11 @@
} else {
inferred = false;
}
-
- final NetworkTemplate template = new NetworkTemplate(networkTemplate,
- subscriberId, networkId);
+ final NetworkTemplate template = new NetworkTemplate(templateType,
+ subscriberId, new String[] { subscriberId },
+ networkId, templateMeteredness, NetworkStats.ROAMING_ALL,
+ NetworkStats.DEFAULT_NETWORK_ALL, NetworkTemplate.NETWORK_TYPE_ALL,
+ NetworkTemplate.OEM_MANAGED_ALL, subscriberIdMatchRule);
if (template.isPersistable()) {
mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule,
warningBytes, limitBytes, lastWarningSnooze,
@@ -2642,10 +2674,14 @@
if (subscriberId != null) {
out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
}
+ writeIntAttribute(out, ATTR_SUBSCRIBER_ID_MATCH_RULE,
+ template.getSubscriberIdMatchRule());
final String networkId = template.getNetworkId();
if (networkId != null) {
out.attribute(null, ATTR_NETWORK_ID, networkId);
}
+ writeIntAttribute(out, ATTR_TEMPLATE_METERED,
+ template.getMeteredness());
writeStringAttribute(out, ATTR_CYCLE_START,
RecurrenceRule.convertZonedDateTime(policy.cycleRule.start));
writeStringAttribute(out, ATTR_CYCLE_END,
@@ -3513,8 +3549,8 @@
final String subscriberId = mSubIdToSubscriberId.get(subId, null);
if (subscriberId != null) {
- ensureActiveMobilePolicyAL(subId, subscriberId);
- maybeUpdateMobilePolicyCycleAL(subId, subscriberId);
+ ensureActiveCarrierPolicyAL(subId, subscriberId);
+ maybeUpdateCarrierPolicyCycleAL(subId, subscriberId);
} else {
Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
}
@@ -5575,11 +5611,15 @@
return;
}
- // Turn mobile data limit off
+ // Turn carrier/mobile data limit off
NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
- NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
+ NetworkTemplate templateCarrier = buildTemplateCarrierMetered(subscriber);
+ NetworkTemplate templateMobile = buildTemplateMobileAll(subscriber);
for (NetworkPolicy policy : policies) {
- if (policy.template.equals(template)) {
+ // All policies loaded from disk will be carrier templates, and setting will also only
+ // set carrier templates, but we clear mobile templates just in case one is set by
+ // some other caller
+ if (policy.template.equals(templateCarrier) || policy.template.equals(templateMobile)) {
policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
policy.inferred = false;
policy.clearSnooze();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 28c64f8..e24c4af 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -6579,15 +6579,14 @@
}
// bubble or inline reply that's immutable?
- // TODO (b/171418004): renable after app outreach
- /*if (n.getBubbleMetadata() != null
+ if (n.getBubbleMetadata() != null
&& n.getBubbleMetadata().getIntent() != null
&& hasFlag(mAmi.getPendingIntentFlags(
n.getBubbleMetadata().getIntent().getTarget()),
PendingIntent.FLAG_IMMUTABLE)) {
throw new IllegalArgumentException(r.getKey() + " Not posted."
+ " PendingIntents attached to bubbles must be mutable");
- }*/
+ }
if (n.actions != null) {
for (Notification.Action action : n.actions) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2f8ba6d..6a399bd 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -341,6 +341,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
+import com.android.internal.content.F2fsUtils;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
import com.android.internal.content.om.OverlayConfig;
@@ -896,6 +897,20 @@
* Only non-null during an OTA, and even then it is nulled again once systemReady().
*/
private @Nullable ArraySet<String> mExistingPackages = null;
+
+ /**
+ * List of code paths that need to be released when the system becomes ready.
+ * <p>
+ * NOTE: We have to delay releasing cblocks for no other reason than we cannot
+ * retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}. When
+ * we no longer need to read that setting, cblock release can occur in the
+ * constructor.
+ *
+ * @see Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL
+ * @see #systemReady()
+ */
+ private @Nullable List<File> mReleaseOnSystemReady;
+
/**
* Whether or not system app permissions should be promoted from install to runtime.
*/
@@ -1413,8 +1428,8 @@
mStaticLibsByDeclaringPackage = new WatchedArrayMap<>();
private final SnapshotCache<WatchedArrayMap<String, WatchedLongSparseArray<SharedLibraryInfo>>>
mStaticLibsByDeclaringPackageSnapshot =
- new SnapshotCache.Auto<>(mSharedLibraries, mSharedLibraries,
- "PackageManagerService.mSharedLibraries");
+ new SnapshotCache.Auto<>(mStaticLibsByDeclaringPackage, mStaticLibsByDeclaringPackage,
+ "PackageManagerService.mStaticLibsByDeclaringPackage");
// Mapping from instrumentation class names to info about them.
@Watched
@@ -7907,6 +7922,21 @@
IoUtils.closeQuietly(handle);
}
}
+ if (ret == PackageManager.INSTALL_SUCCEEDED) {
+ // NOTE: During boot, we have to delay releasing cblocks for no other reason than
+ // we cannot retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}.
+ // When we no longer need to read that setting, cblock release can occur always
+ // occur here directly
+ if (!mSystemReady) {
+ if (mReleaseOnSystemReady == null) {
+ mReleaseOnSystemReady = new ArrayList<>();
+ }
+ mReleaseOnSystemReady.add(dstCodePath);
+ } else {
+ final ContentResolver resolver = mContext.getContentResolver();
+ F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
+ }
+ }
if (ret != PackageManager.INSTALL_SUCCEEDED) {
if (!dstCodePath.exists()) {
return null;
@@ -13224,9 +13254,8 @@
if (!sharedLibraryInfo.isStatic()) {
continue;
}
- final PackageSetting staticLibPkgSetting = getPackageSetting(
- toStaticSharedLibraryPackageName(sharedLibraryInfo.getName(),
- sharedLibraryInfo.getLongVersion()));
+ final PackageSetting staticLibPkgSetting =
+ getPackageSetting(sharedLibraryInfo.getPackageName());
if (staticLibPkgSetting == null) {
Slog.wtf(TAG, "Shared lib without setting: " + sharedLibraryInfo);
continue;
@@ -17778,6 +17807,10 @@
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
mRet = args.copyApk();
}
+ if (mRet == PackageManager.INSTALL_SUCCEEDED) {
+ F2fsUtils.releaseCompressedBlocks(
+ mContext.getContentResolver(), new File(args.getCodePath()));
+ }
if (mParentInstallParams != null) {
mParentInstallParams.tryProcessInstallRequest(args, mRet);
} else {
@@ -17785,7 +17818,6 @@
processInstallRequestsAsync(
res.returnCode == PackageManager.INSTALL_SUCCEEDED,
Collections.singletonList(new InstallRequest(args, res)));
-
}
}
}
@@ -22726,7 +22758,8 @@
*/
public int getPreferredActivitiesInternal(List<WatchedIntentFilter> outFilters,
List<ComponentName> outActivities, String packageName) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return 0;
}
int num = 0;
@@ -22738,9 +22771,13 @@
final Iterator<PreferredActivity> it = pir.filterIterator();
while (it.hasNext()) {
final PreferredActivity pa = it.next();
+ final String prefPackageName = pa.mPref.mComponent.getPackageName();
if (packageName == null
- || (pa.mPref.mComponent.getPackageName().equals(packageName)
- && pa.mPref.mAlways)) {
+ || (prefPackageName.equals(packageName) && pa.mPref.mAlways)) {
+ if (shouldFilterApplicationLocked(
+ mSettings.getPackageLPr(prefPackageName), callingUid, userId)) {
+ continue;
+ }
if (outFilters != null) {
outFilters.add(new WatchedIntentFilter(pa.getIntentFilter()));
}
@@ -24120,8 +24157,15 @@
public void systemReady() {
enforceSystemOrRoot("Only the system can claim the system is ready");
- mSystemReady = true;
final ContentResolver resolver = mContext.getContentResolver();
+ if (mReleaseOnSystemReady != null) {
+ for (int i = mReleaseOnSystemReady.size() - 1; i >= 0; --i) {
+ final File dstCodePath = mReleaseOnSystemReady.get(i);
+ F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
+ }
+ mReleaseOnSystemReady = null;
+ }
+ mSystemReady = true;
ContentObserver co = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
diff --git a/services/core/java/com/android/server/power/FaceDownDetector.java b/services/core/java/com/android/server/power/FaceDownDetector.java
index 816c81d..b237ca2 100644
--- a/services/core/java/com/android/server/power/FaceDownDetector.java
+++ b/services/core/java/com/android/server/power/FaceDownDetector.java
@@ -77,6 +77,8 @@
private boolean mIsEnabled;
+ private int mSensorMaxLatencyMicros;
+
/**
* DeviceConfig flag name, determines how long to disable sensor when user interacts while
* device is flipped.
@@ -202,7 +204,11 @@
if (mActive != shouldBeActive) {
if (shouldBeActive) {
mSensorManager.registerListener(
- this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
+ this,
+ mAccelerometer,
+ SensorManager.SENSOR_DELAY_NORMAL,
+ mSensorMaxLatencyMicros
+ );
if (mPreviousResultType == SCREEN_OFF_RESULT) {
logScreenOff();
}
@@ -226,6 +232,7 @@
pw.println(" mFaceDown=" + mFaceDown);
pw.println(" mActive=" + mActive);
pw.println(" mLastFlipTime=" + mLastFlipTime);
+ pw.println(" mSensorMaxLatencyMicros=" + mSensorMaxLatencyMicros);
pw.println(" mUserInteractionBackoffMillis=" + mUserInteractionBackoffMillis);
pw.println(" mPreviousResultTime=" + mPreviousResultTime);
pw.println(" mPreviousResultType=" + mPreviousResultType);
@@ -356,6 +363,11 @@
3600_000);
}
+ private int getSensorMaxLatencyMicros() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_flipToScreenOffMaxLatencyMicros);
+ }
+
private float getFloatFlagValue(String key, float defaultValue, float min, float max) {
final float value = DeviceConfig.getFloat(NAMESPACE_ATTENTION_MANAGER_SERVICE,
key,
@@ -416,6 +428,7 @@
mZAccelerationThreshold = getZAccelerationThreshold();
mZAccelerationThresholdLenient = mZAccelerationThreshold + 1.0f;
mTimeThreshold = getTimeThreshold();
+ mSensorMaxLatencyMicros = getSensorMaxLatencyMicros();
mUserInteractionBackoffMillis = getUserInteractionBackoffMillis();
final boolean oldEnabled = mIsEnabled;
mIsEnabled = isEnabled();
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 753b42b..0f37450 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -25,6 +25,8 @@
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Binder;
@@ -59,6 +61,7 @@
import android.view.textclassifier.TextSelection;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.content.PackageMonitor;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FunctionalUtils;
import com.android.internal.util.FunctionalUtils.ThrowingConsumer;
@@ -110,6 +113,7 @@
try {
publishBinderService(Context.TEXT_CLASSIFICATION_SERVICE, mManagerService);
mManagerService.startListenSettings();
+ mManagerService.startTrackingPackageChanges();
} catch (Throwable t) {
// Starting this service is not critical to the running of this device and should
// therefore not crash the device. If it fails, log the error and continue.
@@ -119,11 +123,14 @@
@Override
public void onUserStarting(@NonNull TargetUser user) {
+ updatePackageStateForUser(user.getUserIdentifier());
processAnyPendingWork(user.getUserIdentifier());
}
@Override
public void onUserUnlocking(@NonNull TargetUser user) {
+ // refresh if we failed earlier due to locked encrypted user
+ updatePackageStateForUser(user.getUserIdentifier());
// Rebind if we failed earlier due to locked encrypted user
processAnyPendingWork(user.getUserIdentifier());
}
@@ -134,6 +141,14 @@
}
}
+ private void updatePackageStateForUser(int userId) {
+ synchronized (mManagerService.mLock) {
+ // Update the cached disable status, the TextClassfier may not be direct boot aware,
+ // we should update the disable status after user unlock
+ mManagerService.getUserStateLocked(userId).updatePackageStateLocked();
+ }
+ }
+
@Override
public void onUserStopping(@NonNull TargetUser user) {
int userId = user.getUserIdentifier();
@@ -160,6 +175,8 @@
private final String mDefaultTextClassifierPackage;
@Nullable
private final String mSystemTextClassifierPackage;
+ // TODO: consider using device config to control it.
+ private boolean DEBUG = false;
private TextClassificationManagerService(Context context) {
mContext = Objects.requireNonNull(context);
@@ -176,6 +193,46 @@
mSettingsListener.registerObserver();
}
+ void startTrackingPackageChanges() {
+ final PackageMonitor monitor = new PackageMonitor() {
+
+ @Override
+ public void onPackageAdded(String packageName, int uid) {
+ notifyPackageInstallStatusChange(packageName, /* installed*/ true);
+ }
+
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ notifyPackageInstallStatusChange(packageName, /* installed= */ false);
+ }
+
+ @Override
+ public void onPackageModified(String packageName) {
+ final int userId = getChangingUserId();
+ synchronized (mLock) {
+ final UserState userState = getUserStateLocked(userId);
+ final ServiceState serviceState = userState.getServiceStateLocked(packageName);
+ if (serviceState != null) {
+ serviceState.onPackageModifiedLocked();
+ }
+ }
+ }
+
+ private void notifyPackageInstallStatusChange(String packageName, boolean installed) {
+ final int userId = getChangingUserId();
+ synchronized (mLock) {
+ final UserState userState = getUserStateLocked(userId);
+ final ServiceState serviceState = userState.getServiceStateLocked(packageName);
+ if (serviceState != null) {
+ serviceState.onPackageInstallStatusChangeLocked(installed);
+ }
+ }
+ }
+ };
+
+ monitor.register(mContext, null, UserHandle.ALL, true);
+ }
+
@Override
public void onConnectedStateChanged(@ConnectionState int connected) {
}
@@ -452,6 +509,14 @@
if (serviceState == null) {
Slog.d(LOG_TAG, "No configured system TextClassifierService");
callback.onFailure();
+ } else if (!serviceState.isInstalledLocked() || !serviceState.isEnabledLocked()) {
+ if (DEBUG) {
+ Slog.d(LOG_TAG,
+ serviceState.mPackageName + " is not available in user " + userId
+ + ". Installed: " + serviceState.isInstalledLocked()
+ + ", enabled:" + serviceState.isEnabledLocked());
+ }
+ callback.onFailure();
} else if (attemptToBind && !serviceState.bindLocked()) {
Slog.d(LOG_TAG, "Unable to bind TextClassifierService at " + methodName);
callback.onFailure();
@@ -761,6 +826,24 @@
return serviceStates;
}
+ @GuardedBy("mLock")
+ @Nullable
+ private ServiceState getServiceStateLocked(String packageName) {
+ for (ServiceState serviceState : getAllServiceStatesLocked()) {
+ if (serviceState.mPackageName.equals(packageName)) {
+ return serviceState;
+ }
+ }
+ return null;
+ }
+
+ @GuardedBy("mLock")
+ private void updatePackageStateLocked() {
+ for (ServiceState serviceState : getAllServiceStatesLocked()) {
+ serviceState.updatePackageStateLocked();
+ }
+ }
+
void dump(IndentingPrintWriter pw) {
synchronized (mLock) {
pw.increaseIndent();
@@ -814,6 +897,10 @@
ComponentName mBoundComponentName = null;
@GuardedBy("mLock")
int mBoundServiceUid = Process.INVALID_UID;
+ @GuardedBy("mLock")
+ boolean mInstalled;
+ @GuardedBy("mLock")
+ boolean mEnabled;
private ServiceState(
@UserIdInt int userId, @NonNull String packageName, boolean isTrusted) {
@@ -822,6 +909,8 @@
mConnection = new TextClassifierServiceConnection(mUserId);
mIsTrusted = isTrusted;
mBindServiceFlags = createBindServiceFlags(packageName);
+ mInstalled = isPackageInstalledForUser();
+ mEnabled = isServiceEnabledForUser();
}
@Context.BindServiceFlags
@@ -833,6 +922,54 @@
return flags;
}
+ private boolean isPackageInstalledForUser() {
+ try {
+ PackageManager packageManager = mContext.getPackageManager();
+ return packageManager.getPackageInfoAsUser(mPackageName, 0, mUserId) != null;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ private boolean isServiceEnabledForUser() {
+ PackageManager packageManager = mContext.getPackageManager();
+ Intent intent = new Intent(TextClassifierService.SERVICE_INTERFACE);
+ intent.setPackage(mPackageName);
+ ResolveInfo resolveInfo = packageManager.resolveServiceAsUser(intent,
+ PackageManager.GET_SERVICES, mUserId);
+ ServiceInfo serviceInfo = resolveInfo == null ? null : resolveInfo.serviceInfo;
+ return serviceInfo != null;
+ }
+
+ @GuardedBy("mLock")
+ @NonNull
+ private void onPackageInstallStatusChangeLocked(boolean installed) {
+ mInstalled = installed;
+ }
+
+ @GuardedBy("mLock")
+ @NonNull
+ private void onPackageModifiedLocked() {
+ mEnabled = isServiceEnabledForUser();
+ }
+
+ @GuardedBy("mLock")
+ @NonNull
+ private void updatePackageStateLocked() {
+ mInstalled = isPackageInstalledForUser();
+ mEnabled = isServiceEnabledForUser();
+ }
+
+ @GuardedBy("mLock")
+ boolean isInstalledLocked() {
+ return mInstalled;
+ }
+
+ @GuardedBy("mLock")
+ boolean isEnabledLocked() {
+ return mEnabled;
+ }
+
@GuardedBy("mLock")
boolean isBoundLocked() {
return mService != null;
@@ -923,6 +1060,8 @@
pw.printPair("userId", mUserId);
synchronized (mLock) {
pw.printPair("packageName", mPackageName);
+ pw.printPair("installed", mInstalled);
+ pw.printPair("enabled", mEnabled);
pw.printPair("boundComponentName", mBoundComponentName);
pw.printPair("isTrusted", mIsTrusted);
pw.printPair("bindServiceFlags", mBindServiceFlags);
diff --git a/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java b/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java
new file mode 100644
index 0000000..0690d3b
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/ClippingAmplitudeAndFrequencyAdapter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.vibrator;
+
+import android.os.VibratorInfo;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.MathUtils;
+
+import java.util.List;
+
+/**
+ * Adapter that clips frequency values to {@link VibratorInfo#getFrequencyRange()} and
+ * amplitude values to respective {@link VibratorInfo#getMaxAmplitude}.
+ *
+ * <p>Devices with no frequency control will collapse all frequencies to zero and leave
+ * amplitudes unchanged.
+ *
+ * <p>The frequency value returned in segments will be absolute, converted with
+ * {@link VibratorInfo#getAbsoluteFrequency(float)}.
+ */
+final class ClippingAmplitudeAndFrequencyAdapter
+ implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> {
+
+ @Override
+ public int apply(List<VibrationEffectSegment> segments, int repeatIndex, VibratorInfo info) {
+ int segmentCount = segments.size();
+ for (int i = 0; i < segmentCount; i++) {
+ VibrationEffectSegment segment = segments.get(i);
+ if (segment instanceof StepSegment) {
+ segments.set(i, apply((StepSegment) segment, info));
+ } else if (segment instanceof RampSegment) {
+ segments.set(i, apply((RampSegment) segment, info));
+ }
+ }
+ return repeatIndex;
+ }
+
+ private StepSegment apply(StepSegment segment, VibratorInfo info) {
+ float clampedFrequency = clampFrequency(info, segment.getFrequency());
+ return new StepSegment(
+ clampAmplitude(info, clampedFrequency, segment.getAmplitude()),
+ info.getAbsoluteFrequency(clampedFrequency),
+ (int) segment.getDuration());
+ }
+
+ private RampSegment apply(RampSegment segment, VibratorInfo info) {
+ float clampedStartFrequency = clampFrequency(info, segment.getStartFrequency());
+ float clampedEndFrequency = clampFrequency(info, segment.getEndFrequency());
+ return new RampSegment(
+ clampAmplitude(info, clampedStartFrequency, segment.getStartAmplitude()),
+ clampAmplitude(info, clampedEndFrequency, segment.getEndAmplitude()),
+ info.getAbsoluteFrequency(clampedStartFrequency),
+ info.getAbsoluteFrequency(clampedEndFrequency),
+ (int) segment.getDuration());
+ }
+
+ private float clampFrequency(VibratorInfo info, float frequency) {
+ return info.getFrequencyRange().clamp(frequency);
+ }
+
+ private float clampAmplitude(VibratorInfo info, float frequency, float amplitude) {
+ return MathUtils.min(amplitude, info.getMaxAmplitude(frequency));
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
index 7f2b07b..b695150 100644
--- a/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
+++ b/services/core/java/com/android/server/vibrator/DeviceVibrationEffectAdapter.java
@@ -16,159 +16,33 @@
package com.android.server.vibrator;
-import android.hardware.vibrator.IVibrator;
import android.os.VibrationEffect;
import android.os.VibratorInfo;
-import android.os.vibrator.RampSegment;
-import android.os.vibrator.StepSegment;
-import android.os.vibrator.VibrationEffectSegment;
-import android.util.MathUtils;
-import android.util.Range;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/** Adapts a {@link VibrationEffect} to a specific device, taking into account its capabilities. */
-final class DeviceVibrationEffectAdapter implements VibrationEffectModifier<VibratorInfo> {
+final class DeviceVibrationEffectAdapter
+ implements VibrationEffectAdapters.EffectAdapter<VibratorInfo> {
- /** Adapts a sequence of {@link VibrationEffectSegment} to device's capabilities. */
- interface SegmentsAdapter {
+ /** Duration of each step created to simulate a ramp segment. */
+ private static final int RAMP_STEP_DURATION_MILLIS = 5;
- /**
- * Modifies the given segments list by adding/removing segments to it based on the
- * device capabilities specified by given {@link VibratorInfo}.
- *
- * @param segments List of {@link VibrationEffectSegment} to be adapter to the device.
- * @param repeatIndex Repeat index on the current segment list.
- * @param info The device vibrator info that the segments must be adapted to.
- * @return The new repeat index on the modifies list.
- */
- int apply(List<VibrationEffectSegment> segments, int repeatIndex, VibratorInfo info);
- }
-
- private final SegmentsAdapter mAmplitudeFrequencyAdapter;
- private final SegmentsAdapter mStepToRampAdapter;
+ private final List<VibrationEffectAdapters.SegmentsAdapter<VibratorInfo>> mSegmentAdapters;
DeviceVibrationEffectAdapter() {
- this(new ClippingAmplitudeFrequencyAdapter());
- }
-
- DeviceVibrationEffectAdapter(SegmentsAdapter amplitudeFrequencyAdapter) {
- mAmplitudeFrequencyAdapter = amplitudeFrequencyAdapter;
- mStepToRampAdapter = new StepToRampAdapter();
+ mSegmentAdapters = Arrays.asList(
+ // TODO(b/167947076): add filter that removes unsupported primitives
+ // TODO(b/167947076): add filter that replaces unsupported prebaked with fallback
+ new RampToStepAdapter(RAMP_STEP_DURATION_MILLIS),
+ new StepToRampAdapter(),
+ new ClippingAmplitudeAndFrequencyAdapter()
+ );
}
@Override
public VibrationEffect apply(VibrationEffect effect, VibratorInfo info) {
- if (!(effect instanceof VibrationEffect.Composed)) {
- return effect;
- }
-
- VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
- List<VibrationEffectSegment> newSegments = new ArrayList<>(composed.getSegments());
- int newRepeatIndex = composed.getRepeatIndex();
-
- // Maps steps that should be handled by PWLE to ramps.
- // This should be done before frequency is converted from relative to absolute values.
- newRepeatIndex = mStepToRampAdapter.apply(newSegments, newRepeatIndex, info);
-
- // Adapt amplitude and frequency values to device supported ones, converting frequency
- // to absolute values in Hertz.
- newRepeatIndex = mAmplitudeFrequencyAdapter.apply(newSegments, newRepeatIndex, info);
-
- // TODO(b/167947076): add ramp to step adapter
- // TODO(b/167947076): add filter that removes unsupported primitives
- // TODO(b/167947076): add filter that replaces unsupported prebaked with fallback
-
- return new VibrationEffect.Composed(newSegments, newRepeatIndex);
- }
-
- /**
- * Adapter that converts step segments that should be handled as PWLEs to ramp segments.
- *
- * <p>This leves the list unchanged if the device do not have compose PWLE capability.
- */
- private static final class StepToRampAdapter implements SegmentsAdapter {
- @Override
- public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
- VibratorInfo info) {
- if (!info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) {
- // The vibrator do not have PWLE capability, so keep the segments unchanged.
- return repeatIndex;
- }
- int segmentCount = segments.size();
- // Convert steps that require frequency control to ramps.
- for (int i = 0; i < segmentCount; i++) {
- VibrationEffectSegment segment = segments.get(i);
- if ((segment instanceof StepSegment)
- && ((StepSegment) segment).getFrequency() != 0) {
- segments.set(i, apply((StepSegment) segment));
- }
- }
- // Convert steps that are next to ramps to also become ramps, so they can be composed
- // together in the same PWLE waveform.
- for (int i = 1; i < segmentCount; i++) {
- if (segments.get(i) instanceof RampSegment) {
- for (int j = i - 1; j >= 0 && (segments.get(j) instanceof StepSegment); j--) {
- segments.set(j, apply((StepSegment) segments.get(j)));
- }
- }
- }
- return repeatIndex;
- }
-
- private RampSegment apply(StepSegment segment) {
- return new RampSegment(segment.getAmplitude(), segment.getAmplitude(),
- segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration());
- }
- }
-
- /**
- * Adapter that clips frequency values to {@link VibratorInfo#getFrequencyRange()} and
- * amplitude values to respective {@link VibratorInfo#getMaxAmplitude}.
- *
- * <p>Devices with no frequency control will collapse all frequencies to zero and leave
- * amplitudes unchanged.
- *
- * <p>The frequency value returned in segments will be absolute, conveted with
- * {@link VibratorInfo#getAbsoluteFrequency(float)}.
- */
- private static final class ClippingAmplitudeFrequencyAdapter implements SegmentsAdapter {
- @Override
- public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
- VibratorInfo info) {
- int segmentCount = segments.size();
- for (int i = 0; i < segmentCount; i++) {
- VibrationEffectSegment segment = segments.get(i);
- if (segment instanceof StepSegment) {
- segments.set(i, apply((StepSegment) segment, info));
- } else if (segment instanceof RampSegment) {
- segments.set(i, apply((RampSegment) segment, info));
- }
- }
- return repeatIndex;
- }
-
- private StepSegment apply(StepSegment segment, VibratorInfo info) {
- float clampedFrequency = info.getFrequencyRange().clamp(segment.getFrequency());
- return new StepSegment(
- MathUtils.min(segment.getAmplitude(), info.getMaxAmplitude(clampedFrequency)),
- info.getAbsoluteFrequency(clampedFrequency),
- (int) segment.getDuration());
- }
-
- private RampSegment apply(RampSegment segment, VibratorInfo info) {
- Range<Float> frequencyRange = info.getFrequencyRange();
- float clampedStartFrequency = frequencyRange.clamp(segment.getStartFrequency());
- float clampedEndFrequency = frequencyRange.clamp(segment.getEndFrequency());
- return new RampSegment(
- MathUtils.min(segment.getStartAmplitude(),
- info.getMaxAmplitude(clampedStartFrequency)),
- MathUtils.min(segment.getEndAmplitude(),
- info.getMaxAmplitude(clampedEndFrequency)),
- info.getAbsoluteFrequency(clampedStartFrequency),
- info.getAbsoluteFrequency(clampedEndFrequency),
- (int) segment.getDuration());
- }
+ return VibrationEffectAdapters.apply(effect, mSegmentAdapters, info);
}
}
diff --git a/services/core/java/com/android/server/vibrator/RampToStepAdapter.java b/services/core/java/com/android/server/vibrator/RampToStepAdapter.java
new file mode 100644
index 0000000..1e05bdb
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/RampToStepAdapter.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2021 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.vibrator;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.VibratorInfo;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Adapter that converts ramp segments that to a sequence of fixed step segments.
+ *
+ * <p>This leaves the list unchanged if the device have compose PWLE capability.
+ */
+final class RampToStepAdapter implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> {
+
+ private final int mStepDuration;
+
+ RampToStepAdapter(int stepDuration) {
+ mStepDuration = stepDuration;
+ }
+
+ @Override
+ public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
+ VibratorInfo info) {
+ if (info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) {
+ // The vibrator have PWLE capability, so keep the segments unchanged.
+ return repeatIndex;
+ }
+ int segmentCount = segments.size();
+ for (int i = 0; i < segmentCount; i++) {
+ VibrationEffectSegment segment = segments.get(i);
+ if (!(segment instanceof RampSegment)) {
+ continue;
+ }
+ List<StepSegment> steps = apply((RampSegment) segment);
+ segments.remove(i);
+ segments.addAll(i, steps);
+ int addedSegments = steps.size() - 1;
+ if (repeatIndex > i) {
+ repeatIndex += addedSegments;
+ }
+ i += addedSegments;
+ segmentCount += addedSegments;
+ }
+ return repeatIndex;
+ }
+
+ private List<StepSegment> apply(RampSegment ramp) {
+ if (Float.compare(ramp.getStartAmplitude(), ramp.getEndAmplitude()) == 0) {
+ // Amplitude is the same, so return a single step to simulate this ramp.
+ return Arrays.asList(
+ new StepSegment(ramp.getStartAmplitude(), ramp.getStartFrequency(),
+ (int) ramp.getDuration()));
+ }
+
+ List<StepSegment> steps = new ArrayList<>();
+ int stepCount = (int) (ramp.getDuration() + mStepDuration - 1) / mStepDuration;
+ for (int i = 0; i < stepCount - 1; i++) {
+ float pos = (float) i / stepCount;
+ steps.add(new StepSegment(
+ interpolate(ramp.getStartAmplitude(), ramp.getEndAmplitude(), pos),
+ interpolate(ramp.getStartFrequency(), ramp.getEndFrequency(), pos),
+ mStepDuration));
+ }
+ int duration = (int) ramp.getDuration() - mStepDuration * (stepCount - 1);
+ steps.add(new StepSegment(ramp.getEndAmplitude(), ramp.getEndFrequency(), duration));
+ return steps;
+ }
+
+ private static float interpolate(float start, float end, float position) {
+ return start + position * (end - start);
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
new file mode 100644
index 0000000..f78df92
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 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.vibrator;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.VibratorInfo;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+
+import java.util.List;
+
+/**
+ * Adapter that converts step segments that should be handled as PWLEs to ramp segments.
+ *
+ * <p>This leaves the list unchanged if the device do not have compose PWLE capability.
+ */
+final class StepToRampAdapter implements VibrationEffectAdapters.SegmentsAdapter<VibratorInfo> {
+ @Override
+ public int apply(List<VibrationEffectSegment> segments, int repeatIndex,
+ VibratorInfo info) {
+ if (!info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS)) {
+ // The vibrator do not have PWLE capability, so keep the segments unchanged.
+ return repeatIndex;
+ }
+ int segmentCount = segments.size();
+ // Convert steps that require frequency control to ramps.
+ for (int i = 0; i < segmentCount; i++) {
+ VibrationEffectSegment segment = segments.get(i);
+ if ((segment instanceof StepSegment)
+ && ((StepSegment) segment).getFrequency() != 0) {
+ segments.set(i, apply((StepSegment) segment));
+ }
+ }
+ // Convert steps that are next to ramps to also become ramps, so they can be composed
+ // together in the same PWLE waveform.
+ for (int i = 1; i < segmentCount; i++) {
+ if (segments.get(i) instanceof RampSegment) {
+ for (int j = i - 1; j >= 0 && (segments.get(j) instanceof StepSegment); j--) {
+ segments.set(j, apply((StepSegment) segments.get(j)));
+ }
+ }
+ }
+ return repeatIndex;
+ }
+
+ private RampSegment apply(StepSegment segment) {
+ return new RampSegment(segment.getAmplitude(), segment.getAmplitude(),
+ segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration());
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/VibrationEffectAdapters.java b/services/core/java/com/android/server/vibrator/VibrationEffectAdapters.java
new file mode 100644
index 0000000..446d981
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/VibrationEffectAdapters.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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.vibrator;
+
+import android.os.VibrationEffect;
+import android.os.vibrator.VibrationEffectSegment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helpers to adapt a {@link VibrationEffect} to generic modifiers (e.g. device capabilities,
+ * user settings, etc).
+ */
+public final class VibrationEffectAdapters {
+
+ /**
+ * Function that applies a generic modifier to a sequence of {@link VibrationEffectSegment}.
+ *
+ * @param <T> The type of modifiers this adapter accepts.
+ */
+ public interface SegmentsAdapter<T> {
+
+ /**
+ * Add and/or remove segments to the given {@link VibrationEffectSegment} list based on the
+ * given modifier.
+ *
+ * <p>This returns the new {@code repeatIndex} to be used together with the updated list to
+ * specify an equivalent {@link VibrationEffect}.
+ *
+ * @param segments List of {@link VibrationEffectSegment} to be modified.
+ * @param repeatIndex Repeat index on the current segment list.
+ * @param modifier The modifier to be applied to the sequence of segments.
+ * @return The new repeat index on the modifies list.
+ */
+ int apply(List<VibrationEffectSegment> segments, int repeatIndex, T modifier);
+ }
+
+ /**
+ * Function that applies a generic modifier to a {@link VibrationEffect}.
+ *
+ * @param <T> The type of modifiers this adapter accepts.
+ */
+ public interface EffectAdapter<T> {
+
+ /** Applies the modifier to given {@link VibrationEffect}, returning the new effect. */
+ VibrationEffect apply(VibrationEffect effect, T modifier);
+ }
+
+ /**
+ * Applies a sequence of {@link SegmentsAdapter} to the segments of a given
+ * {@link VibrationEffect}, in order.
+ *
+ * @param effect The effect to be adapted to given modifier.
+ * @param adapters The sequence of adapters to be applied to given {@link VibrationEffect}.
+ * @param modifier The modifier to be passed to each adapter that describes the conditions the
+ * {@link VibrationEffect} needs to be adapted to (e.g. device capabilities,
+ * user settings, etc).
+ */
+ public static <T> VibrationEffect apply(VibrationEffect effect,
+ List<SegmentsAdapter<T>> adapters, T modifier) {
+ if (!(effect instanceof VibrationEffect.Composed)) {
+ // Segments adapters can only be applied to Composed effects.
+ return effect;
+ }
+
+ VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+ List<VibrationEffectSegment> newSegments = new ArrayList<>(composed.getSegments());
+ int newRepeatIndex = composed.getRepeatIndex();
+
+ int adapterCount = adapters.size();
+ for (int i = 0; i < adapterCount; i++) {
+ newRepeatIndex = adapters.get(i).apply(newSegments, newRepeatIndex, modifier);
+ }
+
+ return new VibrationEffect.Composed(newSegments, newRepeatIndex);
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/VibrationEffectModifier.java b/services/core/java/com/android/server/vibrator/VibrationEffectModifier.java
deleted file mode 100644
index d287c8f..0000000
--- a/services/core/java/com/android/server/vibrator/VibrationEffectModifier.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2021 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.vibrator;
-
-import android.os.VibrationEffect;
-
-/** Function that applies a generic modifier to a {@link VibrationEffect}. */
-interface VibrationEffectModifier<T> {
-
- /** Applies the modifier to given {@link VibrationEffect}. */
- VibrationEffect apply(VibrationEffect effect, T modifier);
-}
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index b3f1bcd4..e3672f4 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -95,7 +95,7 @@
private final WorkSource mWorkSource = new WorkSource();
private final PowerManager.WakeLock mWakeLock;
private final IBatteryStats mBatteryStatsService;
- private final VibrationEffectModifier<VibratorInfo> mDeviceEffectAdapter =
+ private final DeviceVibrationEffectAdapter mDeviceEffectAdapter =
new DeviceVibrationEffectAdapter();
private final Vibration mVibration;
private final VibrationCallbacks mCallbacks;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3969a5f..d4df2f2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -7013,7 +7013,7 @@
// TODO(b/181207944): Consider removing the if condition and always run
// resolveFixedOrientationConfiguration() since this should be applied for all cases.
if (isFixedOrientationLetterboxAllowed) {
- resolveFixedOrientationConfiguration(newParentConfiguration);
+ resolveFixedOrientationConfiguration(newParentConfiguration, parentWindowingMode);
}
if (mCompatDisplayInsets != null) {
@@ -7160,16 +7160,21 @@
* change and the requested orientation is different from the parent.
*
* <p>If letterboxed due to fixed orientation then aspect ratio restrictions are also applied
- * in this methiod.
+ * in this method.
*/
- private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig) {
+ private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig,
+ int windowingMode) {
mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
if (handlesOrientationChangeFromDescendant()) {
// No need to letterbox because of fixed orientation. Display will handle
// fixed-orientation requests.
return;
}
- if (newParentConfig.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED) {
+ if (WindowConfiguration.inMultiWindowMode(windowingMode) && isResizeable()) {
+ // Ignore orientation request for resizable apps in multi window.
+ return;
+ }
+ if (windowingMode == WINDOWING_MODE_PINNED) {
// PiP bounds have higher priority than the requested orientation. Otherwise the
// activity may be squeezed into a small piece.
return;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 29e55df..5e75ceb 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2835,7 +2835,7 @@
List<IBinder> topActivityToken = new ArrayList<>();
topActivityToken.add(tokens.getActivityToken());
requester.requestAssistData(topActivityToken, true /* fetchData */,
- false /* fetchScreenshot */, true /* allowFetchData */,
+ false /* fetchScreenshot */, false /* fetchStructure */, true /* allowFetchData */,
false /* allowFetchScreenshot*/, true /* ignoreFocusCheck */,
Binder.getCallingUid(), callingPackageName);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 70f2d64..977df93 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1453,8 +1453,7 @@
}
void onDisplayInfoChanged(DisplayInfo info) {
- mSystemGestures.screenWidth = info.logicalWidth;
- mSystemGestures.screenHeight = info.logicalHeight;
+ mSystemGestures.onDisplayInfoChanged(info);
}
private void layoutStatusBar(DisplayFrames displayFrames, Rect contentFrame) {
diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
index f3859b4..513b1b7 100644
--- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManagerGlobal;
@@ -65,6 +66,7 @@
int screenHeight;
int screenWidth;
+ private DisplayInfo mTmpDisplayInfo = new DisplayInfo();
private int mDownPointers;
private boolean mSwipeFireable;
private boolean mDebugFireable;
@@ -75,23 +77,31 @@
mContext = checkNull("context", context);
mHandler = handler;
mCallbacks = checkNull("callbacks", callbacks);
+ onConfigurationChanged();
+ }
+ void onDisplayInfoChanged(DisplayInfo info) {
+ screenWidth = info.logicalWidth;
+ screenHeight = info.logicalHeight;
onConfigurationChanged();
}
void onConfigurationChanged() {
- mSwipeStartThreshold = mContext.getResources()
- .getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
-
+ final Resources r = mContext.getResources();
final Display display = DisplayManagerGlobal.getInstance()
.getRealDisplay(Display.DEFAULT_DISPLAY);
+ display.getDisplayInfo(mTmpDisplayInfo);
+ mSwipeStartThreshold = mTmpDisplayInfo.logicalWidth > mTmpDisplayInfo.logicalHeight
+ ? r.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height_landscape)
+ : r.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height_portrait);
+
final DisplayCutout displayCutout = display.getCutout();
if (displayCutout != null) {
final Rect bounds = displayCutout.getBoundingRectTop();
if (!bounds.isEmpty()) {
// Expand swipe start threshold such that we can catch touches that just start below
// the notch area
- mDisplayCutoutTouchableRegionSize = mContext.getResources().getDimensionPixelSize(
+ mDisplayCutoutTouchableRegionSize = r.getDimensionPixelSize(
com.android.internal.R.dimen.display_cutout_touchable_region_size);
mSwipeStartThreshold += mDisplayCutoutTouchableRegionSize;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7df5744..4a9c1bb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2329,6 +2329,17 @@
}
result |= RELAYOUT_RES_SURFACE_CHANGED;
if (!win.mWillReplaceWindow) {
+ // When FLAG_SHOW_WALLPAPER flag is removed from a window, we usually set a flag
+ // in DC#pendingLayoutChanges and update the wallpaper target later.
+ // However it's possible that FLAG_SHOW_WALLPAPER flag is removed from a window
+ // when the window is about to exit, so we update the wallpaper target
+ // immediately here. Otherwise this window will be stuck in exiting and its
+ // surface remains on the screen.
+ // TODO(b/189856716): Allow destroying surface even if it belongs to the
+ // keyguard target.
+ if (wallpaperMayMove) {
+ displayContent.mWallpaperController.adjustWallpaperWindows();
+ }
focusMayChange = tryStartExitingAnimation(win, winAnimator, focusMayChange);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5f47986..20a992d2 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1500,7 +1500,9 @@
}
boolean didFrameInsetsChange = setReportResizeHints();
- boolean configChanged = !isLastConfigReportedToClient();
+ // The latest configuration will be returned by the out parameter of relayout, so it is
+ // unnecessary to report resize if this window is running relayout.
+ final boolean configChanged = !mInRelayout && !isLastConfigReportedToClient();
if (DEBUG_CONFIGURATION && configChanged) {
Slog.v(TAG_WM, "Win " + this + " config changed: " + getConfiguration());
}
diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/network-policy-mobile.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/network-policy-mobile.xml
new file mode 100644
index 0000000..d1357e7
--- /dev/null
+++ b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/network-policy-mobile.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<policy-list version="12" restrictBackground="false">
+ <network-policy networkTemplate="1" subscriberId="466977604504520" cycleStart="2020-01-09T00:00+08:00[Asia/Taipei]" cyclePeriod="P1M" warningBytes="2147483648" limitBytes="-1" lastWarningSnooze="-1" lastLimitSnooze="-1" metered="true" inferred="true" />
+</policy-list>
+<whitelist />
+
diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/network-policy-wifi-with-subscriberId-match-rule-all-and-templateMetered-no.xml b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/network-policy-wifi-with-subscriberId-match-rule-all-and-templateMetered-no.xml
new file mode 100644
index 0000000..60d7d25
--- /dev/null
+++ b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/netpolicy/network-policy-wifi-with-subscriberId-match-rule-all-and-templateMetered-no.xml
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+<policy-list version="13" restrictBackground="false">
+<network-policy networkTemplate="4" subscriberIdMatchRule="1" networkId="TEST_SSID" templateMetered="0" cycleStart="2020-01-09T00:00+08:00[Asia/Taipei]" cyclePeriod="P1M" warningBytes="2147483648" limitBytes="-1" lastWarningSnooze="-1" lastLimitSnooze="-1" metered="true" inferred="true" />
+</policy-list>
+<whitelist />
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index da6c30e..23517a9 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -50,10 +50,12 @@
import static android.net.NetworkPolicyManager.uidRulesToString;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.METERED_NO;
+import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.TAG_ALL;
import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkTemplate.buildTemplateMobileAll;
+import static android.net.NetworkTemplate.buildTemplateCarrierMetered;
import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
@@ -231,7 +233,8 @@
private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
- private static NetworkTemplate sTemplateMobileAll = buildTemplateMobileAll(TEST_IMSI);
+ private static NetworkTemplate sTemplateCarrierMetered =
+ buildTemplateCarrierMetered(TEST_IMSI);
/**
* Path on assets where files used by {@link NetPolicyXml} are located.
@@ -452,7 +455,7 @@
verify(mNetworkManager).registerObserver(networkObserver.capture());
mNetworkObserver = networkObserver.getValue();
- NetworkPolicy defaultPolicy = mService.buildDefaultMobilePolicy(0, "");
+ NetworkPolicy defaultPolicy = mService.buildDefaultCarrierPolicy(0, "");
mDefaultWarningBytes = defaultPolicy.warningBytes;
mDefaultLimitBytes = defaultPolicy.limitBytes;
}
@@ -1231,7 +1234,7 @@
reset(mTelephonyManager, mNetworkManager, mNotifManager);
TelephonyManager tmSub = expectMobileDefaults();
- mService.snoozeLimit(NetworkTemplate.buildTemplateMobileAll(TEST_IMSI));
+ mService.snoozeLimit(NetworkTemplate.buildTemplateCarrierMetered(TEST_IMSI));
mService.updateNetworks();
verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true);
@@ -1484,7 +1487,7 @@
assertEquals(mDefaultLimitBytes, actualLimitBytes);
}
- private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException {
+ private PersistableBundle setupUpdateCarrierPolicyCycleTests() throws RemoteException {
when(mConnManager.getAllNetworkStateSnapshots())
.thenReturn(new ArrayList<NetworkStateSnapshot>());
@@ -1492,19 +1495,19 @@
PersistableBundle bundle = CarrierConfigManager.getDefaultConfig();
when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle);
- setNetworkPolicies(buildDefaultFakeMobilePolicy());
+ setNetworkPolicies(buildDefaultFakeCarrierPolicy());
return bundle;
}
@Test
- public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException {
+ public void testUpdateCarrierPolicyCycleWithNullConfig() throws RemoteException {
when(mConnManager.getAllNetworkStateSnapshots())
.thenReturn(new ArrayList<NetworkStateSnapshot>());
setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null);
- setNetworkPolicies(buildDefaultFakeMobilePolicy());
+ setNetworkPolicies(buildDefaultFakeCarrierPolicy());
// smoke test to make sure no errors are raised
mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED)
@@ -1515,8 +1518,8 @@
}
@Test
- public void testUpdateMobilePolicyCycleWithInvalidConfig() throws RemoteException {
- PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+ public void testUpdateCarrierPolicyCycleWithInvalidConfig() throws RemoteException {
+ PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
// Test with an invalid CarrierConfig, there should be no changes or crashes.
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100);
bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100);
@@ -1531,8 +1534,8 @@
}
@Test
- public void testUpdateMobilePolicyCycleWithDefaultConfig() throws RemoteException {
- PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+ public void testUpdateCarrierPolicyCycleWithDefaultConfig() throws RemoteException {
+ PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
// Test that we respect the platform values when told to
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
DATA_CYCLE_USE_PLATFORM_DEFAULT);
@@ -1550,11 +1553,11 @@
}
@Test
- public void testUpdateMobilePolicyCycleWithUserOverrides() throws RemoteException {
- PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+ public void testUpdateCarrierPolicyCycleWithUserOverrides() throws RemoteException {
+ PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
// inferred = false implies that a user manually modified this policy.
- NetworkPolicy policy = buildDefaultFakeMobilePolicy();
+ NetworkPolicy policy = buildDefaultFakeCarrierPolicy();
policy.inferred = false;
setNetworkPolicies(policy);
@@ -1573,8 +1576,8 @@
}
@Test
- public void testUpdateMobilePolicyCycleUpdatesDataCycle() throws RemoteException {
- PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+ public void testUpdateCarrierPolicyCycleUpdatesDataCycle() throws RemoteException {
+ PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
@@ -1588,8 +1591,8 @@
}
@Test
- public void testUpdateMobilePolicyCycleDisableThresholds() throws RemoteException {
- PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+ public void testUpdateCarrierPolicyCycleDisableThresholds() throws RemoteException {
+ PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
@@ -1605,8 +1608,8 @@
}
@Test
- public void testUpdateMobilePolicyCycleRevertsToDefault() throws RemoteException {
- PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
+ public void testUpdateCarrierPolicyCycleRevertsToDefault() throws RemoteException {
+ PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
@@ -1775,7 +1778,7 @@
@Test
public void testSetNetworkPolicies_withNullPolicies_doesNotThrow() {
NetworkPolicy[] policies = new NetworkPolicy[3];
- policies[1] = buildDefaultFakeMobilePolicy();
+ policies[1] = buildDefaultFakeCarrierPolicy();
setNetworkPolicies(policies);
assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
@@ -1821,7 +1824,8 @@
// Set warning to 7KB and limit to 10KB.
setNetworkPolicies(new NetworkPolicy(
- sTemplateMobileAll, CYCLE_DAY, TIMEZONE_UTC, 7000L, 10000L, true));
+ sTemplateCarrierMetered, CYCLE_DAY, TIMEZONE_UTC, 7000L, 10000L,
+ true));
postMsgAndWaitForCompletion();
// Verifies that remaining quotas are set to providers.
@@ -1972,6 +1976,40 @@
}
}
+ @Test
+ @NetPolicyXml("network-policy-mobile.xml")
+ public void testStartToSupportCarrierUsagePolicy() throws Exception {
+ NetworkPolicy[] policies = mService.getNetworkPolicies(
+ mServiceContext.getOpPackageName());
+ assertEquals("Unexpected number of network policies", 1, policies.length);
+ NetworkPolicy actualPolicy = policies[0];
+ assertEquals("Unexpected template match rule in network policies",
+ NetworkTemplate.MATCH_CARRIER,
+ actualPolicy.template.getMatchRule());
+ assertEquals("Unexpected subscriberId match rule in network policies",
+ NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT,
+ actualPolicy.template.getSubscriberIdMatchRule());
+ assertEquals("Unexpected template meteredness in network policies",
+ METERED_YES, actualPolicy.template.getMeteredness());
+ }
+
+ @Test
+ @NetPolicyXml("network-policy-wifi-with-subscriberId-match-rule-all-and-templateMetered-no.xml")
+ public void testSupportedCarrierUsagePolicy() throws Exception {
+ NetworkPolicy[] policies = mService.getNetworkPolicies(
+ mServiceContext.getOpPackageName());
+ assertEquals("Unexpected number of network policies", 1, policies.length);
+ NetworkPolicy actualPolicy = policies[0];
+ assertEquals("Unexpected template match rule in network policies",
+ NetworkTemplate.MATCH_WIFI,
+ actualPolicy.template.getMatchRule());
+ assertEquals("Unexpected subscriberId match rule in network policies",
+ NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_ALL,
+ actualPolicy.template.getSubscriberIdMatchRule());
+ assertEquals("Unexpected template meteredness in network policies",
+ METERED_NO, actualPolicy.template.getMeteredness());
+ }
+
private String formatBlockedStateError(int uid, int rule, boolean metered,
boolean backgroundRestricted) {
return String.format(
@@ -2024,8 +2062,8 @@
return builder.build();
}
- private NetworkPolicy buildDefaultFakeMobilePolicy() {
- NetworkPolicy p = mService.buildDefaultMobilePolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
+ private NetworkPolicy buildDefaultFakeCarrierPolicy() {
+ NetworkPolicy p = mService.buildDefaultCarrierPolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
// set a deterministic cycle date
p.cycleRule = new RecurrenceRule(
p.cycleRule.start.withDayOfMonth(DEFAULT_CYCLE_DAY),
@@ -2033,9 +2071,9 @@
return p;
}
- private static NetworkPolicy buildFakeMobilePolicy(int cycleDay, long warningBytes,
+ private static NetworkPolicy buildFakeCarrierPolicy(int cycleDay, long warningBytes,
long limitBytes, boolean inferred) {
- final NetworkTemplate template = buildTemplateMobileAll(FAKE_SUBSCRIBER_ID);
+ final NetworkTemplate template = buildTemplateCarrierMetered(FAKE_SUBSCRIBER_ID);
return new NetworkPolicy(template, cycleDay, TimeZone.getDefault().getID(), warningBytes,
limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred);
}
@@ -2046,8 +2084,8 @@
mServiceContext.getOpPackageName());
assertEquals("Unexpected number of network policies", 1, policies.length);
NetworkPolicy actualPolicy = policies[0];
- NetworkPolicy expectedPolicy = buildFakeMobilePolicy(expectedCycleDay, expectedWarningBytes,
- expectedLimitBytes, expectedInferred);
+ NetworkPolicy expectedPolicy = buildFakeCarrierPolicy(expectedCycleDay,
+ expectedWarningBytes, expectedLimitBytes, expectedInferred);
assertEquals(expectedPolicy, actualPolicy);
}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
index f659698..00b05d4 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
@@ -77,6 +77,38 @@
}
@Test
+ public void testStepAndRampSegments_withoutPwleCapability_convertsRampsToSteps() {
+ VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
+ new RampSegment(/* startAmplitude= */ 1, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ -4, /* endFrequency= */ 2, /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f,
+ /* startFrequency= */ 0, /* endFrequency= */ 0, /* duration= */ 11),
+ new RampSegment(/* startAmplitude= */ 0.65f, /* endAmplitude= */ 0.65f,
+ /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 200)),
+ /* repeatIndex= */ 3);
+
+ VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
+ new StepSegment(/* amplitude= */ 0, Float.NaN, /* duration= */ 10),
+ new StepSegment(/* amplitude= */ 0.5f, Float.NaN, /* duration= */ 100),
+ // 10ms ramp becomes 2 steps
+ new StepSegment(/* amplitude= */ 1, Float.NaN, /* duration= */ 5),
+ new StepSegment(/* amplitude= */ 0.2f, Float.NaN, /* duration= */ 5),
+ // 11ms ramp becomes 3 steps
+ new StepSegment(/* amplitude= */ 0.8f, Float.NaN, /* duration= */ 5),
+ new StepSegment(/* amplitude= */ 0.6f, Float.NaN, /* duration= */ 5),
+ new StepSegment(/* amplitude= */ 0.2f, Float.NaN, /* duration= */ 1),
+ // 200ms ramp with same amplitude becomes a single step
+ new StepSegment(/* amplitude= */ 0.65f, Float.NaN, /* duration= */ 200)),
+ // Repeat index fixed after intermediate steps added
+ /* repeatIndex= */ 4);
+
+ VibratorInfo info = createVibratorInfo(EMPTY_FREQUENCY_MAPPING);
+ assertEquals(expected, mAdapter.apply(effect, info));
+ }
+
+ @Test
public void testStepAndRampSegments_withPwleCapability_convertsStepsToRamps() {
VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
@@ -131,7 +163,7 @@
}
@Test
- public void testStepAndRampSegments_emptyMapping_returnsSameAmplitudesAndFrequencyZero() {
+ public void testStepAndRampSegments_withEmptyFreqMapping_returnsSameAmplitudesAndZeroFreq() {
VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
new StepSegment(/* amplitude= */ 0, /* frequency= */ 1, /* duration= */ 10),
new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 100),
@@ -142,8 +174,11 @@
/* repeatIndex= */ 2);
VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
- new StepSegment(/* amplitude= */ 0, /* frequency= */ Float.NaN, /* duration= */ 10),
- new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ Float.NaN,
+ new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0,
+ /* startFrequency= */ Float.NaN, /* endFrequency= */ Float.NaN,
+ /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.5f,
+ /* startFrequency= */ Float.NaN, /* endFrequency= */ Float.NaN,
/* duration= */ 100),
new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 1,
/* startFrequency= */ Float.NaN, /* endFrequency= */ Float.NaN,
@@ -153,11 +188,13 @@
/* duration= */ 20)),
/* repeatIndex= */ 2);
- assertEquals(expected, mAdapter.apply(effect, createVibratorInfo(EMPTY_FREQUENCY_MAPPING)));
+ VibratorInfo info = createVibratorInfo(EMPTY_FREQUENCY_MAPPING,
+ IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(expected, mAdapter.apply(effect, info));
}
@Test
- public void testStepAndRampSegments_nonEmptyMapping_returnsClippedValues() {
+ public void testStepAndRampSegments_withValidFreqMapping_returnsClippedValues() {
VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 0, /* duration= */ 10),
new StepSegment(/* amplitude= */ 1, /* frequency= */ -1, /* duration= */ 100),
@@ -168,15 +205,21 @@
/* repeatIndex= */ 2);
VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
- new StepSegment(/* amplitude= */ 0.5f, /* frequency= */ 150, /* duration= */ 10),
- new StepSegment(/* amplitude= */ 0.8f, /* frequency= */ 125, /* duration= */ 100),
+ new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.5f,
+ /* startFrequency= */ 150, /* endFrequency= */ 150,
+ /* duration= */ 10),
+ new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.8f,
+ /* startFrequency= */ 125, /* endFrequency= */ 125,
+ /* duration= */ 100),
new RampSegment(/* startAmplitude= */ 0.1f, /* endAmplitude= */ 0.8f,
/* startFrequency= */ 50, /* endFrequency= */ 200, /* duration= */ 50),
new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.1f,
/* startFrequency= */ 200, /* endFrequency= */ 50, /* duration= */ 20)),
/* repeatIndex= */ 2);
- assertEquals(expected, mAdapter.apply(effect, createVibratorInfo(TEST_FREQUENCY_MAPPING)));
+ VibratorInfo info = createVibratorInfo(TEST_FREQUENCY_MAPPING,
+ IVibrator.CAP_COMPOSE_PWLE_EFFECTS);
+ assertEquals(expected, mAdapter.apply(effect, info));
}
private static VibratorInfo createVibratorInfo(VibratorInfo.FrequencyMapping frequencyMapping,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 3869fae..c480258 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -7811,8 +7811,7 @@
inOrder.verify(child).recordDismissalSentiment(anyInt());
}
- // TODO (b/171418004): renable after app outreach
- /*@Test
+ @Test
public void testImmutableBubbleIntent() throws Exception {
when(mAmi.getPendingIntentFlags(pi1))
.thenReturn(FLAG_IMMUTABLE | FLAG_ONE_SHOT);
@@ -7827,7 +7826,7 @@
} catch (IllegalArgumentException e) {
// good
}
- }*/
+ }
@Test
public void testMutableBubbleIntent() throws Exception {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index aed3f52..8216830 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -26,6 +26,7 @@
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
@@ -546,7 +547,7 @@
}
@Test
- public void ignoreRequestedOrientationInSplitWindows() {
+ public void ignoreRequestedOrientationForResizableInSplitWindows() {
final ActivityRecord activity = createActivityWith2LevelTask();
final Task task = activity.getTask();
final Task rootTask = activity.getRootTask();
@@ -578,13 +579,45 @@
}
task.setBounds(bounds);
- // Requests orientation that's different from its bounds.
- activity.setRequestedOrientation(
- isScreenPortrait ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE);
+ final int activityCurOrientation = activity.getConfiguration().orientation;
- // Asserts it has orientation derived requested orientation (fixed orientation letterbox).
- assertEquals(isScreenPortrait ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE,
- activity.getConfiguration().orientation);
+ // Requests orientation that's different from its bounds.
+ activity.setRequestedOrientation(activityCurOrientation == ORIENTATION_LANDSCAPE
+ ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE);
+
+ // Asserts fixed orientation request is ignored, and the orientation is not changed
+ // (fill Task).
+ assertEquals(activityCurOrientation, activity.getConfiguration().orientation);
+ assertFalse(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+ }
+
+ @Test
+ public void respectRequestedOrientationForNonResizableInSplitWindows() {
+ final Task task = new TaskBuilder(mSupervisor)
+ .setCreateParentTask(true).setCreateActivity(true).build();
+ final Task rootTask = task.getRootTask();
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setParentTask(task)
+ .setOnTop(true)
+ .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
+ .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+ .build();
+
+ // Task in landscape.
+ rootTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ task.setBounds(0, 0, 1000, 500);
+ assertEquals(ORIENTATION_LANDSCAPE, task.getConfiguration().orientation);
+
+ // Asserts fixed orientation request is respected, and the orientation is not changed.
+ assertEquals(ORIENTATION_PORTRAIT, activity.getConfiguration().orientation);
+
+ // Clear size compat.
+ activity.clearSizeCompatMode();
+ activity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
+ activity.mDisplayContent.sendNewConfiguration();
+
+ // Relaunching the app should still respect the orientation request.
+ assertEquals(ORIENTATION_PORTRAIT, activity.getConfiguration().orientation);
assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio());
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 6b7fc2f..8fb805b 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4346,7 +4346,7 @@
"+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.deferred\"",
"+g.gsma.rcs.cpm.pager-large",
"+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session\"",
- "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session\"",
+ "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.filetransfer\"",
"+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.fthttp\"",
"+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcs.ftsms\"",
"+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.gsma.callcomposer\"",
diff --git a/tools/aapt/SdkConstants.h b/tools/aapt/SdkConstants.h
index 04fbbe1..955581c 100644
--- a/tools/aapt/SdkConstants.h
+++ b/tools/aapt/SdkConstants.h
@@ -46,6 +46,7 @@
SDK_P = 28,
SDK_Q = 29,
SDK_R = 30,
+ SDK_S = 31,
};
#endif // H_AAPT_SDK_CONSTANTS
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index e8873bf..96f6512 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -58,7 +58,8 @@
{0x056d, SDK_O_MR1},
{0x0586, SDK_P},
{0x0606, SDK_Q},
- {0x0617, SDK_R},
+ {0x0616, SDK_R},
+ {0x064b, SDK_S},
};
static bool less_entry_id(const std::pair<uint16_t, ApiVersion>& p, uint16_t entryId) {
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index aa9aa12..6bb6ddb 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -56,6 +56,7 @@
SDK_P = 28,
SDK_Q = 29,
SDK_R = 30,
+ SDK_S = 31,
};
ApiVersion FindAttributeSdkLevel(const ResourceId& id);
diff --git a/tools/finalize_res/finalize_res.py b/tools/finalize_res/finalize_res.py
new file mode 100755
index 0000000..aaf0187
--- /dev/null
+++ b/tools/finalize_res/finalize_res.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+#-*- coding: utf-8 -*-
+
+# Copyright (C) 2021 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.
+
+"""
+Finalize resource values in <staging-public-group> tags
+
+Usage: finalize_res.py core/res/res/values/public.xml public_finalized.xml
+"""
+
+import re, sys, codecs
+
+def finalize_item(raw):
+ global _type, _id
+ _id += 1
+ return '<public type="%s" name="%s" id="%s" />' % (_type, raw.group(1), '0x{0:0{1}x}'.format(_id-1,8))
+
+def finalize_group(raw):
+ global _type, _id
+ _type = raw.group(1)
+ _id = int(raw.group(2), 16)
+ return re.sub(r'<public name="(.+?)" */>', finalize_item, raw.group(3))
+
+with open(sys.argv[1]) as f:
+ raw = f.read()
+ raw = re.sub(r'<staging-public-group type="(.+?)" first-id="(.+?)">(.+?)</staging-public-group>', finalize_group, raw, flags=re.DOTALL)
+ with open(sys.argv[2], "w") as f:
+ f.write(raw)