Merge "Check availability on start for TetherSettings" into udc-dev
diff --git a/Android.bp b/Android.bp
index ea2c983..4d07913 100644
--- a/Android.bp
+++ b/Android.bp
@@ -81,6 +81,7 @@
"jsr305",
"net-utils-framework-common",
"app-usage-event-protos-lite",
+ "battery-event-protos-lite",
"settings-contextual-card-protos-lite",
"settings-log-bridge-protos-lite",
"settings-telephony-protos-lite",
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ccf002a..21b3fa4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3110,6 +3110,7 @@
<intent-filter>
<action android:name="android.intent.action.BATTERY_LEVEL_CHANGED"/>
<action android:name="com.android.settings.battery.action.CLEAR_BATTERY_CACHE_DATA"/>
+ <action android:name="com.android.settings.battery.action.ACTION_BATTERY_PLUGGING"/>
<action android:name="com.android.settings.battery.action.ACTION_BATTERY_UNPLUGGING"/>
</intent-filter>
</receiver>
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 911a95b..2fd63fc 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -1573,6 +1573,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <color name="screen_flash_color_button_outer_circle_stroke_color">#FFFFFF</color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values-night/colors.xml"
+ line="73"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <color name="switchbar_switch_track_tint">#BFFFFFFF</color>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -3701,6 +3717,38 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="#2E3192""
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable-night/flash_notifications_illustration.xml"
+ line="37"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="#000000""
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable-night/flash_notifications_illustration.xml"
+ line="40"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:color="@color/accessibility_feature_background"/>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -4789,6 +4837,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_01_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_01" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -4869,6 +4933,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_02_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_02" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -4949,6 +5029,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_03_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_03" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5029,6 +5125,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_04_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_04" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5109,6 +5221,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_05_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_05" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5189,6 +5317,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_06_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_06" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5269,6 +5413,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_07_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_07" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5349,6 +5509,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_08_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_08" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5429,6 +5605,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_09_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_09" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5509,6 +5701,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_10_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_10" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5589,6 +5797,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_11_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_11" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -5669,6 +5893,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/screen_flash_color_button_outer_circle_stroke_color" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/screen_flash_color_12_checked_layer.xml"
+ line="41"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <solid android:color="@color/screen_flash_preset_opaque_color_12" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
diff --git a/res-product/values/strings.xml b/res-product/values/strings.xml
index 5b6474e..3569485 100644
--- a/res-product/values/strings.xml
+++ b/res-product/values/strings.xml
@@ -155,6 +155,30 @@
<string name="security_settings_face_enroll_introduction_control_consent_message" product="tablet"></string>
<!-- Message on the face enrollment introduction page that explains privacy controls for face unlock when asking for parental consent. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_enroll_introduction_control_consent_message" product="device"></string>
+ <!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer" product="default">Use your face to unlock your phone or for authentication in apps, like when you sign in or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face.\n\nYour phone can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer" product="tablet">Use your face to unlock your tablet or for authentication in apps, like when you sign in or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the tablet can unlock it when you don\u2019t intend to.\n\nYour tablet can be unlocked by someone else if it\u2019s held up to your face.\n\nYour tablet can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer" product="device">Use your face to unlock your device or for authentication in apps, like when you sign in or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the device can unlock it when you don\u2019t intend to.\n\nYour device can be unlocked by someone else if it\u2019s held up to your face.\n\nYour device can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when attention checking is not supported. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_attention_not_supported" product="default">Use your face to unlock your phone or for authentication in apps, like when you sign in or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face, even if your eyes are closed.\n\nYour phone can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when attention checking is not supported. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_attention_not_supported" product="tablet">Use your face to unlock your tablet or for authentication in apps, like when you sign in or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the tablet can unlock it when you don\u2019t intend to.\n\nYour tablet can be unlocked by someone else if it\u2019s held up to your face, even if your eyes are closed.\n\nYour tablet can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when attention checking is not supported. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_attention_not_supported" product="device">Use your face to unlock your device or for authentication in apps, like when you sign in or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the device can unlock it when you don\u2019t intend to.\n\nYour device can be unlocked by someone else if it\u2019s held up to your face, even if your eyes are closed.\n\nYour device can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when face is class 3. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_class3" product="default">Use your face to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face.\n\nYour phone can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when face is class 3. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_class3" product="tablet">Use your face to unlock your tablet or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the tablet can unlock it when you don\u2019t intend to.\n\nYour tablet can be unlocked by someone else if it\u2019s held up to your face.\n\nYour tablet can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when face is class 3. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_class3" product="device">Use your face to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the device can unlock it when you don\u2019t intend to.\n\nYour device can be unlocked by someone else if it\u2019s held up to your face.\n\nYour device can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when face is class 3 and attention checking is not supported. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_class3_attention_not_supported" product="default">Use your face to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face, even if your eyes are closed.\n\nYour phone can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when face is class 3 and attention checking is not supported. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_class3_attention_not_supported" product="tablet">Use your face to unlock your tablet or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the tablet can unlock it when you don\u2019t intend to.\n\nYour tablet can be unlocked by someone else if it\u2019s held up to your face, even if your eyes are closed.\n\nYour tablet can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
+ <!-- Text shown in face settings explaining what your face can be used for. Used when face is class 3 and attention checking is not supported. [CHAR LIMIT=NONE] -->
+ <string name="security_settings_face_settings_footer_class3_attention_not_supported" product="device">Use your face to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the device can unlock it when you don\u2019t intend to.\n\nYour device can be unlocked by someone else if it\u2019s held up to your face, even if your eyes are closed.\n\nYour device can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
<!-- Introduction detail message shown in fingerprint enrollment dialog [CHAR LIMIT=NONE]-->
<string name="security_settings_fingerprint_enroll_introduction_v3_message">Use your fingerprint to unlock your <xliff:g id="deviceName" example="Pixel">%s</xliff:g> or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
<!-- Introduction detail message shown in fingerprint enrollment dialog when asking for parental consent [CHAR LIMIT=NONE]-->
diff --git a/res/drawable/ic_check_24dp.xml b/res/drawable/ic_check_24dp.xml
index 5801e70..5238901 100644
--- a/res/drawable/ic_check_24dp.xml
+++ b/res/drawable/ic_check_24dp.xml
@@ -18,7 +18,7 @@
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
- android:tint="?androidprv:attr/colorAccentPrimaryVariant">
+ android:tint="?androidprv:attr/colorAccent">
<path
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"
android:fillColor="@android:color/white"/>
diff --git a/res/layout/locale_order_list.xml b/res/layout/locale_order_list.xml
index a1f93cd..acde145 100644
--- a/res/layout/locale_order_list.xml
+++ b/res/layout/locale_order_list.xml
@@ -36,7 +36,7 @@
<Button
android:id="@+id/add_language"
android:layout_width="match_parent"
- android:layout_height="?android:listPreferredItemHeight"
+ android:layout_height="wrap_content"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:drawableStart="@drawable/ic_add_24dp"
diff --git a/res/layout/preference_check_icon.xml b/res/layout/preference_check_icon.xml
index 5652ac6..1b759fc 100644
--- a/res/layout/preference_check_icon.xml
+++ b/res/layout/preference_check_icon.xml
@@ -15,7 +15,7 @@
-->
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyboard_check_icon"
+ android:id="@+id/check_icon"
android:src="@drawable/ic_check_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f23fb5f..dfd8a26 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -729,11 +729,7 @@
<string name="security_settings_face_settings_remove_face_model">Delete face model</string>
<!-- Button text in face settings which lets the user enroll their face [CHAR LIMIT=40] -->
<string name="security_settings_face_settings_enroll">Set up Face Unlock</string>
- <!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_settings_footer">Use your face to unlock your phone or for authentication in apps, like when you sign in or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face.\n\nYour phone can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
- <!-- Text shown in face settings explaining what your face can be used for. Used when attention checking is not supported. [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_settings_footer_attention_not_supported">Use your face to unlock your phone or for authentication in apps, like when you sign in or approve a purchase.\n\nKeep in mind:\nYou can only have one face set up at a time. To add another face, delete the current one.\n\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face, even if your eyes are closed.\n\nYour phone can be unlocked by someone who looks a lot like you, like an identical sibling.</string>
- <!-- Dialog title shown when the user removes an enrollment [CHAR LIMIT=35] -->
+ <!-- Dialog title shown when the user removes an enrollment [CHAR LIMIT=35] -->
<string name="security_settings_face_settings_remove_dialog_title">Delete face model?</string>
<!-- Dialog contents shown when the user removes an enrollment [CHAR LIMIT=NONE] -->
<string name="security_settings_face_settings_remove_dialog_details">Your face model will be permanently and securely deleted.\n\nAfter deletion, you will need your PIN, pattern, or password to unlock your phone or for authentication in apps.</string>
@@ -4214,10 +4210,10 @@
<string name="accessibility_screen_magnification_follow_typing_title">Magnify typing</string>
<!-- Summary for accessibility follow typing preference for magnification. [CHAR LIMIT=none] -->
<string name="accessibility_screen_magnification_follow_typing_summary">Magnifier follows text as you type</string>
- <!-- Title for accessibility magnifier preference where the magnifier never turns off on its own. [CHAR LIMIT=35] -->
- <string name="accessibility_screen_magnification_always_on_title">Always On</string>
- <!-- Summary for accessibility magnifier preference where the magnifier never turns off on its own. [CHAR LIMIT=none] -->
- <string name="accessibility_screen_magnification_always_on_summary">Instead of deactivating magnification when changing apps, it simply zooms out to normal size. Pinch to zoom back in whenever you want.</string>
+ <!-- Title for accessibility magnifier preference where the magnifier never turns off while switching apps. [CHAR LIMIT=35] -->
+ <string name="accessibility_screen_magnification_always_on_title">Keep on while switching apps</string>
+ <!-- Summary for accessibility magnifier preference where the magnifier never turns off while switching apps. [CHAR LIMIT=none] -->
+ <string name="accessibility_screen_magnification_always_on_summary">Magnifier stays on and zooms out when you switch apps</string>
<!-- Title for accessibility on-screen joystick controller preference that controls magnification position. [CHAR LIMIT=35] -->
<string name="accessibility_screen_magnification_joystick_title">Joystick</string>
<!-- Summary for accessibility on-screen joystick controller preference that controls magnification position. [CHAR LIMIT=none] -->
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
index 370392b..a0dac5a 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
@@ -23,6 +23,7 @@
import android.util.Log;
import android.util.TypedValue;
+import androidx.window.embedding.ActivityEmbeddingController;
import androidx.window.embedding.SplitController;
import com.android.settings.R;
@@ -81,4 +82,13 @@
return dm.widthPixels >= (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, MIN_REGULAR_HOMEPAGE_LAYOUT_WIDTH_DP, dm);
}
+
+ /**
+ * Check if activity is already embedded
+ */
+ public static boolean isAlreadyEmbedded(Activity activity) {
+ return ActivityEmbeddingController
+ .getInstance(activity)
+ .isActivityEmbedded(activity);
+ }
}
diff --git a/src/com/android/settings/applications/UsageAccessDetails.java b/src/com/android/settings/applications/UsageAccessDetails.java
index 8085b69..4adb6c1 100644
--- a/src/com/android/settings/applications/UsageAccessDetails.java
+++ b/src/com/android/settings/applications/UsageAccessDetails.java
@@ -30,6 +30,8 @@
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
@@ -46,6 +48,7 @@
public class UsageAccessDetails extends AppInfoWithHeader implements OnPreferenceChangeListener,
OnPreferenceClickListener {
+ private static final String TAG = UsageAccessDetails.class.getSimpleName();
private static final String KEY_APP_OPS_PREFERENCE_SCREEN = "app_ops_preference_screen";
private static final String KEY_APP_OPS_SETTINGS_SWITCH = "app_ops_settings_switch";
private static final String KEY_APP_OPS_SETTINGS_DESC = "app_ops_settings_description";
@@ -65,6 +68,11 @@
super.onCreate(savedInstanceState);
Context context = getActivity();
+ if (TextUtils.equals(mPackageName, context.getPackageName())) {
+ Log.w(TAG, "Unsupported app package.");
+ finish();
+ }
+
mUsageBridge = new AppStateUsageBridge(context, mState, null);
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mDpm = context.getSystemService(DevicePolicyManager.class);
diff --git a/src/com/android/settings/applications/manageapplications/CloneBackend.java b/src/com/android/settings/applications/manageapplications/CloneBackend.java
index 588d834..568631e 100644
--- a/src/com/android/settings/applications/manageapplications/CloneBackend.java
+++ b/src/com/android/settings/applications/manageapplications/CloneBackend.java
@@ -104,7 +104,7 @@
new HashSet<>());
} catch (Exception e) {
if (ManageApplications.DEBUG) {
- Log.e("ankita", "Error occurred creating clone user" + e.getMessage());
+ Log.e(TAG, "Error occurred creating clone user" + e.getMessage());
}
return ERROR_CREATING_CLONE_USER;
}
@@ -125,7 +125,7 @@
if (newlyCreated) {
IActivityManager am = ActivityManagerNative.getDefault();
try {
- am.startUserInBackground(mCloneUserId);
+ am.startProfile(mCloneUserId);
} catch (RemoteException e) {
if (ManageApplications.DEBUG) {
Log.e(TAG, "Error starting clone user " + e.getMessage());
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
index ba1047b..261166b 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceController.java
@@ -18,8 +18,15 @@
import android.content.Context;
import android.content.Intent;
+import android.hardware.biometrics.SensorProperties;
+import android.hardware.face.FaceManager;
+import android.hardware.face.FaceSensorPropertiesInternal;
+import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
+import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
@@ -27,18 +34,47 @@
import com.android.settings.utils.AnnotationSpan;
import com.android.settingslib.HelpUtils;
+import java.util.List;
+
/**
* Footer for face settings showing the help text and help link.
*/
public class FaceSettingsFooterPreferenceController extends BasePreferenceController {
-
+ private static final String TAG = "FaceSettingsFooterPreferenceController";
private static final String ANNOTATION_URL = "url";
-
- private FaceFeatureProvider mProvider;
+ private final FaceFeatureProvider mProvider;
+ private Preference mPreference;
+ private boolean mIsFaceStrong;
public FaceSettingsFooterPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mProvider = FeatureFactory.getFactory(context).getFaceFeatureProvider();
+ FaceManager faceManager = context.getSystemService(FaceManager.class);
+ faceManager.addAuthenticatorsRegisteredCallback(
+ new IFaceAuthenticatorsRegisteredCallback.Stub() {
+ @Override
+ public void onAllAuthenticatorsRegistered(
+ @NonNull List<FaceSensorPropertiesInternal> sensors) {
+ if (sensors.isEmpty()) {
+ Log.e(TAG, "No sensors");
+ return;
+ }
+
+ boolean isFaceStrong = sensors.get(0).sensorStrength
+ == SensorProperties.STRENGTH_STRONG;
+ if (mIsFaceStrong == isFaceStrong) {
+ return;
+ }
+ mIsFaceStrong = isFaceStrong;
+ updateState(mPreference);
+ }
+ });
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(mPreferenceKey);
}
@Override
@@ -55,10 +91,17 @@
final AnnotationSpan.LinkInfo linkInfo =
new AnnotationSpan.LinkInfo(mContext, ANNOTATION_URL, helpIntent);
- final int footerRes = mProvider.isAttentionSupported(mContext)
- ? R.string.security_settings_face_settings_footer
- : R.string.security_settings_face_settings_footer_attention_not_supported;
-
+ int footerRes;
+ boolean isAttentionSupported = mProvider.isAttentionSupported(mContext);
+ if (mIsFaceStrong) {
+ footerRes = isAttentionSupported
+ ? R.string.security_settings_face_settings_footer_class3
+ : R.string.security_settings_face_settings_footer_attention_not_supported;
+ } else {
+ footerRes = isAttentionSupported
+ ? R.string.security_settings_face_settings_footer
+ : R.string.security_settings_face_settings_footer_class3_attention_not_supported;
+ }
preference.setTitle(AnnotationSpan.linkify(
mContext.getText(footerRes), linkInfo));
}
diff --git a/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java b/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
index ac895df..c93a1c6 100644
--- a/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
+++ b/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
@@ -127,8 +127,9 @@
pref.setTitle(mContext.getString(R.string.stylus_textfield_handwriting));
pref.setIcon(R.drawable.ic_text_fields_alt);
pref.setOnPreferenceClickListener(this);
- pref.setChecked(Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, 0) == 1);
+ pref.setChecked(Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED,
+ Secure.STYLUS_HANDWRITING_DEFAULT_VALUE) == 1);
pref.setVisible(currentInputMethodSupportsHandwriting());
return pref;
}
@@ -157,8 +158,8 @@
mContext.startActivity(intent);
break;
case KEY_HANDWRITING:
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED,
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED,
((SwitchPreference) preference).isChecked() ? 1 : 0);
if (((SwitchPreference) preference).isChecked()) {
diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java
index b1661e1..c0ccb76 100644
--- a/src/com/android/settings/datausage/DataUsageList.java
+++ b/src/com/android/settings/datausage/DataUsageList.java
@@ -37,6 +37,7 @@
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
@@ -134,8 +135,14 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final Activity activity = getActivity();
+ if (isGuestUser(getContext())) {
+ Log.e(TAG, "This setting isn't available for guest user");
+ EventLog.writeEvent(0x534e4554, "262741858", -1 /* UID */, "Guest user");
+ finish();
+ return;
+ }
+ final Activity activity = getActivity();
if (!isBandwidthControlEnabled()) {
Log.w(TAG, "No bandwidth control; leaving");
activity.finish();
@@ -251,9 +258,10 @@
@Override
public void onDestroy() {
- mUidDetailProvider.clearCache();
- mUidDetailProvider = null;
-
+ if (mUidDetailProvider != null) {
+ mUidDetailProvider.clearCache();
+ mUidDetailProvider = null;
+ }
super.onDestroy();
}
@@ -646,4 +654,11 @@
}
}
};
+
+ private static boolean isGuestUser(Context context) {
+ if (context == null) return false;
+ final UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager == null) return false;
+ return userManager.isGuestUser();
+ }
}
diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java
index dbbe754..25fc49b 100644
--- a/src/com/android/settings/datausage/DataUsageSummary.java
+++ b/src/com/android/settings/datausage/DataUsageSummary.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.net.NetworkTemplate;
import android.os.Bundle;
+import android.os.UserManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.text.BidiFormatter;
@@ -27,6 +28,8 @@
import android.text.TextUtils;
import android.text.format.Formatter;
import android.text.style.RelativeSizeSpan;
+import android.util.EventLog;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -84,6 +87,12 @@
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Context context = getContext();
+ if (isGuestUser(context)) {
+ Log.e(TAG, "This setting isn't available due to user restriction.");
+ EventLog.writeEvent(0x534e4554, "262243574", -1 /* UID */, "Guest user");
+ finish();
+ return;
+ }
if (!isSimHardwareVisible(context) ||
MobileNetworkUtils.isMobileNetworkUserRestricted(context)) {
@@ -285,4 +294,11 @@
updateState();
mSummaryController.updateState(mSummaryPreference);
}
+
+ private static boolean isGuestUser(Context context) {
+ if (context == null) return false;
+ final UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager == null) return false;
+ return userManager.isGuestUser();
+ }
}
diff --git a/src/com/android/settings/development/StylusHandwritingPreferenceController.java b/src/com/android/settings/development/StylusHandwritingPreferenceController.java
index 69b5bad..12cd781 100644
--- a/src/com/android/settings/development/StylusHandwritingPreferenceController.java
+++ b/src/com/android/settings/development/StylusHandwritingPreferenceController.java
@@ -45,8 +45,8 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean isEnabled = (Boolean) newValue;
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED,
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED,
isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
return true;
@@ -54,16 +54,18 @@
@Override
public void updateState(Preference preference) {
- final int enable = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_OFF);
+ final int enable = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED,
+ Settings.Secure.STYLUS_HANDWRITING_DEFAULT_VALUE);
((SwitchPreference) mPreference).setChecked(enable != SETTING_VALUE_OFF);
}
@Override
protected void onDeveloperOptionsSwitchDisabled() {
super.onDeveloperOptionsSwitchDisabled();
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_OFF);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED,
+ Settings.Secure.STYLUS_HANDWRITING_DEFAULT_VALUE);
((SwitchPreference) mPreference).setChecked(false);
}
}
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java
index 274817e..73ec42b 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java
@@ -22,9 +22,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
-import android.provider.Settings;
import android.provider.SettingsSlicesContract;
-import android.widget.Switch;
import androidx.preference.PreferenceScreen;
@@ -36,15 +34,13 @@
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.android.settingslib.fuelgauge.BatterySaverUtils;
import com.android.settingslib.widget.MainSwitchPreference;
-import com.android.settingslib.widget.OnMainSwitchChangeListener;
-
/**
* Controller to update the battery saver button
*/
public class BatterySaverButtonPreferenceController extends
- TogglePreferenceController implements OnMainSwitchChangeListener, LifecycleObserver,
- OnStart, OnStop, BatterySaverReceiver.BatterySaverListener {
+ TogglePreferenceController implements LifecycleObserver, OnStart, OnStop,
+ BatterySaverReceiver.BatterySaverListener {
private static final long SWITCH_ANIMATION_DURATION = 350L;
private final BatterySaverReceiver mBatterySaverReceiver;
@@ -96,21 +92,10 @@
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
- mPreference.addOnSwitchChangeListener(this);
mPreference.updateStatus(isChecked());
}
@Override
- public void onSwitchChanged(Switch switchView, boolean isChecked) {
- // Cancel preference's check state once it's first time launch
- if (isChecked && (Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 0) == 0)) {
- mPreference.setChecked(false);
- }
- setChecked(isChecked);
- }
-
- @Override
public boolean isChecked() {
return mPowerManager.isPowerSaveMode();
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java
index a437877..07a97dc 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java
@@ -30,6 +30,8 @@
import com.android.settingslib.fuelgauge.BatteryStatus;
import java.time.Duration;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
/** A {@link BatteryUsageBroadcastReceiver} for battery usage data requesting. */
public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver {
@@ -37,7 +39,10 @@
/** An intent action to request Settings to clear cache data. */
public static final String ACTION_CLEAR_BATTERY_CACHE_DATA =
"com.android.settings.battery.action.CLEAR_BATTERY_CACHE_DATA";
- /** An intent action to request Settings to clear cache data. */
+ /** An intent action for power is plugging. */
+ public static final String ACTION_BATTERY_PLUGGING =
+ "com.android.settings.battery.action.ACTION_BATTERY_PLUGGING";
+ /** An intent action for power is unplugging. */
public static final String ACTION_BATTERY_UNPLUGGING =
"com.android.settings.battery.action.ACTION_BATTERY_UNPLUGGING";
@@ -49,6 +54,8 @@
@VisibleForTesting
boolean mFetchBatteryUsageData = false;
+ private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
+
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null || intent.getAction() == null) {
@@ -70,7 +77,11 @@
tryToFetchUsageData(context);
}
break;
+ case ACTION_BATTERY_PLUGGING:
+ sendBatteryEventData(context, BatteryEventType.POWER_CONNECTED);
+ break;
case ACTION_BATTERY_UNPLUGGING:
+ sendBatteryEventData(context, BatteryEventType.POWER_DISCONNECTED);
// Only when fullChargeIntentAction is ACTION_POWER_DISCONNECTED,
// ACTION_BATTERY_UNPLUGGING will be considered as the full charge event and then
// start usage events fetching.
@@ -106,4 +117,12 @@
mFetchBatteryUsageData = true;
BatteryUsageDataLoader.enqueueWork(context, /*isFullChargeStart=*/ true);
}
+
+ private void sendBatteryEventData(Context context, BatteryEventType batteryEventType) {
+ final long timestamp = System.currentTimeMillis();
+ final Intent intent = BatteryUtils.getBatteryIntent(context);
+ final int batteryLevel = BatteryStatus.getBatteryLevel(intent);
+ mExecutor.execute(() -> DatabaseUtils.sendBatteryEventData(context,
+ ConvertUtils.convertToBatteryEvent(timestamp, batteryEventType, batteryLevel)));
+ }
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java
index 42937e5..1b2d4cd 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java
@@ -31,6 +31,8 @@
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
+import com.android.settings.fuelgauge.batteryusage.db.BatteryEventDao;
+import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity;
import com.android.settings.fuelgauge.batteryusage.db.BatteryState;
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao;
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
@@ -52,6 +54,7 @@
private static final int BATTERY_STATE_CODE = 1;
private static final int APP_USAGE_LATEST_TIMESTAMP_CODE = 2;
private static final int APP_USAGE_EVENT_CODE = 3;
+ private static final int BATTERY_EVENT_CODE = 4;
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
@@ -68,11 +71,16 @@
DatabaseUtils.AUTHORITY,
/*path=*/ DatabaseUtils.APP_USAGE_EVENT_TABLE,
/*code=*/ APP_USAGE_EVENT_CODE);
+ sUriMatcher.addURI(
+ DatabaseUtils.AUTHORITY,
+ /*path=*/ DatabaseUtils.BATTERY_EVENT_TABLE,
+ /*code=*/ BATTERY_EVENT_CODE);
}
private Clock mClock;
private BatteryStateDao mBatteryStateDao;
private AppUsageEventDao mAppUsageEventDao;
+ private BatteryEventDao mBatteryEventDao;
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public void setClock(Clock clock) {
@@ -88,6 +96,7 @@
mClock = Clock.systemUTC();
mBatteryStateDao = BatteryStateDatabase.getInstance(getContext()).batteryStateDao();
mAppUsageEventDao = BatteryStateDatabase.getInstance(getContext()).appUsageEventDao();
+ mBatteryEventDao = BatteryStateDatabase.getInstance(getContext()).batteryEventDao();
Log.w(TAG, "create content provider from " + getCallingPackage());
return true;
}
@@ -107,6 +116,8 @@
return getAppUsageEvents(uri);
case APP_USAGE_LATEST_TIMESTAMP_CODE:
return getAppUsageLatestTimestamp(uri);
+ case BATTERY_EVENT_CODE:
+ return getBatteryEvents(uri);
default:
throw new IllegalArgumentException("unknown URI: " + uri);
}
@@ -138,6 +149,14 @@
Log.e(TAG, "insert() from:" + uri + " error:" + e);
return null;
}
+ case BATTERY_EVENT_CODE:
+ try {
+ mBatteryEventDao.insert(BatteryEventEntity.create(contentValues));
+ return uri;
+ } catch (RuntimeException e) {
+ Log.e(TAG, "insert() from:" + uri + " error:" + e);
+ return null;
+ }
default:
throw new IllegalArgumentException("unknown URI: " + uri);
}
@@ -190,7 +209,6 @@
}
Log.w(TAG, "query app usage events in " + (mClock.millis() - timestamp) + "/ms");
return cursor;
-
}
private Cursor getAppUsageLatestTimestamp(Uri uri) {
@@ -210,6 +228,19 @@
return cursor;
}
+ private Cursor getBatteryEvents(Uri uri) {
+ final long queryTimestamp = getQueryTimestamp(uri);
+ final long timestamp = mClock.millis();
+ Cursor cursor = null;
+ try {
+ cursor = mBatteryEventDao.getAllAfter(queryTimestamp);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "query() from:" + uri + " error:" + e);
+ }
+ Log.w(TAG, "query app usage events in " + (mClock.millis() - timestamp) + "/ms");
+ return cursor;
+ }
+
// If URI contains query parameter QUERY_KEY_USERID, use the value directly.
// Otherwise, return null.
private List<Long> getQueryUserIds(Uri uri) {
diff --git a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
index fcf934f..c6c548f 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java
@@ -38,6 +38,7 @@
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
+import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -125,6 +126,15 @@
return values;
}
+ /** Converts {@link BatteryEvent} to content values */
+ public static ContentValues convertBatteryEventToContentValues(final BatteryEvent event) {
+ final ContentValues values = new ContentValues();
+ values.put(BatteryEventEntity.KEY_TIMESTAMP, event.getTimestamp());
+ values.put(BatteryEventEntity.KEY_BATTERY_EVENT_TYPE, event.getType().getNumber());
+ values.put(BatteryEventEntity.KEY_BATTERY_LEVEL, event.getBatteryLevel());
+ return values;
+ }
+
/** Gets the encoded string from {@link BatteryInformation} instance. */
public static String convertBatteryInformationToString(
final BatteryInformation batteryInformation) {
@@ -237,6 +247,29 @@
return eventBuilder.build();
}
+ /** Converts to {@link BatteryEvent} from {@link BatteryEventType} */
+ public static BatteryEvent convertToBatteryEvent(
+ long timestamp, BatteryEventType type, int batteryLevel) {
+ final BatteryEvent.Builder eventBuilder = BatteryEvent.newBuilder();
+ eventBuilder.setTimestamp(timestamp);
+ eventBuilder.setType(type);
+ eventBuilder.setBatteryLevel(batteryLevel);
+ return eventBuilder.build();
+ }
+
+ /** Converts to {@link BatteryEvent} from {@link Cursor} */
+ public static BatteryEvent convertToBatteryEventFromCursor(final Cursor cursor) {
+ final BatteryEvent.Builder eventBuilder = BatteryEvent.newBuilder();
+ eventBuilder.setTimestamp(getLongFromCursor(cursor, BatteryEventEntity.KEY_TIMESTAMP));
+ eventBuilder.setType(
+ BatteryEventType.forNumber(
+ getIntegerFromCursor(
+ cursor, BatteryEventEntity.KEY_BATTERY_EVENT_TYPE)));
+ eventBuilder.setBatteryLevel(
+ getIntegerFromCursor(cursor, BatteryEventEntity.KEY_BATTERY_LEVEL));
+ return eventBuilder.build();
+ }
+
/** Converts UTC timestamp to local time string for logging only, so use the US locale for
* better readability in debugging. */
public static String utcToLocalTimeForLogging(long timestamp) {
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java
index 1f25ae0..6b007de 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java
@@ -72,6 +72,8 @@
private final Handler mHandler;
private final DataProcessor.UsageMapAsyncResponse mCallbackFunction;
+ private final List<AppUsageEvent> mAppUsageEventList = new ArrayList<>();
+ private final List<BatteryEvent> mBatteryEventList = new ArrayList<>();
private Context mContext;
private UserManager mUserManager;
@@ -84,12 +86,12 @@
private boolean mIsCurrentBatteryHistoryLoaded = false;
private boolean mIsCurrentAppUsageLoaded = false;
private boolean mIsDatabaseAppUsageLoaded = false;
+ private boolean mIsBatteryEventLoaded = false;
// Used to identify whether screen-on time data should be shown in the UI.
private boolean mShowScreenOnTime = true;
// Used to identify whether battery level data should be shown in the UI.
private boolean mShowBatteryLevel = true;
- private List<AppUsageEvent> mAppUsageEventList = new ArrayList<>();
/**
* The indexed {@link AppUsagePeriod} list data for each corresponding time slot.
* <p>{@code Long} stands for the userId.</p>
@@ -146,6 +148,8 @@
loadDatabaseAppUsageList();
// Loads the latest app usage list from the service.
loadCurrentAppUsageList();
+ // Loads the battery event list from database.
+ loadBatteryEventList();
} else {
// If there is no battery level data, only load the battery history data from service
// and show it as the app list directly.
@@ -175,6 +179,11 @@
}
@VisibleForTesting
+ boolean getIsBatteryEventLoaded() {
+ return mIsBatteryEventLoaded;
+ }
+
+ @VisibleForTesting
boolean getIsCurrentBatteryHistoryLoaded() {
return mIsCurrentBatteryHistoryLoaded;
}
@@ -290,7 +299,7 @@
return null;
}
final long startTime = System.currentTimeMillis();
- // Loads the current battery usage data from the battery stats service.
+ // Loads the app usage data from the database.
final List<AppUsageEvent> appUsageEventList =
DatabaseUtils.getAppUsageEventForUsers(
mContext, Calendar.getInstance(), getCurrentUserIds(),
@@ -314,6 +323,35 @@
}.execute();
}
+ private void loadBatteryEventList() {
+ new AsyncTask<Void, Void, List<BatteryEvent>>() {
+ @Override
+ protected List<BatteryEvent> doInBackground(Void... voids) {
+ final long startTime = System.currentTimeMillis();
+ // Loads the battery event data from the database.
+ final List<BatteryEvent> batteryEventList =
+ DatabaseUtils.getBatteryEvents(
+ mContext, Calendar.getInstance(), mRawStartTimestamp);
+ Log.d(TAG, String.format("execute loadBatteryEventList size=%d in %d/ms",
+ batteryEventList.size(), (System.currentTimeMillis() - startTime)));
+ return batteryEventList;
+ }
+
+ @Override
+ protected void onPostExecute(
+ final List<BatteryEvent> batteryEventList) {
+ if (batteryEventList == null || batteryEventList.isEmpty()) {
+ Log.d(TAG, "batteryEventList is null or empty");
+ } else {
+ mBatteryEventList.clear();
+ mBatteryEventList.addAll(batteryEventList);
+ }
+ mIsBatteryEventLoaded = true;
+ tryToProcessAppUsageData();
+ }
+ }.execute();
+ }
+
private void loadAndApplyBatteryMapFromServiceOnly() {
new AsyncTask<Void, Void, BatteryCallbackData>() {
@Override
@@ -344,9 +382,8 @@
}
private void tryToProcessAppUsageData() {
- // Only when all app usage events has been loaded, start processing app usage data to an
- // intermediate result for further use.
- if (!mIsCurrentAppUsageLoaded || !mIsDatabaseAppUsageLoaded) {
+ // Ignore processing the data if any required data is not loaded.
+ if (!mIsCurrentAppUsageLoaded || !mIsDatabaseAppUsageLoaded || !mIsBatteryEventLoaded) {
return;
}
processAppUsageData();
@@ -360,16 +397,16 @@
}
// Generates the indexed AppUsagePeriod list data for each corresponding time slot for
// further use.
- mAppUsagePeriodMap = DataProcessor.generateAppUsagePeriodMap(
- mRawStartTimestamp, mHourlyBatteryLevelsPerDay, mAppUsageEventList);
+ mAppUsagePeriodMap = DataProcessor.generateAppUsagePeriodMap(mRawStartTimestamp,
+ mHourlyBatteryLevelsPerDay, mAppUsageEventList, mBatteryEventList);
}
private void tryToGenerateFinalDataAndApplyCallback() {
- // Only when both battery history data and app usage events data has been loaded, start the
- // final data processing.
+ // Ignore processing the data if any required data is not loaded.
if (!mIsCurrentBatteryHistoryLoaded
|| !mIsCurrentAppUsageLoaded
- || !mIsDatabaseAppUsageLoaded) {
+ || !mIsDatabaseAppUsageLoaded
+ || !mIsBatteryEventLoaded) {
return;
}
generateFinalDataAndApplyCallback();
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
index 38d4e69..6270eb3 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
@@ -95,6 +95,14 @@
static final int SELECTED_INDEX_ALL = BatteryChartViewModel.SELECTED_INDEX_ALL;
@VisibleForTesting
+ static final Comparator<AppUsageEvent> APP_USAGE_EVENT_TIMESTAMP_COMPARATOR =
+ Comparator.comparing(AppUsageEvent::getTimestamp);
+
+ @VisibleForTesting
+ static final Comparator<BatteryEvent> BATTERY_EVENT_TIMESTAMP_COMPARATOR =
+ Comparator.comparing(BatteryEvent::getTimestamp);
+
+ @VisibleForTesting
static boolean sDebug = false;
@VisibleForTesting
@@ -110,8 +118,6 @@
public static final String CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER =
"CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER";
- public static final Comparator<AppUsageEvent> TIMESTAMP_COMPARATOR =
- Comparator.comparing(AppUsageEvent::getTimestamp);
/** A callback listener when battery usage loading async task is executed. */
public interface UsageMapAsyncResponse {
@@ -266,14 +272,16 @@
generateAppUsagePeriodMap(
final long rawStartTimestamp,
final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay,
- final List<AppUsageEvent> appUsageEventList) {
+ final List<AppUsageEvent> appUsageEventList,
+ final List<BatteryEvent> batteryEventList) {
if (appUsageEventList.isEmpty()) {
Log.w(TAG, "appUsageEventList is empty");
return null;
}
- // Sorts the appUsageEventList in ascending order based on the timestamp before
- // distribution.
- Collections.sort(appUsageEventList, TIMESTAMP_COMPARATOR);
+ // Sorts the appUsageEventList and batteryEventList in ascending order based on the
+ // timestamp before distribution.
+ Collections.sort(appUsageEventList, APP_USAGE_EVENT_TIMESTAMP_COMPARATOR);
+ Collections.sort(batteryEventList, BATTERY_EVENT_TIMESTAMP_COMPARATOR);
final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>> resultMap =
new ArrayMap<>();
@@ -309,8 +317,8 @@
// The value could be null when there is no data in the hourly slot.
dailyMap.put(
hourlyIndex,
- buildAppUsagePeriodList(
- hourlyAppUsageEventList, startTimestamp, endTimestamp));
+ buildAppUsagePeriodList(hourlyAppUsageEventList, batteryEventList,
+ startTimestamp, endTimestamp));
}
}
return resultMap;
@@ -717,7 +725,8 @@
@VisibleForTesting
@Nullable
static Map<Long, Map<String, List<AppUsagePeriod>>> buildAppUsagePeriodList(
- final List<AppUsageEvent> allAppUsageEvents, final long startTime, final long endTime) {
+ final List<AppUsageEvent> allAppUsageEvents, final List<BatteryEvent> batteryEventList,
+ final long startTime, final long endTime) {
if (allAppUsageEvents.isEmpty()) {
return null;
}
@@ -763,12 +772,14 @@
usageEvents.addAll(deviceEvents);
// Sorts the usageEvents in ascending order based on the timestamp before computing the
// period.
- Collections.sort(usageEvents, TIMESTAMP_COMPARATOR);
+ Collections.sort(usageEvents, APP_USAGE_EVENT_TIMESTAMP_COMPARATOR);
// A package might have multiple instances. Computes the usage period per instance id
// and then merges them into the same user-package map.
final List<AppUsagePeriod> usagePeriodList =
- buildAppUsagePeriodListPerInstance(usageEvents, startTime, endTime);
+ excludePowerConnectedTimeFromAppUsagePeriodList(
+ buildAppUsagePeriodListPerInstance(usageEvents, startTime, endTime),
+ batteryEventList);
if (!usagePeriodList.isEmpty()) {
addToUsagePeriodMap(allUsagePeriods, usagePeriodList, eventUserId, packageName);
}
@@ -837,6 +848,53 @@
}
@VisibleForTesting
+ static List<AppUsagePeriod> excludePowerConnectedTimeFromAppUsagePeriodList(
+ final List<AppUsagePeriod> usagePeriodList,
+ final List<BatteryEvent> batteryEventList) {
+ final List<AppUsagePeriod> resultList = new ArrayList<>();
+ for (AppUsagePeriod inputPeriod : usagePeriodList) {
+ long lastStartTime = inputPeriod.getStartTime();
+ for (BatteryEvent batteryEvent : batteryEventList) {
+ if (batteryEvent.getTimestamp() < inputPeriod.getStartTime()) {
+ // Because the batteryEventList has been sorted, here is to mark the power
+ // connection state when the usage period starts. If power is connected when
+ // the usage period starts, the starting period will be ignored; otherwise it
+ // will be added.
+ if (batteryEvent.getType() == BatteryEventType.POWER_CONNECTED) {
+ lastStartTime = 0;
+ } else if (batteryEvent.getType() == BatteryEventType.POWER_DISCONNECTED) {
+ lastStartTime = inputPeriod.getStartTime();
+ }
+ continue;
+ }
+ if (batteryEvent.getTimestamp() > inputPeriod.getEndTime()) {
+ // Because the batteryEventList has been sorted, if any event is already after
+ // the end time, all the following events should be able to drop directly.
+ break;
+ }
+
+ if (batteryEvent.getType() == BatteryEventType.POWER_CONNECTED
+ && lastStartTime != 0) {
+ resultList.add(AppUsagePeriod.newBuilder()
+ .setStartTime(lastStartTime)
+ .setEndTime(batteryEvent.getTimestamp())
+ .build());
+ lastStartTime = 0;
+ } else if (batteryEvent.getType() == BatteryEventType.POWER_DISCONNECTED) {
+ lastStartTime = batteryEvent.getTimestamp();
+ }
+ }
+ if (lastStartTime != 0) {
+ resultList.add(AppUsagePeriod.newBuilder()
+ .setStartTime(lastStartTime)
+ .setEndTime(inputPeriod.getEndTime())
+ .build());
+ }
+ }
+ return resultList;
+ }
+
+ @VisibleForTesting
static long getScreenOnTime(
final Map<Long, Map<String, List<AppUsagePeriod>>> appUsageMap,
final long userId,
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
index ef1434c..84a39bb 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
@@ -64,10 +64,12 @@
/** An authority name of the battery content provider. */
public static final String AUTHORITY = "com.android.settings.battery.usage.provider";
- /** A table name for battery usage history. */
- public static final String BATTERY_STATE_TABLE = "BatteryState";
/** A table name for app usage events. */
public static final String APP_USAGE_EVENT_TABLE = "AppUsageEvent";
+ /** A table name for battery events. */
+ public static final String BATTERY_EVENT_TABLE = "BatteryEvent";
+ /** A table name for battery usage history. */
+ public static final String BATTERY_STATE_TABLE = "BatteryState";
/** A path name for app usage latest timestamp query. */
public static final String APP_USAGE_LATEST_TIMESTAMP_PATH = "appUsageLatestTimestamp";
/** A class name for battery usage data provider. */
@@ -84,13 +86,6 @@
*/
public static final long USAGE_QUERY_BUFFER_HOURS = Duration.ofHours(3).toMillis();
- /** A content URI to access battery usage states data. */
- public static final Uri BATTERY_CONTENT_URI =
- new Uri.Builder()
- .scheme(ContentResolver.SCHEME_CONTENT)
- .authority(AUTHORITY)
- .appendPath(BATTERY_STATE_TABLE)
- .build();
/** A content URI to access app usage events data. */
public static final Uri APP_USAGE_EVENT_URI =
new Uri.Builder()
@@ -98,6 +93,20 @@
.authority(AUTHORITY)
.appendPath(APP_USAGE_EVENT_TABLE)
.build();
+ /** A content URI to access battery events data. */
+ public static final Uri BATTERY_EVENT_URI =
+ new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(AUTHORITY)
+ .appendPath(BATTERY_EVENT_TABLE)
+ .build();
+ /** A content URI to access battery usage states data. */
+ public static final Uri BATTERY_CONTENT_URI =
+ new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(AUTHORITY)
+ .appendPath(BATTERY_STATE_TABLE)
+ .build();
// For testing only.
@VisibleForTesting
@@ -106,6 +115,8 @@
static Supplier<Cursor> sFakeAppUsageEventSupplier;
@VisibleForTesting
static Supplier<Cursor> sFakeAppUsageLatestTimestampSupplier;
+ @VisibleForTesting
+ static Supplier<Cursor> sFakeBatteryEventSupplier;
private DatabaseUtils() {
}
@@ -176,6 +187,32 @@
return appUsageEventList;
}
+ /** Returns the battery event data since the query timestamp in battery event table. */
+ public static List<BatteryEvent> getBatteryEvents(
+ Context context,
+ final Calendar calendar,
+ final long rawStartTimestamp) {
+ final long startTime = System.currentTimeMillis();
+ final long sixDaysAgoTimestamp = getTimestampSixDaysAgo(calendar);
+ final long queryTimestamp = Math.max(rawStartTimestamp, sixDaysAgoTimestamp);
+ Log.d(TAG, "getBatteryEvents for timestamp: " + queryTimestamp);
+ // Builds the content uri everytime to avoid cache.
+ final Uri batteryEventUri =
+ new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(AUTHORITY)
+ .appendPath(BATTERY_EVENT_TABLE)
+ .appendQueryParameter(
+ QUERY_KEY_TIMESTAMP, Long.toString(queryTimestamp))
+ .build();
+
+ final List<BatteryEvent> batteryEventList =
+ loadBatteryEventsFromContentProvider(context, batteryEventUri);
+ Log.d(TAG, String.format("getBatteryEvents size=%d in %d/ms", batteryEventList.size(),
+ (System.currentTimeMillis() - startTime)));
+ return batteryEventList;
+ }
+
/** Long: for timestamp and String: for BatteryHistEntry.getKey() */
public static Map<Long, Map<String, BatteryHistEntry>> getHistoryMapSinceLastFullCharge(
Context context, Calendar calendar) {
@@ -210,8 +247,9 @@
try {
final BatteryStateDatabase database = BatteryStateDatabase
.getInstance(context.getApplicationContext());
- database.batteryStateDao().clearAll();
database.appUsageEventDao().clearAll();
+ database.batteryEventDao().clearAll();
+ database.batteryStateDao().clearAll();
} catch (RuntimeException e) {
Log.e(TAG, "clearAll() failed", e);
}
@@ -226,8 +264,9 @@
.getInstance(context.getApplicationContext());
final long earliestTimestamp = Clock.systemUTC().millis()
- Duration.ofDays(DATA_RETENTION_INTERVAL_DAY).toMillis();
- database.batteryStateDao().clearAllBefore(earliestTimestamp);
database.appUsageEventDao().clearAllBefore(earliestTimestamp);
+ database.batteryEventDao().clearAllBefore(earliestTimestamp);
+ database.batteryStateDao().clearAllBefore(earliestTimestamp);
} catch (RuntimeException e) {
Log.e(TAG, "clearAllBefore() failed", e);
}
@@ -292,6 +331,23 @@
return valuesList;
}
+ static ContentValues sendBatteryEventData(
+ final Context context, final BatteryEvent batteryEvent) {
+ final long startTime = System.currentTimeMillis();
+ ContentValues contentValues = ConvertUtils.convertBatteryEventToContentValues(batteryEvent);
+ final ContentResolver resolver = context.getContentResolver();
+ try {
+ resolver.insert(BATTERY_EVENT_URI, contentValues);
+ Log.d(TAG, "insert() battery event data into database: " + batteryEvent.toString());
+ } catch (Exception e) {
+ Log.e(TAG, "insert() battery event data into database error:\n" + e);
+ }
+ Log.d(TAG, String.format("sendBatteryEventData() in %d/ms",
+ (System.currentTimeMillis() - startTime)));
+ clearMemory();
+ return contentValues;
+ }
+
static List<ContentValues> sendBatteryEntryData(
final Context context,
final List<BatteryEntry> batteryEntryList,
@@ -392,6 +448,8 @@
public static void dump(Context context, PrintWriter writer) {
writeString(context, writer, "BatteryLevelChanged",
Intent.ACTION_BATTERY_LEVEL_CHANGED);
+ writeString(context, writer, "BatteryPlugging",
+ BatteryUsageBroadcastReceiver.ACTION_BATTERY_PLUGGING);
writeString(context, writer, "BatteryUnplugging",
BatteryUsageBroadcastReceiver.ACTION_BATTERY_UNPLUGGING);
writeString(context, writer, "ClearBatteryCacheData",
@@ -475,6 +533,32 @@
return appUsageEventList;
}
+ private static List<BatteryEvent> loadBatteryEventsFromContentProvider(
+ Context context, Uri batteryEventUri) {
+ final List<BatteryEvent> batteryEventList = new ArrayList<>();
+ context = getParentContext(context);
+ if (context == null) {
+ return batteryEventList;
+ }
+ try (Cursor cursor = sFakeBatteryEventSupplier != null
+ ? sFakeBatteryEventSupplier.get()
+ : context.getContentResolver().query(batteryEventUri, null, null, null)) {
+ if (cursor == null || cursor.getCount() == 0) {
+ return batteryEventList;
+ }
+ // Loads and recovers all AppUsageEvent data from cursor.
+ while (cursor.moveToNext()) {
+ batteryEventList.add(ConvertUtils.convertToBatteryEventFromCursor(cursor));
+ }
+ try {
+ cursor.close();
+ } catch (Exception e) {
+ Log.e(TAG, "cursor.close() failed", e);
+ }
+ }
+ return batteryEventList;
+ }
+
private static Map<Long, Map<String, BatteryHistEntry>> loadHistoryMapFromContentProvider(
Context context, Uri batteryStateUri) {
context = DatabaseUtils.getParentContext(context);
diff --git a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDao.java b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDao.java
new file mode 100644
index 0000000..a638d09
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDao.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 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.settings.fuelgauge.batteryusage.db;
+
+import android.database.Cursor;
+
+import androidx.room.Dao;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
+
+import java.util.List;
+
+/** Data access object for accessing {@link BatteryEventEntity} in the database. */
+@Dao
+public interface BatteryEventDao {
+ /** Inserts a {@link BatteryEventEntity} data into the database. */
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void insert(BatteryEventEntity event);
+
+ /** Gets all recorded data. */
+ @Query("SELECT * FROM BatteryEventEntity ORDER BY timestamp DESC")
+ List<BatteryEventEntity> getAll();
+
+ /** Gets the {@link Cursor} of all recorded data after a specific timestamp. */
+ @Query("SELECT * FROM BatteryEventEntity WHERE timestamp > :timestamp ORDER BY timestamp DESC")
+ Cursor getAllAfter(long timestamp);
+
+ /** Deletes all recorded data before a specific timestamp. */
+ @Query("DELETE FROM BatteryEventEntity WHERE timestamp <= :timestamp")
+ void clearAllBefore(long timestamp);
+
+ /** Clears all recorded data in the database. */
+ @Query("DELETE FROM BatteryEventEntity")
+ void clearAll();
+}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventEntity.java b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventEntity.java
new file mode 100644
index 0000000..66cadda
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventEntity.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2023 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.settings.fuelgauge.batteryusage.db;
+
+import android.content.ContentValues;
+
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+import com.android.settings.fuelgauge.batteryusage.ConvertUtils;
+
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+
+import java.util.Locale;
+
+/** A {@link Entity} class to save battery events into database. */
+@Entity
+public class BatteryEventEntity {
+ /** Keys for accessing {@link ContentValues}. */
+ public static final String KEY_TIMESTAMP = "timestamp";
+ public static final String KEY_BATTERY_EVENT_TYPE = "batteryEventType";
+ public static final String KEY_BATTERY_LEVEL = "batteryLevel";
+
+ @PrimaryKey(autoGenerate = true)
+ private long mId;
+
+ public final long timestamp;
+ public final int batteryEventType;
+ public final int batteryLevel;
+
+ public BatteryEventEntity(
+ final long timestamp,
+ final int batteryEventType,
+ final int batteryLevel) {
+ this.timestamp = timestamp;
+ this.batteryEventType = batteryEventType;
+ this.batteryLevel = batteryLevel;
+ }
+
+ /** Sets the auto-generated content ID. */
+ public void setId(long id) {
+ this.mId = id;
+ }
+
+ /** Gets the auto-generated content ID. */
+ public long getId() {
+ return mId;
+ }
+
+ @Override
+ public String toString() {
+ final String recordAtDateTime = ConvertUtils.utcToLocalTimeForLogging(timestamp);
+ final StringBuilder builder = new StringBuilder()
+ .append("\nBatteryEvent{")
+ .append(String.format(Locale.US,
+ "\n\ttimestamp=%s|batteryEventType=%d|batteryLevel=%d",
+ recordAtDateTime, batteryEventType, batteryLevel))
+ .append("\n}");
+ return builder.toString();
+ }
+
+ /** Creates new {@link BatteryEventEntity} from {@link ContentValues}. */
+ public static BatteryEventEntity create(ContentValues contentValues) {
+ Builder builder = BatteryEventEntity.newBuilder();
+ if (contentValues.containsKey(KEY_TIMESTAMP)) {
+ builder.setTimestamp(contentValues.getAsLong(KEY_TIMESTAMP));
+ }
+ if (contentValues.containsKey(KEY_BATTERY_EVENT_TYPE)) {
+ builder.setBatteryEventType(contentValues.getAsInteger(KEY_BATTERY_EVENT_TYPE));
+ }
+ if (contentValues.containsKey(KEY_BATTERY_LEVEL)) {
+ builder.setBatteryLevel(contentValues.getAsInteger(KEY_BATTERY_LEVEL));
+ }
+ return builder.build();
+ }
+
+ /** Creates a new {@link Builder} instance. */
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ /** A convenience builder class to improve readability. */
+ public static class Builder {
+ private long mTimestamp;
+ private int mBatteryEventType;
+ private int mBatteryLevel;
+
+ /** Sets the timestamp. */
+ @CanIgnoreReturnValue
+ public Builder setTimestamp(final long timestamp) {
+ mTimestamp = timestamp;
+ return this;
+ }
+
+ /** Sets the battery event type. */
+ @CanIgnoreReturnValue
+ public Builder setBatteryEventType(final int batteryEventType) {
+ mBatteryEventType = batteryEventType;
+ return this;
+ }
+
+ /** Sets the battery level. */
+ @CanIgnoreReturnValue
+ public Builder setBatteryLevel(final int batteryLevel) {
+ mBatteryLevel = batteryLevel;
+ return this;
+ }
+
+ /** Builds the {@link BatteryEventEntity}. */
+ public BatteryEventEntity build() {
+ return new BatteryEventEntity(
+ mTimestamp,
+ mBatteryEventType,
+ mBatteryLevel);
+ }
+
+ private Builder() {}
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDatabase.java b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDatabase.java
index 4c8df7e..466a7ca 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDatabase.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDatabase.java
@@ -25,24 +25,26 @@
/** A {@link RoomDatabase} for battery usage states history. */
@Database(
- entities = {BatteryState.class, AppUsageEventEntity.class},
+ entities = {AppUsageEventEntity.class, BatteryEventEntity.class, BatteryState.class},
version = 1)
public abstract class BatteryStateDatabase extends RoomDatabase {
private static final String TAG = "BatteryStateDatabase";
private static BatteryStateDatabase sBatteryStateDatabase;
- /** Provides DAO for battery state table. */
- public abstract BatteryStateDao batteryStateDao();
/** Provides DAO for app usage event table. */
public abstract AppUsageEventDao appUsageEventDao();
+ /** Provides DAO for battery event table. */
+ public abstract BatteryEventDao batteryEventDao();
+ /** Provides DAO for battery state table. */
+ public abstract BatteryStateDao batteryStateDao();
/** Gets or creates an instance of {@link RoomDatabase}. */
public static BatteryStateDatabase getInstance(Context context) {
if (sBatteryStateDatabase == null) {
sBatteryStateDatabase =
Room.databaseBuilder(
- context, BatteryStateDatabase.class, "battery-usage-db-v7")
+ context, BatteryStateDatabase.class, "battery-usage-db-v8")
// Allows accessing data in the main thread for dumping bugreport.
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
diff --git a/src/com/android/settings/fuelgauge/protos/Android.bp b/src/com/android/settings/fuelgauge/protos/Android.bp
index 2c63af4..3af2aef 100644
--- a/src/com/android/settings/fuelgauge/protos/Android.bp
+++ b/src/com/android/settings/fuelgauge/protos/Android.bp
@@ -8,17 +8,25 @@
}
java_library {
+ name: "app-usage-event-protos-lite",
+ proto: {
+ type: "lite",
+ },
+ srcs: ["app_usage_event.proto"],
+}
+
+java_library {
+ name: "battery-event-protos-lite",
+ proto: {
+ type: "lite",
+ },
+ srcs: ["battery_event.proto"],
+}
+
+java_library {
name: "fuelgauge-usage-state-protos-lite",
proto: {
type: "lite",
},
srcs: ["fuelgauge_usage_state.proto"],
}
-
-java_library {
- name: "app-usage-event-protos-lite",
- proto: {
- type: "lite",
- },
- srcs: ["app_usage_event.proto"],
-}
\ No newline at end of file
diff --git a/src/com/android/settings/fuelgauge/protos/battery_event.proto b/src/com/android/settings/fuelgauge/protos/battery_event.proto
new file mode 100644
index 0000000..80ccb3b
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/protos/battery_event.proto
@@ -0,0 +1,17 @@
+syntax = "proto2";
+
+option java_multiple_files = true;
+option java_package = "com.android.settings.fuelgauge.batteryusage";
+option java_outer_classname = "BatteryEventProto";
+
+enum BatteryEventType {
+ UNKNOWN_EVENT = 0;
+ POWER_CONNECTED = 1;
+ POWER_DISCONNECTED = 2;
+}
+
+message BatteryEvent {
+ optional int64 timestamp = 1;
+ optional BatteryEventType type = 2;
+ optional int32 battery_level = 3;
+}
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java
index 893ad4c..8278be8 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutPickerController.java
@@ -28,6 +28,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.TickButtonPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -38,7 +39,7 @@
public class NewKeyboardLayoutPickerController extends BasePreferenceController implements
InputManager.InputDeviceListener, LifecycleObserver, OnStart, OnStop {
private final InputManager mIm;
- private final Map<KeyboardLayoutPreference, KeyboardLayout> mPreferenceMap;
+ private final Map<TickButtonPreference, KeyboardLayout> mPreferenceMap;
private Fragment mParent;
private int mInputDeviceId;
@@ -102,16 +103,15 @@
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
-
- if (!(preference instanceof KeyboardLayoutPreference)) {
+ if (!(preference instanceof TickButtonPreference)) {
return false;
}
- final KeyboardLayoutPreference pref = (KeyboardLayoutPreference) preference;
- pref.setCheckMark(true);
+ final TickButtonPreference pref = (TickButtonPreference) preference;
+ pref.setSelected(true);
if (mPreviousSelection != null && !mPreviousSelection.equals(preference.getKey())) {
- KeyboardLayoutPreference preSelectedPref = mScreen.findPreference(mPreviousSelection);
- preSelectedPref.setCheckMark(false);
+ TickButtonPreference preSelectedPref = mScreen.findPreference(mPreviousSelection);
+ preSelectedPref.setSelected(false);
}
setLayout(pref);
mPreviousSelection = preference.getKey();
@@ -140,12 +140,13 @@
return;
}
for (KeyboardLayout layout : mKeyboardLayouts) {
- final KeyboardLayoutPreference pref;
+ final TickButtonPreference pref;
+ pref = new TickButtonPreference(mScreen.getContext());
+ pref.setTitle(layout.getLabel());
+
if (mLayout.equals(layout.getLabel())) {
- pref = new KeyboardLayoutPreference(mScreen.getContext(), layout.getLabel(), true);
+ pref.setSelected(true);
mPreviousSelection = layout.getDescriptor();
- } else {
- pref = new KeyboardLayoutPreference(mScreen.getContext(), layout.getLabel(), false);
}
pref.setKey(layout.getDescriptor());
mScreen.addPreference(pref);
@@ -153,7 +154,7 @@
}
}
- private void setLayout(KeyboardLayoutPreference preference) {
+ private void setLayout(TickButtonPreference preference) {
mIm.setKeyboardLayoutForInputDevice(
mInputDeviceIdentifier,
mUserId,
diff --git a/src/com/android/settings/network/DefaultSubscriptionReceiver.java b/src/com/android/settings/network/DefaultSubscriptionReceiver.java
new file mode 100644
index 0000000..cdaf48f
--- /dev/null
+++ b/src/com/android/settings/network/DefaultSubscriptionReceiver.java
@@ -0,0 +1,59 @@
+package com.android.settings.network;
+
+import static com.android.internal.telephony.TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+public class DefaultSubscriptionReceiver extends BroadcastReceiver {
+
+ private Context mContext;
+ private DefaultSubscriptionListener mListener;
+
+ public DefaultSubscriptionReceiver(Context context, DefaultSubscriptionListener listener) {
+ mContext = context;
+ mListener = listener;
+ }
+
+ public void registerReceiver() {
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
+ filter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
+ filter.addAction(ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
+ filter.addAction(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
+ mContext.registerReceiver(this, filter);
+ }
+
+ public void unRegisterReceiver() {
+ mContext.unregisterReceiver(this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
+ mListener.onDefaultDataChanged(SubscriptionManager.getDefaultDataSubscriptionId());
+ } else if (SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED.equals(action)) {
+ mListener.onDefaultSubInfoChanged(SubscriptionManager.getDefaultSubscriptionId());
+ } else if (TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED.equals(action)) {
+ mListener.onDefaultVoiceChanged(SubscriptionManager.getDefaultVoiceSubscriptionId());
+ } else if (SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED.equals(action)) {
+ mListener.onDefaultSmsChanged(SubscriptionManager.getDefaultSmsSubscriptionId());
+ }
+ }
+
+ public interface DefaultSubscriptionListener {
+ default void onDefaultSubInfoChanged(int defaultSubId) {
+ }
+ default void onDefaultDataChanged(int defaultDataSubId) {
+ }
+ default void onDefaultVoiceChanged(int defaultVoiceSubId) {
+ }
+ default void onDefaultSmsChanged(int defaultSmsSubId) {
+ }
+ }
+}
diff --git a/src/com/android/settings/network/InternetPreferenceController.java b/src/com/android/settings/network/InternetPreferenceController.java
index 898585c..bc2e71e 100644
--- a/src/com/android/settings/network/InternetPreferenceController.java
+++ b/src/com/android/settings/network/InternetPreferenceController.java
@@ -27,9 +27,7 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import android.util.Log;
import androidx.annotation.IdRes;
import androidx.annotation.VisibleForTesting;
@@ -45,9 +43,7 @@
import com.android.settings.wifi.WifiSummaryUpdater;
import com.android.settingslib.Utils;
import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
-import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
@@ -60,7 +56,8 @@
*/
public class InternetPreferenceController extends AbstractPreferenceController implements
LifecycleObserver, SummaryUpdater.OnSummaryChangeListener,
- InternetUpdater.InternetChangeListener, MobileNetworkRepository.MobileNetworkCallback {
+ InternetUpdater.InternetChangeListener, MobileNetworkRepository.MobileNetworkCallback,
+ DefaultSubscriptionReceiver.DefaultSubscriptionListener {
public static final String KEY = "internet_settings";
@@ -71,6 +68,8 @@
private LifecycleOwner mLifecycleOwner;
private MobileNetworkRepository mMobileNetworkRepository;
private List<SubscriptionInfoEntity> mSubInfoEntityList = new ArrayList<>();
+ private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ private DefaultSubscriptionReceiver mDataSubscriptionChangedReceiver;
@VisibleForTesting
static Map<Integer, Integer> sIconMap = new HashMap<>();
@@ -102,6 +101,7 @@
mInternetType = mInternetUpdater.getInternetType();
mLifecycleOwner = lifecycleOwner;
mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+ mDataSubscriptionChangedReceiver = new DefaultSubscriptionReceiver(context, this);
lifecycle.addObserver(this);
}
@@ -160,6 +160,8 @@
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mMobileNetworkRepository.updateEntity();
mSummaryHelper.register(true);
+ mDataSubscriptionChangedReceiver.registerReceiver();
+ mDefaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
}
/** @OnLifecycleEvent(ON_PAUSE) */
@@ -167,6 +169,7 @@
public void onPause() {
mMobileNetworkRepository.removeRegister(this);
mSummaryHelper.register(false);
+ mDataSubscriptionChangedReceiver.unRegisterReceiver();
}
/**
@@ -212,11 +215,11 @@
if (subInfo.isActiveDataSubscriptionId) {
activeSubInfo = subInfo;
}
- if (subInfo.isDefaultDataSubscription) {
+ if (subInfo.getSubId() == getDefaultDataSubscriptionId()) {
defaultSubInfo = subInfo;
}
}
- if (activeSubInfo == null) {
+ if (activeSubInfo == null || defaultSubInfo == null) {
return;
}
activeSubInfo = activeSubInfo.isSubscriptionVisible ? activeSubInfo : defaultSubInfo;
@@ -237,9 +240,20 @@
return mSubInfoEntityList;
}
+ @VisibleForTesting
+ protected int getDefaultDataSubscriptionId() {
+ return mDefaultDataSubId;
+ }
+
@Override
public void onAvailableSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
mSubInfoEntityList = subInfoEntityList;
updateState(mPreference);
}
+
+ @Override
+ public void onDefaultDataChanged(int defaultDataSubId) {
+ mDefaultDataSubId = defaultDataSubId;
+ updateState(mPreference);
+ }
}
diff --git a/src/com/android/settings/network/MobileNetworkRepository.java b/src/com/android/settings/network/MobileNetworkRepository.java
index f5ea968..170d921 100644
--- a/src/com/android/settings/network/MobileNetworkRepository.java
+++ b/src/com/android/settings/network/MobileNetworkRepository.java
@@ -18,14 +18,9 @@
import static android.telephony.SubscriptionManager.PROFILE_CLASS_PROVISIONING;
import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
-import static com.android.internal.telephony.TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED;
-
import android.annotation.NonNull;
import android.app.settings.SettingsEnums;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
@@ -99,7 +94,6 @@
private AirplaneModeObserver mAirplaneModeObserver;
private Uri mAirplaneModeSettingUri;
private MetricsFeatureProvider mMetricsFeatureProvider;
- private IntentFilter mFilter = new IntentFilter();
private Map<Integer, MobileDataContentObserver> mDataContentObserverMap = new HashMap<>();
private int mPhysicalSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
private int mLogicalSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
@@ -112,12 +106,7 @@
private Map<Integer, SubscriptionInfo> mSubscriptionInfoMap = new ArrayMap<>();
private Map<Integer, TelephonyManager> mTelephonyManagerMap = new HashMap<>();
private Map<Integer, PhoneCallStateTelephonyCallback> mTelephonyCallbackMap = new HashMap<>();
- private BroadcastReceiver mDataSubscriptionChangedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- onSubscriptionsChanged();
- }
- };
+
@NonNull
public static MobileNetworkRepository getInstance(Context context) {
synchronized (sInstanceLock) {
@@ -143,10 +132,6 @@
mMobileNetworkInfoDao = mMobileNetworkDatabase.mMobileNetworkInfoDao();
mAirplaneModeObserver = new AirplaneModeObserver(new Handler(Looper.getMainLooper()));
mAirplaneModeSettingUri = Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON);
- mFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
- mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
- mFilter.addAction(ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
- mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
}
private class AirplaneModeObserver extends ContentObserver {
@@ -188,7 +173,6 @@
mSubscriptionManager.addOnSubscriptionsChangedListener(mContext.getMainExecutor(),
this);
mAirplaneModeObserver.register(mContext);
- mContext.registerReceiver(mDataSubscriptionChangedReceiver, mFilter);
if (DEBUG) {
Log.d(TAG, "addRegister done");
}
@@ -271,7 +255,6 @@
if (sCallbacks.isEmpty()) {
mSubscriptionManager.removeOnSubscriptionsChangedListener(this);
mAirplaneModeObserver.unRegister(mContext);
- mContext.unregisterReceiver(mDataSubscriptionChangedReceiver);
mDataContentObserverMap.forEach((id, observer) -> {
observer.unRegister(mContext);
});
@@ -524,16 +507,11 @@
SubscriptionUtil.getFormattedPhoneNumber(context, subInfo),
firstRemovableSubInfo == null ? false
: firstRemovableSubInfo.getSubscriptionId() == subId,
- String.valueOf(SubscriptionUtil.getDefaultSimConfig(context, subId)),
SubscriptionUtil.isDefaultSubscription(context, subId),
mSubscriptionManager.isValidSubscriptionId(subId),
mSubscriptionManager.isUsableSubscriptionId(subId),
mSubscriptionManager.isActiveSubscriptionId(subId),
true /*availableSubInfo*/,
- mSubscriptionManager.getDefaultVoiceSubscriptionId() == subId,
- mSubscriptionManager.getDefaultSmsSubscriptionId() == subId,
- mSubscriptionManager.getDefaultDataSubscriptionId() == subId,
- mSubscriptionManager.getDefaultSubscriptionId() == subId,
mSubscriptionManager.getActiveDataSubscriptionId() == subId);
}
}
diff --git a/src/com/android/settings/network/NetworkProviderCallsSmsController.java b/src/com/android/settings/network/NetworkProviderCallsSmsController.java
index 0c71aa7..5eec3d9 100644
--- a/src/com/android/settings/network/NetworkProviderCallsSmsController.java
+++ b/src/com/android/settings/network/NetworkProviderCallsSmsController.java
@@ -38,14 +38,13 @@
import com.android.settingslib.Utils;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
-import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
import java.util.List;
public class NetworkProviderCallsSmsController extends AbstractPreferenceController implements
- LifecycleObserver, MobileNetworkRepository.MobileNetworkCallback {
+ LifecycleObserver, MobileNetworkRepository.MobileNetworkCallback,
+ DefaultSubscriptionReceiver.DefaultSubscriptionListener {
private static final String TAG = "NetworkProviderCallsSmsController";
private static final String KEY = "calls_and_sms";
@@ -58,6 +57,9 @@
private LifecycleOwner mLifecycleOwner;
private MobileNetworkRepository mMobileNetworkRepository;
private List<SubscriptionInfoEntity> mSubInfoEntityList;
+ private int mDefaultVoiceSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ private int mDefaultSmsSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ private DefaultSubscriptionReceiver mDataSubscriptionChangedReceiver;
/**
* The summary text and click behavior of the "Calls & SMS" item on the
@@ -73,6 +75,7 @@
== View.LAYOUT_DIRECTION_RTL;
mLifecycleOwner = lifecycleOwner;
mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+ mDataSubscriptionChangedReceiver = new DefaultSubscriptionReceiver(context, this);
if (lifecycle != null) {
lifecycle.addObserver(this);
}
@@ -83,11 +86,15 @@
mMobileNetworkRepository.addRegister(mLifecycleOwner, this,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mMobileNetworkRepository.updateEntity();
+ mDataSubscriptionChangedReceiver.registerReceiver();
+ mDefaultVoiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
+ mDefaultSmsSubId = SubscriptionManager.getDefaultSmsSubscriptionId();
}
@OnLifecycleEvent(Event.ON_PAUSE)
public void onPause() {
mMobileNetworkRepository.removeRegister(this);
+ mDataSubscriptionChangedReceiver.unRegisterReceiver();
}
@Override
@@ -145,16 +152,16 @@
protected CharSequence getPreferredStatus(SubscriptionInfoEntity subInfo, int subsSize,
int subId) {
String status = "";
- boolean isDataPreferred = subInfo.isDefaultVoiceSubscription;
- boolean isSmsPreferred = subInfo.isDefaultSmsSubscription;
+ boolean isCallPreferred = subInfo.getSubId() == getDefaultVoiceSubscriptionId();
+ boolean isSmsPreferred = subInfo.getSubId() == getDefaultSmsSubscriptionId();
if (!subInfo.isValidSubscription || !isInService(subId)) {
status = setSummaryResId(subsSize > 1 ? R.string.calls_sms_unavailable :
R.string.calls_sms_temp_unavailable);
} else {
- if (isDataPreferred && isSmsPreferred) {
+ if (isCallPreferred && isSmsPreferred) {
status = setSummaryResId(R.string.calls_sms_preferred);
- } else if (isDataPreferred) {
+ } else if (isCallPreferred) {
status = setSummaryResId(R.string.calls_sms_calls_preferred);
} else if (isSmsPreferred) {
status = setSummaryResId(R.string.calls_sms_sms_preferred);
@@ -226,4 +233,26 @@
mSubInfoEntityList = activeSubInfoList;
update();
}
+
+ @VisibleForTesting
+ protected int getDefaultVoiceSubscriptionId() {
+ return mDefaultVoiceSubId;
+ }
+
+ @VisibleForTesting
+ protected int getDefaultSmsSubscriptionId() {
+ return mDefaultSmsSubId;
+ }
+
+ @Override
+ public void onDefaultVoiceChanged(int defaultVoiceSubId) {
+ mDefaultVoiceSubId = defaultVoiceSubId;
+ update();
+ }
+
+ @Override
+ public void onDefaultSmsChanged(int defaultSmsSubId) {
+ mDefaultSmsSubId = defaultSmsSubId;
+ update();
+ }
}
diff --git a/src/com/android/settings/network/NetworkProviderSimListController.java b/src/com/android/settings/network/NetworkProviderSimListController.java
index db27291..89cb73c 100644
--- a/src/com/android/settings/network/NetworkProviderSimListController.java
+++ b/src/com/android/settings/network/NetworkProviderSimListController.java
@@ -23,7 +23,6 @@
import android.graphics.drawable.Drawable;
import android.telephony.SubscriptionManager;
import android.util.ArrayMap;
-import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.LifecycleOwner;
@@ -38,16 +37,15 @@
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
-import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class NetworkProviderSimListController extends AbstractPreferenceController implements
- LifecycleObserver, MobileNetworkRepository.MobileNetworkCallback {
+ LifecycleObserver, MobileNetworkRepository.MobileNetworkCallback,
+ DefaultSubscriptionReceiver.DefaultSubscriptionListener {
private static final String TAG = "NetworkProviderSimListCtrl";
private static final String KEY_PREFERENCE_CATEGORY_SIM = "provider_model_sim_category";
private static final String KEY_PREFERENCE_SIM = "provider_model_sim_list";
@@ -58,6 +56,7 @@
private LifecycleOwner mLifecycleOwner;
private MobileNetworkRepository mMobileNetworkRepository;
private List<SubscriptionInfoEntity> mSubInfoEntityList = new ArrayList<>();
+ private DefaultSubscriptionReceiver mDataSubscriptionChangedReceiver;
public NetworkProviderSimListController(Context context, Lifecycle lifecycle,
LifecycleOwner lifecycleOwner) {
@@ -66,6 +65,7 @@
mPreferences = new ArrayMap<>();
mLifecycleOwner = lifecycleOwner;
mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+ mDataSubscriptionChangedReceiver = new DefaultSubscriptionReceiver(context, this);
lifecycle.addObserver(this);
}
@@ -74,11 +74,13 @@
mMobileNetworkRepository.addRegister(mLifecycleOwner, this,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mMobileNetworkRepository.updateEntity();
+ mDataSubscriptionChangedReceiver.registerReceiver();
}
@OnLifecycleEvent(ON_PAUSE)
public void onPause() {
mMobileNetworkRepository.removeRegister(this);
+ mDataSubscriptionChangedReceiver.unRegisterReceiver();
}
@Override
@@ -130,7 +132,8 @@
public CharSequence getSummary(SubscriptionInfoEntity subInfo, CharSequence displayName) {
if (subInfo.isActiveSubscriptionId) {
- CharSequence config = subInfo.defaultSimConfig;
+ CharSequence config = SubscriptionUtil.getDefaultSimConfig(mContext,
+ subInfo.getSubId());
CharSequence summary = mContext.getResources().getString(
R.string.sim_category_active_sim);
if (config == "") {
@@ -185,4 +188,22 @@
refreshSummary(mPreferenceCategory);
update();
}
+
+ @Override
+ public void onDefaultDataChanged(int defaultDataSubId) {
+ refreshSummary(mPreferenceCategory);
+ update();
+ }
+
+ @Override
+ public void onDefaultVoiceChanged(int defaultVoiceSubId) {
+ refreshSummary(mPreferenceCategory);
+ update();
+ }
+
+ @Override
+ public void onDefaultSmsChanged(int defaultSmsSubId) {
+ refreshSummary(mPreferenceCategory);
+ update();
+ }
}
diff --git a/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java b/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
index de45e62..249c855 100644
--- a/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
@@ -40,10 +40,12 @@
@Override
protected int getDefaultSubscriptionId() {
+ int defaultCallSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
for (SubscriptionInfoEntity subInfo : mSubInfoEntityList) {
- if (subInfo.isActiveSubscriptionId && subInfo.isDefaultVoiceSubscription) {
+ int subId = subInfo.getSubId();
+ if (subInfo.isActiveSubscriptionId && subId == defaultCallSubId) {
mSubscriptionInfoEntity = subInfo;
- return Integer.parseInt(subInfo.subId);
+ return subId;
}
}
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
index c8f7acf..cb18b33 100644
--- a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
@@ -36,11 +36,10 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
+import com.android.settings.network.DefaultSubscriptionReceiver;
import com.android.settings.network.MobileNetworkRepository;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
-import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
import java.util.ArrayList;
import java.util.List;
@@ -52,7 +51,8 @@
*/
public abstract class DefaultSubscriptionController extends TelephonyBasePreferenceController
implements LifecycleObserver, Preference.OnPreferenceChangeListener,
- MobileNetworkRepository.MobileNetworkCallback {
+ MobileNetworkRepository.MobileNetworkCallback,
+ DefaultSubscriptionReceiver.DefaultSubscriptionListener {
private static final String TAG = "DefaultSubController";
protected ListPreference mPreference;
@@ -60,6 +60,7 @@
protected TelecomManager mTelecomManager;
protected MobileNetworkRepository mMobileNetworkRepository;
protected LifecycleOwner mLifecycleOwner;
+ private DefaultSubscriptionReceiver mDataSubscriptionChangedReceiver;
private static final String EMERGENCY_ACCOUNT_HANDLE_ID = "E";
private static final ComponentName PSTN_CONNECTION_SERVICE_COMPONENT =
@@ -76,6 +77,7 @@
mIsRtlMode = context.getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL;
mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+ mDataSubscriptionChangedReceiver = new DefaultSubscriptionReceiver(context, this);
mLifecycleOwner = lifecycleOwner;
if (lifecycle != null) {
lifecycle.addObserver(this);
@@ -110,12 +112,13 @@
// Can not get default subId from database until get the callback, add register by subId
// later.
mMobileNetworkRepository.addRegisterBySubId(getDefaultSubscriptionId());
-
+ mDataSubscriptionChangedReceiver.registerReceiver();
}
@OnLifecycleEvent(ON_PAUSE)
public void onPause() {
mMobileNetworkRepository.removeRegister(this);
+ mDataSubscriptionChangedReceiver.unRegisterReceiver();
}
@Override
@@ -308,4 +311,16 @@
updateEntries();
refreshSummary(mPreference);
}
+
+ @Override
+ public void onDefaultVoiceChanged(int defaultVoiceSubId) {
+ updateEntries();
+ refreshSummary(mPreference);
+ }
+
+ @Override
+ public void onDefaultSmsChanged(int defaultSmsSubId) {
+ updateEntries();
+ refreshSummary(mPreference);
+ }
}
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index cf78942..4b6a728 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -20,8 +20,6 @@
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -36,13 +34,11 @@
import androidx.preference.SwitchPreference;
import com.android.settings.R;
-import com.android.settings.network.MobileDataContentObserver;
import com.android.settings.network.MobileNetworkRepository;
import com.android.settings.wifi.WifiPickerTrackerHelper;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
-import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
import java.util.ArrayList;
import java.util.List;
@@ -234,13 +230,14 @@
public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
mSubscriptionInfoEntityList = subInfoEntityList;
mSubscriptionInfoEntityList.forEach(entity -> {
- if (Integer.parseInt(entity.subId) == mSubId) {
+ if (entity.getSubId() == mSubId) {
mSubscriptionInfoEntity = entity;
}
});
+ int subId = mSubscriptionInfoEntity.getSubId();
if (mSubscriptionInfoEntity != null
- && mSubscriptionInfoEntity.isDefaultDataSubscription) {
- mDefaultSubId = Integer.parseInt(mSubscriptionInfoEntity.subId);
+ && subId == SubscriptionManager.getDefaultDataSubscriptionId()) {
+ mDefaultSubId = subId;
}
update();
refreshSummary(mPreference);
diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
index 265eb16..02455a1 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java
@@ -1011,7 +1011,7 @@
private static CharSequence getPreferredCallStatus(Context context,
SubscriptionInfoEntity subInfo) {
String status = "";
- if (subInfo.isDefaultVoiceSubscription) {
+ if (subInfo.getSubId() == SubscriptionManager.getDefaultVoiceSubscriptionId()) {
status = setSummaryResId(context, R.string.calls_sms_preferred);
}
@@ -1021,7 +1021,7 @@
private static CharSequence getPreferredSmsStatus(Context context,
SubscriptionInfoEntity subInfo) {
String status = "";
- if (subInfo.isDefaultSmsSubscription) {
+ if (subInfo.getSubId() == SubscriptionManager.getDefaultSmsSubscriptionId()) {
status = setSummaryResId(context, R.string.calls_sms_preferred);
}
diff --git a/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java b/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
index fddd358..be37513 100644
--- a/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
@@ -44,10 +44,12 @@
@Override
protected int getDefaultSubscriptionId() {
+ int defaultSmsSubId = SubscriptionManager.getDefaultSmsSubscriptionId();
for (SubscriptionInfoEntity subInfo : mSubInfoEntityList) {
- if (subInfo.isActiveSubscriptionId && subInfo.isDefaultSmsSubscription) {
+ int subId = subInfo.getSubId();
+ if (subInfo.isActiveSubscriptionId && subId == defaultSmsSubId) {
mSubscriptionInfoEntity = subInfo;
- return Integer.parseInt(subInfo.subId);
+ return subId;
}
}
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
diff --git a/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java b/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java
index 8e2d735..8b851b8 100644
--- a/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java
+++ b/src/com/android/settings/regionalpreferences/NumberingSystemItemController.java
@@ -34,6 +34,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.widget.TickButtonPreference;
import java.util.Locale;
@@ -138,7 +139,7 @@
String key = supportedLocale.getUnicodeLocaleType(
ExtensionTypes.NUMBERING_SYSTEM);
pref.setKey(key == null ? RegionalPreferencesDataUtils.DEFAULT_VALUE : key);
- pref.setTickEnable(isSameNumberingSystem(targetLocale, supportedLocale));
+ pref.setSelected(isSameNumberingSystem(targetLocale, supportedLocale));
screen.addPreference(pref);
}
}
@@ -162,7 +163,7 @@
TickButtonPreference pref = (TickButtonPreference) mPreferenceScreen.getPreference(i);
Log.i(TAG, "[onPreferenceClick] key is " + pref.getKey());
if (pref.getKey().equals(preference.getKey())) {
- pref.setTickEnable(true);
+ pref.setSelected(true);
Locale updatedLocale =
saveNumberingSystemToLocale(
Locale.forLanguageTag(mSelectedLanguage), pref.getKey());
@@ -176,7 +177,7 @@
mParentFragment.setArguments(bundle);
continue;
}
- pref.setTickEnable(false);
+ pref.setSelected(false);
}
}
diff --git a/src/com/android/settings/regionalpreferences/RegionalPreferencesFragment.java b/src/com/android/settings/regionalpreferences/RegionalPreferencesFragment.java
index 03bc8ac..ea9b7b3 100644
--- a/src/com/android/settings/regionalpreferences/RegionalPreferencesFragment.java
+++ b/src/com/android/settings/regionalpreferences/RegionalPreferencesFragment.java
@@ -29,6 +29,7 @@
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.widget.TickButtonPreference;
/** A fragment to include each kind of regional preferences. */
public class RegionalPreferencesFragment extends SettingsPreferenceFragment {
@@ -63,7 +64,7 @@
TickButtonPreference pref = (TickButtonPreference) mPreferenceScreen.getPreference(i);
Log.i(TAG, "[onPreferenceClick] key is " + pref.getKey());
if (pref.getKey().equals(preference.getKey())) {
- pref.setTickEnable(true);
+ pref.setSelected(true);
RegionalPreferencesDataUtils.savePreference(
getPrefContext(),
mType,
@@ -72,7 +73,7 @@
? null : preference.getKey());
continue;
}
- pref.setTickEnable(false);
+ pref.setSelected(false);
}
return true;
}
@@ -115,7 +116,7 @@
String value = RegionalPreferencesDataUtils.getDefaultUnicodeExtensionData(
getPrefContext(), mType);
pref.setKey(item);
- pref.setTickEnable(!value.isEmpty() && item.equals(value));
+ pref.setSelected(!value.isEmpty() && item.equals(value));
mPreferenceScreen.addPreference(pref);
}
return super.onCreateView(inflater, container, savedInstanceState);
diff --git a/src/com/android/settings/regionalpreferences/TickButtonPreference.java b/src/com/android/settings/regionalpreferences/TickButtonPreference.java
deleted file mode 100644
index c01521f..0000000
--- a/src/com/android/settings/regionalpreferences/TickButtonPreference.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2022 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.settings.regionalpreferences;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-import com.android.settingslib.widget.TwoTargetPreference;
-
-/** A preference with tick button */
-public class TickButtonPreference extends TwoTargetPreference {
- private static final String TAG = TickButtonPreference.class.getSimpleName();
- private boolean mIsTickEnabled;
- private View mWidgetFrame;
- private View mDivider;
-
- public TickButtonPreference(Context context) {
- super(context, null);
- }
-
- /** Set this preference to be selected. */
- public void setTickEnable(boolean isEnable) {
- mIsTickEnabled = isEnable;
- if (mWidgetFrame != null) {
- mWidgetFrame.setVisibility(isEnable ? View.VISIBLE : View.INVISIBLE);
- }
- }
-
- /** Check if this preference is selected. */
- public boolean isTickEnabled() {
- return mIsTickEnabled;
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
- super.onBindViewHolder(holder);
- mDivider = holder.findViewById(R.id.two_target_divider);
- mWidgetFrame = holder.findViewById(android.R.id.widget_frame);
- if (mDivider != null) {
- mDivider.setVisibility(View.GONE);
- }
- if (mWidgetFrame != null) {
- mWidgetFrame.setVisibility(mIsTickEnabled ? View.VISIBLE : View.INVISIBLE);
- }
- }
-
- @Override
- protected int getSecondTargetResId() {
- super.getSecondTargetResId();
- return R.layout.preference_widget_tick;
- }
-}
diff --git a/src/com/android/settings/search/SearchResultTrampoline.java b/src/com/android/settings/search/SearchResultTrampoline.java
index bcd8ee0..6ba0338 100644
--- a/src/com/android/settings/search/SearchResultTrampoline.java
+++ b/src/com/android/settings/search/SearchResultTrampoline.java
@@ -102,7 +102,8 @@
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
- if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)) {
+ if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)
+ || ActivityEmbeddingUtils.isAlreadyEmbedded(this)) {
startActivity(intent);
} else if (isSettingsIntelligence(callingActivity)) {
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SETTINGS_SEARCH_ALWAYS_EXPAND)) {
diff --git a/src/com/android/settings/inputmethod/KeyboardLayoutPreference.java b/src/com/android/settings/widget/TickButtonPreference.java
similarity index 61%
rename from src/com/android/settings/inputmethod/KeyboardLayoutPreference.java
rename to src/com/android/settings/widget/TickButtonPreference.java
index f9f858b..c55da2c 100644
--- a/src/com/android/settings/inputmethod/KeyboardLayoutPreference.java
+++ b/src/com/android/settings/widget/TickButtonPreference.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.inputmethod;
+package com.android.settings.widget;
import android.content.Context;
import android.view.View;
@@ -25,29 +25,33 @@
import com.android.settings.R;
-public class KeyboardLayoutPreference extends Preference {
-
+/** A preference with tick icon. */
+public class TickButtonPreference extends Preference {
private ImageView mCheckIcon;
- private boolean mIsMark;
+ private boolean mIsSelected = false;
- public KeyboardLayoutPreference(Context context, String layoutName, boolean defaultMark) {
+ public TickButtonPreference(Context context) {
super(context);
setWidgetLayoutResource(R.layout.preference_check_icon);
- setTitle(layoutName);
- mIsMark = defaultMark;
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
- mCheckIcon = (ImageView) holder.findViewById(R.id.keyboard_check_icon);
- setCheckMark(mIsMark);
+ mCheckIcon = (ImageView) holder.findViewById(R.id.check_icon);
+ setSelected(mIsSelected);
}
- public void setCheckMark(boolean isMark) {
+ /** Set icon state.*/
+ public void setSelected(boolean isSelected) {
if (mCheckIcon != null) {
- mCheckIcon.setVisibility(isMark ? View.VISIBLE : View.INVISIBLE);
- mIsMark = isMark;
+ mCheckIcon.setVisibility(isSelected ? View.VISIBLE : View.INVISIBLE);
}
+ mIsSelected = isSelected;
+ }
+
+ /** Return state of presenting icon. */
+ public boolean isSelected() {
+ return mIsSelected;
}
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index 6c9d498..e6f0b31 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -28,7 +28,6 @@
import android.provider.Settings;
import android.util.EventLog;
import android.util.Log;
-import android.view.WindowManager;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentTransaction;
@@ -100,7 +99,6 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
if (savedInstanceState != null) {
String qrCode = savedInstanceState.getString(KEY_QR_CODE);
diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceControllerTest.java
new file mode 100644
index 0000000..bf3d9f7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsFooterPreferenceControllerTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2023 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.settings.biometrics.face;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.hardware.face.FaceManager;
+import android.hardware.face.FaceSensorProperties;
+import android.hardware.face.FaceSensorPropertiesInternal;
+import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
+import android.os.Looper;
+import android.os.RemoteException;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settingslib.widget.FooterPreference;
+
+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.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class FaceSettingsFooterPreferenceControllerTest {
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ private static final String PREF_KEY = "security_face_footer";
+ @Mock
+ private FaceManager mFaceManager;
+ @Captor
+ private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mCaptor;
+ private Preference mPreference;
+ private Context mContext;
+ private FaceSettingsFooterPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ mContext = spy(RuntimeEnvironment.application);
+ if (Looper.myLooper() == null) {
+ Looper.prepare(); // needed to create the preference screen
+ }
+ ShadowApplication.getInstance().setSystemService(Context.FACE_SERVICE, mFaceManager);
+
+ mController = new FaceSettingsFooterPreferenceController(mContext, PREF_KEY);
+ PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
+ mPreference = new FooterPreference(mContext);
+ mPreference.setKey(PREF_KEY);
+ screen.addPreference(mPreference);
+
+ mController.displayPreference(screen);
+ }
+
+ @Test
+ public void isSliceable_returnFalse() {
+ assertThat(mController.isSliceable()).isFalse();
+ }
+
+ @Test
+ public void testString_faceNotClass3() throws RemoteException {
+ verify(mFaceManager).addAuthenticatorsRegisteredCallback(mCaptor.capture());
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.security_settings_face_settings_footer));
+
+ List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ FaceSensorProperties.STRENGTH_WEAK,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ mCaptor.getValue().onAllAuthenticatorsRegistered(props);
+
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.security_settings_face_settings_footer));
+ }
+
+ @Test
+ public void testString_faceClass3() throws RemoteException {
+ verify(mFaceManager).addAuthenticatorsRegisteredCallback(mCaptor.capture());
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.security_settings_face_settings_footer));
+
+ List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal(
+ 0 /* id */,
+ FaceSensorProperties.STRENGTH_STRONG,
+ 1 /* maxTemplatesAllowed */,
+ new ArrayList<>() /* componentInfo */,
+ FaceSensorProperties.TYPE_UNKNOWN,
+ true /* supportsFaceDetection */,
+ true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
+ mCaptor.getValue().onAllAuthenticatorsRegistered(props);
+
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.security_settings_face_settings_footer_class3));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
index 56a8373..fc3e6c0 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
@@ -286,8 +286,8 @@
@Test
public void handwritingPreference_checkedWhenFlagTrue() {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, 1);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
@@ -297,8 +297,8 @@
@Test
public void handwritingPreference_uncheckedWhenFlagFalse() {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, 0);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, 0);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
@@ -308,22 +308,22 @@
@Test
public void handwritingPreference_updatesFlagOnClick() {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, 0);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, 0);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
handwritingPref.performClick();
assertThat(handwritingPref.isChecked()).isEqualTo(true);
- assertThat(Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, -1)).isEqualTo(1);
+ assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, -1)).isEqualTo(1);
}
@Test
public void handwritingPreference_startsHandwritingSettingsOnClickIfChecked() {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, 0);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, 0);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
@@ -335,8 +335,8 @@
@Test
public void handwritingPreference_doesNotStartHandwritingSettingsOnClickIfNotChecked() {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, 1);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
@@ -350,8 +350,8 @@
public void handwritingPreference_doesNotStartHandwritingSettingsIfNoIntent() {
when(mInputMethodInfo.createStylusHandwritingSettingsActivityIntent())
.thenReturn(null);
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, 1);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
index 3a10132..f7db0d5 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
@@ -22,6 +22,7 @@
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -31,6 +32,7 @@
import android.net.ConnectivityManager;
import android.net.NetworkTemplate;
import android.os.Bundle;
+import android.os.UserManager;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
@@ -60,6 +62,9 @@
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.android.controller.ActivityController;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
@@ -74,6 +79,8 @@
private TemplatePreference.NetworkServices mNetworkServices;
@Mock
private LoaderManager mLoaderManager;
+ @Mock
+ private UserManager mUserManager;
private Activity mActivity;
private DataUsageList mDataUsageList;
@@ -90,6 +97,8 @@
mDataUsageList.mDataStateListener = mMobileDataEnabledListener;
doReturn(mActivity).when(mDataUsageList).getContext();
+ doReturn(mUserManager).when(mActivity).getSystemService(UserManager.class);
+ doReturn(false).when(mUserManager).isGuestUser();
ReflectionHelpers.setField(mDataUsageList, "mDataStateListener",
mMobileDataEnabledListener);
ReflectionHelpers.setField(mDataUsageList, "services", mNetworkServices);
@@ -97,6 +106,27 @@
}
@Test
+ @Config(shadows = ShadowDataUsageBaseFragment.class)
+ public void onCreate_isNotGuestUser_shouldNotFinish() {
+ doReturn(false).when(mUserManager).isGuestUser();
+ doNothing().when(mDataUsageList).processArgument();
+
+ mDataUsageList.onCreate(null);
+
+ verify(mDataUsageList, never()).finish();
+ }
+
+ @Test
+ @Config(shadows = ShadowDataUsageBaseFragment.class)
+ public void onCreate_isGuestUser_shouldFinish() {
+ doReturn(true).when(mUserManager).isGuestUser();
+
+ mDataUsageList.onCreate(null);
+
+ verify(mDataUsageList).finish();
+ }
+
+ @Test
public void resume_shouldListenDataStateChange() {
ReflectionHelpers.setField(
mDataUsageList, "mVisibilityLoggerMixin", mock(VisibilityLoggerMixin.class));
@@ -239,4 +269,17 @@
}
return pinnedHeader.findViewById(R.id.filter_spinner);
}
+
+ @Implements(DataUsageBaseFragment.class)
+ public static class ShadowDataUsageBaseFragment {
+ @Implementation
+ public void onCreate(Bundle icicle) {
+ // do nothing
+ }
+
+ @Implementation
+ protected boolean isBandwidthControlEnabled() {
+ return true;
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
index 68d49fc..4ac7387 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java
@@ -31,13 +31,14 @@
import android.content.Context;
import android.content.res.Resources;
import android.net.NetworkPolicyManager;
+import android.os.UserManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.fragment.app.FragmentActivity;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
-
import com.android.settings.testutils.shadow.ShadowDashboardFragment;
import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
@@ -45,13 +46,15 @@
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@@ -66,16 +69,22 @@
})
@RunWith(RobolectricTestRunner.class)
public class DataUsageSummaryTest {
-
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Spy
+ Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ private UserManager mUserManager;
@Mock
private NetworkPolicyManager mNetworkPolicyManager;
@Mock
private NetworkStatsManager mNetworkStatsManager;
private TelephonyManager mTelephonyManager;
- private Context mContext;
private Resources mResources;
private FragmentActivity mActivity;
+ private DataUsageSummary mDataUsageSummary;
+
/**
* This set up is contrived to get a passing test so that the build doesn't block without tests.
* These tests should be updated as code gets refactored to improve testability.
@@ -83,12 +92,13 @@
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+ doReturn(false).when(mUserManager).isGuestUser();
+
ShadowApplication shadowContext = ShadowApplication.getInstance();
ShadowUserManager.getShadow().setIsAdminUser(true);
shadowContext.setSystemService(Context.NETWORK_POLICY_SERVICE, mNetworkPolicyManager);
- mContext = spy(RuntimeEnvironment.application);
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
final ShadowTelephonyManager shadowTelephonyManager = Shadows.shadowOf(mTelephonyManager);
shadowTelephonyManager.setTelephonyManagerForSubscriptionId(
@@ -101,6 +111,12 @@
doReturn(true).when(mResources).getBoolean(R.bool.config_show_sim_info);
doReturn(mNetworkStatsManager).when(mActivity).getSystemService(NetworkStatsManager.class);
+
+ mDataUsageSummary = spy(new DataUsageSummary());
+ doReturn(mContext).when(mDataUsageSummary).getContext();
+ doNothing().when(mDataUsageSummary).enableProxySubscriptionManager(any());
+ doReturn(true).when(mDataUsageSummary).removePreference(anyString());
+ doNothing().when(mDataUsageSummary).addWifiSection();
}
@Test
@@ -201,4 +217,22 @@
verify(dataUsageSummary).addWifiSection();
verify(dataUsageSummary, never()).addMobileSection(anyInt());
}
+
+ @Test
+ public void onCreate_isNotGuestUser_shouldNotFinish() {
+ doReturn(false).when(mUserManager).isGuestUser();
+
+ mDataUsageSummary.onCreate(null);
+
+ verify(mDataUsageSummary, never()).finish();
+ }
+
+ @Test
+ public void onCreate_isGuestUser_shouldFinish() {
+ doReturn(true).when(mUserManager).isGuestUser();
+
+ mDataUsageSummary.onCreate(null);
+
+ verify(mDataUsageSummary).finish();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/development/StylusHandwritingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/StylusHandwritingPreferenceControllerTest.java
index 12b5fe9..51b83b3 100644
--- a/tests/robotests/src/com/android/settings/development/StylusHandwritingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/StylusHandwritingPreferenceControllerTest.java
@@ -63,8 +63,8 @@
public void onPreferenceChange_settingEnabled_stylusHandwritingShouldBeOn() {
mController.onPreferenceChange(mPreference, true /* new value */);
- final int mode = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, -1 /* default */);
+ final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, -1 /* default */);
assertThat(mode).isEqualTo(SETTING_VALUE_ON);
}
@@ -73,16 +73,16 @@
public void onPreferenceChange_settingEnabled_stylusHandwritingShouldBeOff() {
mController.onPreferenceChange(mPreference, false /* new value */);
- final int mode = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, -1 /* default */);
+ final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, -1 /* default */);
assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
}
@Test
public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_OFF);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_OFF);
mController.updateState(mPreference);
verify(mPreference).setChecked(false);
@@ -90,22 +90,11 @@
@Test
public void updateState_settingEnabled_preferenceShouldBeChecked() {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_ON);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.STYLUS_HANDWRITING_ENABLED, SETTING_VALUE_ON);
mController.updateState(mPreference);
verify(mPreference).setChecked(true);
}
- @Test
- public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
- mController.onDeveloperOptionsSwitchDisabled();
-
- final int mode = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.STYLUS_HANDWRITING_ENABLED, -1 /* default */);
-
- assertThat(mode).isEqualTo(SETTING_VALUE_OFF);
- verify(mPreference).setChecked(false);
- verify(mPreference).setEnabled(false);
- }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
index 9a7ef40..7398e5c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerTest.java
@@ -26,7 +26,6 @@
import android.content.Context;
import android.os.PowerManager;
-import android.provider.Settings;
import android.provider.SettingsSlicesContract;
import androidx.preference.PreferenceScreen;
@@ -73,24 +72,6 @@
}
@Test
- public void onSwitchChanged_isCheckedButNotAcked_preferenceIsUnchecked() {
- setLowPowerWarningAcked(/* acked= */ 0);
-
- mController.onSwitchChanged(/* switchView= */ null, /* isChecked= */ true);
-
- assertThat(mPreference.isChecked()).isFalse();
- }
-
- @Test
- public void onSwitchChanged_isCheckedAndAcked_setPowerSaveMode() {
- setLowPowerWarningAcked(/* acked= */ 1);
-
- mController.onSwitchChanged(/* switchView= */ null, /* isChecked= */ true);
-
- verify(mPowerManager).setPowerSaveModeEnabled(true);
- }
-
- @Test
public void updateState_lowPowerOn_preferenceIsChecked() {
when(mPowerManager.isPowerSaveMode()).thenReturn(true);
@@ -140,16 +121,4 @@
public void isPublicSlice_returnsTrue() {
assertThat(mController.isPublicSlice()).isTrue();
}
-
- // 0 means not acked, 1 means acked.
- private void setLowPowerWarningAcked(int acked) {
- Settings.Secure.putInt(
- mContext.getContentResolver(),
- Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
- acked);
- Settings.Secure.putInt(
- mContext.getContentResolver(),
- Settings.Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED,
- acked);
- }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProviderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProviderTest.java
index e5547c5..05a6f2b 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProviderTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProviderTest.java
@@ -31,6 +31,7 @@
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
+import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity;
import com.android.settings.fuelgauge.batteryusage.db.BatteryState;
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
import com.android.settings.testutils.BatteryTestUtils;
@@ -354,6 +355,28 @@
}
@Test
+ public void insert_batteryEvent_returnsExpectedResult() {
+ mProvider.onCreate();
+ ContentValues values = new ContentValues();
+ values.put(BatteryEventEntity.KEY_TIMESTAMP, 10001L);
+ values.put(BatteryEventEntity.KEY_BATTERY_EVENT_TYPE,
+ BatteryEventType.POWER_CONNECTED.getNumber());
+ values.put(BatteryEventEntity.KEY_BATTERY_LEVEL, 66);
+
+ final Uri uri = mProvider.insert(DatabaseUtils.BATTERY_EVENT_URI, values);
+
+ assertThat(uri).isEqualTo(DatabaseUtils.BATTERY_EVENT_URI);
+ // Verifies the AppUsageEventEntity content.
+ final List<BatteryEventEntity> entities =
+ BatteryStateDatabase.getInstance(mContext).batteryEventDao().getAll();
+ assertThat(entities).hasSize(1);
+ assertThat(entities.get(0).timestamp).isEqualTo(10001L);
+ assertThat(entities.get(0).batteryEventType).isEqualTo(
+ BatteryEventType.POWER_CONNECTED.getNumber());
+ assertThat(entities.get(0).batteryLevel).isEqualTo(66);
+ }
+
+ @Test
public void delete_throwsUnsupportedOperationException() {
assertThrows(
UnsupportedOperationException.class,
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java
index fe1bff6..6b8073b 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java
@@ -39,6 +39,7 @@
import android.os.UserHandle;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
+import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity;
import org.junit.Before;
import org.junit.Test;
@@ -195,6 +196,22 @@
}
@Test
+ public void convertBatteryEventToContentValues_normalCase_returnsExpectedContentValues() {
+ final BatteryEvent batteryEvent =
+ BatteryEvent.newBuilder()
+ .setTimestamp(10001L)
+ .setType(BatteryEventType.POWER_CONNECTED)
+ .setBatteryLevel(66)
+ .build();
+ final ContentValues values =
+ ConvertUtils.convertBatteryEventToContentValues(batteryEvent);
+ assertThat(values.getAsLong(BatteryEventEntity.KEY_TIMESTAMP)).isEqualTo(10001L);
+ assertThat(values.getAsInteger(BatteryEventEntity.KEY_BATTERY_EVENT_TYPE)).isEqualTo(
+ BatteryEventType.POWER_CONNECTED.getNumber());
+ assertThat(values.getAsInteger(BatteryEventEntity.KEY_BATTERY_LEVEL)).isEqualTo(66);
+ }
+
+ @Test
public void convertToBatteryHistEntry_returnsExpectedResult() {
final int expectedType = 3;
when(mMockBatteryEntry.getUid()).thenReturn(1001);
@@ -406,6 +423,15 @@
}
@Test
+ public void convertToBatteryEvent_normalCase_returnsExpectedResult() {
+ final BatteryEvent batteryEvent = ConvertUtils.convertToBatteryEvent(
+ 666L, BatteryEventType.POWER_DISCONNECTED, 88);
+ assertThat(batteryEvent.getTimestamp()).isEqualTo(666L);
+ assertThat(batteryEvent.getType()).isEqualTo(BatteryEventType.POWER_DISCONNECTED);
+ assertThat(batteryEvent.getBatteryLevel()).isEqualTo(88);
+ }
+
+ @Test
public void getLocale_nullContext_returnDefaultLocale() {
assertThat(ConvertUtils.getLocale(/*context=*/ null))
.isEqualTo(Locale.getDefault());
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
index aab91e0..753a7f7 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java
@@ -183,7 +183,7 @@
assertThat(dataProcessManager.getIsCurrentBatteryHistoryLoaded()).isTrue();
assertThat(dataProcessManager.getShowScreenOnTime()).isTrue();
final List<AppUsageEvent> appUsageEventList = dataProcessManager.getAppUsageEventList();
- Collections.sort(appUsageEventList, DataProcessor.TIMESTAMP_COMPARATOR);
+ Collections.sort(appUsageEventList, DataProcessor.APP_USAGE_EVENT_TIMESTAMP_COMPARATOR);
assertThat(appUsageEventList.size()).isEqualTo(6);
assertAppUsageEvent(
appUsageEventList.get(0), AppUsageEventType.ACTIVITY_RESUMED, /*timestamp=*/ 1);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
index aa15472..66e48c0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
@@ -250,7 +250,7 @@
final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>> periodMap =
DataProcessor.generateAppUsagePeriodMap(
- 14400000L, hourlyBatteryLevelsPerDay, appUsageEventList);
+ 14400000L, hourlyBatteryLevelsPerDay, appUsageEventList, new ArrayList<>());
assertThat(periodMap).hasSize(3);
// Day 1
@@ -288,7 +288,7 @@
hourlyBatteryLevelsPerDay.add(
new BatteryLevelData.PeriodBatteryLevelData(new ArrayList<>(), new ArrayList<>()));
assertThat(DataProcessor.generateAppUsagePeriodMap(
- 0L, hourlyBatteryLevelsPerDay, new ArrayList<>())).isNull();
+ 0L, hourlyBatteryLevelsPerDay, new ArrayList<>(), new ArrayList<>())).isNull();
}
@Test
@@ -1669,7 +1669,8 @@
/*instanceId=*/ 4, packageName2));
final Map<Long, Map<String, List<AppUsagePeriod>>> appUsagePeriodMap =
- DataProcessor.buildAppUsagePeriodList(appUsageEvents, 0, 5);
+ DataProcessor.buildAppUsagePeriodList(
+ appUsageEvents, new ArrayList<>(), 0, 5);
assertThat(appUsagePeriodMap).hasSize(2);
final Map<String, List<AppUsagePeriod>> userMap1 = appUsagePeriodMap.get(1L);
@@ -1693,7 +1694,7 @@
@Test
public void buildAppUsagePeriodList_emptyEventList_returnNull() {
assertThat(DataProcessor.buildAppUsagePeriodList(
- new ArrayList<>(), 0, 1)).isNull();
+ new ArrayList<>(), new ArrayList<>(), 0, 1)).isNull();
}
@Test
@@ -1705,7 +1706,7 @@
AppUsageEventType.DEVICE_SHUTDOWN, /*timestamp=*/ 2));
assertThat(DataProcessor.buildAppUsagePeriodList(
- appUsageEvents, 0, 3)).isNull();
+ appUsageEvents, new ArrayList<>(), 0, 3)).isNull();
}
@Test
@@ -1766,6 +1767,89 @@
}
@Test
+ public void excludePowerConnectedTime_startEndNotCharging_returnExpectedResult() {
+ final List<AppUsagePeriod> appUsagePeriodList = List.of(
+ AppUsagePeriod.newBuilder().setStartTime(100).setEndTime(200).build());
+ final List<BatteryEvent> batteryEventList = List.of(
+ BatteryEvent.newBuilder().setTimestamp(50).setType(
+ BatteryEventType.POWER_DISCONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(166).setType(
+ BatteryEventType.POWER_CONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(188).setType(
+ BatteryEventType.POWER_DISCONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(280).setType(
+ BatteryEventType.POWER_CONNECTED).build());
+
+ final List<AppUsagePeriod> resultList =
+ DataProcessor.excludePowerConnectedTimeFromAppUsagePeriodList(
+ appUsagePeriodList, batteryEventList);
+
+ assertThat(resultList).hasSize(2);
+ assertAppUsagePeriod(resultList.get(0), 100, 166);
+ assertAppUsagePeriod(resultList.get(1), 188, 200);
+ }
+
+ @Test
+ public void excludePowerConnectedTime_startEndInCharging_returnExpectedResult() {
+ final List<AppUsagePeriod> appUsagePeriodList = List.of(
+ AppUsagePeriod.newBuilder().setStartTime(100).setEndTime(200).build());
+ final List<BatteryEvent> batteryEventList = List.of(
+ BatteryEvent.newBuilder().setTimestamp(50).setType(
+ BatteryEventType.POWER_DISCONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(80).setType(
+ BatteryEventType.POWER_CONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(120).setType(
+ BatteryEventType.POWER_DISCONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(150).setType(
+ BatteryEventType.POWER_CONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(160).setType(
+ BatteryEventType.POWER_DISCONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(180).setType(
+ BatteryEventType.POWER_CONNECTED).build());
+
+ final List<AppUsagePeriod> resultList =
+ DataProcessor.excludePowerConnectedTimeFromAppUsagePeriodList(
+ appUsagePeriodList, batteryEventList);
+
+ assertThat(resultList).hasSize(2);
+ assertAppUsagePeriod(resultList.get(0), 120, 150);
+ assertAppUsagePeriod(resultList.get(1), 160, 180);
+ }
+
+ @Test
+ public void excludePowerConnectedTime_wholePeriodNotCharging_returnExpectedResult() {
+ final List<AppUsagePeriod> appUsagePeriodList = List.of(
+ AppUsagePeriod.newBuilder().setStartTime(100).setEndTime(200).build());
+ final List<BatteryEvent> batteryEventList = List.of(
+ BatteryEvent.newBuilder().setTimestamp(50).setType(
+ BatteryEventType.POWER_DISCONNECTED).build(),
+ BatteryEvent.newBuilder().setTimestamp(80).setType(
+ BatteryEventType.POWER_CONNECTED).build());
+
+ final List<AppUsagePeriod> resultList =
+ DataProcessor.excludePowerConnectedTimeFromAppUsagePeriodList(
+ appUsagePeriodList, batteryEventList);
+
+ assertThat(resultList).isEmpty();
+ }
+
+ @Test
+ public void excludePowerConnectedTime_wholePeriodInCharging_returnExpectedResult() {
+ final List<AppUsagePeriod> appUsagePeriodList = List.of(
+ AppUsagePeriod.newBuilder().setStartTime(100).setEndTime(200).build());
+ final List<BatteryEvent> batteryEventList = List.of(
+ BatteryEvent.newBuilder().setTimestamp(50).setType(
+ BatteryEventType.POWER_DISCONNECTED).build());
+
+ final List<AppUsagePeriod> resultList =
+ DataProcessor.excludePowerConnectedTimeFromAppUsagePeriodList(
+ appUsagePeriodList, batteryEventList);
+
+ assertThat(resultList).hasSize(1);
+ assertAppUsagePeriod(resultList.get(0), 100, 200);
+ }
+
+ @Test
public void getScreenOnTime_returnExpectedResult() {
final long userId = 1;
final String packageName = "com.android.settings";
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java
index 0cb3d1d..20799d4 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtilsTest.java
@@ -36,6 +36,7 @@
import android.os.UserManager;
import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
+import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity;
import com.android.settings.testutils.BatteryTestUtils;
import org.junit.Before;
@@ -137,6 +138,28 @@
}
@Test
+ public void sendBatteryEventData_returnsExpectedList() {
+ final BatteryEvent batteryEvent =
+ BatteryEvent.newBuilder()
+ .setTimestamp(10001L)
+ .setType(BatteryEventType.POWER_CONNECTED)
+ .setBatteryLevel(66)
+ .build();
+
+ final ContentValues contentValues =
+ DatabaseUtils.sendBatteryEventData(mContext, batteryEvent);
+
+ assertThat(contentValues.getAsInteger(BatteryEventEntity.KEY_TIMESTAMP))
+ .isEqualTo(10001L);
+ assertThat(contentValues.getAsInteger(BatteryEventEntity.KEY_BATTERY_EVENT_TYPE))
+ .isEqualTo(BatteryEventType.POWER_CONNECTED.getNumber());
+ assertThat(contentValues.getAsInteger(BatteryEventEntity.KEY_BATTERY_LEVEL))
+ .isEqualTo(66);
+ // Verifies the inserted ContentValues into content provider.
+ verify(mMockContentResolver).insert(DatabaseUtils.BATTERY_EVENT_URI, contentValues);
+ }
+
+ @Test
public void sendBatteryEntryData_nullBatteryIntent_returnsNullValue() {
doReturn(null).when(mContext).registerReceiver(any(), any());
assertThat(
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDaoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDaoTest.java
new file mode 100644
index 0000000..941f444
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDaoTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 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.settings.fuelgauge.batteryusage.db;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.database.Cursor;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.testutils.BatteryTestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link BatteryEventDao}. */
+@RunWith(RobolectricTestRunner.class)
+public final class BatteryEventDaoTest {
+ private Context mContext;
+ private BatteryStateDatabase mDatabase;
+ private BatteryEventDao mBatteryEventDao;
+
+ @Before
+ public void setUp() {
+ mContext = ApplicationProvider.getApplicationContext();
+ mDatabase = BatteryTestUtils.setUpBatteryStateDatabase(mContext);
+ mBatteryEventDao = mDatabase.batteryEventDao();
+ }
+
+ @After
+ public void closeDb() {
+ mDatabase.close();
+ BatteryStateDatabase.setBatteryStateDatabase(/*database=*/ null);
+ }
+
+ @Test
+ public void getAllAfter_returnExpectedResult() {
+ mBatteryEventDao.insert(BatteryEventEntity.newBuilder()
+ .setTimestamp(100L)
+ .setBatteryEventType(1)
+ .setBatteryLevel(66)
+ .build());
+ mBatteryEventDao.insert(BatteryEventEntity.newBuilder()
+ .setTimestamp(200L)
+ .setBatteryEventType(2)
+ .setBatteryLevel(88)
+ .build());
+
+ final Cursor cursor = mBatteryEventDao.getAllAfter(160L);
+ assertThat(cursor.getCount()).isEqualTo(1);
+ cursor.moveToFirst();
+ assertThat(cursor.getLong(cursor.getColumnIndex(BatteryEventEntity.KEY_TIMESTAMP)))
+ .isEqualTo(200L);
+ assertThat(cursor.getInt(cursor.getColumnIndex(BatteryEventEntity.KEY_BATTERY_EVENT_TYPE)))
+ .isEqualTo(2);
+ assertThat(cursor.getInt(cursor.getColumnIndex(BatteryEventEntity.KEY_BATTERY_LEVEL)))
+ .isEqualTo(88);
+
+ mBatteryEventDao.clearAll();
+ assertThat(mBatteryEventDao.getAll()).isEmpty();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventEntityTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventEntityTest.java
new file mode 100644
index 0000000..a34d651
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventEntityTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 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.settings.fuelgauge.batteryusage.db;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link BatteryEventEntity}. */
+@RunWith(RobolectricTestRunner.class)
+public final class BatteryEventEntityTest {
+
+ @Test
+ public void testBuilder_returnsExpectedResult() {
+ final long timestamp = 10001L;
+ final int batteryEventType = 1;
+ final int batteryLevel = 66;
+
+ BatteryEventEntity entity = BatteryEventEntity
+ .newBuilder()
+ .setTimestamp(timestamp)
+ .setBatteryEventType(batteryEventType)
+ .setBatteryLevel(batteryLevel)
+ .build();
+
+ // Verifies the app relative information.
+ assertThat(entity.timestamp).isEqualTo(timestamp);
+ assertThat(entity.batteryEventType).isEqualTo(batteryEventType);
+ assertThat(entity.batteryLevel).isEqualTo(batteryLevel);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
index 88fa83a..d8605de 100644
--- a/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -16,10 +16,6 @@
package com.android.settings.wifi.dpp;
-import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
-
-import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -77,12 +73,6 @@
}
@Test
- public void launchActivity_shouldAddFlagSecure() {
- assertThat(mActivity.getWindow().getAttributes().flags & FLAG_SECURE)
- .isEqualTo(FLAG_SECURE);
- }
-
- @Test
public void handleIntent_isGuestUser_shouldFinish() {
when(mUserManager.isGuestUser()).thenReturn(true);
diff --git a/tests/unit/src/com/android/settings/network/InternetPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/InternetPreferenceControllerTest.java
index 8beeffb..4e9339f 100644
--- a/tests/unit/src/com/android/settings/network/InternetPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/InternetPreferenceControllerTest.java
@@ -129,6 +129,8 @@
private class MockInternetPreferenceController extends
com.android.settings.network.InternetPreferenceController {
+
+ private int mDefaultDataSubscriptionId;
public MockInternetPreferenceController(Context context, Lifecycle lifecycle,
LifecycleOwner lifecycleOwner) {
super(context, lifecycle, lifecycleOwner);
@@ -145,18 +147,26 @@
mSubscriptionInfoEntity = list;
}
+ @Override
+ protected int getDefaultDataSubscriptionId() {
+ return mDefaultDataSubscriptionId;
+ }
+
+ public void setDefaultDataSubscriptionId(int subscriptionId) {
+ mDefaultDataSubscriptionId = subscriptionId;
+ }
+
}
private SubscriptionInfoEntity setupSubscriptionInfoEntity(String subId, int slotId,
int carrierId, String displayName, String mcc, String mnc, String countryIso,
int cardId, boolean isVisible, boolean isValid, boolean isActive, boolean isAvailable,
- boolean isDefaultData, boolean isActiveData) {
+ boolean isActiveData) {
return new SubscriptionInfoEntity(subId, slotId, carrierId,
displayName, displayName, 0, mcc, mnc, countryIso, false, cardId,
TelephonyManager.DEFAULT_PORT_INDEX, false, null,
SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, displayName, isVisible,
- "1234567890", true, "default", false, isValid, true, isActive, isAvailable, false,
- false, isDefaultData, false, isActiveData);
+ "1234567890", true, false, isValid, true, isActive, isAvailable, isActiveData);
}
@Test
@@ -183,7 +193,7 @@
mController.onResume();
mController.onPause();
- verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
+ verify(mContext, times(2)).unregisterReceiver(any(BroadcastReceiver.class));
verify(mConnectivityManager, times(2)).unregisterNetworkCallback(
any(ConnectivityManager.NetworkCallback.class));
}
@@ -218,10 +228,11 @@
@Test
public void updateCellularSummary_getActiveSubscriptionInfo_cbrs() {
+ mController.setDefaultDataSubscriptionId(Integer.parseInt(SUB_ID_2));
mActiveSubInfo = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, false, true, true, true, false, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, false, true, true, true, true);
mDefaultDataSubInfo = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, false, true, true, true, true, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, false, true, true, true, false);
mSubscriptionInfoEntityList.add(mActiveSubInfo);
mSubscriptionInfoEntityList.add(mDefaultDataSubInfo);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
@@ -231,7 +242,7 @@
assertThat(mPreference.getSummary()).isEqualTo(DISPLAY_NAME_2);
mActiveSubInfo = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, false, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
mSubscriptionInfoEntityList.add(mActiveSubInfo);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
mController.onAvailableSubInfoChanged(mSubscriptionInfoEntityList);
diff --git a/tests/unit/src/com/android/settings/network/NetworkProviderCallsSmsControllerTest.java b/tests/unit/src/com/android/settings/network/NetworkProviderCallsSmsControllerTest.java
index 007251a..51aecc5 100644
--- a/tests/unit/src/com/android/settings/network/NetworkProviderCallsSmsControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/NetworkProviderCallsSmsControllerTest.java
@@ -100,6 +100,8 @@
private List<SubscriptionInfoEntity> mSubscriptionInfoEntity;
private boolean mIsInService;
+ private int mDefaultVoiceSubscriptionId;
+ private int mDefaultSmsSubscriptionId;
@Override
protected List<SubscriptionInfoEntity> getSubscriptionInfoList() {
@@ -118,6 +120,24 @@
public void setInService(boolean inService) {
mIsInService = inService;
}
+
+ @Override
+ protected int getDefaultVoiceSubscriptionId() {
+ return mDefaultVoiceSubscriptionId;
+ }
+
+ @Override
+ protected int getDefaultSmsSubscriptionId() {
+ return mDefaultSmsSubscriptionId;
+ }
+
+ public void setDefaultVoiceSubscriptionId(int subscriptionId) {
+ mDefaultVoiceSubscriptionId = subscriptionId;
+ }
+
+ public void setDefaultSmsSubscriptionId(int subscriptionId) {
+ mDefaultSmsSubscriptionId = subscriptionId;
+ }
}
@Before
@@ -163,15 +183,13 @@
private SubscriptionInfoEntity setupSubscriptionInfoEntity(String subId, int slotId,
int carrierId, String displayName, String mcc, String mnc, String countryIso,
- int cardId, boolean isValid, boolean isActive, boolean isAvailable,
- boolean isDefaultCall, boolean isDefaultSms) {
+ int cardId, boolean isValid, boolean isActive, boolean isAvailable) {
return new SubscriptionInfoEntity(subId, slotId, carrierId,
displayName, displayName, 0, mcc, mnc, countryIso, false, cardId,
TelephonyManager.DEFAULT_PORT_INDEX, false, null,
SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, displayName, false,
- "1234567890", true, "default", false, isValid,
- true, isActive, isAvailable, isDefaultCall, isDefaultSms, false, false,
- false);
+ "1234567890", true, false, isValid,
+ true, isActive, isAvailable, false);
}
@Test
@@ -181,7 +199,7 @@
mSubInfo1 = setupSubscriptionInfoEntity(INVALID_SUB_ID,
SubscriptionManager.INVALID_SIM_SLOT_INDEX, TelephonyManager.UNKNOWN_CARRIER_ID,
DISPLAY_NAME_1, SUB_MCC_1, SUB_MNC_1, SUB_COUNTRY_ISO_1,
- TelephonyManager.UNINITIALIZED_CARD_ID, false, true, true, false, false);
+ TelephonyManager.UNINITIALIZED_CARD_ID, false, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
displayPreferenceWithLifecycle();
@@ -202,9 +220,9 @@
mSubInfo1 = setupSubscriptionInfoEntity(INVALID_SUB_ID,
SubscriptionManager.INVALID_SIM_SLOT_INDEX, TelephonyManager.UNKNOWN_CARRIER_ID,
DISPLAY_NAME_1, SUB_MCC_1, SUB_MNC_1, SUB_COUNTRY_ISO_1,
- TelephonyManager.UNINITIALIZED_CARD_ID, false, true, true, false, false);
+ TelephonyManager.UNINITIALIZED_CARD_ID, false, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
@@ -226,7 +244,7 @@
public void getSummary_oneSubscription_returnDisplayName() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, false, false);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
displayPreferenceWithLifecycle();
@@ -239,9 +257,9 @@
public void getSummary_allSubscriptionsHaveNoPreferredStatus_returnDisplayName() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, false, false);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
@@ -257,10 +275,13 @@
@UiThreadTest
public void getSummary_oneSubscriptionsIsCallPreferredTwoIsSmsPreferred_returnStatus() {
+ mController.setDefaultVoiceSubscriptionId(Integer.parseInt(SUB_ID_1));
+ mController.setDefaultSmsSubscriptionId(Integer.parseInt(SUB_ID_2));
+
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, false);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, true);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
@@ -284,10 +305,13 @@
@UiThreadTest
public void getSummary_oneSubscriptionsIsSmsPreferredTwoIsCallPreferred_returnStatus() {
+ mController.setDefaultSmsSubscriptionId(Integer.parseInt(SUB_ID_1));
+ mController.setDefaultVoiceSubscriptionId(Integer.parseInt(SUB_ID_2));
+
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, false, true);
- mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, true, false);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
+ mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 2, 2, DISPLAY_NAME_2, SUB_MCC_2,
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
@@ -311,10 +335,13 @@
@UiThreadTest
public void getSummary_oneSubscriptionsIsSmsPreferredAndIsCallPreferred_returnStatus() {
+ mController.setDefaultSmsSubscriptionId(Integer.parseInt(SUB_ID_1));
+ mController.setDefaultVoiceSubscriptionId(Integer.parseInt(SUB_ID_1));
+
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
diff --git a/tests/unit/src/com/android/settings/network/NetworkProviderSimListControllerTest.java b/tests/unit/src/com/android/settings/network/NetworkProviderSimListControllerTest.java
index 1c4238a..c4e0f64 100644
--- a/tests/unit/src/com/android/settings/network/NetworkProviderSimListControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/NetworkProviderSimListControllerTest.java
@@ -152,13 +152,11 @@
private SubscriptionInfoEntity setupSubscriptionInfoEntity(String subId, int slotId,
int carrierId, String displayName, String mcc, String mnc, String countryIso,
- int cardId, CharSequence defaultSimConfig, boolean isValid, boolean isActive,
- boolean isAvailable, boolean isDefaultCall, boolean isDefaultSms) {
+ int cardId, boolean isValid, boolean isActive, boolean isAvailable) {
return new SubscriptionInfoEntity(subId, slotId, carrierId, displayName, displayName, 0,
mcc, mnc, countryIso, false, cardId, TelephonyManager.DEFAULT_PORT_INDEX, false,
null, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, displayName, false,
- "1234567890", true, defaultSimConfig.toString(), false, isValid, true, isActive,
- isAvailable, isDefaultCall, isDefaultSms, false, false, false);
+ "1234567890", true, false, isValid, true, isActive, isAvailable, false);
}
private String setSummaryResId(String resName, String value) {
@@ -173,7 +171,7 @@
@UiThreadTest
public void getSummary_tapToActivePSim() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, "", true, false, true, false, false);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, false, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
displayPreferenceWithLifecycle();
@@ -186,7 +184,7 @@
@UiThreadTest
public void getSummary_inactivePSim() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, "", true, false, true, false, false);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, false, true);
doReturn(true).when(mSubscriptionManager).canDisablePhysicalSubscription();
mSubscriptionInfoEntityList.add(mSubInfo1);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
@@ -201,15 +199,13 @@
@UiThreadTest
public void getSummary_defaultCalls() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1,
- setSummaryResId("sim_category_default_active_sim",
- setSummaryResId("default_active_sim_calls")), true, true, true, true,
- false);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
displayPreferenceWithLifecycle();
- CharSequence defaultCall = mSubInfo1.defaultSimConfig;
+ CharSequence defaultCall = SubscriptionUtil.getDefaultSimConfig(mContext,
+ Integer.parseInt(SUB_ID_1));
final StringBuilder summary = new StringBuilder();
summary.append(setSummaryResId("sim_category_active_sim", null))
.append(defaultCall);
@@ -225,14 +221,13 @@
.append(", ")
.append(setSummaryResId("default_active_sim_sms"));
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1,
- setSummaryResId("sim_category_default_active_sim", defaultConfig.toString()), true,
- true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
displayPreferenceWithLifecycle();
- CharSequence defaultCall = mSubInfo1.defaultSimConfig;
+ CharSequence defaultCall = SubscriptionUtil.getDefaultSimConfig(mContext,
+ Integer.parseInt(SUB_ID_1));
final StringBuilder summary = new StringBuilder();
summary.append(setSummaryResId("sim_category_active_sim", null))
.append(defaultCall);
@@ -245,9 +240,9 @@
@UiThreadTest
public void getAvailablePhysicalSubscription_withTwoPhysicalSims_returnTwo() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, "", true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, "", true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
diff --git a/tests/unit/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
index ffc9f9b..bbec5bb 100644
--- a/tests/unit/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
@@ -135,15 +135,12 @@
private SubscriptionInfoEntity setupSubscriptionInfoEntity(String subId, int slotId,
int carrierId, String displayName, String mcc, String mnc, String countryIso,
- int cardId, boolean isValid, boolean isActive, boolean isAvailable,
- boolean isDefaultCall, boolean isDefaultSms) {
+ int cardId, boolean isValid, boolean isActive, boolean isAvailable) {
return new SubscriptionInfoEntity(subId, slotId, carrierId,
displayName, displayName, 0, mcc, mnc, countryIso, false, cardId,
TelephonyManager.DEFAULT_PORT_INDEX, false, null,
SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, displayName, false,
- "1234567890", true, "default", false, isValid,
- true, isActive, isAvailable, isDefaultCall,
- isDefaultSms, false, false, false);
+ "1234567890", true, false, isValid, true, isActive, isAvailable, false);
}
@Test
@@ -164,9 +161,9 @@
@Test
public void onPreferenceChange_prefChangedToSub2_callbackCalledCorrectly() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mController.setDefaultSubscription(Integer.parseInt(mSubInfo1.subId));
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
@@ -181,9 +178,9 @@
@Test
public void onPreferenceChange_prefChangedToAlwaysAsk_callbackCalledCorrectly() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mController.setDefaultSubscription(Integer.parseInt(mSubInfo1.subId));
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
@@ -201,9 +198,9 @@
public void onPreferenceChange_prefBecomesAvailable_onPreferenceChangeCallbackNotNull() {
// Start with only one sub active, so the pref is not available
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mController.setDefaultSubscription(Integer.parseInt(mSubInfo1.subId));
mSubscriptionInfoEntityList.add(mSubInfo1);
mController.setDefaultSubscription(Integer.parseInt(mSubInfo1.subId));
@@ -225,9 +222,9 @@
@Test
public void onSubscriptionsChanged_twoSubscriptionsDefaultChanges_selectedEntryGetsUpdated() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mController.setDefaultSubscription(Integer.parseInt(mSubInfo1.subId));
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
@@ -246,9 +243,9 @@
@Test
public void onSubscriptionsChanged_goFromTwoSubscriptionsToOne_prefDisappears() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
mController.setDefaultSubscription(Integer.parseInt(mSubInfo1.subId));
@@ -273,9 +270,9 @@
@UiThreadTest
public void onSubscriptionsChanged_goFromOneSubscriptionToTwo_prefAppears() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubscriptionInfoEntityList.add(mSubInfo1);
mController.setDefaultSubscription(Integer.parseInt(mSubInfo1.subId));
mController.setSubscriptionInfoList(mSubscriptionInfoEntityList);
@@ -297,11 +294,11 @@
@Test
public void onSubscriptionsChanged_goFromTwoToThreeSubscriptions_listGetsUpdated() {
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, 1, 1, DISPLAY_NAME_1, SUB_MCC_1,
- SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true, true, true);
+ SUB_MNC_1, SUB_COUNTRY_ISO_1, 1, true, true, true);
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, 1, 1, DISPLAY_NAME_2, SUB_MCC_2,
- SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true, false, false);
+ SUB_MNC_2, SUB_COUNTRY_ISO_2, 1, true, true, true);
mSubInfo3 = setupSubscriptionInfoEntity(SUB_ID_3, 1, 1, DISPLAY_NAME_3, SUB_MCC_3,
- SUB_MNC_3, SUB_COUNTRY_ISO_3, 1, true, true, true, false, false);
+ SUB_MNC_3, SUB_COUNTRY_ISO_3, 1, true, true, true);
mController.setDefaultSubscription(Integer.parseInt(mSubInfo1.subId));
mSubscriptionInfoEntityList.add(mSubInfo1);
mSubscriptionInfoEntityList.add(mSubInfo2);
diff --git a/tests/unit/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
index 16e3963..0373396 100644
--- a/tests/unit/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
@@ -114,15 +114,13 @@
}
private SubscriptionInfoEntity setupSubscriptionInfoEntity(String subId, String displayName,
- boolean isOpportunistic, boolean isValid, boolean isActive, boolean isAvailable,
- boolean isDefaultData) {
+ boolean isOpportunistic, boolean isValid, boolean isActive, boolean isAvailable) {
int id = Integer.parseInt(subId);
return new SubscriptionInfoEntity(subId, id, id,
displayName, displayName, 0, "mcc", "mnc", "countryIso", false, id,
TelephonyManager.DEFAULT_PORT_INDEX, isOpportunistic, null,
SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, displayName, false,
- "1234567890", true, "default", false, isValid, true, isActive, isAvailable, false,
- false, isDefaultData, false, false);
+ "1234567890", true, false, isValid, true, isActive, isAvailable, false);
}
private MobileNetworkInfoEntity setupMobileNetworkInfoEntity(String subId,
@@ -141,8 +139,7 @@
@Test
public void isDialogNeeded_disableSingleSim_returnFalse() {
- mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true,
- true);
+ mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true);
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
doReturn(1).when(mTelephonyManager).getActiveModemCount();
@@ -151,14 +148,12 @@
@Test
public void isDialogNeeded_enableNonDefaultSimInMultiSimMode_returnTrue() {
- mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true,
- false);
+ mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true);
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), false);
doReturn(1).when(mTelephonyManager).getActiveModemCount();
// Ideally, it would be better if we could set the default data subscription to
// SUB_ID_OTHER, and set that as an active subscription id.
- mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, DISPLAY_NAME_2, false, true, true, true,
- true);
+ mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, DISPLAY_NAME_2, false, true, true, true);
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
doReturn(2).when(mTelephonyManager).getActiveModemCount();
@@ -180,8 +175,7 @@
@Test
public void onPreferenceChange_singleSim_On_shouldEnableData() {
- mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true,
- true);
+ mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true);
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
mController.setSubscriptionInfoEntity(mSubInfo1);
mController.setMobileNetworkInfoEntity(mNetworkInfo1);
@@ -194,8 +188,7 @@
@Test
public void onPreferenceChange_multiSim_On_shouldEnableData() {
- mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true,
- true);
+ mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true);
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
mController.setSubscriptionInfoEntity(mSubInfo1);
mController.setMobileNetworkInfoEntity(mNetworkInfo1);
@@ -219,8 +212,7 @@
@Test
public void updateState_opportunistic_disabled() {
- mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true,
- true);
+ mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true);
mController.init(mFragmentManager, SUB_ID, mSubInfo1, mNetworkInfo1);
mController.updateState(mPreference);
@@ -232,8 +224,7 @@
@Test
public void updateState_notOpportunistic_enabled() {
- mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true,
- true);
+ mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true);
mController.init(mFragmentManager, SUB_ID, mSubInfo1, mNetworkInfo1);
mController.updateState(mPreference);
diff --git a/tests/unit/src/com/android/settings/regionalpreferences/NumberingSystemItemControllerTest.java b/tests/unit/src/com/android/settings/regionalpreferences/NumberingSystemItemControllerTest.java
index 5ec33db..708987e 100644
--- a/tests/unit/src/com/android/settings/regionalpreferences/NumberingSystemItemControllerTest.java
+++ b/tests/unit/src/com/android/settings/regionalpreferences/NumberingSystemItemControllerTest.java
@@ -33,6 +33,8 @@
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
+import com.android.settings.widget.TickButtonPreference;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;