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"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<issues format="4">
|
<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
|
<issue
|
||||||
id="HardCodedColor"
|
id="HardCodedColor"
|
||||||
severity="Error"
|
severity="Error"
|
||||||
@@ -1949,6 +1297,22 @@
|
|||||||
column="5"/>
|
column="5"/>
|
||||||
</issue>
|
</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
|
<issue
|
||||||
id="HardCodedColor"
|
id="HardCodedColor"
|
||||||
severity="Error"
|
severity="Error"
|
||||||
@@ -3277,6 +2641,22 @@
|
|||||||
column="5"/>
|
column="5"/>
|
||||||
</issue>
|
</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
|
<issue
|
||||||
id="HardCodedColor"
|
id="HardCodedColor"
|
||||||
severity="Error"
|
severity="Error"
|
||||||
@@ -4685,6 +4065,22 @@
|
|||||||
column="11"/>
|
column="11"/>
|
||||||
</issue>
|
</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
|
<issue
|
||||||
id="HardCodedColor"
|
id="HardCodedColor"
|
||||||
severity="Error"
|
severity="Error"
|
||||||
@@ -5101,6 +4497,102 @@
|
|||||||
column="15"/>
|
column="15"/>
|
||||||
</issue>
|
</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
|
<issue
|
||||||
id="HardCodedColor"
|
id="HardCodedColor"
|
||||||
severity="Error"
|
severity="Error"
|
||||||
@@ -6973,103 +6465,4 @@
|
|||||||
column="5"/>
|
column="5"/>
|
||||||
</issue>
|
</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>
|
</issues>
|
@@ -12141,8 +12141,8 @@
|
|||||||
<string name="title_have_satellite_plan">Satellite messaging is included with your account</string>
|
<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] -->
|
<!-- 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>
|
<string name="title_no_satellite_plan">Satellite messaging isn\u2019t included with your account</string>
|
||||||
<!-- text view add satellite messaging" [CHAR_LIMIT=NONE] -->
|
<!-- text view "Learn more" [CHAR_LIMIT=NONE] -->
|
||||||
<string name="summary_add_satellite_setting">Add satellite messaging</string>
|
<string name="summary_add_satellite_setting">Learn More</string>
|
||||||
<!-- Category name "How it works" [CHAR_LIMIT=NONE] -->
|
<!-- Category name "How it works" [CHAR_LIMIT=NONE] -->
|
||||||
<string name="category_name_how_it_works">How it works</string>
|
<string name="category_name_how_it_works">How it works</string>
|
||||||
<!-- Title for satellite connection guide [CHAR_LIMIT=NONE] -->
|
<!-- 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 Handler mHandler = new Handler(Looper.getMainLooper());
|
||||||
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
|
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
|
||||||
@Nullable
|
@Nullable
|
||||||
private AlertDialog mLoadingDialog = null;
|
private AlertDialog mProgressDialog = null;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean mShouldTriggerAudioSharingShareThenPairFlow = false;
|
boolean mShouldTriggerAudioSharingShareThenPairFlow = false;
|
||||||
private CopyOnWriteArrayList<BluetoothDevice> mDevicesWithMetadataChangedListener =
|
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.
|
// 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
|
// The BluetoothDevicePreference summary will be blank for seconds between "Pairing..." and
|
||||||
// "Connecting..." To help users better understand the process, we listen to metadata change
|
// "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.
|
// gets to BOND_BONDED.
|
||||||
final BluetoothAdapter.OnMetadataChangedListener mMetadataListener =
|
final BluetoothAdapter.OnMetadataChangedListener mMetadataListener =
|
||||||
new BluetoothAdapter.OnMetadataChangedListener() {
|
new BluetoothAdapter.OnMetadataChangedListener() {
|
||||||
@@ -97,7 +97,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
|||||||
public void onMetadataChanged(@NonNull BluetoothDevice device, int key,
|
public void onMetadataChanged(@NonNull BluetoothDevice device, int key,
|
||||||
@Nullable byte[] value) {
|
@Nullable byte[] value) {
|
||||||
Log.d(getLogTag(), "onMetadataChanged device = " + device + ", key = " + key);
|
Log.d(getLogTag(), "onMetadataChanged device = " + device + ", key = " + key);
|
||||||
if (mShouldTriggerAudioSharingShareThenPairFlow && mLoadingDialog == null
|
if (mShouldTriggerAudioSharingShareThenPairFlow && mProgressDialog == null
|
||||||
&& device.getBondState() == BluetoothDevice.BOND_BONDED
|
&& device.getBondState() == BluetoothDevice.BOND_BONDED
|
||||||
&& mSelectedList.contains(device)) {
|
&& mSelectedList.contains(device)) {
|
||||||
triggerAudioSharingShareThenPairFlow(device);
|
triggerAudioSharingShareThenPairFlow(device);
|
||||||
@@ -355,7 +355,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mJustBonded = device;
|
mJustBonded = device;
|
||||||
// Show connecting device loading state
|
// Show connecting device progress
|
||||||
String aliasName = device.getAlias();
|
String aliasName = device.getAlias();
|
||||||
String deviceName = TextUtils.isEmpty(aliasName) ? device.getAddress()
|
String deviceName = TextUtils.isEmpty(aliasName) ? device.getAddress()
|
||||||
: aliasName;
|
: aliasName;
|
||||||
@@ -387,9 +387,9 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
|||||||
// TODO: use DialogFragment
|
// TODO: use DialogFragment
|
||||||
private void showConnectingDialog(@NonNull String message) {
|
private void showConnectingDialog(@NonNull String message) {
|
||||||
postOnMainThread(() -> {
|
postOnMainThread(() -> {
|
||||||
if (mLoadingDialog != null) {
|
if (mProgressDialog != null) {
|
||||||
Log.d(getLogTag(), "showConnectingDialog, is already showing");
|
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())) {
|
if (textView != null && !message.equals(textView.getText().toString())) {
|
||||||
Log.d(getLogTag(), "showConnectingDialog, update message");
|
Log.d(getLogTag(), "showConnectingDialog, update message");
|
||||||
// TODO: use string res once finalized
|
// TODO: use string res once finalized
|
||||||
@@ -401,7 +401,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
|||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
LayoutInflater inflater = LayoutInflater.from(builder.getContext());
|
LayoutInflater inflater = LayoutInflater.from(builder.getContext());
|
||||||
View customView = inflater.inflate(
|
View customView = inflater.inflate(
|
||||||
R.layout.dialog_audio_sharing_loading_state, /* root= */
|
R.layout.dialog_audio_sharing_progress, /* root= */
|
||||||
null);
|
null);
|
||||||
TextView textView = customView.findViewById(R.id.message);
|
TextView textView = customView.findViewById(R.id.message);
|
||||||
if (textView != null) {
|
if (textView != null) {
|
||||||
@@ -410,15 +410,15 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
|
|||||||
}
|
}
|
||||||
AlertDialog dialog = builder.setView(customView).setCancelable(false).create();
|
AlertDialog dialog = builder.setView(customView).setCancelable(false).create();
|
||||||
dialog.setCanceledOnTouchOutside(false);
|
dialog.setCanceledOnTouchOutside(false);
|
||||||
mLoadingDialog = dialog;
|
mProgressDialog = dialog;
|
||||||
dialog.show();
|
dialog.show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dismissConnectingDialog() {
|
private void dismissConnectingDialog() {
|
||||||
postOnMainThread(() -> {
|
postOnMainThread(() -> {
|
||||||
if (mLoadingDialog != null) {
|
if (mProgressDialog != null) {
|
||||||
mLoadingDialog.dismiss();
|
mProgressDialog.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.provider.SettingsSlicesContract;
|
import android.provider.SettingsSlicesContract;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.core.graphics.drawable.IconCompat;
|
import androidx.core.graphics.drawable.IconCompat;
|
||||||
import androidx.slice.Slice;
|
import androidx.slice.Slice;
|
||||||
@@ -36,10 +37,16 @@ import androidx.slice.builders.SliceAction;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SubSettings;
|
import com.android.settings.SubSettings;
|
||||||
import com.android.settings.connecteddevice.BluetoothDashboardFragment;
|
import com.android.settings.connecteddevice.BluetoothDashboardFragment;
|
||||||
|
import com.android.settings.network.SatelliteRepository;
|
||||||
import com.android.settings.slices.CustomSliceRegistry;
|
import com.android.settings.slices.CustomSliceRegistry;
|
||||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||||
import com.android.settings.slices.SliceBuilderUtils;
|
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.
|
* 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 PendingIntent primaryAction = getPrimaryAction(context);
|
||||||
final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon,
|
final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon,
|
||||||
ListBuilder.ICON_IMAGE, title);
|
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)
|
return new ListBuilder(context, CustomSliceRegistry.BLUETOOTH_URI, ListBuilder.INFINITY)
|
||||||
.setAccentColor(color)
|
.setAccentColor(color)
|
||||||
.addRow(new RowBuilder()
|
.addRow(rowBuilder)
|
||||||
.setTitle(title)
|
|
||||||
.addEndItem(toggleSliceAction)
|
|
||||||
.setPrimaryAction(primarySliceAction))
|
|
||||||
.build();
|
.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) {
|
public static Intent getIntent(Context context) {
|
||||||
final String screenTitle = context.getText(R.string.bluetooth_settings_title).toString();
|
final String screenTitle = context.getText(R.string.bluetooth_settings_title).toString();
|
||||||
final Uri contentUri = new Uri.Builder().appendPath(
|
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.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||||
|
|
||||||
public class AudioSharingRetryDialogFragment extends InstrumentedDialogFragment {
|
public class AudioSharingErrorDialogFragment extends InstrumentedDialogFragment {
|
||||||
private static final String TAG = "AudioSharingRetryDialog";
|
private static final String TAG = "AudioSharingErrorDialog";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
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.
|
* @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.");
|
Log.d(TAG, "Dialog is showing, return.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Show up the retry dialog.");
|
Log.d(TAG, "Show up the error dialog.");
|
||||||
AudioSharingRetryDialogFragment dialogFrag = new AudioSharingRetryDialogFragment();
|
AudioSharingErrorDialogFragment dialogFrag = new AudioSharingErrorDialogFragment();
|
||||||
dialogFrag.show(manager, TAG);
|
dialogFrag.show(manager, TAG);
|
||||||
}
|
}
|
||||||
|
|
@@ -40,8 +40,8 @@ import com.google.common.base.Strings;
|
|||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFragment {
|
public class AudioSharingProgressDialogFragment extends InstrumentedDialogFragment {
|
||||||
private static final String TAG = "AudioSharingLoadingDlg";
|
private static final String TAG = "AudioSharingProgressDlg";
|
||||||
|
|
||||||
private static final String BUNDLE_KEY_MESSAGE = "bundle_key_message";
|
private static final String BUNDLE_KEY_MESSAGE = "bundle_key_message";
|
||||||
private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(15);
|
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 host The Fragment this dialog will be hosted by.
|
||||||
* @param message The content to be shown on the dialog.
|
* @param message The content to be shown on the dialog.
|
||||||
@@ -85,16 +85,15 @@ public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFr
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sMessage = message;
|
sMessage = message;
|
||||||
Log.d(TAG, "Show up the loading dialog.");
|
Log.d(TAG, "Show up the progress dialog.");
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString(BUNDLE_KEY_MESSAGE, message);
|
args.putString(BUNDLE_KEY_MESSAGE, message);
|
||||||
AudioSharingLoadingStateDialogFragment dialogFrag =
|
AudioSharingProgressDialogFragment dialogFrag = new AudioSharingProgressDialogFragment();
|
||||||
new AudioSharingLoadingStateDialogFragment();
|
|
||||||
dialogFrag.setArguments(args);
|
dialogFrag.setArguments(args);
|
||||||
dialogFrag.show(manager, TAG);
|
dialogFrag.show(manager, TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Dismiss the {@link AudioSharingLoadingStateDialogFragment} dialog. */
|
/** Dismiss the {@link AudioSharingProgressDialogFragment} dialog. */
|
||||||
public static void dismiss(@Nullable Fragment host) {
|
public static void dismiss(@Nullable Fragment host) {
|
||||||
if (host == null || !BluetoothUtils.isAudioSharingEnabled()) return;
|
if (host == null || !BluetoothUtils.isAudioSharingEnabled()) return;
|
||||||
final FragmentManager manager;
|
final FragmentManager manager;
|
||||||
@@ -119,7 +118,7 @@ public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFr
|
|||||||
String message = args.getString(BUNDLE_KEY_MESSAGE, "");
|
String message = args.getString(BUNDLE_KEY_MESSAGE, "");
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
LayoutInflater inflater = LayoutInflater.from(builder.getContext());
|
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);
|
null);
|
||||||
TextView textView = customView.findViewById(R.id.message);
|
TextView textView = customView.findViewById(R.id.message);
|
||||||
if (!Strings.isNullOrEmpty(message)) textView.setText(message);
|
if (!Strings.isNullOrEmpty(message)) textView.setText(message);
|
@@ -41,7 +41,9 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.UiThread;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
@@ -69,7 +71,6 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -113,14 +114,21 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
private final Executor mExecutor;
|
private final Executor mExecutor;
|
||||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
private final OnAudioSharingStateChangedListener mListener;
|
private final OnAudioSharingStateChangedListener mListener;
|
||||||
|
@VisibleForTesting IntentFilter mIntentFilter;
|
||||||
private Map<Integer, List<BluetoothDevice>> mGroupedConnectedDevices = new HashMap<>();
|
private Map<Integer, List<BluetoothDevice>> mGroupedConnectedDevices = new HashMap<>();
|
||||||
@Nullable private AudioSharingDeviceItem mTargetActiveItem;
|
@Nullable private AudioSharingDeviceItem mTargetActiveItem;
|
||||||
private List<AudioSharingDeviceItem> mDeviceItemsForSharing = new ArrayList<>();
|
private List<AudioSharingDeviceItem> mDeviceItemsForSharing = new ArrayList<>();
|
||||||
@VisibleForTesting IntentFilter mIntentFilter;
|
|
||||||
private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
|
private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
|
||||||
private AtomicInteger mIntentHandleStage =
|
private AtomicInteger mIntentHandleStage =
|
||||||
new AtomicInteger(StartIntentHandleStage.TO_HANDLE.ordinal());
|
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<>();
|
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
|
@VisibleForTesting
|
||||||
BroadcastReceiver mReceiver =
|
BroadcastReceiver mReceiver =
|
||||||
@@ -153,6 +161,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
public void onBroadcastStartFailed(int reason) {
|
public void onBroadcastStartFailed(int reason) {
|
||||||
Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
|
Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
|
||||||
updateSwitch();
|
updateSwitch();
|
||||||
|
showErrorDialog();
|
||||||
mMetricsFeatureProvider.action(
|
mMetricsFeatureProvider.action(
|
||||||
mContext,
|
mContext,
|
||||||
SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED,
|
SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED,
|
||||||
@@ -178,7 +187,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
+ reason
|
+ reason
|
||||||
+ ", broadcastId = "
|
+ ", broadcastId = "
|
||||||
+ broadcastId);
|
+ broadcastId);
|
||||||
|
mStoppingSharing.compareAndSet(true, false);
|
||||||
updateSwitch();
|
updateSwitch();
|
||||||
|
AudioSharingUtils.postOnMainThread(mContext,
|
||||||
|
() -> dismissStaleDialogsOtherThanErrorDialog());
|
||||||
AudioSharingUtils.toastMessage(
|
AudioSharingUtils.toastMessage(
|
||||||
mContext,
|
mContext,
|
||||||
mContext.getString(R.string.audio_sharing_sharing_stopped_label));
|
mContext.getString(R.string.audio_sharing_sharing_stopped_label));
|
||||||
@@ -219,7 +231,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
TAG,
|
TAG,
|
||||||
"Skip handleOnBroadcastReady: null assistant or "
|
"Skip handleOnBroadcastReady: null assistant or "
|
||||||
+ "sink has active local source.");
|
+ "sink has active local source.");
|
||||||
cleanUp();
|
cleanUpStatesForStartSharing();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleOnBroadcastReady();
|
handleOnBroadcastReady();
|
||||||
@@ -264,17 +276,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
+ source
|
+ source
|
||||||
+ ", reason = "
|
+ ", reason = "
|
||||||
+ reason);
|
+ reason);
|
||||||
mMetricsFeatureProvider.action(
|
if (mSinksInAdding.contains(sink)) {
|
||||||
mContext,
|
stopAudioSharing();
|
||||||
SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
|
showErrorDialog();
|
||||||
SettingsEnums.AUDIO_SHARING_SETTINGS);
|
mMetricsFeatureProvider.action(
|
||||||
AudioSharingUtils.toastMessage(
|
mContext,
|
||||||
mContext,
|
SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
|
||||||
String.format(
|
SettingsEnums.AUDIO_SHARING_SETTINGS);
|
||||||
Locale.US,
|
}
|
||||||
"Fail to add source to %s reason %d",
|
|
||||||
sink.getAddress(),
|
|
||||||
reason));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -298,13 +307,33 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
@NonNull BluetoothDevice sink,
|
@NonNull BluetoothDevice sink,
|
||||||
int sourceId,
|
int sourceId,
|
||||||
@NonNull BluetoothLeBroadcastReceiveState state) {
|
@NonNull BluetoothLeBroadcastReceiveState state) {
|
||||||
|
if (mStoppingSharing.get()) {
|
||||||
|
Log.d(TAG, "Skip onReceiveStateChanged, stopping broadcast");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (BluetoothUtils.isConnected(state)) {
|
if (BluetoothUtils.isConnected(state)) {
|
||||||
if (mSinksInAdding.contains(sink)) {
|
if (mSinksInAdding.contains(sink)) {
|
||||||
mSinksInAdding.remove(sink);
|
mSinksInAdding.remove(sink);
|
||||||
}
|
}
|
||||||
dismissLoadingStateDialogIfNeeded();
|
dismissProgressDialogIfNeeded();
|
||||||
Log.d(TAG, "onReceiveStateChanged() connected, sink = " + sink
|
Log.d(TAG, "onReceiveStateChanged() connected, sink = " + sink
|
||||||
+ ", remaining sinks = " + mSinksInAdding);
|
+ ", 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;
|
return;
|
||||||
}
|
}
|
||||||
stopAudioSharing();
|
stopAudioSharing();
|
||||||
|
mMetricsFeatureProvider.action(
|
||||||
|
mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +573,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
mSinksInAdding.clear();
|
mSinksInAdding.clear();
|
||||||
// TODO: use string res once finalized.
|
// TODO: use string res once finalized.
|
||||||
AudioSharingUtils.postOnMainThread(mContext,
|
AudioSharingUtils.postOnMainThread(mContext,
|
||||||
() -> AudioSharingLoadingStateDialogFragment.show(mFragment,
|
() -> AudioSharingProgressDialogFragment.show(mFragment,
|
||||||
"Starting audio stream..."));
|
"Starting audio stream..."));
|
||||||
mMetricsFeatureProvider.action(
|
mMetricsFeatureProvider.action(
|
||||||
mContext,
|
mContext,
|
||||||
@@ -553,9 +584,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
|
|
||||||
private void stopAudioSharing() {
|
private void stopAudioSharing() {
|
||||||
if (mBroadcast != null) {
|
if (mBroadcast != null) {
|
||||||
mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId());
|
int broadcastId = mBroadcast.getLatestBroadcastId();
|
||||||
mMetricsFeatureProvider.action(
|
if (broadcastId != -1) {
|
||||||
mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF);
|
mBroadcast.stopBroadcast(broadcastId);
|
||||||
|
mStoppingSharing.compareAndSet(false, true);
|
||||||
|
mSinksInAdding.clear();
|
||||||
|
mSinksToWaitFor.clear();
|
||||||
|
}
|
||||||
|
cleanUpStatesForStartSharing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,11 +653,22 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
/* userTriggered= */ false,
|
/* userTriggered= */ false,
|
||||||
/* deviceCountInSharing= */ targetActiveSinks.isEmpty() ? 0 : 1,
|
/* deviceCountInSharing= */ targetActiveSinks.isEmpty() ? 0 : 1,
|
||||||
/* candidateDeviceCount= */ mDeviceItemsForSharing.size());
|
/* candidateDeviceCount= */ mDeviceItemsForSharing.size());
|
||||||
|
// Auto add primary/active sinks w/o user interactions.
|
||||||
if (!targetActiveSinks.isEmpty() && mTargetActiveItem != null) {
|
if (!targetActiveSinks.isEmpty() && mTargetActiveItem != null) {
|
||||||
Log.d(TAG, "handleOnBroadcastReady: automatically add source to active sinks.");
|
Log.d(TAG, "handleOnBroadcastReady: automatically add source to active sinks.");
|
||||||
addSourceToTargetSinks(targetActiveSinks, mTargetActiveItem.getName());
|
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);
|
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING);
|
||||||
mTargetActiveItem = null;
|
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(
|
if (mIntentHandleStage.compareAndSet(
|
||||||
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
||||||
StartIntentHandleStage.HANDLED.ordinal())
|
StartIntentHandleStage.HANDLED.ordinal())
|
||||||
@@ -631,31 +678,42 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
|
List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
|
||||||
target.getGroupId(), ImmutableList.of());
|
target.getGroupId(), ImmutableList.of());
|
||||||
addSourceToTargetSinks(targetSinks, target.getName());
|
addSourceToTargetSinks(targetSinks, target.getName());
|
||||||
cleanUp();
|
cleanUpStatesForStartSharing();
|
||||||
// TODO: Add metric for auto add by intent
|
// TODO: Add metric for auto add by intent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Still mark intent as handled if early returned due to preconditions not met
|
||||||
mIntentHandleStage.compareAndSet(
|
mIntentHandleStage.compareAndSet(
|
||||||
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
||||||
StartIntentHandleStage.HANDLED.ordinal());
|
StartIntentHandleStage.HANDLED.ordinal());
|
||||||
if (mFragment == null) {
|
if (mFragment == null) {
|
||||||
Log.d(TAG, "handleOnBroadcastReady: dialog fail to show due to null fragment.");
|
Log.d(TAG, "handleOnBroadcastReady: dialog fail to show due to null fragment.");
|
||||||
dismissLoadingStateDialogIfNeeded();
|
// Clean up states before early return.
|
||||||
cleanUp();
|
dismissProgressDialogIfNeeded();
|
||||||
|
cleanUpStatesForStartSharing();
|
||||||
return;
|
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 =
|
AudioSharingDialogFragment.DialogEventListener listener =
|
||||||
new AudioSharingDialogFragment.DialogEventListener() {
|
new AudioSharingDialogFragment.DialogEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPositiveClick() {
|
public void onPositiveClick() {
|
||||||
// Could go to other pages, dismiss the loading dialog.
|
// Could go to other pages, dismiss the progress dialog.
|
||||||
dismissLoadingStateDialogIfNeeded();
|
dismissProgressDialogIfNeeded();
|
||||||
cleanUp();
|
cleanUpStatesForStartSharing();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -663,14 +721,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
|
List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
|
||||||
item.getGroupId(), ImmutableList.of());
|
item.getGroupId(), ImmutableList.of());
|
||||||
addSourceToTargetSinks(targetSinks, item.getName());
|
addSourceToTargetSinks(targetSinks, item.getName());
|
||||||
cleanUp();
|
cleanUpStatesForStartSharing();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCancelClick() {
|
public void onCancelClick() {
|
||||||
// Could go to other pages, dismiss the loading dialog.
|
// Could go to other pages, dismiss the progress dialog.
|
||||||
dismissLoadingStateDialogIfNeeded();
|
dismissProgressDialogIfNeeded();
|
||||||
cleanUp();
|
cleanUpStatesForStartSharing();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
AudioSharingUtils.postOnMainThread(
|
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 {
|
private static final class MainSwitchAccessibilityDelegate extends View.AccessibilityDelegate {
|
||||||
@Override
|
@Override
|
||||||
public boolean onRequestSendAccessibilityEvent(
|
public boolean onRequestSendAccessibilityEvent(
|
||||||
@@ -742,25 +830,25 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
private void addSourceToTargetSinks(List<BluetoothDevice> targetActiveSinks,
|
private void addSourceToTargetSinks(List<BluetoothDevice> targetActiveSinks,
|
||||||
@NonNull String sinkName) {
|
@NonNull String sinkName) {
|
||||||
mSinksInAdding.addAll(targetActiveSinks);
|
mSinksInAdding.addAll(targetActiveSinks);
|
||||||
AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
|
|
||||||
// TODO: move to res once finalized
|
// TODO: move to res once finalized
|
||||||
String loadingMessage = "Sharing with " + sinkName + "...";
|
String progressMessage = "Sharing with " + sinkName + "...";
|
||||||
showLoadingStateDialog(loadingMessage);
|
showProgressDialog(progressMessage);
|
||||||
|
AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showLoadingStateDialog(@NonNull String loadingMessage) {
|
private void showProgressDialog(@NonNull String progressMessage) {
|
||||||
AudioSharingUtils.postOnMainThread(mContext,
|
AudioSharingUtils.postOnMainThread(mContext,
|
||||||
() -> AudioSharingLoadingStateDialogFragment.show(mFragment, loadingMessage));
|
() -> AudioSharingProgressDialogFragment.show(mFragment, progressMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dismissLoadingStateDialogIfNeeded() {
|
private void dismissProgressDialogIfNeeded() {
|
||||||
if (mSinksInAdding.isEmpty()) {
|
if (mSinksInAdding.isEmpty()) {
|
||||||
AudioSharingUtils.postOnMainThread(mContext,
|
AudioSharingUtils.postOnMainThread(mContext,
|
||||||
() -> AudioSharingLoadingStateDialogFragment.dismiss(mFragment));
|
() -> AudioSharingProgressDialogFragment.dismiss(mFragment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanUp() {
|
private void cleanUpStatesForStartSharing() {
|
||||||
mGroupedConnectedDevices.clear();
|
mGroupedConnectedDevices.clear();
|
||||||
mDeviceItemsForSharing.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.Utils;
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
|
||||||
|
// LINT.IfChange
|
||||||
public class BasebandVersionPreferenceController extends BasePreferenceController {
|
public class BasebandVersionPreferenceController extends BasePreferenceController {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -45,3 +46,4 @@ public class BasebandVersionPreferenceController extends BasePreferenceControlle
|
|||||||
mContext.getString(R.string.device_info_default));
|
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("os_firmware_version", R.string.firmware_version)
|
||||||
+PreferenceWidget("security_key", R.string.security_patch)
|
+PreferenceWidget("security_key", R.string.security_patch)
|
||||||
+PreferenceWidget("module_version", R.string.module_version)
|
+PreferenceWidget("module_version", R.string.module_version)
|
||||||
+PreferenceWidget("base_band", R.string.baseband_version)
|
+BasebandVersionPreference()
|
||||||
+PreferenceWidget("kernel_version", R.string.kernel_version)
|
+KernelVersionPreference()
|
||||||
+PreferenceWidget("os_build_number", R.string.build_number)
|
+SimpleBuildNumberPreference()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PreferenceWidget(override val key: String, override val title: Int) :
|
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.settings.core.BasePreferenceController;
|
||||||
import com.android.settingslib.DeviceInfoUtils;
|
import com.android.settingslib.DeviceInfoUtils;
|
||||||
|
|
||||||
|
// LINT.IfChange
|
||||||
public class KernelVersionPreferenceController extends BasePreferenceController {
|
public class KernelVersionPreferenceController extends BasePreferenceController {
|
||||||
|
|
||||||
public KernelVersionPreferenceController(Context context, String preferenceKey) {
|
public KernelVersionPreferenceController(Context context, String preferenceKey) {
|
||||||
@@ -37,3 +38,4 @@ public class KernelVersionPreferenceController extends BasePreferenceController
|
|||||||
return DeviceInfoUtils.getFormattedKernelVersion(mContext);
|
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;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
|
|
||||||
|
// LINT.IfChange
|
||||||
public class SimpleBuildNumberPreferenceController extends BasePreferenceController {
|
public class SimpleBuildNumberPreferenceController extends BasePreferenceController {
|
||||||
|
|
||||||
public SimpleBuildNumberPreferenceController(Context context,
|
public SimpleBuildNumberPreferenceController(Context context,
|
||||||
@@ -39,3 +40,4 @@ public class SimpleBuildNumberPreferenceController extends BasePreferenceControl
|
|||||||
return BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY);
|
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.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.UserInfo;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -80,10 +79,7 @@ public class OnDeviceRecognitionPreferenceController extends BasePreferenceContr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void show(Preference preference) {
|
private void show(Preference preference) {
|
||||||
final List<UserHandle> userHandles = new ArrayList<>();
|
final List<UserHandle> userHandles = UserManager.get(mContext).getEnabledProfiles();
|
||||||
for (UserInfo userInfo : UserManager.get(mContext).getUsers()) {
|
|
||||||
userHandles.add(userInfo.getUserHandle());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only a single profile is installed. Proceed with its settings.
|
// Only a single profile is installed. Proceed with its settings.
|
||||||
if (userHandles.size() == 1) {
|
if (userHandles.size() == 1) {
|
||||||
|
@@ -89,7 +89,7 @@ class MobileNetworkListFragment : DashboardFragment() {
|
|||||||
private val simRepositoryFactory: (Context) -> SimRepository = ::SimRepository
|
private val simRepositoryFactory: (Context) -> SimRepository = ::SimRepository
|
||||||
) : BaseSearchIndexProvider(R.xml.network_provider_sims_list) {
|
) : BaseSearchIndexProvider(R.xml.network_provider_sims_list) {
|
||||||
public override fun isPageSearchEnabled(context: Context): Boolean =
|
public override fun isPageSearchEnabled(context: Context): Boolean =
|
||||||
simRepositoryFactory(context).showMobileNetworkPage()
|
simRepositoryFactory(context).canEnterMobileNetworkPage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,7 @@ constructor(
|
|||||||
private var isAirplaneModeOn = false
|
private var isAirplaneModeOn = false
|
||||||
|
|
||||||
override fun getAvailabilityStatus() =
|
override fun getAvailabilityStatus() =
|
||||||
if (SimRepository(mContext).showMobileNetworkPage()) AVAILABLE
|
if (SimRepository(mContext).showMobileNetworkPageEntrance()) AVAILABLE
|
||||||
else CONDITIONALLY_UNAVAILABLE
|
else CONDITIONALLY_UNAVAILABLE
|
||||||
|
|
||||||
override fun displayPreference(screen: PreferenceScreen) {
|
override fun displayPreference(screen: PreferenceScreen) {
|
||||||
|
@@ -53,8 +53,8 @@ import androidx.compose.ui.text.style.TextAlign
|
|||||||
import androidx.lifecycle.LifecycleRegistry
|
import androidx.lifecycle.LifecycleRegistry
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.SidecarFragment
|
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.SubscriptionActionDialogActivity
|
||||||
import com.android.settings.network.telephony.SubscriptionRepository
|
|
||||||
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity
|
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity
|
||||||
import com.android.settings.network.telephony.requireSubscriptionManager
|
import com.android.settings.network.telephony.requireSubscriptionManager
|
||||||
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
|
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
|
||||||
@@ -578,6 +578,10 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
|||||||
subId: Int,
|
subId: Int,
|
||||||
isNewTask: Boolean = false,
|
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 {
|
val intent = Intent(context, SimOnboardingActivity::class.java).apply {
|
||||||
putExtra(SUB_ID, subId)
|
putExtra(SUB_ID, subId)
|
||||||
if(isNewTask) {
|
if(isNewTask) {
|
||||||
|
@@ -48,7 +48,7 @@ constructor(
|
|||||||
|
|
||||||
override fun getSummary(): CharSequence {
|
override fun getSummary(): CharSequence {
|
||||||
val summaryResId =
|
val summaryResId =
|
||||||
if (simRepository.showMobileNetworkPage()) {
|
if (simRepository.showMobileNetworkPageEntrance()) {
|
||||||
R.string.network_dashboard_summary_mobile
|
R.string.network_dashboard_summary_mobile
|
||||||
} else {
|
} else {
|
||||||
R.string.network_dashboard_summary_no_mobile
|
R.string.network_dashboard_summary_no_mobile
|
||||||
|
@@ -21,7 +21,6 @@ import android.provider.Settings
|
|||||||
import android.telephony.SubscriptionInfo
|
import android.telephony.SubscriptionInfo
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.datausage.BillingCyclePreferenceController.Companion.BillingCycleSearchItem
|
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.CarrierSettingsVersionPreferenceController.Companion.CarrierSettingsVersionSearchItem
|
||||||
import com.android.settings.network.telephony.DataUsagePreferenceController.Companion.DataUsageSearchItem
|
import com.android.settings.network.telephony.DataUsagePreferenceController.Companion.DataUsageSearchItem
|
||||||
import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
|
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.settings.spa.search.SpaSearchRepository.Companion.searchIndexProviderOf
|
||||||
import com.android.settingslib.search.SearchIndexableData
|
import com.android.settingslib.search.SearchIndexableData
|
||||||
import com.android.settingslib.search.SearchIndexableRaw
|
import com.android.settingslib.search.SearchIndexableRaw
|
||||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
|
||||||
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
|
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
|
||||||
|
|
||||||
class MobileNetworkSettingsSearchIndex(
|
class MobileNetworkSettingsSearchIndex(
|
||||||
@@ -109,12 +107,8 @@ class MobileNetworkSettingsSearchIndex(
|
|||||||
companion object {
|
companion object {
|
||||||
/** suppress full page if user is not admin */
|
/** suppress full page if user is not admin */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isMobileNetworkSettingsSearchable(context: Context): Boolean {
|
fun isMobileNetworkSettingsSearchable(context: Context): Boolean =
|
||||||
val isAirplaneMode by context.settingsGlobalBoolean(Settings.Global.AIRPLANE_MODE_ON)
|
SimRepository(context).canEnterMobileNetworkPage()
|
||||||
return SubscriptionUtil.isSimHardwareVisible(context) &&
|
|
||||||
!isAirplaneMode &&
|
|
||||||
context.userManager.isAdminUser
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
|
fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
|
||||||
listOf(
|
listOf(
|
||||||
|
@@ -18,13 +18,24 @@ package com.android.settings.network.telephony
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
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.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 packageManager = context.packageManager
|
||||||
private val userManager = context.userManager
|
private val userManager = context.userManager
|
||||||
|
|
||||||
/** Gets whether we show mobile network settings page to the current user. */
|
/** Gets whether show mobile network settings page entrance to the current user. */
|
||||||
fun showMobileNetworkPage(): Boolean =
|
fun showMobileNetworkPageEntrance(): Boolean =
|
||||||
packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) && userManager.isAdminUser
|
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.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.RingtonePreference;
|
import com.android.settings.RingtonePreference;
|
||||||
|
|
||||||
public class NotificationSoundPreference extends RingtonePreference {
|
public class NotificationSoundPreference extends RingtonePreference {
|
||||||
@@ -49,6 +48,20 @@ public class NotificationSoundPreference extends RingtonePreference {
|
|||||||
updateRingtoneName(mRingtone);
|
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
|
@Override
|
||||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
@@ -69,16 +82,7 @@ public class NotificationSoundPreference extends RingtonePreference {
|
|||||||
AsyncTask ringtoneNameTask = new AsyncTask<Object, Void, CharSequence>() {
|
AsyncTask ringtoneNameTask = new AsyncTask<Object, Void, CharSequence>() {
|
||||||
@Override
|
@Override
|
||||||
protected CharSequence doInBackground(Object... params) {
|
protected CharSequence doInBackground(Object... params) {
|
||||||
if (uri == null) {
|
return generateRingtoneTitle(uri);
|
||||||
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 */);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -458,7 +458,7 @@ public class ZenModeBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> getDefaultRuleIds() {
|
private static List<String> getDefaultRuleIds() {
|
||||||
return ZenModeConfig.DEFAULT_RULE_IDS;
|
return ZenModeConfig.getDefaultRuleIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationManager.Policy toNotificationPolicy(ZenPolicy policy) {
|
NotificationManager.Policy toNotificationPolicy(ZenPolicy policy) {
|
||||||
|
@@ -206,7 +206,12 @@ public class SimSlotChangeHandler {
|
|||||||
if (hasActiveEsimSubscription()) {
|
if (hasActiveEsimSubscription()) {
|
||||||
if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
|
if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
|
||||||
Log.i(TAG, "Enabled profile exists. DSDS condition satisfied.");
|
Log.i(TAG, "Enabled profile exists. DSDS condition satisfied.");
|
||||||
startDsdsDialogActivity();
|
if (Flags.isDualSimOnboardingEnabled()) {
|
||||||
|
// enable dsds by sim onboarding flow
|
||||||
|
handleRemovableSimInsertWhenDsds(removableSlotInfo);
|
||||||
|
} else {
|
||||||
|
startDsdsDialogActivity();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "Enabled profile exists. DSDS condition not satisfied.");
|
Log.i(TAG, "Enabled profile exists. DSDS condition not satisfied.");
|
||||||
startChooseSimActivity(true);
|
startChooseSimActivity(true);
|
||||||
|
@@ -212,7 +212,7 @@ open class NetworkCellularGroupProvider : SettingsPageProvider, SearchablePage {
|
|||||||
const val fileName = "NetworkCellularGroupProvider"
|
const val fileName = "NetworkCellularGroupProvider"
|
||||||
|
|
||||||
private fun isPageSearchable(context: Context) =
|
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.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.preference.PreferenceViewHolder;
|
import androidx.preference.PreferenceViewHolder;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -35,6 +37,10 @@ public class TickButtonPreference extends TwoTargetPreference {
|
|||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TickButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||||
super.onBindViewHolder(holder);
|
super.onBindViewHolder(holder);
|
||||||
|
@@ -69,6 +69,9 @@ android_robolectric_test {
|
|||||||
"com_android_server_accessibility_flags_lib",
|
"com_android_server_accessibility_flags_lib",
|
||||||
"flag-junit",
|
"flag-junit",
|
||||||
"flag-junit-base",
|
"flag-junit-base",
|
||||||
|
"kotlin-test",
|
||||||
|
"mockito-robolectric-prebuilt", // mockito deps order matters!
|
||||||
|
"mockito-kotlin2",
|
||||||
"notification_flags_lib",
|
"notification_flags_lib",
|
||||||
"platform-test-annotations",
|
"platform-test-annotations",
|
||||||
"testables",
|
"testables",
|
||||||
|
@@ -51,14 +51,14 @@ import org.robolectric.shadows.androidx.fragment.FragmentController;
|
|||||||
ShadowAlertDialogCompat.class,
|
ShadowAlertDialogCompat.class,
|
||||||
ShadowBluetoothAdapter.class,
|
ShadowBluetoothAdapter.class,
|
||||||
})
|
})
|
||||||
public class AudioSharingRetryDialogFragmentTest {
|
public class AudioSharingErrorDialogFragmentTest {
|
||||||
@Rule
|
@Rule
|
||||||
public final MockitoRule mocks = MockitoJUnit.rule();
|
public final MockitoRule mocks = MockitoJUnit.rule();
|
||||||
@Rule
|
@Rule
|
||||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||||
|
|
||||||
private Fragment mParent;
|
private Fragment mParent;
|
||||||
private AudioSharingRetryDialogFragment mFragment;
|
private AudioSharingErrorDialogFragment mFragment;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -70,7 +70,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
|||||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
mFragment = new AudioSharingRetryDialogFragment();
|
mFragment = new AudioSharingErrorDialogFragment();
|
||||||
mParent = new Fragment();
|
mParent = new Fragment();
|
||||||
FragmentController.setupFragment(
|
FragmentController.setupFragment(
|
||||||
mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
|
mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
|
||||||
@@ -91,7 +91,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onCreateDialog_flagOff_dialogNotExist() {
|
public void onCreateDialog_flagOff_dialogNotExist() {
|
||||||
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingRetryDialogFragment.show(mParent);
|
AudioSharingErrorDialogFragment.show(mParent);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNull();
|
assertThat(dialog).isNull();
|
||||||
@@ -100,7 +100,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onCreateDialog_unattachedFragment_dialogNotExist() {
|
public void onCreateDialog_unattachedFragment_dialogNotExist() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingRetryDialogFragment.show(new Fragment());
|
AudioSharingErrorDialogFragment.show(new Fragment());
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNull();
|
assertThat(dialog).isNull();
|
||||||
@@ -109,7 +109,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onCreateDialog_flagOn_showDialog() {
|
public void onCreateDialog_flagOn_showDialog() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingRetryDialogFragment.show(mParent);
|
AudioSharingErrorDialogFragment.show(mParent);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
@@ -119,7 +119,7 @@ public class AudioSharingRetryDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onCreateDialog_clickOk_dialogDismiss() {
|
public void onCreateDialog_clickOk_dialogDismiss() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingRetryDialogFragment.show(mParent);
|
AudioSharingErrorDialogFragment.show(mParent);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
@@ -52,7 +52,7 @@ import org.robolectric.shadows.androidx.fragment.FragmentController;
|
|||||||
ShadowAlertDialogCompat.class,
|
ShadowAlertDialogCompat.class,
|
||||||
ShadowBluetoothAdapter.class,
|
ShadowBluetoothAdapter.class,
|
||||||
})
|
})
|
||||||
public class AudioSharingLoadingStateDialogFragmentTest {
|
public class AudioSharingProgressDialogFragmentTest {
|
||||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||||
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
private static final String TEST_MESSAGE2 = "message2";
|
private static final String TEST_MESSAGE2 = "message2";
|
||||||
|
|
||||||
private Fragment mParent;
|
private Fragment mParent;
|
||||||
private AudioSharingLoadingStateDialogFragment mFragment;
|
private AudioSharingProgressDialogFragment mFragment;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -72,7 +72,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
mFragment = new AudioSharingLoadingStateDialogFragment();
|
mFragment = new AudioSharingProgressDialogFragment();
|
||||||
mParent = new Fragment();
|
mParent = new Fragment();
|
||||||
FragmentController.setupFragment(
|
FragmentController.setupFragment(
|
||||||
mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
|
mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
|
||||||
@@ -93,7 +93,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onCreateDialog_flagOff_dialogNotExist() {
|
public void onCreateDialog_flagOff_dialogNotExist() {
|
||||||
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNull();
|
assertThat(dialog).isNull();
|
||||||
@@ -102,7 +102,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onCreateDialog_unattachedFragment_dialogNotExist() {
|
public void onCreateDialog_unattachedFragment_dialogNotExist() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingLoadingStateDialogFragment.show(new Fragment(), TEST_MESSAGE1);
|
AudioSharingProgressDialogFragment.show(new Fragment(), TEST_MESSAGE1);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNull();
|
assertThat(dialog).isNull();
|
||||||
@@ -111,7 +111,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onCreateDialog_flagOn_showDialog() {
|
public void onCreateDialog_flagOn_showDialog() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
@@ -124,13 +124,13 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void dismissDialog_succeed() {
|
public void dismissDialog_succeed() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
assertThat(dialog.isShowing()).isTrue();
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
|
|
||||||
AudioSharingLoadingStateDialogFragment.dismiss(mParent);
|
AudioSharingProgressDialogFragment.dismiss(mParent);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
assertThat(dialog.isShowing()).isFalse();
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
}
|
}
|
||||||
@@ -138,13 +138,13 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void showDialog_sameMessage_keepExistingDialog() {
|
public void showDialog_sameMessage_keepExistingDialog() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
assertThat(dialog.isShowing()).isTrue();
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
|
|
||||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
assertThat(dialog.isShowing()).isTrue();
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
@Test
|
@Test
|
||||||
public void showDialog_newMessage_keepAndUpdateDialog() {
|
public void showDialog_newMessage_keepAndUpdateDialog() {
|
||||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE1);
|
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE1);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
@@ -161,7 +161,7 @@ public class AudioSharingLoadingStateDialogFragmentTest {
|
|||||||
assertThat(view).isNotNull();
|
assertThat(view).isNotNull();
|
||||||
assertThat(view.getText().toString()).isEqualTo(TEST_MESSAGE1);
|
assertThat(view.getText().toString()).isEqualTo(TEST_MESSAGE1);
|
||||||
|
|
||||||
AudioSharingLoadingStateDialogFragment.show(mParent, TEST_MESSAGE2);
|
AudioSharingProgressDialogFragment.show(mParent, TEST_MESSAGE2);
|
||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
assertThat(dialog.isShowing()).isTrue();
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
assertThat(view.getText().toString()).isEqualTo(TEST_MESSAGE2);
|
assertThat(view.getText().toString()).isEqualTo(TEST_MESSAGE2);
|
@@ -146,6 +146,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||||
@Mock private VolumeControlProfile mVolumeControl;
|
@Mock private VolumeControlProfile mVolumeControl;
|
||||||
@Mock private BluetoothLeBroadcastMetadata mMetadata;
|
@Mock private BluetoothLeBroadcastMetadata mMetadata;
|
||||||
|
@Mock private BluetoothLeBroadcastReceiveState mState;
|
||||||
@Mock private CompoundButton mBtnView;
|
@Mock private CompoundButton mBtnView;
|
||||||
@Mock private CachedBluetoothDevice mCachedDevice1;
|
@Mock private CachedBluetoothDevice mCachedDevice1;
|
||||||
@Mock private CachedBluetoothDevice mCachedDevice2;
|
@Mock private CachedBluetoothDevice mCachedDevice2;
|
||||||
@@ -499,7 +500,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
|
|
||||||
verify(mBroadcast).startPrivateBroadcast();
|
verify(mBroadcast).startPrivateBroadcast();
|
||||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
// No loading state dialog.
|
// No progress dialog.
|
||||||
assertThat(childFragments).isEmpty();
|
assertThat(childFragments).isEmpty();
|
||||||
|
|
||||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
@@ -519,10 +520,9 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||||
when(mBtnView.isEnabled()).thenReturn(true);
|
when(mBtnView.isEnabled()).thenReturn(true);
|
||||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
when(mState.getBroadcastId()).thenReturn(1);
|
||||||
when(state.getBroadcastId()).thenReturn(1);
|
|
||||||
when(mBroadcast.getLatestBroadcastId()).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);
|
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||||
@@ -531,7 +531,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
verify(mBroadcast).startPrivateBroadcast();
|
verify(mBroadcast).startPrivateBroadcast();
|
||||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
AudioSharingProgressDialogFragment.class.getName());
|
||||||
|
|
||||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
@@ -549,27 +549,92 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPlaybackStarted_showJoinAudioSharingDialog() {
|
public void onPlaybackStarted_singleActiveDevice_showJoinAudioSharingDialog() {
|
||||||
FeatureFlagUtils.setEnabled(
|
FeatureFlagUtils.setEnabled(
|
||||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||||
when(mBtnView.isEnabled()).thenReturn(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());
|
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
||||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
|
||||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
verify(mBroadcast).startPrivateBroadcast();
|
verify(mBroadcast).startPrivateBroadcast();
|
||||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
AudioSharingProgressDialogFragment.class.getName());
|
||||||
AudioSharingLoadingStateDialogFragment loadingFragment =
|
|
||||||
(AudioSharingLoadingStateDialogFragment) Iterables.getOnlyElement(childFragments);
|
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
|
// TODO: use string res once finalized
|
||||||
String expectedMessage = "Starting audio stream...";
|
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);
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
@@ -577,13 +642,13 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
.action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING));
|
.action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING));
|
||||||
// TODO: use string res once finalized
|
// TODO: use string res once finalized
|
||||||
expectedMessage = "Sharing with " + TEST_DEVICE_NAME2 + "...";
|
expectedMessage = "Sharing with " + TEST_DEVICE_NAME2 + "...";
|
||||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||||
|
|
||||||
childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
assertThat(childFragments)
|
assertThat(childFragments)
|
||||||
.comparingElementsUsing(CLAZZNAME_EQUALS)
|
.comparingElementsUsing(CLAZZNAME_EQUALS)
|
||||||
.containsExactly(AudioSharingDialogFragment.class.getName(),
|
.containsExactly(AudioSharingDialogFragment.class.getName(),
|
||||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
AudioSharingProgressDialogFragment.class.getName());
|
||||||
|
|
||||||
Pair<Integer, Object>[] eventData = new Pair[0];
|
Pair<Integer, Object>[] eventData = new Pair[0];
|
||||||
for (Fragment fragment : childFragments) {
|
for (Fragment fragment : childFragments) {
|
||||||
@@ -616,18 +681,19 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPlaybackStarted_clickShareBtnOnDialog_addSource() {
|
public void onPlaybackStarted_oneActiveOnConnected_clickShareBtnOnDialog_addSource() {
|
||||||
FeatureFlagUtils.setEnabled(
|
FeatureFlagUtils.setEnabled(
|
||||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||||
when(mBtnView.isEnabled()).thenReturn(true);
|
when(mBtnView.isEnabled()).thenReturn(true);
|
||||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||||
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
||||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
|
||||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
verify(mBroadcast).startPrivateBroadcast();
|
verify(mBroadcast).startPrivateBroadcast();
|
||||||
|
when(mBroadcast.isEnabled(null)).thenReturn(true);
|
||||||
|
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
@@ -642,32 +708,33 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
|
|
||||||
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||||
assertThat(dialog.isShowing()).isFalse();
|
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();
|
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
AudioSharingProgressDialogFragment.class.getName());
|
||||||
AudioSharingLoadingStateDialogFragment loadingFragment =
|
AudioSharingProgressDialogFragment progressFragment =
|
||||||
(AudioSharingLoadingStateDialogFragment) Iterables.getOnlyElement(childFragments);
|
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||||
// TODO: use string res once finalized
|
// TODO: use string res once finalized
|
||||||
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME1 + "...";
|
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME1 + "...";
|
||||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||||
|
|
||||||
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPlaybackStarted_clickCancelBtnOnDialog_doNothing() {
|
public void onPlaybackStarted_oneActiveOnConnected_clickCancelBtnOnDialog_doNothing() {
|
||||||
FeatureFlagUtils.setEnabled(
|
FeatureFlagUtils.setEnabled(
|
||||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||||
when(mBtnView.isEnabled()).thenReturn(true);
|
when(mBtnView.isEnabled()).thenReturn(true);
|
||||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||||
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of());
|
||||||
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
|
||||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
verify(mBroadcast).startPrivateBroadcast();
|
verify(mBroadcast).startPrivateBroadcast();
|
||||||
|
when(mBroadcast.isEnabled(null)).thenReturn(true);
|
||||||
|
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
@@ -682,15 +749,15 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
|
|
||||||
verify(mAssistant, never()).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
verify(mAssistant, never()).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||||
assertThat(dialog.isShowing()).isFalse();
|
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();
|
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
AudioSharingProgressDialogFragment.class.getName());
|
||||||
AudioSharingLoadingStateDialogFragment loadingFragment =
|
AudioSharingProgressDialogFragment progressFragment =
|
||||||
(AudioSharingLoadingStateDialogFragment) Iterables.getOnlyElement(childFragments);
|
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||||
// TODO: use string res once finalized
|
// TODO: use string res once finalized
|
||||||
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME2 + "...";
|
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME2 + "...";
|
||||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||||
|
|
||||||
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||||
}
|
}
|
||||||
@@ -754,28 +821,63 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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(
|
mController.mBroadcastAssistantCallback.onSourceAddFailed(
|
||||||
mDevice1, mMetadata, /* reason= */ 1);
|
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)
|
verify(mFeatureFactory.metricsFeatureProvider)
|
||||||
.action(
|
.action(
|
||||||
mContext,
|
mContext,
|
||||||
SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
|
SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
|
||||||
SettingsEnums.AUDIO_SHARING_SETTINGS);
|
SettingsEnums.AUDIO_SHARING_SETTINGS);
|
||||||
|
|
||||||
|
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAssistantCallbacks_onReceiveStateChanged_dismissLoadingDialog() {
|
public void testAssistantCallbacks_onReceiveStateChanged_dismissProgressDialog() {
|
||||||
AudioSharingLoadingStateDialogFragment.show(mParentFragment, TEST_DEVICE_NAME1);
|
AudioSharingProgressDialogFragment.show(mParentFragment, TEST_DEVICE_NAME1);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
AudioSharingProgressDialogFragment.class.getName());
|
||||||
|
|
||||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
when(mState.getBisSyncState()).thenReturn(ImmutableList.of(1L));
|
||||||
when(state.getBisSyncState()).thenReturn(ImmutableList.of(1L));
|
|
||||||
mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1,
|
mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1,
|
||||||
state);
|
mState);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
assertThat(childFragments).isEmpty();
|
assertThat(childFragments).isEmpty();
|
||||||
@@ -783,11 +885,9 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAssistantCallbacks_doNothing() {
|
public void testAssistantCallbacks_doNothing() {
|
||||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
|
||||||
|
|
||||||
// Do nothing
|
// Do nothing
|
||||||
mController.mBroadcastAssistantCallback.onReceiveStateChanged(
|
mController.mBroadcastAssistantCallback.onReceiveStateChanged(
|
||||||
mDevice1, /* sourceId= */ 1, state);
|
mDevice1, /* sourceId= */ 1, mState);
|
||||||
mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1);
|
mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1);
|
||||||
mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1);
|
mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1);
|
||||||
mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1);
|
mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1);
|
||||||
@@ -923,13 +1023,13 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
List<Fragment> childFragments = parentFragment.getChildFragmentManager().getFragments();
|
List<Fragment> childFragments = parentFragment.getChildFragmentManager().getFragments();
|
||||||
// Skip audio sharing dialog.
|
// Skip audio sharing dialog.
|
||||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
AudioSharingProgressDialogFragment.class.getName());
|
||||||
// The loading state dialog shows sharing state for the auto add second sink.
|
// Progress dialog shows sharing progress for the auto add second sink.
|
||||||
AudioSharingLoadingStateDialogFragment loadingFragment =
|
AudioSharingProgressDialogFragment progressFragment =
|
||||||
(AudioSharingLoadingStateDialogFragment) Iterables.getOnlyElement(childFragments);
|
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
|
||||||
// TODO: use string res once finalized
|
// TODO: use string res once finalized
|
||||||
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME1 + "...";
|
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME1 + "...";
|
||||||
checkLoadingStateDialogMessage(loadingFragment, expectedMessage);
|
checkProgressDialogMessage(progressFragment, expectedMessage);
|
||||||
|
|
||||||
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
|
||||||
}
|
}
|
||||||
@@ -944,7 +1044,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||||
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly(
|
||||||
AudioSharingLoadingStateDialogFragment.class.getName());
|
AudioSharingProgressDialogFragment.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Fragment setUpFragmentWithStartSharingIntent() {
|
private Fragment setUpFragmentWithStartSharingIntent() {
|
||||||
@@ -964,12 +1064,12 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkLoadingStateDialogMessage(
|
private void checkProgressDialogMessage(
|
||||||
@NonNull AudioSharingLoadingStateDialogFragment fragment,
|
@NonNull AudioSharingProgressDialogFragment fragment,
|
||||||
@NonNull String expectedMessage) {
|
@NonNull String expectedMessage) {
|
||||||
TextView loadingMessage = fragment.getDialog() == null ? null
|
TextView progressMessage = fragment.getDialog() == null ? null
|
||||||
: fragment.getDialog().findViewById(R.id.message);
|
: fragment.getDialog().findViewById(R.id.message);
|
||||||
assertThat(loadingMessage).isNotNull();
|
assertThat(progressMessage).isNotNull();
|
||||||
assertThat(loadingMessage.getText().toString()).isEqualTo(expectedMessage);
|
assertThat(progressMessage.getText().toString()).isEqualTo(expectedMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,7 @@ import org.robolectric.RuntimeEnvironment;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
// LINT.IfChange
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class BasebandVersionPreferenceControllerTest {
|
public class BasebandVersionPreferenceControllerTest {
|
||||||
@Mock
|
@Mock
|
||||||
@@ -68,3 +69,4 @@ public class BasebandVersionPreferenceControllerTest {
|
|||||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
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.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
// LINT.IfChange
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class KernelVersionPreferenceControllerTest {
|
public class KernelVersionPreferenceControllerTest {
|
||||||
|
|
||||||
@@ -49,3 +50,4 @@ public class KernelVersionPreferenceControllerTest {
|
|||||||
DeviceInfoUtils.getFormattedKernelVersion(mContext));
|
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.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
// LINT.IfChange
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class SimpleBuildNumberPreferenceControllerTest {
|
public class SimpleBuildNumberPreferenceControllerTest {
|
||||||
|
|
||||||
@@ -48,3 +49,4 @@ public class SimpleBuildNumberPreferenceControllerTest {
|
|||||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
|
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 static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.AutomaticZenRule;
|
import android.app.AutomaticZenRule;
|
||||||
|
import android.app.Flags;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.NotificationManager.Policy;
|
import android.app.NotificationManager.Policy;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.platform.test.annotations.DisableFlags;
|
||||||
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.service.notification.ZenModeConfig;
|
import android.service.notification.ZenModeConfig;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
@@ -53,12 +57,15 @@ public class ZenModeBackendTest {
|
|||||||
private NotificationManager mNotificationManager;
|
private NotificationManager mNotificationManager;
|
||||||
|
|
||||||
private static final String GENERIC_RULE_NAME = "test";
|
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 static final String DEFAULT_ID_2 = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private ZenModeBackend mBackend;
|
private ZenModeBackend mBackend;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
@@ -161,6 +168,10 @@ public class ZenModeBackendTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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() {
|
public void updateState_checkRuleOrderingDescending_withDefaultRules() {
|
||||||
final int NUM_RULES = 4;
|
final int NUM_RULES = 4;
|
||||||
|
|
||||||
@@ -168,8 +179,8 @@ public class ZenModeBackendTest {
|
|||||||
true);
|
true);
|
||||||
Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR);
|
Arrays.sort(rules, ZenModeBackend.RULE_COMPARATOR);
|
||||||
|
|
||||||
assertEquals(rules[0].getKey(), DEFAULT_ID_1);
|
assertEquals(DEFAULT_ID_1, rules[0].getKey());
|
||||||
assertEquals(rules[1].getKey(), DEFAULT_ID_2);
|
assertEquals(DEFAULT_ID_2, rules[1].getKey());
|
||||||
// NON-DEFAULT RULES check ordering, most recent at the bottom/end
|
// NON-DEFAULT RULES check ordering, most recent at the bottom/end
|
||||||
for (int i = 0; i < NUM_RULES; i++) {
|
for (int i = 0; i < NUM_RULES; i++) {
|
||||||
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i + 2].getKey());
|
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i + 2].getKey());
|
||||||
|
@@ -36,7 +36,7 @@ class MobileNetworkListFragmentTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isPageSearchEnabled_showMobileNetworkPage_returnTrue() {
|
fun isPageSearchEnabled_showMobileNetworkPage_returnTrue() {
|
||||||
mockSimRepository.stub { on { showMobileNetworkPage() } doReturn true }
|
mockSimRepository.stub { on { canEnterMobileNetworkPage() } doReturn true }
|
||||||
|
|
||||||
val isEnabled = SearchIndexProvider { mockSimRepository }.isPageSearchEnabled(context)
|
val isEnabled = SearchIndexProvider { mockSimRepository }.isPageSearchEnabled(context)
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ class MobileNetworkListFragmentTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isPageSearchEnabled_hideMobileNetworkPage_returnFalse() {
|
fun isPageSearchEnabled_hideMobileNetworkPage_returnFalse() {
|
||||||
mockSimRepository.stub { on { showMobileNetworkPage() } doReturn false }
|
mockSimRepository.stub { on { canEnterMobileNetworkPage() } doReturn false }
|
||||||
|
|
||||||
val isEnabled = SearchIndexProvider { mockSimRepository }.isPageSearchEnabled(context)
|
val isEnabled = SearchIndexProvider { mockSimRepository }.isPageSearchEnabled(context)
|
||||||
|
|
||||||
|
@@ -71,7 +71,7 @@ class TopLevelNetworkEntryPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getSummary_hasMobile_shouldReturnMobileSummary() {
|
fun getSummary_hasMobile_shouldReturnMobileSummary() {
|
||||||
mockSimRepository.stub { on { showMobileNetworkPage() } doReturn true }
|
mockSimRepository.stub { on { showMobileNetworkPageEntrance() } doReturn true }
|
||||||
|
|
||||||
val summary = controller.summary
|
val summary = controller.summary
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ class TopLevelNetworkEntryPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getSummary_noMobile_shouldReturnNoMobileSummary() {
|
fun getSummary_noMobile_shouldReturnNoMobileSummary() {
|
||||||
mockSimRepository.stub { on { showMobileNetworkPage() } doReturn false }
|
mockSimRepository.stub { on { showMobileNetworkPageEntrance() } doReturn false }
|
||||||
|
|
||||||
val summary = controller.summary
|
val summary = controller.summary
|
||||||
|
|
||||||
|
@@ -37,50 +37,76 @@ class SimRepositoryTest {
|
|||||||
|
|
||||||
private val mockPackageManager = mock<PackageManager>()
|
private val mockPackageManager = mock<PackageManager>()
|
||||||
|
|
||||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
private val context: Context =
|
||||||
on { userManager } doReturn mockUserManager
|
spy(ApplicationProvider.getApplicationContext()) {
|
||||||
on { packageManager } doReturn mockPackageManager
|
on { userManager } doReturn mockUserManager
|
||||||
}
|
on { packageManager } doReturn mockPackageManager
|
||||||
|
}
|
||||||
|
|
||||||
private val repository = SimRepository(context)
|
private val repository = SimRepository(context)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun showMobileNetworkPage_adminUserAndHasTelephony_returnTrue() {
|
fun showMobileNetworkPageEntrance_adminUserAndHasTelephony_returnTrue() {
|
||||||
mockUserManager.stub {
|
mockUserManager.stub { on { isAdminUser } doReturn true }
|
||||||
on { isAdminUser } doReturn true
|
|
||||||
}
|
|
||||||
mockPackageManager.stub {
|
mockPackageManager.stub {
|
||||||
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn true
|
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn true
|
||||||
}
|
}
|
||||||
|
|
||||||
val showMobileNetworkPage = repository.showMobileNetworkPage()
|
val showMobileNetworkPage = repository.showMobileNetworkPageEntrance()
|
||||||
|
|
||||||
assertThat(showMobileNetworkPage).isTrue()
|
assertThat(showMobileNetworkPage).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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 {
|
mockUserManager.stub {
|
||||||
on { isAdminUser } doReturn false
|
on { isAdminUser } doReturn true
|
||||||
|
on { hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS) } doReturn false
|
||||||
}
|
}
|
||||||
mockPackageManager.stub {
|
mockPackageManager.stub {
|
||||||
on { hasSystemFeature(PackageManager.FEATURE_TELEPHONY) } doReturn true
|
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 {
|
mockUserManager.stub {
|
||||||
on { isAdminUser } doReturn true
|
on { isAdminUser } doReturn true
|
||||||
|
on { hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS) } doReturn true
|
||||||
}
|
}
|
||||||
mockPackageManager.stub {
|
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()
|
assertThat(showMobileNetworkPage).isFalse()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user