Snap for 12404440 from 9cdd1108c3
to 24Q4-release
Change-Id: Iaf43ac3fd61ffff035ebf51289ef758f4ca42b47
This commit is contained in:
@@ -1,658 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<issues format="4">
|
||||
|
||||
<issue
|
||||
id="LintError"
|
||||
severity="Error"
|
||||
message="No `.class` files were found in project ".", so none of the classfile based checks could be run. Does the project need to be built first?"
|
||||
category="Lint"
|
||||
priority="10"
|
||||
summary="Lint Failure"
|
||||
explanation="This issue type represents a problem running lint itself. Examples include failure to find bytecode for source files (which means certain detectors could not be run), parsing errors in lint configuration files, etc.
These errors are not errors in your own code, but they are shown to make it clear that some checks were not completed.">
|
||||
<location
|
||||
file="."/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="38"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="38"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="39"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="39"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="52"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="52"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="53"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="53"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="66"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="66"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="67"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview.xml"
|
||||
line="67"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="46"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0" android:color="#001A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="46"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="47"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF1A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="47"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="60"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0" android:color="#001A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="60"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="61"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF1A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="61"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="74"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0" android:color="#001A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="74"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="75"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF1A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_three_finger_preview_tablet.xml"
|
||||
line="75"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_two_finger_preview.xml"
|
||||
line="38"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_two_finger_preview.xml"
|
||||
line="38"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_two_finger_preview.xml"
|
||||
line="39"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_two_finger_preview.xml"
|
||||
line="39"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_two_finger_preview.xml"
|
||||
line="52"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_two_finger_preview.xml"
|
||||
line="52"
|
||||
column="34"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_two_finger_preview.xml"
|
||||
line="53"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0.695" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_two_finger_preview.xml"
|
||||
line="53"
|
||||
column="38"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_two_finger_preview_tablet.xml"
|
||||
line="46"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0" android:color="#001A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_two_finger_preview_tablet.xml"
|
||||
line="46"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_two_finger_preview_tablet.xml"
|
||||
line="47"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF1A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_two_finger_preview_tablet.xml"
|
||||
line="47"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0" android:color="#00669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_two_finger_preview_tablet.xml"
|
||||
line="60"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0" android:color="#001A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_two_finger_preview_tablet.xml"
|
||||
line="60"
|
||||
column="36"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF669DF6"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable-night/accessibility_gesture_navigation_two_finger_preview_tablet.xml"
|
||||
line="61"
|
||||
column="39"/>
|
||||
</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=" <item android:offset="0.69" android:color="#FF1A73E8"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/accessibility_gesture_navigation_two_finger_preview_tablet.xml"
|
||||
line="61"
|
||||
column="39"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -1949,6 +1297,22 @@
|
||||
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="pointer_fill_outline_color">#FFFFFF</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values-night/colors.xml"
|
||||
line="81"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -3277,6 +2641,22 @@
|
||||
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="pointer_fill_outline_color">#000000</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="223"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -4685,6 +4065,22 @@
|
||||
column="11"/>
|
||||
</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
|
||||
file="res/drawable/ic_pointer_and_touchpad.xml"
|
||||
line="22"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -5101,6 +4497,102 @@
|
||||
column="15"/>
|
||||
</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/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="25"
|
||||
column="25"/>
|
||||
</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/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="25"
|
||||
column="25"/>
|
||||
</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/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="47"
|
||||
column="29"/>
|
||||
</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/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="47"
|
||||
column="29"/>
|
||||
</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/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="64"
|
||||
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=" android:color="@color/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="64"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -6973,103 +6465,4 @@
|
||||
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=" android:color="@color/accessibility_feature_background"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/ic_pointer_and_touchpad.xml"
|
||||
line="22"
|
||||
column="13"/>
|
||||
</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="pointer_fill_outline_color">#FFFFFF</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values-night/colors.xml"
|
||||
line="81"
|
||||
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="pointer_fill_outline_color">#000000</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="223"
|
||||
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=" android:color="@color/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="25"
|
||||
column="25"/>
|
||||
</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/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="47"
|
||||
column="25"/>
|
||||
</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/pointer_fill_outline_color" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
|
||||
<location
|
||||
file="res/drawable/pointer_icon_fill_color_foreground.xml"
|
||||
line="64"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
</issues>
|
@@ -12141,8 +12141,8 @@
|
||||
<string name="title_have_satellite_plan">Satellite messaging is included with your account</string>
|
||||
<!-- Title for category "Your mobile plan when satellite is not included in plan" [CHAR_LIMIT=NONE] -->
|
||||
<string name="title_no_satellite_plan">Satellite messaging isn\u2019t included with your account</string>
|
||||
<!-- text view add satellite messaging" [CHAR_LIMIT=NONE] -->
|
||||
<string name="summary_add_satellite_setting">Add satellite messaging</string>
|
||||
<!-- text view "Learn more" [CHAR_LIMIT=NONE] -->
|
||||
<string name="summary_add_satellite_setting">Learn More</string>
|
||||
<!-- Category name "How it works" [CHAR_LIMIT=NONE] -->
|
||||
<string name="category_name_how_it_works">How it works</string>
|
||||
<!-- Title for satellite connection guide [CHAR_LIMIT=NONE] -->
|
||||
|
@@ -72,7 +72,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
|
||||
@Nullable
|
||||
private AlertDialog mLoadingDialog = null;
|
||||
private AlertDialog mProgressDialog = null;
|
||||
@VisibleForTesting
|
||||
boolean mShouldTriggerAudioSharingShareThenPairFlow = false;
|
||||
private CopyOnWriteArrayList<BluetoothDevice> mDevicesWithMetadataChangedListener =
|
||||
@@ -89,7 +89,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
||||
// In share then pair flow, we have to wait on this page till the device is connected.
|
||||
// The BluetoothDevicePreference summary will be blank for seconds between "Pairing..." and
|
||||
// "Connecting..." To help users better understand the process, we listen to metadata change
|
||||
// as well and show a loading dialog with "Connecting to ...." once BluetoothDevice.getState()
|
||||
// as well and show a progress dialog with "Connecting to ...." once BluetoothDevice.getState()
|
||||
// gets to BOND_BONDED.
|
||||
final BluetoothAdapter.OnMetadataChangedListener mMetadataListener =
|
||||
new BluetoothAdapter.OnMetadataChangedListener() {
|
||||
@@ -97,7 +97,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
||||
public void onMetadataChanged(@NonNull BluetoothDevice device, int key,
|
||||
@Nullable byte[] value) {
|
||||
Log.d(getLogTag(), "onMetadataChanged device = " + device + ", key = " + key);
|
||||
if (mShouldTriggerAudioSharingShareThenPairFlow && mLoadingDialog == null
|
||||
if (mShouldTriggerAudioSharingShareThenPairFlow && mProgressDialog == null
|
||||
&& device.getBondState() == BluetoothDevice.BOND_BONDED
|
||||
&& mSelectedList.contains(device)) {
|
||||
triggerAudioSharingShareThenPairFlow(device);
|
||||
@@ -355,7 +355,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
||||
return;
|
||||
}
|
||||
mJustBonded = device;
|
||||
// Show connecting device loading state
|
||||
// Show connecting device progress
|
||||
String aliasName = device.getAlias();
|
||||
String deviceName = TextUtils.isEmpty(aliasName) ? device.getAddress()
|
||||
: aliasName;
|
||||
@@ -387,9 +387,9 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
||||
// TODO: use DialogFragment
|
||||
private void showConnectingDialog(@NonNull String message) {
|
||||
postOnMainThread(() -> {
|
||||
if (mLoadingDialog != null) {
|
||||
if (mProgressDialog != null) {
|
||||
Log.d(getLogTag(), "showConnectingDialog, is already showing");
|
||||
TextView textView = mLoadingDialog.findViewById(R.id.message);
|
||||
TextView textView = mProgressDialog.findViewById(R.id.message);
|
||||
if (textView != null && !message.equals(textView.getText().toString())) {
|
||||
Log.d(getLogTag(), "showConnectingDialog, update message");
|
||||
// TODO: use string res once finalized
|
||||
@@ -401,7 +401,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = LayoutInflater.from(builder.getContext());
|
||||
View customView = inflater.inflate(
|
||||
R.layout.dialog_audio_sharing_loading_state, /* root= */
|
||||
R.layout.dialog_audio_sharing_progress, /* root= */
|
||||
null);
|
||||
TextView textView = customView.findViewById(R.id.message);
|
||||
if (textView != null) {
|
||||
@@ -410,15 +410,15 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
||||
}
|
||||
AlertDialog dialog = builder.setView(customView).setCancelable(false).create();
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
mLoadingDialog = dialog;
|
||||
mProgressDialog = dialog;
|
||||
dialog.show();
|
||||
});
|
||||
}
|
||||
|
||||
private void dismissConnectingDialog() {
|
||||
postOnMainThread(() -> {
|
||||
if (mLoadingDialog != null) {
|
||||
mLoadingDialog.dismiss();
|
||||
if (mProgressDialog != null) {
|
||||
mProgressDialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.slice.Slice;
|
||||
@@ -36,10 +37,16 @@ import androidx.slice.builders.SliceAction;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.connecteddevice.BluetoothDashboardFragment;
|
||||
import com.android.settings.network.SatelliteRepository;
|
||||
import com.android.settings.slices.CustomSliceRegistry;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* Utility class to build a Bluetooth Slice, and handle all associated actions.
|
||||
*/
|
||||
@@ -80,18 +87,34 @@ public class BluetoothSliceBuilder {
|
||||
final PendingIntent primaryAction = getPrimaryAction(context);
|
||||
final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon,
|
||||
ListBuilder.ICON_IMAGE, title);
|
||||
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
|
||||
null /* actionTitle */, isBluetoothEnabled);
|
||||
|
||||
RowBuilder rowBuilder = new RowBuilder();
|
||||
rowBuilder.setTitle(title);
|
||||
rowBuilder.setPrimaryAction(primarySliceAction);
|
||||
if (!isSatelliteOn(context)) {
|
||||
final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
|
||||
null /* actionTitle */, isBluetoothEnabled);
|
||||
rowBuilder.addEndItem(toggleSliceAction);
|
||||
}
|
||||
return new ListBuilder(context, CustomSliceRegistry.BLUETOOTH_URI, ListBuilder.INFINITY)
|
||||
.setAccentColor(color)
|
||||
.addRow(new RowBuilder()
|
||||
.setTitle(title)
|
||||
.addEndItem(toggleSliceAction)
|
||||
.setPrimaryAction(primarySliceAction))
|
||||
.addRow(rowBuilder)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static boolean isSatelliteOn(Context context) {
|
||||
boolean result = false;
|
||||
SatelliteRepository satelliteRepository = new SatelliteRepository(context);
|
||||
try {
|
||||
result = satelliteRepository.requestIsSessionStarted(
|
||||
Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
Log.e(TAG, "Error to get satellite status : " + e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Intent getIntent(Context context) {
|
||||
final String screenTitle = context.getText(R.string.bluetooth_settings_title).toString();
|
||||
final Uri contentUri = new Uri.Builder().appendPath(
|
||||
|
@@ -29,8 +29,8 @@ import androidx.fragment.app.FragmentManager;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
|
||||
public class AudioSharingRetryDialogFragment extends InstrumentedDialogFragment {
|
||||
private static final String TAG = "AudioSharingRetryDialog";
|
||||
public class AudioSharingErrorDialogFragment extends InstrumentedDialogFragment {
|
||||
private static final String TAG = "AudioSharingErrorDialog";
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
@@ -39,7 +39,7 @@ public class AudioSharingRetryDialogFragment extends InstrumentedDialogFragment
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the {@link AudioSharingRetryDialogFragment} dialog.
|
||||
* Display the {@link AudioSharingErrorDialogFragment} dialog.
|
||||
*
|
||||
* @param host The Fragment this dialog will be hosted.
|
||||
*/
|
||||
@@ -57,8 +57,8 @@ public class AudioSharingRetryDialogFragment extends InstrumentedDialogFragment
|
||||
Log.d(TAG, "Dialog is showing, return.");
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Show up the retry dialog.");
|
||||
AudioSharingRetryDialogFragment dialogFrag = new AudioSharingRetryDialogFragment();
|
||||
Log.d(TAG, "Show up the error dialog.");
|
||||
AudioSharingErrorDialogFragment dialogFrag = new AudioSharingErrorDialogFragment();
|
||||
dialogFrag.show(manager, TAG);
|
||||
}
|
||||
|
@@ -40,8 +40,8 @@ import com.google.common.base.Strings;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFragment {
|
||||
private static final String TAG = "AudioSharingLoadingDlg";
|
||||
public class AudioSharingProgressDialogFragment extends InstrumentedDialogFragment {
|
||||
private static final String TAG = "AudioSharingProgressDlg";
|
||||
|
||||
private static final String BUNDLE_KEY_MESSAGE = "bundle_key_message";
|
||||
private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(15);
|
||||
@@ -58,7 +58,7 @@ public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFr
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the {@link AudioSharingLoadingStateDialogFragment} dialog.
|
||||
* Display the {@link AudioSharingProgressDialogFragment} dialog.
|
||||
*
|
||||
* @param host The Fragment this dialog will be hosted by.
|
||||
* @param message The content to be shown on the dialog.
|
||||
@@ -85,16 +85,15 @@ public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFr
|
||||
return;
|
||||
}
|
||||
sMessage = message;
|
||||
Log.d(TAG, "Show up the loading dialog.");
|
||||
Log.d(TAG, "Show up the progress dialog.");
|
||||
Bundle args = new Bundle();
|
||||
args.putString(BUNDLE_KEY_MESSAGE, message);
|
||||
AudioSharingLoadingStateDialogFragment dialogFrag =
|
||||
new AudioSharingLoadingStateDialogFragment();
|
||||
AudioSharingProgressDialogFragment dialogFrag = new AudioSharingProgressDialogFragment();
|
||||
dialogFrag.setArguments(args);
|
||||
dialogFrag.show(manager, TAG);
|
||||
}
|
||||
|
||||
/** Dismiss the {@link AudioSharingLoadingStateDialogFragment} dialog. */
|
||||
/** Dismiss the {@link AudioSharingProgressDialogFragment} dialog. */
|
||||
public static void dismiss(@Nullable Fragment host) {
|
||||
if (host == null || !BluetoothUtils.isAudioSharingEnabled()) return;
|
||||
final FragmentManager manager;
|
||||
@@ -119,7 +118,7 @@ public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFr
|
||||
String message = args.getString(BUNDLE_KEY_MESSAGE, "");
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = LayoutInflater.from(builder.getContext());
|
||||
View customView = inflater.inflate(R.layout.dialog_audio_sharing_loading_state, /* root= */
|
||||
View customView = inflater.inflate(R.layout.dialog_audio_sharing_progress, /* root= */
|
||||
null);
|
||||
TextView textView = customView.findViewById(R.id.message);
|
||||
if (!Strings.isNullOrEmpty(message)) textView.setText(message);
|
@@ -41,7 +41,9 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
@@ -69,7 +71,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -113,14 +114,21 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
private final Executor mExecutor;
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
private final OnAudioSharingStateChangedListener mListener;
|
||||
@VisibleForTesting IntentFilter mIntentFilter;
|
||||
private Map<Integer, List<BluetoothDevice>> mGroupedConnectedDevices = new HashMap<>();
|
||||
@Nullable private AudioSharingDeviceItem mTargetActiveItem;
|
||||
private List<AudioSharingDeviceItem> mDeviceItemsForSharing = new ArrayList<>();
|
||||
@VisibleForTesting IntentFilter mIntentFilter;
|
||||
private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
|
||||
private AtomicInteger mIntentHandleStage =
|
||||
new AtomicInteger(StartIntentHandleStage.TO_HANDLE.ordinal());
|
||||
// The sinks in adding source process. We show the progress dialog based on this list.
|
||||
private CopyOnWriteArrayList<BluetoothDevice> mSinksInAdding = new CopyOnWriteArrayList<>();
|
||||
// The primary/active sinks in adding source process.
|
||||
// To avoid users advance to share then pair flow before the primary/active sinks successfully
|
||||
// join the audio sharing, we will wait for the process complete for this list of sinks and then
|
||||
// popup audio sharing dialog with options to pair new device.
|
||||
private CopyOnWriteArrayList<BluetoothDevice> mSinksToWaitFor = new CopyOnWriteArrayList<>();
|
||||
private AtomicBoolean mStoppingSharing = new AtomicBoolean(false);
|
||||
|
||||
@VisibleForTesting
|
||||
BroadcastReceiver mReceiver =
|
||||
@@ -153,6 +161,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
public void onBroadcastStartFailed(int reason) {
|
||||
Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
|
||||
updateSwitch();
|
||||
showErrorDialog();
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED,
|
||||
@@ -178,7 +187,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
+ reason
|
||||
+ ", broadcastId = "
|
||||
+ broadcastId);
|
||||
mStoppingSharing.compareAndSet(true, false);
|
||||
updateSwitch();
|
||||
AudioSharingUtils.postOnMainThread(mContext,
|
||||
() -> dismissStaleDialogsOtherThanErrorDialog());
|
||||
AudioSharingUtils.toastMessage(
|
||||
mContext,
|
||||
mContext.getString(R.string.audio_sharing_sharing_stopped_label));
|
||||
@@ -219,7 +231,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
TAG,
|
||||
"Skip handleOnBroadcastReady: null assistant or "
|
||||
+ "sink has active local source.");
|
||||
cleanUp();
|
||||
cleanUpStatesForStartSharing();
|
||||
return;
|
||||
}
|
||||
handleOnBroadcastReady();
|
||||
@@ -264,17 +276,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
+ source
|
||||
+ ", reason = "
|
||||
+ reason);
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
|
||||
SettingsEnums.AUDIO_SHARING_SETTINGS);
|
||||
AudioSharingUtils.toastMessage(
|
||||
mContext,
|
||||
String.format(
|
||||
Locale.US,
|
||||
"Fail to add source to %s reason %d",
|
||||
sink.getAddress(),
|
||||
reason));
|
||||
if (mSinksInAdding.contains(sink)) {
|
||||
stopAudioSharing();
|
||||
showErrorDialog();
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
|
||||
SettingsEnums.AUDIO_SHARING_SETTINGS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -298,13 +307,33 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
@NonNull BluetoothDevice sink,
|
||||
int sourceId,
|
||||
@NonNull BluetoothLeBroadcastReceiveState state) {
|
||||
if (mStoppingSharing.get()) {
|
||||
Log.d(TAG, "Skip onReceiveStateChanged, stopping broadcast");
|
||||
return;
|
||||
}
|
||||
if (BluetoothUtils.isConnected(state)) {
|
||||
if (mSinksInAdding.contains(sink)) {
|
||||
mSinksInAdding.remove(sink);
|
||||
}
|
||||
dismissLoadingStateDialogIfNeeded();
|
||||
dismissProgressDialogIfNeeded();
|
||||
Log.d(TAG, "onReceiveStateChanged() connected, sink = " + sink
|
||||
+ ", remaining sinks = " + mSinksInAdding);
|
||||
if (mSinksToWaitFor.contains(sink)) {
|
||||
mSinksToWaitFor.remove(sink);
|
||||
if (mSinksToWaitFor.isEmpty()) {
|
||||
// To avoid users advance to share then pair flow before the
|
||||
// primary/active sinks successfully join the audio sharing,
|
||||
// popup dialog till adding source complete for mSinksToWaitFor.
|
||||
Pair<Integer, Object>[] eventData =
|
||||
AudioSharingUtils.buildAudioSharingDialogEventData(
|
||||
SettingsEnums.AUDIO_SHARING_SETTINGS,
|
||||
SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE,
|
||||
/* userTriggered= */ false,
|
||||
/* deviceCountInSharing= */ 1,
|
||||
/* candidateDeviceCount= */ 0);
|
||||
showAudioSharingDialog(eventData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -411,6 +440,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
return;
|
||||
}
|
||||
stopAudioSharing();
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,7 +573,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
mSinksInAdding.clear();
|
||||
// TODO: use string res once finalized.
|
||||
AudioSharingUtils.postOnMainThread(mContext,
|
||||
() -> AudioSharingLoadingStateDialogFragment.show(mFragment,
|
||||
() -> AudioSharingProgressDialogFragment.show(mFragment,
|
||||
"Starting audio stream..."));
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
@@ -553,9 +584,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
|
||||
private void stopAudioSharing() {
|
||||
if (mBroadcast != null) {
|
||||
mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId());
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF);
|
||||
int broadcastId = mBroadcast.getLatestBroadcastId();
|
||||
if (broadcastId != -1) {
|
||||
mBroadcast.stopBroadcast(broadcastId);
|
||||
mStoppingSharing.compareAndSet(false, true);
|
||||
mSinksInAdding.clear();
|
||||
mSinksToWaitFor.clear();
|
||||
}
|
||||
cleanUpStatesForStartSharing();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,11 +653,22 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
/* userTriggered= */ false,
|
||||
/* deviceCountInSharing= */ targetActiveSinks.isEmpty() ? 0 : 1,
|
||||
/* candidateDeviceCount= */ mDeviceItemsForSharing.size());
|
||||
// Auto add primary/active sinks w/o user interactions.
|
||||
if (!targetActiveSinks.isEmpty() && mTargetActiveItem != null) {
|
||||
Log.d(TAG, "handleOnBroadcastReady: automatically add source to active sinks.");
|
||||
addSourceToTargetSinks(targetActiveSinks, mTargetActiveItem.getName());
|
||||
// To avoid users advance to share then pair flow before the primary/active sinks
|
||||
// successfully join the audio sharing, save the primary/active sinks in mSinksToWaitFor
|
||||
// and popup dialog till adding source complete for these sinks.
|
||||
if (mDeviceItemsForSharing.isEmpty()) {
|
||||
mSinksToWaitFor.clear();
|
||||
mSinksToWaitFor.addAll(targetActiveSinks);
|
||||
}
|
||||
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING);
|
||||
mTargetActiveItem = null;
|
||||
// When audio sharing page is brought up by intent with EXTRA_START_LE_AUDIO_SHARING
|
||||
// == true, plus there is one active lea headset and one connected lea headset, we
|
||||
// should auto add these sinks without user interactions.
|
||||
if (mIntentHandleStage.compareAndSet(
|
||||
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
||||
StartIntentHandleStage.HANDLED.ordinal())
|
||||
@@ -631,31 +678,42 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
|
||||
target.getGroupId(), ImmutableList.of());
|
||||
addSourceToTargetSinks(targetSinks, target.getName());
|
||||
cleanUp();
|
||||
cleanUpStatesForStartSharing();
|
||||
// TODO: Add metric for auto add by intent
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Still mark intent as handled if early returned due to preconditions not met
|
||||
mIntentHandleStage.compareAndSet(
|
||||
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
||||
StartIntentHandleStage.HANDLED.ordinal());
|
||||
if (mFragment == null) {
|
||||
Log.d(TAG, "handleOnBroadcastReady: dialog fail to show due to null fragment.");
|
||||
dismissLoadingStateDialogIfNeeded();
|
||||
cleanUp();
|
||||
// Clean up states before early return.
|
||||
dismissProgressDialogIfNeeded();
|
||||
cleanUpStatesForStartSharing();
|
||||
return;
|
||||
}
|
||||
showDialog(eventData);
|
||||
// To avoid users advance to share then pair flow before the primary/active sinks
|
||||
// successfully join the audio sharing, popup dialog till adding source complete for
|
||||
// mSinksToWaitFor.
|
||||
if (mSinksToWaitFor.isEmpty() && !mStoppingSharing.get()) {
|
||||
showAudioSharingDialog(eventData);
|
||||
}
|
||||
}
|
||||
|
||||
private void showDialog(Pair<Integer, Object>[] eventData) {
|
||||
private void showAudioSharingDialog(Pair<Integer, Object>[] eventData) {
|
||||
if (!BluetoothUtils.isBroadcasting(mBtManager)) {
|
||||
Log.d(TAG, "Skip showAudioSharingDialog, broadcast is stopped");
|
||||
return;
|
||||
}
|
||||
AudioSharingDialogFragment.DialogEventListener listener =
|
||||
new AudioSharingDialogFragment.DialogEventListener() {
|
||||
@Override
|
||||
public void onPositiveClick() {
|
||||
// Could go to other pages, dismiss the loading dialog.
|
||||
dismissLoadingStateDialogIfNeeded();
|
||||
cleanUp();
|
||||
// Could go to other pages, dismiss the progress dialog.
|
||||
dismissProgressDialogIfNeeded();
|
||||
cleanUpStatesForStartSharing();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -663,14 +721,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
|
||||
item.getGroupId(), ImmutableList.of());
|
||||
addSourceToTargetSinks(targetSinks, item.getName());
|
||||
cleanUp();
|
||||
cleanUpStatesForStartSharing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelClick() {
|
||||
// Could go to other pages, dismiss the loading dialog.
|
||||
dismissLoadingStateDialogIfNeeded();
|
||||
cleanUp();
|
||||
// Could go to other pages, dismiss the progress dialog.
|
||||
dismissProgressDialogIfNeeded();
|
||||
cleanUpStatesForStartSharing();
|
||||
}
|
||||
};
|
||||
AudioSharingUtils.postOnMainThread(
|
||||
@@ -684,6 +742,36 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
});
|
||||
}
|
||||
|
||||
private void showErrorDialog() {
|
||||
AudioSharingUtils.postOnMainThread(mContext,
|
||||
() -> {
|
||||
// Remove all stale dialogs before showing error dialog
|
||||
dismissStaleDialogsOtherThanErrorDialog();
|
||||
AudioSharingErrorDialogFragment.show(mFragment);
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void dismissStaleDialogsOtherThanErrorDialog() {
|
||||
List<Fragment> fragments = new ArrayList<Fragment>();
|
||||
try {
|
||||
if (mFragment != null) {
|
||||
fragments =
|
||||
mFragment.getChildFragmentManager().getFragments();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Fail to dismiss stale dialogs: " + e.getMessage());
|
||||
}
|
||||
for (Fragment fragment : fragments) {
|
||||
if (fragment != null && fragment instanceof DialogFragment
|
||||
&& !(fragment instanceof AudioSharingErrorDialogFragment)
|
||||
&& ((DialogFragment) fragment).getDialog() != null) {
|
||||
Log.d(TAG, "Remove stale dialog = " + fragment.getTag());
|
||||
((DialogFragment) fragment).dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MainSwitchAccessibilityDelegate extends View.AccessibilityDelegate {
|
||||
@Override
|
||||
public boolean onRequestSendAccessibilityEvent(
|
||||
@@ -742,25 +830,25 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||
private void addSourceToTargetSinks(List<BluetoothDevice> targetActiveSinks,
|
||||
@NonNull String sinkName) {
|
||||
mSinksInAdding.addAll(targetActiveSinks);
|
||||
AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
|
||||
// TODO: move to res once finalized
|
||||
String loadingMessage = "Sharing with " + sinkName + "...";
|
||||
showLoadingStateDialog(loadingMessage);
|
||||
String progressMessage = "Sharing with " + sinkName + "...";
|
||||
showProgressDialog(progressMessage);
|
||||
AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
|
||||
}
|
||||
|
||||
private void showLoadingStateDialog(@NonNull String loadingMessage) {
|
||||
private void showProgressDialog(@NonNull String progressMessage) {
|
||||
AudioSharingUtils.postOnMainThread(mContext,
|
||||
() -> AudioSharingLoadingStateDialogFragment.show(mFragment, loadingMessage));
|
||||
() -> AudioSharingProgressDialogFragment.show(mFragment, progressMessage));
|
||||
}
|
||||
|
||||
private void dismissLoadingStateDialogIfNeeded() {
|
||||
private void dismissProgressDialogIfNeeded() {
|
||||
if (mSinksInAdding.isEmpty()) {
|
||||
AudioSharingUtils.postOnMainThread(mContext,
|
||||
() -> AudioSharingLoadingStateDialogFragment.dismiss(mFragment));
|
||||
() -> AudioSharingProgressDialogFragment.dismiss(mFragment));
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanUp() {
|
||||
private void cleanUpStatesForStartSharing() {
|
||||
mGroupedConnectedDevices.clear();
|
||||
mDeviceItemsForSharing.clear();
|
||||
}
|
||||
|
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.deviceinfo.firmwareversion
|
||||
|
||||
import android.content.Context
|
||||
import android.os.SystemProperties
|
||||
import androidx.preference.Preference
|
||||
import com.android.settings.R
|
||||
import com.android.settings.Utils
|
||||
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
|
||||
import com.android.settingslib.metadata.PreferenceMetadata
|
||||
import com.android.settingslib.metadata.PreferenceSummaryProvider
|
||||
import com.android.settingslib.preference.PreferenceBinding
|
||||
|
||||
// LINT.IfChange
|
||||
class BasebandVersionPreference :
|
||||
PreferenceMetadata,
|
||||
PreferenceSummaryProvider,
|
||||
PreferenceAvailabilityProvider,
|
||||
PreferenceBinding {
|
||||
|
||||
override val key: String
|
||||
get() = "base_band"
|
||||
|
||||
override val title: Int
|
||||
get() = R.string.baseband_version
|
||||
|
||||
override fun getSummary(context: Context): CharSequence? =
|
||||
SystemProperties.get(BASEBAND_PROPERTY, context.getString(R.string.device_info_default))
|
||||
|
||||
override fun isAvailable(context: Context) = !Utils.isWifiOnly(context)
|
||||
|
||||
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
|
||||
super.bind(preference, metadata)
|
||||
preference.isSelectable = false
|
||||
preference.isCopyingEnabled = true
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val BASEBAND_PROPERTY: String = "gsm.version.baseband"
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(BasebandVersionPreferenceController.java)
|
@@ -25,6 +25,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
// LINT.IfChange
|
||||
public class BasebandVersionPreferenceController extends BasePreferenceController {
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -45,3 +46,4 @@ public class BasebandVersionPreferenceController extends BasePreferenceControlle
|
||||
mContext.getString(R.string.device_info_default));
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(BasebandVersionPreference.kt)
|
||||
|
@@ -50,9 +50,9 @@ class FirmwareVersionScreen : PreferenceScreenCreator, PreferenceSummaryProvider
|
||||
+PreferenceWidget("os_firmware_version", R.string.firmware_version)
|
||||
+PreferenceWidget("security_key", R.string.security_patch)
|
||||
+PreferenceWidget("module_version", R.string.module_version)
|
||||
+PreferenceWidget("base_band", R.string.baseband_version)
|
||||
+PreferenceWidget("kernel_version", R.string.kernel_version)
|
||||
+PreferenceWidget("os_build_number", R.string.build_number)
|
||||
+BasebandVersionPreference()
|
||||
+KernelVersionPreference()
|
||||
+SimpleBuildNumberPreference()
|
||||
}
|
||||
|
||||
private class PreferenceWidget(override val key: String, override val title: Int) :
|
||||
|
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.deviceinfo.firmwareversion
|
||||
|
||||
import android.content.Context
|
||||
import androidx.preference.Preference
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.DeviceInfoUtils
|
||||
import com.android.settingslib.metadata.PreferenceMetadata
|
||||
import com.android.settingslib.metadata.PreferenceSummaryProvider
|
||||
import com.android.settingslib.preference.PreferenceBinding
|
||||
|
||||
// LINT.IfChange
|
||||
class KernelVersionPreference : PreferenceMetadata, PreferenceSummaryProvider, PreferenceBinding {
|
||||
|
||||
override val key: String
|
||||
get() = "kernel_version"
|
||||
|
||||
override val title: Int
|
||||
get() = R.string.kernel_version
|
||||
|
||||
override fun getSummary(context: Context): CharSequence? =
|
||||
DeviceInfoUtils.getFormattedKernelVersion(context)
|
||||
|
||||
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
|
||||
super.bind(preference, metadata)
|
||||
preference.isSelectable = false
|
||||
preference.isCopyingEnabled = true
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(KernelVersionPreferenceController.java)
|
@@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.DeviceInfoUtils;
|
||||
|
||||
// LINT.IfChange
|
||||
public class KernelVersionPreferenceController extends BasePreferenceController {
|
||||
|
||||
public KernelVersionPreferenceController(Context context, String preferenceKey) {
|
||||
@@ -37,3 +38,4 @@ public class KernelVersionPreferenceController extends BasePreferenceController
|
||||
return DeviceInfoUtils.getFormattedKernelVersion(mContext);
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(KernelVersionPreference.kt)
|
||||
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.deviceinfo.firmwareversion
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.text.BidiFormatter
|
||||
import android.view.View.LAYOUT_DIRECTION_RTL
|
||||
import androidx.preference.Preference
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.metadata.PreferenceMetadata
|
||||
import com.android.settingslib.metadata.PreferenceSummaryProvider
|
||||
import com.android.settingslib.preference.PreferenceBinding
|
||||
|
||||
// LINT.IfChange
|
||||
class SimpleBuildNumberPreference :
|
||||
PreferenceMetadata, PreferenceSummaryProvider, PreferenceBinding {
|
||||
|
||||
override val key: String
|
||||
get() = "os_build_number"
|
||||
|
||||
override val title: Int
|
||||
get() = R.string.build_number
|
||||
|
||||
override fun isIndexable(context: Context) = false
|
||||
|
||||
override fun getSummary(context: Context): CharSequence? {
|
||||
val isRtl = context.resources.configuration.layoutDirection == LAYOUT_DIRECTION_RTL
|
||||
return BidiFormatter.getInstance(isRtl).unicodeWrap(Build.DISPLAY)
|
||||
}
|
||||
|
||||
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
|
||||
super.bind(preference, metadata)
|
||||
preference.isSelectable = false
|
||||
preference.isCopyingEnabled = true
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(SimpleBuildNumberPreferenceController.java)
|
@@ -22,6 +22,7 @@ import android.text.BidiFormatter;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
// LINT.IfChange
|
||||
public class SimpleBuildNumberPreferenceController extends BasePreferenceController {
|
||||
|
||||
public SimpleBuildNumberPreferenceController(Context context,
|
||||
@@ -39,3 +40,4 @@ public class SimpleBuildNumberPreferenceController extends BasePreferenceControl
|
||||
return BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY);
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(SimpleBuildNumberPreference.kt)
|
||||
|
@@ -20,7 +20,6 @@ import android.app.Dialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
@@ -80,10 +79,7 @@ public class OnDeviceRecognitionPreferenceController extends BasePreferenceContr
|
||||
}
|
||||
|
||||
private void show(Preference preference) {
|
||||
final List<UserHandle> userHandles = new ArrayList<>();
|
||||
for (UserInfo userInfo : UserManager.get(mContext).getUsers()) {
|
||||
userHandles.add(userInfo.getUserHandle());
|
||||
}
|
||||
final List<UserHandle> userHandles = UserManager.get(mContext).getEnabledProfiles();
|
||||
|
||||
// Only a single profile is installed. Proceed with its settings.
|
||||
if (userHandles.size() == 1) {
|
||||
|
@@ -89,7 +89,7 @@ class MobileNetworkListFragment : DashboardFragment() {
|
||||
private val simRepositoryFactory: (Context) -> SimRepository = ::SimRepository
|
||||
) : BaseSearchIndexProvider(R.xml.network_provider_sims_list) {
|
||||
public override fun isPageSearchEnabled(context: Context): Boolean =
|
||||
simRepositoryFactory(context).showMobileNetworkPage()
|
||||
simRepositoryFactory(context).canEnterMobileNetworkPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -57,7 +57,7 @@ constructor(
|
||||
private var isAirplaneModeOn = false
|
||||
|
||||
override fun getAvailabilityStatus() =
|
||||
if (SimRepository(mContext).showMobileNetworkPage()) AVAILABLE
|
||||
if (SimRepository(mContext).showMobileNetworkPageEntrance()) AVAILABLE
|
||||
else CONDITIONALLY_UNAVAILABLE
|
||||
|
||||
override fun displayPreference(screen: PreferenceScreen) {
|
||||
|
@@ -53,8 +53,8 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.lifecycle.LifecycleRegistry
|
||||
import com.android.settings.R
|
||||
import com.android.settings.SidecarFragment
|
||||
import com.android.settings.network.telephony.SimRepository
|
||||
import com.android.settings.network.telephony.SubscriptionActionDialogActivity
|
||||
import com.android.settings.network.telephony.SubscriptionRepository
|
||||
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity
|
||||
import com.android.settings.network.telephony.requireSubscriptionManager
|
||||
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
|
||||
@@ -578,6 +578,10 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
||||
subId: Int,
|
||||
isNewTask: Boolean = false,
|
||||
) {
|
||||
if (!SimRepository(context).canEnterMobileNetworkPage()) {
|
||||
Log.i(TAG, "Unable to start SimOnboardingActivity due to missing permissions")
|
||||
return
|
||||
}
|
||||
val intent = Intent(context, SimOnboardingActivity::class.java).apply {
|
||||
putExtra(SUB_ID, subId)
|
||||
if(isNewTask) {
|
||||
|
@@ -48,7 +48,7 @@ constructor(
|
||||
|
||||
override fun getSummary(): CharSequence {
|
||||
val summaryResId =
|
||||
if (simRepository.showMobileNetworkPage()) {
|
||||
if (simRepository.showMobileNetworkPageEntrance()) {
|
||||
R.string.network_dashboard_summary_mobile
|
||||
} else {
|
||||
R.string.network_dashboard_summary_no_mobile
|
||||
|
@@ -21,7 +21,6 @@ import android.provider.Settings
|
||||
import android.telephony.SubscriptionInfo
|
||||
import com.android.settings.R
|
||||
import com.android.settings.datausage.BillingCyclePreferenceController.Companion.BillingCycleSearchItem
|
||||
import com.android.settings.network.SubscriptionUtil
|
||||
import com.android.settings.network.telephony.CarrierSettingsVersionPreferenceController.Companion.CarrierSettingsVersionSearchItem
|
||||
import com.android.settings.network.telephony.DataUsagePreferenceController.Companion.DataUsageSearchItem
|
||||
import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
|
||||
@@ -36,7 +35,6 @@ import com.android.settings.spa.search.SpaSearchRepository.Companion.createSearc
|
||||
import com.android.settings.spa.search.SpaSearchRepository.Companion.searchIndexProviderOf
|
||||
import com.android.settingslib.search.SearchIndexableData
|
||||
import com.android.settingslib.search.SearchIndexableRaw
|
||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
||||
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
|
||||
|
||||
class MobileNetworkSettingsSearchIndex(
|
||||
@@ -109,12 +107,8 @@ class MobileNetworkSettingsSearchIndex(
|
||||
companion object {
|
||||
/** suppress full page if user is not admin */
|
||||
@JvmStatic
|
||||
fun isMobileNetworkSettingsSearchable(context: Context): Boolean {
|
||||
val isAirplaneMode by context.settingsGlobalBoolean(Settings.Global.AIRPLANE_MODE_ON)
|
||||
return SubscriptionUtil.isSimHardwareVisible(context) &&
|
||||
!isAirplaneMode &&
|
||||
context.userManager.isAdminUser
|
||||
}
|
||||
fun isMobileNetworkSettingsSearchable(context: Context): Boolean =
|
||||
SimRepository(context).canEnterMobileNetworkPage()
|
||||
|
||||
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
|
||||
listOf(
|
||||
|
@@ -18,13 +18,24 @@ package com.android.settings.network.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
||||
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
|
||||
|
||||
class SimRepository(context: Context) {
|
||||
class SimRepository(private val context: Context) {
|
||||
private val packageManager = context.packageManager
|
||||
private val userManager = context.userManager
|
||||
|
||||
/** Gets whether we show mobile network settings page to the current user. */
|
||||
fun showMobileNetworkPage(): Boolean =
|
||||
/** Gets whether show mobile network settings page entrance to the current user. */
|
||||
fun showMobileNetworkPageEntrance(): Boolean =
|
||||
packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) && userManager.isAdminUser
|
||||
|
||||
/** Gets whether current user can enter mobile network settings page. */
|
||||
fun canEnterMobileNetworkPage(): Boolean {
|
||||
val isAirplaneMode by context.settingsGlobalBoolean(Settings.Global.AIRPLANE_MODE_ON)
|
||||
return showMobileNetworkPageEntrance() &&
|
||||
!isAirplaneMode &&
|
||||
!userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)
|
||||
}
|
||||
}
|
||||
|
@@ -24,9 +24,8 @@ import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import android.util.Log;
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.android.settings.RingtonePreference;
|
||||
|
||||
public class NotificationSoundPreference extends RingtonePreference {
|
||||
@@ -49,6 +48,20 @@ public class NotificationSoundPreference extends RingtonePreference {
|
||||
updateRingtoneName(mRingtone);
|
||||
}
|
||||
|
||||
protected String generateRingtoneTitle(Uri uri) {
|
||||
if (uri == null) {
|
||||
return getContext().getString(com.android.internal.R.string.ringtone_silent);
|
||||
} else if (RingtoneManager.isDefault(uri)) {
|
||||
return getContext().getString(com.android.settings.R.string.notification_sound_default);
|
||||
} else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
|
||||
return getContext().getString(
|
||||
com.android.settings.R.string.notification_unknown_sound_title);
|
||||
} else {
|
||||
return Ringtone.getTitle(getContext(), uri, false /* followSettingsUri */,
|
||||
true /* allowRemote */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (data != null) {
|
||||
@@ -69,16 +82,7 @@ public class NotificationSoundPreference extends RingtonePreference {
|
||||
AsyncTask ringtoneNameTask = new AsyncTask<Object, Void, CharSequence>() {
|
||||
@Override
|
||||
protected CharSequence doInBackground(Object... params) {
|
||||
if (uri == null) {
|
||||
return getContext().getString(com.android.internal.R.string.ringtone_silent);
|
||||
} else if (RingtoneManager.isDefault(uri)) {
|
||||
return getContext().getString(R.string.notification_sound_default);
|
||||
} else if(ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
|
||||
return getContext().getString(R.string.notification_unknown_sound_title);
|
||||
} else {
|
||||
return Ringtone.getTitle(getContext(), uri, false /* followSettingsUri */,
|
||||
true /* allowRemote */);
|
||||
}
|
||||
return generateRingtoneTitle(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -458,7 +458,7 @@ public class ZenModeBackend {
|
||||
}
|
||||
|
||||
private static List<String> getDefaultRuleIds() {
|
||||
return ZenModeConfig.DEFAULT_RULE_IDS;
|
||||
return ZenModeConfig.getDefaultRuleIds();
|
||||
}
|
||||
|
||||
NotificationManager.Policy toNotificationPolicy(ZenPolicy policy) {
|
||||
|
@@ -206,7 +206,12 @@ public class SimSlotChangeHandler {
|
||||
if (hasActiveEsimSubscription()) {
|
||||
if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
|
||||
Log.i(TAG, "Enabled profile exists. DSDS condition satisfied.");
|
||||
startDsdsDialogActivity();
|
||||
if (Flags.isDualSimOnboardingEnabled()) {
|
||||
// enable dsds by sim onboarding flow
|
||||
handleRemovableSimInsertWhenDsds(removableSlotInfo);
|
||||
} else {
|
||||
startDsdsDialogActivity();
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "Enabled profile exists. DSDS condition not satisfied.");
|
||||
startChooseSimActivity(true);
|
||||
|
@@ -212,7 +212,7 @@ open class NetworkCellularGroupProvider : SettingsPageProvider, SearchablePage {
|
||||
const val fileName = "NetworkCellularGroupProvider"
|
||||
|
||||
private fun isPageSearchable(context: Context) =
|
||||
Flags.isDualSimOnboardingEnabled() && SimRepository(context).showMobileNetworkPage()
|
||||
Flags.isDualSimOnboardingEnabled() && SimRepository(context).canEnterMobileNetworkPage()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,8 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -35,6 +37,10 @@ public class TickButtonPreference extends TwoTargetPreference {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public TickButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
|
@@ -69,6 +69,9 @@ android_robolectric_test {
|
||||
"com_android_server_accessibility_flags_lib",
|
||||
"flag-junit",
|
||||
"flag-junit-base",
|
||||
"kotlin-test",
|
||||
"mockito-robolectric-prebuilt", // mockito deps order matters!
|
||||
"mockito-kotlin2",
|
||||
"notification_flags_lib",
|
||||
"platform-test-annotations",
|
||||
"testables",
|
||||
|
@@ -51,14 +51,14 @@ import org.robolectric.shadows.androidx.fragment.FragmentController;
|
||||
ShadowAlertDialogCompat.class,
|
||||
ShadowBluetoothAdapter.class,
|
||||
})
|
||||
public class AudioSharingRetryDialogFragmentTest {
|
||||
public class AudioSharingErrorDialogFragmentTest {
|
||||
@Rule
|
||||
public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
@Rule
|
||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||
|
||||
private Fragment mParent;
|
||||
private AudioSharingRetryDialogFragment mFragment;
|
||||
private AudioSharingErrorDialogFragment mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -70,7 +70,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
mFragment = new AudioSharingRetryDialogFragment();
|
||||
mFragment = new AudioSharingErrorDialogFragment();
|
||||
mParent = new Fragment();
|
||||
FragmentController.setupFragment(
|
||||
mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
|
||||
@@ -91,7 +91,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
||||
@Test
|
||||
public void onCreateDialog_flagOff_dialogNotExist() {
|
||||
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingRetryDialogFragment.show(mParent);
|
||||
AudioSharingErrorDialogFragment.show(mParent);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNull();
|
||||
@@ -100,7 +100,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
||||
@Test
|
||||
public void onCreateDialog_unattachedFragment_dialogNotExist() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingRetryDialogFragment.show(new Fragment());
|
||||
AudioSharingErrorDialogFragment.show(new Fragment());
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNull();
|
||||
@@ -109,7 +109,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
||||
@Test
|
||||
public void onCreateDialog_flagOn_showDialog() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingRetryDialogFragment.show(mParent);
|
||||
AudioSharingErrorDialogFragment.show(mParent);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
@@ -119,7 +119,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
||||
@Test
|
||||
public void onCreateDialog_clickOk_dialogDismiss() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingRetryDialogFragment.show(mParent);
|
||||
AudioSharingErrorDialogFragment.show(mParent);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
@@ -52,7 +52,7 @@ import org.robolectric.shadows.androidx.fragment.FragmentController;
|
||||
ShadowAlertDialogCompat.class,
|
||||
ShadowBluetoothAdapter.class,
|
||||
})
|
||||
public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
public class AudioSharingProgressDialogFragmentTest {
|
||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||
|
||||
@@ -60,7 +60,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
private static final String TEST_MESSAGE2 = "message2";
|
||||
|
||||
private Fragment mParent;
|
||||
private AudioSharingLoadingStateDialogFragment mFragment;
|
||||
private AudioSharingProgressDialogFragment mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -72,7 +72,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
mFragment = new AudioSharingLoadingStateDialogFragment();
|
||||
mFragment = new AudioSharingProgressDialogFragment();
|
||||
mParent = new Fragment();
|
||||
FragmentController.setupFragment(
|
||||
mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
|
||||
@@ -93,7 +93,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
@Test
|
||||
public void onCreateDialog_flagOff_dialogNotExist() {
|
||||
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNull();
|
||||
@@ -102,7 +102,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
@Test
|
||||
public void onCreateDialog_unattachedFragment_dialogNotExist() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingLoadingStateDialogFragment.show(new Fragment(), TEST_MESSAGE1);
|
||||
AudioSharingProgressDialogFragment.show(new Fragment(), TEST_MESSAGE1);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNull();
|
||||
@@ -111,7 +111,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
@Test
|
||||
public void onCreateDialog_flagOn_showDialog() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
@@ -124,13 +124,13 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
@Test
|
||||
public void dismissDialog_succeed() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
|
||||
AudioSharingLoadingStateDialogFragment.dismiss(mParent);
|
||||
AudioSharingProgressDialogFragment.dismiss(mParent);
|
||||
shadowMainLooper().idle();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
}
|
||||
@@ -138,13 +138,13 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
@Test
|
||||
public void showDialog_sameMessage_keepExistingDialog() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
|
||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
shadowMainLooper().idle();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
}
|
||||
@@ -152,7 +152,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
@Test
|
||||
public void showDialog_newMessage_keepAndUpdateDialog() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||
shadowMainLooper().idle();
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
@@ -161,7 +161,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
||||
assertThat(view).isNotNull();
|
||||
assertThat(view.getText().toString()).isEqualTo(TEST_MESSAGE1);
|
||||
|
||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE2);
|
||||
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE2);
|
||||
shadowMainLooper().idle();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
assertThat(view.getText().toString()).isEqualTo(TEST_MESSAGE2);
|
@@ -146,6 +146,7 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||
@Mock private VolumeControlProfile mVolumeControl;
|
||||
@Mock private BluetoothLeBroadcastMetadata mMetadata;
|
||||
@Mock private BluetoothLeBroadcastReceiveState mState;
|
||||
@Mock private CompoundButton mBtnView;
|
||||
@Mock private CachedBluetoothDevice mCachedDevice1;
|
||||
@Mock private CachedBluetoothDevice mCachedDevice2;
|
||||
@@ -499,7 +500,7 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
|
||||
verify(mBroadcast).startPrivateBroadcast();
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
// No loading state dialog.
|
||||
// No progress dialog.
|
||||
assertThat(childFragments).isEmpty();
|
||||
|
||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||
@@ -519,10 +520,9 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||
when(mBtnView.isEnabled()).thenReturn(true);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
when(state.getBroadcastId()).thenReturn(1);
|
||||
when(mState.getBroadcastId()).thenReturn(1);
|
||||
when(mBroadcast.getLatestBroadcastId()).thenReturn(1);
|
||||
when(mAssistant.getAllSources(mDevice2)).thenReturn(ImmutableList.of(state));
|
||||
when(mAssistant.getAllSources(mDevice2)).thenReturn(ImmutableList.of(mState));
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||
@@ -531,7 +531,7 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
verify(mBroadcast).startPrivateBroadcast();
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
|
||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
@@ -549,27 +549,92 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPlaybackStarted_showJoinAudioSharingDialog() {
|
||||
public void onPlaybackStarted_singleActiveDevice_showJoinAudioSharingDialog() {
|
||||
FeatureFlagUtils.setEnabled(
|
||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||
when(mBtnView.isEnabled()).thenReturn(true);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2));
|
||||
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
verify(mBroadcast).startPrivateBroadcast();
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
||||
AudioSharingLoadingStateDialogFragment loadingFragment =
|
||||
(AudioSharingLoadingStateDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
|
||||
when(mBroadcast.isEnabled(null)).thenReturn(true);
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING));
|
||||
|
||||
when(mState.getBisSyncState()).thenReturn(ImmutableList.of(1L));
|
||||
mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice2, /* sourceId= */ 1,
|
||||
mState);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments)
|
||||
.comparingElementsUsing(CLAZZNAME_EQUALS)
|
||||
.containsExactly(AudioSharingDialogFragment.class.getName());
|
||||
|
||||
Pair<Integer, Object>[] eventData = new Pair[0];
|
||||
for (Fragment fragment : childFragments) {
|
||||
if (fragment instanceof AudioSharingDialogFragment) {
|
||||
eventData = ((AudioSharingDialogFragment) fragment).getEventData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertThat(eventData)
|
||||
.asList()
|
||||
.containsExactly(
|
||||
Pair.create(
|
||||
AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
|
||||
SettingsEnums.AUDIO_SHARING_SETTINGS),
|
||||
Pair.create(
|
||||
AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
|
||||
SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE),
|
||||
Pair.create(
|
||||
AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 0),
|
||||
Pair.create(
|
||||
AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
|
||||
.ordinal(),
|
||||
1),
|
||||
Pair.create(
|
||||
AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
|
||||
.ordinal(),
|
||||
0));
|
||||
|
||||
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPlaybackStarted_oneActiveOnConnected_showJoinAudioSharingDialog() {
|
||||
FeatureFlagUtils.setEnabled(
|
||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||
when(mBtnView.isEnabled()).thenReturn(true);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
verify(mBroadcast).startPrivateBroadcast();
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
AudioSharingProgressDialogFragment progressFragment =
|
||||
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||
// TODO: use string res once finalized
|
||||
String expectedMessage = "Starting audio stream...";
|
||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
||||
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||
|
||||
when(mBroadcast.isEnabled(null)).thenReturn(true);
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
@@ -577,13 +642,13 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
.action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING));
|
||||
// TODO: use string res once finalized
|
||||
expectedMessage = "Sharing with " + TEST_DEVICE_NAME2 + "...";
|
||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
||||
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||
|
||||
childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments)
|
||||
.comparingElementsUsing(CLAZZNAME_EQUALS)
|
||||
.containsExactly(AudioSharingDialogFragment.class.getName(),
|
||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
|
||||
Pair<Integer, Object>[] eventData = new Pair[0];
|
||||
for (Fragment fragment : childFragments) {
|
||||
@@ -616,18 +681,19 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPlaybackStarted_clickShareBtnOnDialog_addSource() {
|
||||
public void onPlaybackStarted_oneActiveOnConnected_clickShareBtnOnDialog_addSource() {
|
||||
FeatureFlagUtils.setEnabled(
|
||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||
when(mBtnView.isEnabled()).thenReturn(true);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
verify(mBroadcast).startPrivateBroadcast();
|
||||
when(mBroadcast.isEnabled(null)).thenReturn(true);
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
@@ -642,32 +708,33 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
|
||||
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
// Loading state dialog shows sharing state for the user chosen sink.
|
||||
// Progress dialog shows sharing progress for the user chosen sink.
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
||||
AudioSharingLoadingStateDialogFragment loadingFragment =
|
||||
(AudioSharingLoadingStateDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
AudioSharingProgressDialogFragment progressFragment =
|
||||
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||
// TODO: use string res once finalized
|
||||
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME1 + "...";
|
||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
||||
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||
|
||||
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPlaybackStarted_clickCancelBtnOnDialog_doNothing() {
|
||||
public void onPlaybackStarted_oneActiveOnConnected_clickCancelBtnOnDialog_doNothing() {
|
||||
FeatureFlagUtils.setEnabled(
|
||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||
when(mBtnView.isEnabled()).thenReturn(true);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
verify(mBroadcast).startPrivateBroadcast();
|
||||
when(mBroadcast.isEnabled(null)).thenReturn(true);
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
@@ -682,15 +749,15 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
|
||||
verify(mAssistant, never()).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
// Loading state dialog shows sharing state for the auto add active sink.
|
||||
// Progress dialog shows sharing progress for the auto add active sink.
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
||||
AudioSharingLoadingStateDialogFragment loadingFragment =
|
||||
(AudioSharingLoadingStateDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
AudioSharingProgressDialogFragment progressFragment =
|
||||
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||
// TODO: use string res once finalized
|
||||
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME2 + "...";
|
||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
||||
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||
|
||||
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||
}
|
||||
@@ -754,28 +821,63 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAssistantCallbacks_onSourceAddFailed_logAction() {
|
||||
public void testAssistantCallbacks_onSourceAddFailed_twoDevices_showErrorAndLogAction() {
|
||||
FeatureFlagUtils.setEnabled(
|
||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||
when(mBtnView.isEnabled()).thenReturn(true);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
verify(mBroadcast).startPrivateBroadcast();
|
||||
|
||||
when(mBroadcast.isEnabled(null)).thenReturn(true);
|
||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
verify(mAssistant).addSource(mDevice2, mMetadata, /* isGroupOp= */ false);
|
||||
|
||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
View btnView = dialog.findViewById(R.id.positive_btn);
|
||||
assertThat(btnView).isNotNull();
|
||||
btnView.performClick();
|
||||
shadowMainLooper().idle();
|
||||
|
||||
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
|
||||
mController.mBroadcastAssistantCallback.onSourceAddFailed(
|
||||
mDevice1, mMetadata, /* reason= */ 1);
|
||||
shadowMainLooper().idle();
|
||||
|
||||
// Progress dialog shows sharing progress for the user chosen sink.
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingErrorDialogFragment.class.getName());
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(
|
||||
mContext,
|
||||
SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
|
||||
SettingsEnums.AUDIO_SHARING_SETTINGS);
|
||||
|
||||
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAssistantCallbacks_onReceiveStateChanged_dismissLoadingDialog() {
|
||||
AudioSharingLoadingStateDialogFragment.show(mParentFragment, TEST_DEVICE_NAME1);
|
||||
public void testAssistantCallbacks_onReceiveStateChanged_dismissProgressDialog() {
|
||||
AudioSharingProgressDialogFragment.show(mParentFragment, TEST_DEVICE_NAME1);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
|
||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
when(state.getBisSyncState()).thenReturn(ImmutableList.of(1L));
|
||||
when(mState.getBisSyncState()).thenReturn(ImmutableList.of(1L));
|
||||
mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1,
|
||||
state);
|
||||
mState);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).isEmpty();
|
||||
@@ -783,11 +885,9 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
|
||||
@Test
|
||||
public void testAssistantCallbacks_doNothing() {
|
||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
|
||||
// Do nothing
|
||||
mController.mBroadcastAssistantCallback.onReceiveStateChanged(
|
||||
mDevice1, /* sourceId= */ 1, state);
|
||||
mDevice1, /* sourceId= */ 1, mState);
|
||||
mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1);
|
||||
mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1);
|
||||
mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1);
|
||||
@@ -923,13 +1023,13 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
List<Fragment> childFragments = parentFragment.getChildFragmentManager().getFragments();
|
||||
// Skip audio sharing dialog.
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
||||
// The loading state dialog shows sharing state for the auto add second sink.
|
||||
AudioSharingLoadingStateDialogFragment loadingFragment =
|
||||
(AudioSharingLoadingStateDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
// Progress dialog shows sharing progress for the auto add second sink.
|
||||
AudioSharingProgressDialogFragment progressFragment =
|
||||
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||
// TODO: use string res once finalized
|
||||
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME1 + "...";
|
||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
||||
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||
|
||||
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||
}
|
||||
@@ -944,7 +1044,7 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
||||
AudioSharingProgressDialogFragment.class.getName());
|
||||
}
|
||||
|
||||
private Fragment setUpFragmentWithStartSharingIntent() {
|
||||
@@ -964,12 +1064,12 @@ public class AudioSharingSwitchBarControllerTest {
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private void checkLoadingStateDialogMessage(
|
||||
@NonNull AudioSharingLoadingStateDialogFragment fragment,
|
||||
private void checkProgressDialogMessage(
|
||||
@NonNull AudioSharingProgressDialogFragment fragment,
|
||||
@NonNull String expectedMessage) {
|
||||
TextView loadingMessage = fragment.getDialog() == null ? null
|
||||
TextView progressMessage = fragment.getDialog() == null ? null
|
||||
: fragment.getDialog().findViewById(R.id.message);
|
||||
assertThat(loadingMessage).isNotNull();
|
||||
assertThat(loadingMessage.getText().toString()).isEqualTo(expectedMessage);
|
||||
assertThat(progressMessage).isNotNull();
|
||||
assertThat(progressMessage.getText().toString()).isEqualTo(expectedMessage);
|
||||
}
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
// LINT.IfChange
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BasebandVersionPreferenceControllerTest {
|
||||
@Mock
|
||||
@@ -68,3 +69,4 @@ public class BasebandVersionPreferenceControllerTest {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(BasebandVersionPreferenceTest.kt)
|
||||
|
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.deviceinfo.firmwareversion
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.sysprop.TelephonyProperties
|
||||
import android.telephony.TelephonyManager
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
// LINT.IfChange
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class BasebandVersionPreferenceTest {
|
||||
private lateinit var telephonyManager: TelephonyManager
|
||||
|
||||
private val context: Context =
|
||||
object : ContextWrapper(ApplicationProvider.getApplicationContext()) {
|
||||
override fun getSystemService(name: String): Any? =
|
||||
when {
|
||||
name == getSystemServiceName(TelephonyManager::class.java) -> telephonyManager
|
||||
else -> super.getSystemService(name)
|
||||
}
|
||||
}
|
||||
|
||||
private val basebandVersionPreference = BasebandVersionPreference()
|
||||
|
||||
@Test
|
||||
fun isAvailable_wifiOnly_unavailable() {
|
||||
telephonyManager = mock { on { isDataCapable } doReturn false }
|
||||
assertThat(basebandVersionPreference.isAvailable(context)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isAvailable_hasMobile_available() {
|
||||
TelephonyProperties.baseband_version(listOf("test"))
|
||||
telephonyManager = mock { on { isDataCapable } doReturn true }
|
||||
assertThat(basebandVersionPreference.isAvailable(context)).isTrue()
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(BasebandVersionPreferenceControllerTest.java)
|
@@ -29,6 +29,7 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
// LINT.IfChange
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class KernelVersionPreferenceControllerTest {
|
||||
|
||||
@@ -49,3 +50,4 @@ public class KernelVersionPreferenceControllerTest {
|
||||
DeviceInfoUtils.getFormattedKernelVersion(mContext));
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(KernelVersionPreferenceTest.kt)
|
||||
|
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.deviceinfo.firmwareversion
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.settingslib.DeviceInfoUtils
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
// LINT.IfChange
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class KernelVersionPreferenceTest {
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
private val kernelVersionPreference = KernelVersionPreference()
|
||||
|
||||
@Test
|
||||
fun getSummary() {
|
||||
assertThat(kernelVersionPreference.getSummary(context))
|
||||
.isEqualTo(DeviceInfoUtils.getFormattedKernelVersion(context))
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(KernelVersionPreferenceControllerTest.java)
|
@@ -29,6 +29,7 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
// LINT.IfChange
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class SimpleBuildNumberPreferenceControllerTest {
|
||||
|
||||
@@ -48,3 +49,4 @@ public class SimpleBuildNumberPreferenceControllerTest {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(SimpleBuildNumberPreferenceTest.kt)
|
||||
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.deviceinfo.firmwareversion
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.text.BidiFormatter
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import java.util.Locale
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
// LINT.IfChange
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class SimpleBuildNumberPreferenceTest {
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
private val simpleBuildNumberPreference = SimpleBuildNumberPreference()
|
||||
|
||||
@Test
|
||||
fun isIndexable() {
|
||||
assertThat(simpleBuildNumberPreference.isIndexable(context)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSummary_ltr() {
|
||||
context.resources.configuration.setLayoutDirection(Locale.ENGLISH)
|
||||
assertThat(simpleBuildNumberPreference.getSummary(context))
|
||||
.isEqualTo(BidiFormatter.getInstance(false).unicodeWrap(Build.DISPLAY))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSummary_rtl() {
|
||||
context.resources.configuration.setLayoutDirection(Locale("ar"))
|
||||
assertThat(simpleBuildNumberPreference.getSummary(context))
|
||||
.isEqualTo(BidiFormatter.getInstance(true).unicodeWrap(Build.DISPLAY))
|
||||
}
|
||||
}
|
||||
// LINT.ThenChange(SimpleBuildNumberPreferenceControllerTest.java)
|
@@ -23,14 +23,18 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AutomaticZenRule;
|
||||
import android.app.Flags;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.NotificationManager.Policy;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.platform.test.annotations.DisableFlags;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -53,12 +57,15 @@ public class ZenModeBackendTest {
|
||||
private NotificationManager mNotificationManager;
|
||||
|
||||
private static final String GENERIC_RULE_NAME = "test";
|
||||
private static final String DEFAULT_ID_1 = ZenModeConfig.EVENTS_DEFAULT_RULE_ID;
|
||||
private static final String DEFAULT_ID_1 = ZenModeConfig.EVENTS_OBSOLETE_RULE_ID;
|
||||
private static final String DEFAULT_ID_2 = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
|
||||
|
||||
private Context mContext;
|
||||
private ZenModeBackend mBackend;
|
||||
|
||||
@Rule
|
||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
@@ -161,6 +168,10 @@ public class ZenModeBackendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
// With MODES_UI the Events rule is not default and is sorted differently. Most likely this
|
||||
// whole test class should be disabled since ZenModeBackend should never be used with
|
||||
// MODES_UI. However the other tests pass, so...
|
||||
@DisableFlags(Flags.FLAG_MODES_UI)
|
||||
public void updateState_checkRuleOrderingDescending_withDefaultRules() {
|
||||
final int NUM_RULES = 4;
|
||||
|
||||
@@ -168,8 +179,8 @@ public class ZenModeBackendTest {
|
||||
true);
|
||||
Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR);
|
||||
|
||||
assertEquals(rules[0].getKey(), DEFAULT_ID_1);
|
||||
assertEquals(rules[1].getKey(), DEFAULT_ID_2);
|
||||
assertEquals(DEFAULT_ID_1, rules[0].getKey());
|
||||
assertEquals(DEFAULT_ID_2, rules[1].getKey());
|
||||
// NON-DEFAULT RULES check ordering, most recent at the bottom/end
|
||||
for (int i = 0; i < NUM_RULES; i++) {
|
||||
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i + 2].getKey());
|
||||
|
@@ -36,7 +36,7 @@ class MobileNetworkListFragmentTest {
|
||||
|
||||
@Test
|
||||
fun isPageSearchEnabled_showMobileNetworkPage_returnTrue() {
|
||||
mockSimRepository.stub { on { showMobileNetworkPage() } doReturn true }
|
||||
mockSimRepository.stub { on { canEnterMobileNetworkPage() } doReturn true }
|
||||
|
||||
val isEnabled = SearchIndexProvider { mockSimRepository }.isPageSearchEnabled(context)
|
||||
|
||||
@@ -45,7 +45,7 @@ class MobileNetworkListFragmentTest {
|
||||
|
||||
@Test
|
||||
fun isPageSearchEnabled_hideMobileNetworkPage_returnFalse() {
|
||||
mockSimRepository.stub { on { showMobileNetworkPage() } doReturn false }
|
||||
mockSimRepository.stub { on { canEnterMobileNetworkPage() } doReturn false }
|
||||
|
||||
val isEnabled = SearchIndexProvider { mockSimRepository }.isPageSearchEnabled(context)
|
||||
|
||||
|
@@ -71,7 +71,7 @@ class TopLevelNetworkEntryPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
fun getSummary_hasMobile_shouldReturnMobileSummary() {
|
||||
mockSimRepository.stub { on { showMobileNetworkPage() } doReturn true }
|
||||
mockSimRepository.stub { on { showMobileNetworkPageEntrance() } doReturn true }
|
||||
|
||||
val summary = controller.summary
|
||||
|
||||
@@ -84,7 +84,7 @@ class TopLevelNetworkEntryPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
fun getSummary_noMobile_shouldReturnNoMobileSummary() {
|
||||
mockSimRepository.stub { on { showMobileNetworkPage() } doReturn false }
|
||||
mockSimRepository.stub { on { showMobileNetworkPageEntrance() } doReturn false }
|
||||
|
||||
val summary = controller.summary
|
||||
|
||||
|
@@ -37,50 +37,76 @@ class SimRepositoryTest {
|
||||
|
||||
private val mockPackageManager = mock<PackageManager>()
|
||||
|
||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||
on { userManager } doReturn mockUserManager
|
||||
on { packageManager } doReturn mockPackageManager
|
||||
}
|
||||
private val context: Context =
|
||||
spy(ApplicationProvider.getApplicationContext()) {
|
||||
on { userManager } doReturn mockUserManager
|
||||
on { packageManager } doReturn mockPackageManager
|
||||
}
|
||||
|
||||
private val repository = SimRepository(context)
|
||||
|
||||
@Test
|
||||
fun showMobileNetworkPage_adminUserAndHasTelephony_returnTrue() {
|
||||
mockUserManager.stub {
|
||||
on { isAdminUser } doReturn true
|
||||
}
|
||||
fun showMobileNetworkPageEntrance_adminUserAndHasTelephony_returnTrue() {
|
||||
mockUserManager.stub { on { isAdminUser } doReturn true }
|
||||
mockPackageManager.stub {
|
||||
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn true
|
||||
}
|
||||
|
||||
val showMobileNetworkPage = repository.showMobileNetworkPage()
|
||||
val showMobileNetworkPage = repository.showMobileNetworkPageEntrance()
|
||||
|
||||
assertThat(showMobileNetworkPage).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun showMobileNetworkPage_notAdminUser_returnFalse() {
|
||||
fun showMobileNetworkPageEntrance_notAdminUser_returnFalse() {
|
||||
mockUserManager.stub { on { isAdminUser } doReturn false }
|
||||
mockPackageManager.stub {
|
||||
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn true
|
||||
}
|
||||
|
||||
val showMobileNetworkPage = repository.showMobileNetworkPageEntrance()
|
||||
|
||||
assertThat(showMobileNetworkPage).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun showMobileNetworkPageEntrance_noTelephony_returnFalse() {
|
||||
mockUserManager.stub { on { isAdminUser } doReturn true }
|
||||
mockPackageManager.stub {
|
||||
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn false
|
||||
}
|
||||
|
||||
val showMobileNetworkPage = repository.showMobileNetworkPageEntrance()
|
||||
|
||||
assertThat(showMobileNetworkPage).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canEnterMobileNetworkPage_allowConfigMobileNetwork_returnTrue() {
|
||||
mockUserManager.stub {
|
||||
on { isAdminUser } doReturn false
|
||||
on { isAdminUser } doReturn true
|
||||
on { hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS) } doReturn false
|
||||
}
|
||||
mockPackageManager.stub {
|
||||
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn true
|
||||
}
|
||||
|
||||
val showMobileNetworkPage = repository.showMobileNetworkPage()
|
||||
val showMobileNetworkPage = repository.canEnterMobileNetworkPage()
|
||||
|
||||
assertThat(showMobileNetworkPage).isFalse()
|
||||
assertThat(showMobileNetworkPage).isTrue()
|
||||
}
|
||||
|
||||
@Test fun showMobileNetworkPage_noTelephony_returnFalse() {
|
||||
@Test
|
||||
fun canEnterMobileNetworkPage_disallowConfigMobileNetwork_returnFalse() {
|
||||
mockUserManager.stub {
|
||||
on { isAdminUser } doReturn true
|
||||
on { hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS) } doReturn true
|
||||
}
|
||||
mockPackageManager.stub {
|
||||
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn false
|
||||
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn true
|
||||
}
|
||||
|
||||
val showMobileNetworkPage = repository.showMobileNetworkPage()
|
||||
val showMobileNetworkPage = repository.canEnterMobileNetworkPage()
|
||||
|
||||
assertThat(showMobileNetworkPage).isFalse()
|
||||
}
|
||||
|
Reference in New Issue
Block a user