summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/provider/Settings.java10
-rw-r--r--core/java/com/android/internal/widget/LocalImageResolver.java7
-rw-r--r--core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java9
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java3
-rw-r--r--packages/SystemUI/res/drawable/accessibility_magnification_setting_view_bg.xml27
-rw-r--r--packages/SystemUI/res/drawable/accessibility_magnification_setting_view_btn_bg.xml28
-rw-r--r--packages/SystemUI/res/drawable/accessibility_magnifier_btn_bg.xml27
-rw-r--r--packages/SystemUI/res/drawable/ic_magnification_menu_close.xml29
-rw-r--r--packages/SystemUI/res/drawable/ic_magnification_menu_large.xml25
-rw-r--r--packages/SystemUI/res/drawable/ic_magnification_menu_medium.xml25
-rw-r--r--packages/SystemUI/res/drawable/ic_magnification_menu_small.xml25
-rw-r--r--packages/SystemUI/res/drawable/ic_move_magnification.xml13
-rw-r--r--packages/SystemUI/res/drawable/ic_open_in_new_fullscreen.xml48
-rw-r--r--packages/SystemUI/res/layout/window_magnification_settings_view.xml152
-rw-r--r--packages/SystemUI/res/layout/window_magnifier_view.xml36
-rw-r--r--packages/SystemUI/res/values/colors.xml4
-rw-r--r--packages/SystemUI/res/values/dimens.xml9
-rw-r--r--packages/SystemUI/res/values/strings.xml35
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/MagnificationGestureDetector.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java260
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java592
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java49
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java187
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java12
-rw-r--r--services/core/java/com/android/server/notification/ReviewNotificationPermissionsJobService.java4
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsJobServiceTest.java5
33 files changed, 1679 insertions, 131 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a7c72730a89f..baf3eecadedd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7822,6 +7822,16 @@ public final class Settings {
"accessibility_display_magnification_auto_update";
/**
+ * Accessibility Window Magnification Allow diagonal scrolling value. The value is boolean.
+ * 1 : on, 0 : off
+ *
+ * @hide
+ */
+ public static final String ACCESSIBILITY_ALLOW_DIAGONAL_SCROLLING =
+ "accessibility_allow_diagonal_scrolling";
+
+
+ /**
* Setting that specifies what mode the soft keyboard is in (default or hidden). Can be
* modified from an AccessibilityService using the SoftKeyboardController.
*
diff --git a/core/java/com/android/internal/widget/LocalImageResolver.java b/core/java/com/android/internal/widget/LocalImageResolver.java
index b866723954b5..b11ea2961c17 100644
--- a/core/java/com/android/internal/widget/LocalImageResolver.java
+++ b/core/java/com/android/internal/widget/LocalImageResolver.java
@@ -25,6 +25,7 @@ import android.graphics.ImageDecoder;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Size;
@@ -108,6 +109,12 @@ public class LocalImageResolver {
}
break;
case Icon.TYPE_RESOURCE:
+ if (!(TextUtils.isEmpty(icon.getResPackage())
+ || context.getPackageName().equals(icon.getResPackage()))) {
+ // We can't properly resolve icons from other packages here, so fall back.
+ return icon.loadDrawable(context);
+ }
+
Drawable result = resolveImage(icon.getResId(), context, maxWidth, maxHeight);
if (result != null) {
return tintDrawable(icon, result);
diff --git a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
index c63d18bfa531..0cee526651a6 100644
--- a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
@@ -270,4 +270,13 @@ public class LocalImageResolverTest {
assertThat(bd.getBitmap().getHeight()).isEqualTo(originalHeight);
}
+
+ @Test
+ public void resolveImage_iconWithOtherPackageResource_usesPackageContextDefinition()
+ throws IOException {
+ Icon icon = Icon.createWithResource("this_is_invalid", R.drawable.test32x24);
+ Drawable d = LocalImageResolver.resolveImage(icon, mContext);
+ // This drawable must not be loaded - if it was, the code ignored the package specification.
+ assertThat(d).isNull();
+ }
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java
index 98438cde7c68..b6b88375a0a2 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java
@@ -189,7 +189,8 @@ public class InstallStaging extends AlertActivity {
out.write(buffer, 0, bytesRead);
}
}
- } catch (IOException | SecurityException | IllegalStateException e) {
+ } catch (IOException | SecurityException | IllegalStateException
+ | IllegalArgumentException e) {
Log.w(LOG_TAG, "Error staging apk from content URI", e);
return false;
}
diff --git a/packages/SystemUI/res/drawable/accessibility_magnification_setting_view_bg.xml b/packages/SystemUI/res/drawable/accessibility_magnification_setting_view_bg.xml
new file mode 100644
index 000000000000..4da47af665f2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/accessibility_magnification_setting_view_bg.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="rectangle">
+ <solid android:color="@color/accessibility_magnifier_bg" />
+ <corners android:radius="24dp" />
+ <stroke
+ android:color="@color/accessibility_magnifier_bg_stroke"
+ android:width="1dp" />
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/accessibility_magnification_setting_view_btn_bg.xml b/packages/SystemUI/res/drawable/accessibility_magnification_setting_view_btn_bg.xml
new file mode 100644
index 000000000000..5c9dd569b9d7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/accessibility_magnification_setting_view_btn_bg.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+android:color="?android:attr/colorControlHighlight">
+<item android:id="@android:id/mask">
+ <shape android:shape="oval">
+ <solid android:color="@color/accessibility_magnifier_bg" />
+ <size
+ android:width="56dp"
+ android:height="56dp"/>
+ <corners android:radius="2dp"/>
+ </shape>
+</item>
+</ripple> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/accessibility_magnifier_btn_bg.xml b/packages/SystemUI/res/drawable/accessibility_magnifier_btn_bg.xml
new file mode 100644
index 000000000000..f633b3e3702d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/accessibility_magnifier_btn_bg.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid android:color="@color/accessibility_magnifier_bg" />
+ <size
+ android:width="56dp"
+ android:height="56dp"/>
+ <corners android:radius="2dp"/>
+ <stroke
+ android:color="@color/accessibility_magnifier_bg_stroke"
+ android:width="1dp" />
+ </shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_magnification_menu_close.xml b/packages/SystemUI/res/drawable/ic_magnification_menu_close.xml
new file mode 100644
index 000000000000..a44a484d6e39
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_magnification_menu_close.xml
@@ -0,0 +1,29 @@
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="32"
+ android:viewportHeight="32">
+ <path
+ android:pathData="M7.3334,24.6667L24.6674,7.3334M7.3334,7.3334L24.6674,24.6667"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"
+ android:fillType="evenOdd"
+ android:strokeLineCap="round"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_magnification_menu_large.xml b/packages/SystemUI/res/drawable/ic_magnification_menu_large.xml
new file mode 100644
index 000000000000..1ab0d4d3bf12
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_magnification_menu_large.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:width="24dp"
+ android:height="24dp">
+ <path
+ android:pathData="M3 21L21 21C22.1 21 23 20.1 23 19L23 5C23 3.9 22.1 3 21 3L3 3C1.9 3 1 3.9 1 5L1 19C1 20.1 1.9 21 3 21ZM3 5L21 5L21 19L3 19L3 5ZM4 15L16.75 15L16.75 6L4 6L4 15Z"
+ android:fillType="evenOdd"
+ android:fillColor="#000000" />
+</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_magnification_menu_medium.xml b/packages/SystemUI/res/drawable/ic_magnification_menu_medium.xml
new file mode 100644
index 000000000000..6fc89a69f36e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_magnification_menu_medium.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:width="24dp"
+ android:height="24dp">
+ <path
+ android:pathData="M3 21L21 21C22.1 21 23 20.1 23 19L23 5C23 3.9 22.1 3 21 3L3 3C1.9 3 1 3.9 1 5L1 19C1 20.1 1.9 21 3 21ZM3 5L21 5L21 19L3 19L3 5ZM4 12.75L13.75 12.75L13.75 6L4 6L4 12.75Z"
+ android:fillType="evenOdd"
+ android:fillColor="#000000" />
+</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_magnification_menu_small.xml b/packages/SystemUI/res/drawable/ic_magnification_menu_small.xml
new file mode 100644
index 000000000000..fd7357424f32
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_magnification_menu_small.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:width="24dp"
+ android:height="24dp">
+ <path
+ android:pathData="M3 21L21 21C22.1 21 23 20.1 23 19L23 5C23 3.9 22.1 3 21 3L3 3C1.9 3 1 3.9 1 5L1 19C1 20.1 1.9 21 3 21ZM3 5L21 5L21 19L3 19L3 5ZM4 10.5L8.5 10.5L8.5 6L4 6L4 10.5Z"
+ android:fillType="evenOdd"
+ android:fillColor="#000000" />
+</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_move_magnification.xml b/packages/SystemUI/res/drawable/ic_move_magnification.xml
index 96db3651ac25..1bff559ff3df 100644
--- a/packages/SystemUI/res/drawable/ic_move_magnification.xml
+++ b/packages/SystemUI/res/drawable/ic_move_magnification.xml
@@ -23,18 +23,21 @@
<size
android:height="@dimen/magnification_drag_view_size"
android:width="@dimen/magnification_drag_view_size"/>
+ <corners android:topLeftRadius="12dp"/>
+
</shape>
</item>
<item
android:gravity="center">
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="30dp"
- android:height="30dp"
android:viewportWidth="24"
- android:viewportHeight="24">
+ android:viewportHeight="24"
+ android:width="24dp"
+ android:height="24dp">
<path
- android:pathData="M18.19,12.44l-3.24,-1.62c1.29,-1 2.12,-2.56 2.12,-4.32c0,-3.03 -2.47,-5.5 -5.5,-5.5s-5.5,2.47 -5.5,5.5c0,2.13 1.22,3.98 3,4.89v3.26c-2.11,-0.45 -2.01,-0.44 -2.26,-0.44c-0.53,0 -1.03,0.21 -1.41,0.59L4,16.22l5.09,5.09C9.52,21.75 10.12,22 10.74,22h6.3c0.98,0 1.81,-0.7 1.97,-1.67l0.8,-4.71C20.03,14.32 19.38,13.04 18.19,12.44zM17.84,15.29L17.04,20h-6.3c-0.09,0 -0.17,-0.04 -0.24,-0.1l-3.68,-3.68l4.25,0.89V6.5c0,-0.28 0.22,-0.5 0.5,-0.5c0.28,0 0.5,0.22 0.5,0.5v6h1.76l3.46,1.73C17.69,14.43 17.91,14.86 17.84,15.29zM8.07,6.5c0,-1.93 1.57,-3.5 3.5,-3.5s3.5,1.57 3.5,3.5c0,0.95 -0.38,1.81 -1,2.44V6.5c0,-1.38 -1.12,-2.5 -2.5,-2.5c-1.38,0 -2.5,1.12 -2.5,2.5v2.44C8.45,8.31 8.07,7.45 8.07,6.5z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M13.2217 21.7734C12.8857 22.1094 12.288 22.712 12 23C12 23 11.1143 22.1094 10.7783 21.7734L8.33494 19.3301L9.55662 18.1084L12 20.5518L14.4434 18.1084L15.665 19.3301L13.2217 21.7734ZM19.3301 15.665L18.1084 14.4433L20.5518 12L18.1084 9.5566L19.3301 8.33492L21.7735 10.7783C22.1094 11.1142 22.4241 11.4241 23 12C22.4241 12.5759 22.3963 12.5988 21.7735 13.2217L19.3301 15.665ZM14.4434 14.4433C13.7714 15.1153 12.957 15.4512 12 15.4512C11.043 15.4512 10.2285 15.1153 9.55662 14.4433C8.88469 13.7714 8.54873 12.957 8.54873 12C8.54873 11.043 8.88469 10.2285 9.55662 9.5566C10.2285 8.88468 11.043 8.54871 12 8.54871C12.957 8.54871 13.7714 8.88467 14.4434 9.5566C15.1153 10.2285 15.4512 11.043 15.4512 12C15.4512 12.957 15.1153 13.7714 14.4434 14.4433ZM4.66988 15.665L2.22651 13.2217C1.89055 12.8857 1.28791 12.288 1 12C1.28791 11.712 1.89055 11.1143 2.22651 10.7783L4.66988 8.33492L5.89157 9.5566L3.4482 12L5.89157 14.4433L4.66988 15.665ZM14.4434 5.89155L12 3.44818L9.55662 5.89155L8.33494 4.66987L10.7783 2.2265C11.1389 1.86592 11.2963 1.70369 12 1C12.5758 1.57585 12.8857 1.89053 13.2217 2.2265L15.665 4.66986L14.4434 5.89155Z"
+ android:fillColor="#ffffff" />
</vector>
</item>
</layer-list>
diff --git a/packages/SystemUI/res/drawable/ic_open_in_new_fullscreen.xml b/packages/SystemUI/res/drawable/ic_open_in_new_fullscreen.xml
index 36a1224a78c9..c7434f5e46fd 100644
--- a/packages/SystemUI/res/drawable/ic_open_in_new_fullscreen.xml
+++ b/packages/SystemUI/res/drawable/ic_open_in_new_fullscreen.xml
@@ -13,35 +13,19 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item>
- <shape android:shape="rectangle">
- <solid android:color="@color/magnification_switch_button_color" />
- <size
- android:width="48dp"
- android:height="48dp" />
- </shape>
- </item>
-
- <item
- android:gravity="center">
- <vector
- android:width="36dp"
- android:height="36dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <group>
- <clip-path
- android:pathData="M0,0h24v24h-24z"/>
- <path
- android:pathData="M11,6.05V8.05H14.59L8,14.64V11.05H6V18.05H13V16.05H9.41L16,9.46V13.05H18V6.05H11Z"
- android:fillColor="#ffffff"/>
- <path
- android:pathData="M20,4.05V20.05H4V4.05H20ZM22,2.05H2V22.05H22V2.05Z"
- android:fillColor="#ffffff"/>
- </group>
- </vector>
- </item>
-
-</layer-list>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="36dp"
+ android:height="36dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <group>
+ <clip-path
+ android:pathData="M0,0h24v24h-24z"/>
+ <path
+ android:pathData="M11,6.05V8.05H14.59L8,14.64V11.05H6V18.05H13V16.05H9.41L16,9.46V13.05H18V6.05H11Z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M20,4.05V20.05H4V4.05H20ZM22,2.05H2V22.05H22V2.05Z"
+ android:fillColor="#000000"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/layout/window_magnification_settings_view.xml b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
new file mode 100644
index 000000000000..6d8847cce644
--- /dev/null
+++ b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/magnifier_panel_view"
+ android:layout_width="@dimen/magnification_max_size"
+ android:layout_height="match_parent"
+ android:background="@drawable/accessibility_magnification_setting_view_bg"
+ android:orientation="vertical">
+ <LinearLayout
+ android:layout_width="@dimen/magnification_max_size"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/accessibility_magnifier_size"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:focusable="true"
+ android:layout_gravity="center_vertical|left"
+ android:layout_marginStart="20dp"/>
+
+ <Button
+ android:id="@+id/magnifier_edit_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/accessibility_magnifier_edit"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:focusable="true"
+ android:layout_gravity="right"
+ android:layout_marginEnd="20dp"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="@dimen/magnification_max_size"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <ImageButton
+ android:id="@+id/magnifier_small_button"
+ android:layout_width="0dp"
+ android:layout_height="56dp"
+ android:scaleType="center"
+ android:layout_weight="1"
+ android:layout_marginStart="12dp"/>
+
+ <ImageButton
+ android:id="@+id/magnifier_medium_button"
+ android:layout_width="0dp"
+ android:layout_height="56dp"
+ android:scaleType="center"
+ android:layout_weight="1"/>
+
+ <ImageButton
+ android:id="@+id/magnifier_large_button"
+ android:layout_width="0dp"
+ android:layout_height="56dp"
+ android:scaleType="center"
+ android:layout_weight="1"/>
+
+ <ImageButton
+ android:id="@+id/magnifier_full_button"
+ android:layout_width="0dp"
+ android:layout_height="56dp"
+ android:scaleType="center"
+ android:layout_weight="1"
+ android:layout_marginEnd="12dp"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingTop="8dp"
+ android:paddingEnd="20dp"
+ android:paddingStart="20dp"
+ android:focusable="true">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
+ android:ellipsize="marquee"
+ android:gravity="center_vertical"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:text="@string/accessibility_allow_diagonal_scrolling"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textColor="?android:attr/textColorAlertDialogListItem" />
+ </LinearLayout>
+
+ <Switch
+ android:id="@+id/magnifier_horizontal_lock_switch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right|center"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"/>
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/accessibility_magnification_zoom"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:focusable="true"
+ android:layout_marginStart="20dp"
+ android:paddingTop="2dp"
+ android:paddingBottom="10dp"/>
+
+ <SeekBar
+ android:id="@+id/magnifier_zoom_seekbar"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:progress="0"
+ android:max="6"
+ android:layout_marginEnd="20dp"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"/>
+
+
+ <Button
+ android:id="@+id/magnifier_close_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/accessibility_magnification_close"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:focusable="true"
+ android:layout_gravity="center_horizontal"
+ android:paddingBottom="24dp"/>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/window_magnifier_view.xml b/packages/SystemUI/res/layout/window_magnifier_view.xml
index 7c755e546589..0bff47ccf722 100644
--- a/packages/SystemUI/res/layout/window_magnifier_view.xml
+++ b/packages/SystemUI/res/layout/window_magnifier_view.xml
@@ -16,33 +16,25 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:screenReaderFocusable="true">
- <View
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="@dimen/magnification_outer_border_margin"
- android:importantForAccessibility="no"
- android:background="@android:color/black"/>
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
<View
+ android:id="@+id/magnification_inner_border"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_margin="@dimen/magnification_inner_border_margin"
- android:importantForAccessibility="no"
+ android:layout_margin="@dimen/magnification_outer_border_margin"
android:background="@color/magnification_border_color"/>
<RelativeLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:importantForAccessibility="noHideDescendants">
+ android:layout_height="match_parent">
<View
android:id="@+id/left_handle"
android:layout_width="@dimen/magnification_border_drag_size"
android:layout_height="match_parent"
- android:layout_above="@+id/bottom_handle"/>
+ android:layout_alignParentStart="true"/>
<View
android:id="@+id/top_handle"
@@ -54,7 +46,6 @@
android:id="@+id/right_handle"
android:layout_width="@dimen/magnification_border_drag_size"
android:layout_height="match_parent"
- android:layout_above="@+id/bottom_handle"
android:layout_alignParentEnd="true"/>
<View
@@ -68,7 +59,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/magnification_mirror_surface_margin"/>
-
</RelativeLayout>
<ImageView
@@ -79,7 +69,17 @@
android:layout_gravity="right|bottom"
android:padding="@dimen/magnifier_drag_handle_padding"
android:scaleType="center"
- android:importantForAccessibility="no"
android:src="@drawable/ic_move_magnification"/>
-</FrameLayout> \ No newline at end of file
+ <ImageView
+ android:id="@+id/close_button"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:layout_margin="30dp"
+ android:padding="@dimen/magnification_switch_button_padding"
+ android:layout_gravity="right|bottom"
+ android:scaleType="center"
+ android:visibility="gone"
+ android:background="@drawable/accessibility_magnifier_btn_bg"
+ android:src="@drawable/ic_magnification_menu_close" />
+</FrameLayout>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 1eece4cee179..26bf1034df11 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -166,8 +166,12 @@
<!-- Window magnification colors -->
<color name="magnification_border_color">#FF9900</color>
+ <color name="magnification_border_color_change">#0000FF</color>
<color name="magnification_switch_button_color">#7F000000</color>
<color name="magnification_drag_handle_color">#B3000000</color>
+ <color name="accessibility_magnifier_bg">#FCFCFC</color>
+ <color name="accessibility_magnifier_bg_stroke">#E0E0E0</color>
+ <color name="accessibility_magnifier_icon_color">#252525</color>
<!-- Volume dialog colors -->
<color name="volume_dialog_background_color">@android:color/transparent</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 786b6b884605..5a1e0be12332 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1065,8 +1065,10 @@
<dimen name="magnification_frame_move_long">25dp</dimen>
<dimen name="magnification_drag_view_size">36dp</dimen>
<dimen name="magnification_controls_size">90dp</dimen>
- <dimen name="magnification_switch_button_size">48dp</dimen>
+ <dimen name="magnification_switch_button_size">56dp</dimen>
+ <dimen name="magnification_switch_button_padding">6dp</dimen>
<dimen name="magnification_switch_button_margin">16dp</dimen>
+ <dimen name="magnification_close_button_padding">15dp</dimen>
<dimen name="magnifier_left_right_controls_width">35dp</dimen>
<dimen name="magnifier_left_right_controls_height">45dp</dimen>
<dimen name="magnifier_up_down_controls_width">45dp</dimen>
@@ -1074,10 +1076,15 @@
<!-- The extra padding to show the whole outer border -->
<dimen name="magnifier_drag_handle_padding">3dp</dimen>
<dimen name="magnification_max_frame_size">300dp</dimen>
+
<!-- How far from the right edge of the screen you need to drag the window before the button
repositions to the other side. -->
<dimen name="magnification_button_reposition_threshold_from_edge">32dp</dimen>
+ <dimen name="magnification_drag_size">15dp</dimen>
+ <dimen name="magnification_max_size">360dp</dimen>
+ <dimen name="magnifier_panel_size">265dp</dimen>
+
<!-- Home Controls -->
<dimen name="controls_header_menu_size">48dp</dimen>
<dimen name="controls_header_bottom_margin">24dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 7f3caeca5a62..b844f11d0015 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2109,6 +2109,41 @@
<!-- Click action label for magnification switch. [CHAR LIMIT=NONE] -->
<string name="magnification_mode_switch_click_label">Switch</string>
+ <!-- Title of the magnification option button allow diagonal scrolling [CHAR LIMIT=NONE]-->
+ <string name="accessibility_allow_diagonal_scrolling">Allow diagonal scrolling</string>
+ <!-- Title of the magnification option button Resize [CHAR LIMIT=NONE]-->
+ <string name="accessibility_resize">Resize</string>
+ <!-- Title of the magnification option button Change type [CHAR LIMIT=NONE]-->
+ <string name="accessibility_change_magnification_type">Change magnification type</string>
+ <!-- Title of the magnification option button End resizing [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_end_resizing">End resizing</string>
+
+ <!-- Description of the window magnification Top handle [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_top_handle">Top handle</string>
+ <!-- Description of the window magnification Left handle [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_left_handle">Left handle</string>
+ <!-- Description of the window magnification Right handle [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_right_handle">Right handle</string>
+ <!-- Description of the window magnification Bottom handle [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_bottom_handle">Bottom handle</string>
+
+ <!-- Title of the window magnification panel option Magnifier size [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnifier_size">Magnifier size</string>
+ <!-- Title of the window magnification panel option Zoom [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_zoom">Zoom</string>
+ <!-- Click action label for magnification panel medium size [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_medium">Medium</string>
+ <!-- Click action label for magnification panel small size [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_small">Small</string>
+ <!-- Click action label for magnification panel large size [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_large">Large</string>
+ <!-- Click action label for magnification panel Close [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_close">Close</string>
+ <!-- Click action label for edit magnification size [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnifier_edit">Edit</string>
+ <!-- Click action label for magnification panel settings [CHAR LIMIT=NONE]-->
+ <string name="accessibility_magnification_magnifier_window_settings">Magnifier window settings</string>
+
<!-- Accessibility floating menu strings -->
<!-- Message for the accessibility floating button migration tooltip. It shows when the user use gestural navigation then upgrade their system. It will tell the user they could customize or replace the floating button in Settings. [CHAR LIMIT=100] -->
<string name="accessibility_floating_button_migration_tooltip">Tap to open accessibility features. Customize or replace this button in Settings.\n\n<annotation id="link">View settings</annotation></string>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationGestureDetector.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationGestureDetector.java
index 4b30ec3e6f6f..c91082c618c5 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationGestureDetector.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationGestureDetector.java
@@ -23,6 +23,7 @@ import android.graphics.PointF;
import android.os.Handler;
import android.view.Display;
import android.view.MotionEvent;
+import android.view.View;
import android.view.ViewConfiguration;
/**
@@ -41,7 +42,7 @@ class MagnificationGestureDetector {
*
* @return {@code true} if this gesture is handled.
*/
- boolean onSingleTap();
+ boolean onSingleTap(View view);
/**
* Called when the user is performing dragging gesture. It is started after the offset
@@ -52,7 +53,7 @@ class MagnificationGestureDetector {
* @param offsetY The Y offset in screen coordinate.
* @return {@code true} if this gesture is handled.
*/
- boolean onDrag(float offsetX, float offsetY);
+ boolean onDrag(View view, float offsetX, float offsetY);
/**
* Notified when a tap occurs with the down {@link MotionEvent} that triggered it. This will
@@ -109,7 +110,7 @@ class MagnificationGestureDetector {
* @param event The current motion event.
* @return {@code True} if the {@link OnGestureListener} consumes the event, else false.
*/
- boolean onTouch(MotionEvent event) {
+ boolean onTouch(View view, MotionEvent event) {
final float rawX = event.getRawX();
final float rawY = event.getRawY();
boolean handled = false;
@@ -125,12 +126,12 @@ class MagnificationGestureDetector {
break;
case MotionEvent.ACTION_MOVE:
stopSingleTapDetectionIfNeeded(rawX, rawY);
- handled |= notifyDraggingGestureIfNeeded(rawX, rawY);
+ handled |= notifyDraggingGestureIfNeeded(view, rawX, rawY);
break;
case MotionEvent.ACTION_UP:
stopSingleTapDetectionIfNeeded(rawX, rawY);
if (mDetectSingleTap) {
- handled |= mOnGestureListener.onSingleTap();
+ handled |= mOnGestureListener.onSingleTap(view);
}
// Fall through
case MotionEvent.ACTION_CANCEL:
@@ -163,7 +164,7 @@ class MagnificationGestureDetector {
mDetectSingleTap = false;
}
- private boolean notifyDraggingGestureIfNeeded(float x, float y) {
+ private boolean notifyDraggingGestureIfNeeded(View view, float x, float y) {
if (!mDraggingDetected) {
return false;
}
@@ -173,7 +174,7 @@ class MagnificationGestureDetector {
final float offsetX = x - mPointerLocation.x;
final float offsetY = y - mPointerLocation.y;
mPointerLocation.set(x, y);
- return mOnGestureListener.onDrag(offsetX, offsetY);
+ return mOnGestureListener.onDrag(view, offsetX, offsetY);
}
private void reset() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index dbd215d9c713..59a5b1534990 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -213,18 +213,18 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
if (!mIsVisible) {
return false;
}
- return mGestureDetector.onTouch(event);
+ return mGestureDetector.onTouch(v, event);
}
@Override
- public boolean onSingleTap() {
+ public boolean onSingleTap(View v) {
mSingleTapDetected = true;
handleSingleTap();
return true;
}
@Override
- public boolean onDrag(float offsetX, float offsetY) {
+ public boolean onDrag(View v, float offsetX, float offsetY) {
moveButton(offsetX, offsetY);
return true;
}
@@ -292,9 +292,12 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
* @param resetPosition if the button position needs be reset
*/
private void showButton(int mode, boolean resetPosition) {
+ if (mode != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
+ return;
+ }
if (mMagnificationMode != mode) {
mMagnificationMode = mode;
- mImageView.setImageResource(getIconResId(mode));
+ mImageView.setImageResource(getIconResId(mMagnificationMode));
}
if (!mIsVisible) {
onConfigurationChanged(mContext.getResources().getConfiguration());
@@ -408,6 +411,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
private static ImageView createView(Context context) {
ImageView imageView = new ImageView(context);
+ imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setClickable(true);
imageView.setFocusable(true);
imageView.setAlpha(0f);
@@ -415,10 +419,8 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
}
@VisibleForTesting
- static int getIconResId(int mode) {
- return (mode == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)
- ? R.drawable.ic_open_in_new_window
- : R.drawable.ic_open_in_new_fullscreen;
+ static int getIconResId(int mode) { // TODO(b/242233514): delete non used param
+ return R.drawable.ic_open_in_new_window;
}
private static LayoutParams createLayoutParams(Context context) {
@@ -461,4 +463,4 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
new Rect(0, 0, mImageView.getWidth(), mImageView.getHeight())));
});
}
-}
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index d7fead16e269..f4701ed50ccc 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -233,6 +233,13 @@ public class WindowMagnification extends CoreStartable implements WindowMagnifie
}
@Override
+ public void onModeSwitch(int displayId, int newMode) {
+ if (mWindowMagnificationConnectionImpl != null) {
+ mWindowMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
+ }
+ }
+
+ @Override
public void requestWindowMagnificationConnection(boolean connect) {
if (connect) {
setWindowMagnificationConnection();
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 1eedae6f01b0..813f4ddbab0b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -19,8 +19,11 @@ package com.android.systemui.accessibility;
import static android.view.WindowInsets.Type.systemGestures;
import static android.view.WindowManager.LayoutParams;
+import static com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
+import static java.lang.Math.abs;
+
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.NonNull;
@@ -41,6 +44,8 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.Log;
import android.util.Range;
import android.util.Size;
@@ -62,6 +67,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.widget.FrameLayout;
+import android.widget.ImageView;
import androidx.core.math.MathUtils;
@@ -93,6 +99,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
private static final Range<Float> A11Y_ACTION_SCALE_RANGE = new Range<>(2.0f, 8.0f);
private static final float A11Y_CHANGE_SCALE_DIFFERENCE = 1.0f;
private static final float ANIMATION_BOUNCE_EFFECT_SCALE = 1.05f;
+ private static final float[] MAGNIFICATION_SCALE_OPTIONS = {1.0f, 1.4f, 1.8f, 2.5f};
private final Context mContext;
private final Resources mResources;
@@ -145,7 +152,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
// The root of the mirrored content
private SurfaceControl mMirrorSurface;
- private View mDragView;
+ private ImageView mDragView;
+ private ImageView mCloseView;
private View mLeftDrag;
private View mTopDrag;
private View mRightDrag;
@@ -162,6 +170,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
private final Runnable mWindowInsetChangeRunnable;
// MirrorView is the mirror window which displays the magnified content.
private View mMirrorView;
+ private View mMirrorBorderView;
private SurfaceView mMirrorSurfaceView;
private int mMirrorSurfaceMargin;
private int mBorderDragSize;
@@ -172,6 +181,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
* repositions to the other side.
*/
private int mButtonRepositionThresholdFromEdge;
+
// The boundary of magnification frame.
private final Rect mMagnificationFrameBoundary = new Rect();
// The top Y of the system gesture rect at the bottom. Set to -1 if it is invalid.
@@ -192,6 +202,18 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
private boolean mOverlapWithGestureInsets;
private boolean mIsDragging;
+ // Window Magnification Setting view
+ private WindowMagnificationSettings mWindowMagnificationSettings;
+
+ private static final int MAX_HORIZONTAL_MOVE_ANGLE = 50;
+ private static final int HORIZONTAL = 1;
+ private static final int VERTICAL = 0;
+ private static final double HORIZONTAL_LOCK_BASE =
+ Math.tan(Math.toRadians(MAX_HORIZONTAL_MOVE_ANGLE));
+
+ private boolean mAllowDiagonalScrolling = false;
+ private boolean mEditSizeEnable = false;
+
@Nullable
private MirrorWindowControl mMirrorWindowControl;
@@ -223,7 +245,12 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mWindowBounds = new Rect(mWm.getCurrentWindowMetrics().getBounds());
mResources = mContext.getResources();
- mScale = mResources.getInteger(R.integer.magnification_default_scale);
+ mScale = Settings.Secure.getFloatForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ mResources.getInteger(R.integer.magnification_default_scale),
+ UserHandle.USER_CURRENT);
+
+
mBounceEffectDuration = mResources.getInteger(
com.android.internal.R.integer.config_shortAnimTime);
updateDimensions();
@@ -241,6 +268,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mGestureDetector =
new MagnificationGestureDetector(mContext, handler, this);
+ mWindowMagnificationSettings =
+ new WindowMagnificationSettings(mContext, mWindowMagnificationSettingsCallback,
+ mSfVsyncFrameProvider);
+
// Initialize listeners.
mMirrorViewRunnable = () -> {
if (mMirrorView != null) {
@@ -326,6 +357,26 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
return false;
}
+ private void changeMagnificationSize(@MagnificationSize int index) {
+ final int initSize = Math.min(mWindowBounds.width(), mWindowBounds.height()) / 3;
+ int size = (int) (initSize * MAGNIFICATION_SCALE_OPTIONS[index]);
+ setWindowSize(size, size);
+ }
+
+ private void setEditMagnifierSizeMode(boolean enable) {
+ mEditSizeEnable = enable;
+ applyResourcesValues();
+
+ if (isWindowVisible()) {
+ updateDimensions();
+ applyTapExcludeRegion();
+ }
+ }
+
+ private void setDiagonalScrolling(boolean enable) {
+ mAllowDiagonalScrolling = enable;
+ }
+
/**
* Wraps {@link WindowMagnificationController#deleteWindowMagnification()}} with transition
* animation. If the window magnification is enabling, it runs the animation in reverse.
@@ -346,6 +397,9 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
if (!isWindowVisible()) {
return;
}
+
+ closeMagnificationSettings();
+
if (mMirrorSurface != null) {
mTransaction.remove(mMirrorSurface).apply();
mMirrorSurface = null;
@@ -368,6 +422,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mMirrorViewBounds.setEmpty();
mSourceBounds.setEmpty();
updateSystemUIStateIfNeeded();
+ setEditMagnifierSizeMode(false);
+
mContext.unregisterComponentCallbacks(this);
// Notify source bounds empty when magnification is deleted.
mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId, new Rect());
@@ -505,7 +561,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
/** Returns the rotation degree change of two {@link Surface.Rotation} */
private int getDegreeFromRotation(@Surface.Rotation int newRotation,
- @Surface.Rotation int oldRotation) {
+ @Surface.Rotation int oldRotation) {
final int rotationDiff = oldRotation - newRotation;
final int degree = (rotationDiff + 4) % 4 * 90;
return degree;
@@ -534,6 +590,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mMirrorView = LayoutInflater.from(mContext).inflate(R.layout.window_magnifier_view, null);
mMirrorSurfaceView = mMirrorView.findViewById(R.id.surface_view);
+ mMirrorBorderView = mMirrorView.findViewById(R.id.magnification_inner_border);
+
// Allow taps to go through to the mirror SurfaceView below.
mMirrorSurfaceView.addOnLayoutChangeListener(mMirrorSurfaceViewLayoutChangeListener);
@@ -600,6 +658,18 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
}
}
+ private void showMagnificationSettings() {
+ if (mWindowMagnificationSettings != null) {
+ mWindowMagnificationSettings.showSettingPanel();
+ }
+ }
+
+ private void closeMagnificationSettings() {
+ if (mWindowMagnificationSettings != null) {
+ mWindowMagnificationSettings.hideSettingPanel();
+ }
+ }
+
/**
* Sets the window size with given width and height in pixels without changing the
* window center. The width or the height will be clamped in the range
@@ -668,12 +738,14 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mTopDrag = mMirrorView.findViewById(R.id.top_handle);
mRightDrag = mMirrorView.findViewById(R.id.right_handle);
mBottomDrag = mMirrorView.findViewById(R.id.bottom_handle);
+ mCloseView = mMirrorView.findViewById(R.id.close_button);
mDragView.setOnTouchListener(this);
mLeftDrag.setOnTouchListener(this);
mTopDrag.setOnTouchListener(this);
mRightDrag.setOnTouchListener(this);
mBottomDrag.setOnTouchListener(this);
+ mCloseView.setOnTouchListener(this);
}
/**
@@ -743,8 +815,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v == mDragView || v == mLeftDrag || v == mTopDrag || v == mRightDrag
- || v == mBottomDrag) {
- return mGestureDetector.onTouch(event);
+ || v == mBottomDrag || v == mCloseView) {
+ return mGestureDetector.onTouch(v, event);
}
return false;
}
@@ -768,6 +840,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
int right = displayFrame.right - (halfWidth - (int) (halfWidth / scale));
int top = displayFrame.top + (halfHeight - (int) (halfHeight / scale));
int bottom = displayFrame.bottom - (halfHeight - (int) (halfHeight / scale));
+
mSourceBounds.set(left, top, right, bottom);
// SourceBound's center is equal to center[X,Y] but calculated from MagnificationFrame's
@@ -950,7 +1023,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
* or {@link Float#NaN} to leave unchanged.
*/
void enableWindowMagnificationInternal(float scale, float centerX, float centerY,
- float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY) {
+ float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY) {
if (Float.compare(scale, 1.0f) <= 0) {
deleteWindowMagnification();
return;
@@ -983,6 +1056,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
if (!isWindowVisible()) {
createMirrorWindow();
showControls();
+ applyResourcesValues();
} else {
modifyWindowMagnification(false);
}
@@ -997,6 +1071,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
if (mAnimationController.isAnimating() || !isWindowVisible() || mScale == scale) {
return;
}
+
enableWindowMagnificationInternal(scale, Float.NaN, Float.NaN);
mHandler.removeCallbacks(mUpdateStateDescriptionRunnable);
mHandler.postDelayed(mUpdateStateDescriptionRunnable, UPDATE_STATE_DESCRIPTION_DELAY_MS);
@@ -1014,19 +1089,42 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
if (mAnimationController.isAnimating() || mMirrorSurfaceView == null) {
return;
}
+
+ if (!mAllowDiagonalScrolling) {
+ int direction = selectDirectionForMove(abs(offsetX), abs(offsetY));
+
+ if (direction == HORIZONTAL) {
+ offsetY = 0;
+ } else {
+ offsetX = 0;
+ }
+ }
+
if (updateMagnificationFramePosition((int) offsetX, (int) offsetY)) {
modifyWindowMagnification(false);
}
}
void moveWindowMagnifierToPosition(float positionX, float positionY,
- IRemoteMagnificationAnimationCallback callback) {
+ IRemoteMagnificationAnimationCallback callback) {
if (mMirrorSurfaceView == null) {
return;
}
mAnimationController.moveWindowMagnifierToPosition(positionX, positionY, callback);
}
+ private int selectDirectionForMove(float diffX, float diffY) {
+ int direction = 0;
+ float result = diffY / diffX;
+
+ if (result <= HORIZONTAL_LOCK_BASE) {
+ direction = HORIZONTAL; // horizontal move
+ } else {
+ direction = VERTICAL; // vertical move
+ }
+ return direction;
+ }
+
/**
* Gets the scale.
*
@@ -1072,17 +1170,143 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
}
@Override
- public boolean onSingleTap() {
- animateBounceEffect();
+ public boolean onSingleTap(View view) {
+ handleSingleTap(view);
return true;
}
@Override
- public boolean onDrag(float offsetX, float offsetY) {
- move((int) offsetX, (int) offsetY);
+ public boolean onDrag(View view, float offsetX, float offsetY) {
+ if (mEditSizeEnable) {
+ changeWindowSize(view, offsetX, offsetY);
+ } else {
+ move((int) offsetX, (int) offsetY);
+ }
+ return true;
+ }
+
+ private void handleSingleTap(View view) {
+ int id = view.getId();
+ if (id == R.id.drag_handle) {
+ showMagnificationSettings();
+ } else if (id == R.id.close_button) {
+ setEditMagnifierSizeMode(false);
+ } else {
+ animateBounceEffect();
+ }
+ }
+
+ private void applyResourcesValues() {
+ mMirrorBorderView.setBackgroundColor(mResources.getColor(mEditSizeEnable
+ ? R.color.magnification_border_color_change : R.color.magnification_border_color));
+
+ if (mEditSizeEnable) {
+ mDragView.setVisibility(View.GONE);
+ mCloseView.setVisibility(View.VISIBLE);
+ } else {
+ mDragView.setVisibility(View.VISIBLE);
+ mCloseView.setVisibility(View.GONE);
+ }
+ }
+
+ public boolean changeWindowSize(View view, float offsetX, float offsetY) {
+ boolean bRTL = isRTL(mContext);
+ final int initSize = Math.min(mWindowBounds.width(), mWindowBounds.height()) / 3;
+
+ final int maxHeightSize = mWindowBounds.height() - 2 * mMirrorSurfaceMargin;
+ final int maxWidthSize = mWindowBounds.width() - 2 * mMirrorSurfaceMargin;
+
+ Rect tempRect = new Rect();
+ tempRect.set(mMagnificationFrame);
+
+ if (view == mLeftDrag) {
+ if (bRTL) {
+ tempRect.right += offsetX;
+ if (tempRect.right > mWindowBounds.width()) {
+ return false;
+ }
+ } else {
+ tempRect.left += offsetX;
+ if (tempRect.left < 0) {
+ return false;
+ }
+ }
+ } else if (view == mRightDrag) {
+ if (bRTL) {
+ tempRect.left += offsetX;
+ if (tempRect.left < 0) {
+ return false;
+ }
+ } else {
+ tempRect.right += offsetX;
+ if (tempRect.right > mWindowBounds.width()) {
+ return false;
+ }
+ }
+ } else if (view == mTopDrag) {
+ tempRect.top += offsetY;
+ if (tempRect.top < 0) {
+ return false;
+ }
+ } else if (view == mBottomDrag) {
+ tempRect.bottom += offsetY;
+ if (tempRect.bottom > mWindowBounds.height()) {
+ return false;
+ }
+ }
+
+ if (tempRect.width() < initSize || tempRect.height() < initSize
+ || tempRect.width() > maxWidthSize || tempRect.height() > maxHeightSize) {
+ return false;
+ }
+
+ mMagnificationFrame.set(tempRect);
+
+ computeBounceAnimationScale();
+ calculateMagnificationFrameBoundary();
+
+ modifyWindowMagnification(true);
return true;
}
+ private static boolean isRTL(Context context) {
+ Configuration config = context.getResources().getConfiguration();
+ if (config == null) {
+ return false;
+ }
+ return (config.screenLayout & Configuration.SCREENLAYOUT_LAYOUTDIR_MASK)
+ == Configuration.SCREENLAYOUT_LAYOUTDIR_RTL;
+ }
+
+ private WindowMagnificationSettingsCallback mWindowMagnificationSettingsCallback =
+ new WindowMagnificationSettingsCallback() {
+ @Override
+ public void onSetDiagonalScrolling(boolean enable) {
+ setDiagonalScrolling(enable);
+ }
+
+ @Override
+ public void onModeSwitch(int newMode) {
+ mWindowMagnifierCallback.onModeSwitch(mDisplayId, newMode);
+ }
+
+ @Override
+ public void onSetMagnifierSize(@MagnificationSize int index) {
+ changeMagnificationSize(index);
+ }
+
+ @Override
+ public void onEditMagnifierSizeMode(boolean enable) {
+ setEditMagnifierSizeMode(enable);
+ }
+
+ @Override
+ public void onMagnifierScale(float scale) {
+ mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
+ A11Y_ACTION_SCALE_RANGE.clamp(scale));
+ }
+ };
+
@Override
public boolean onStart(float x, float y) {
mIsDragging = true;
@@ -1138,7 +1362,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
pw.println(" mMagnificationFrame:"
+ (isWindowVisible() ? mMagnificationFrame : "empty"));
pw.println(" mSourceBounds:"
- + (mSourceBounds.isEmpty() ? "empty" : mSourceBounds));
+ + (mSourceBounds.isEmpty() ? "empty" : mSourceBounds));
pw.println(" mSystemGestureTop:" + mSystemGestureTop);
pw.println(" mMagnificationFrameOffsetX:" + mMagnificationFrameOffsetX);
pw.println(" mMagnificationFrameOffsetY:" + mMagnificationFrameOffsetY);
@@ -1149,6 +1373,11 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
+ final AccessibilityAction clickAction = new AccessibilityAction(
+ AccessibilityAction.ACTION_CLICK.getId(), mContext.getResources().getString(
+ R.string.magnification_mode_switch_click_label));
+ info.addAction(clickAction);
+ info.setClickable(true);
info.addAction(
new AccessibilityAction(R.id.accessibility_action_zoom_in,
mContext.getString(R.string.accessibility_control_zoom_in)));
@@ -1176,7 +1405,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
}
private boolean performA11yAction(int action) {
- if (action == R.id.accessibility_action_zoom_in) {
+ if (action == AccessibilityAction.ACTION_CLICK.getId()) {
+ // Simulate tapping the drag view so it opens the Settings.
+ handleSingleTap(mDragView);
+ } else if (action == R.id.accessibility_action_zoom_in) {
final float scale = mScale + A11Y_CHANGE_SCALE_DIFFERENCE;
mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
A11Y_ACTION_SCALE_RANGE.clamp(scale));
@@ -1199,4 +1431,4 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
return true;
}
}
-}
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
new file mode 100644
index 000000000000..9cffd5d609a7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility;
+
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
+import android.annotation.IntDef;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.graphics.Insets;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.MathUtils;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.AccessibilityDelegate;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.view.WindowMetrics;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+import android.widget.Switch;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
+import com.android.systemui.R;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+
+/**
+ * Class to set value about WindowManificationSettings.
+ */
+class WindowMagnificationSettings implements MagnificationGestureDetector.OnGestureListener {
+ private static final String TAG = "WindowMagnificationSettings";
+ private final Context mContext;
+ private final AccessibilityManager mAccessibilityManager;
+ private final WindowManager mWindowManager;
+
+ private final Runnable mWindowInsetChangeRunnable;
+ private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
+
+ private final LayoutParams mParams;
+ @VisibleForTesting
+ final Rect mDraggableWindowBounds = new Rect();
+ private boolean mIsVisible = false;
+ private final MagnificationGestureDetector mGestureDetector;
+ private boolean mSingleTapDetected = false;
+
+ private SeekBar mZoomSeekbar;
+ private Switch mAllowDiagonalScrollingSwitch;
+ private LinearLayout mPanelView;
+ private LinearLayout mSettingView;
+ private LinearLayout mButtonView;
+ private ImageButton mSmallButton;
+ private ImageButton mMediumButton;
+ private ImageButton mLargeButton;
+ private Button mCloseButton;
+ private Button mEditButton;
+ private ImageButton mChangeModeButton;
+ private boolean mAllowDiagonalScrolling = false;
+ private static final float A11Y_CHANGE_SCALE_DIFFERENCE = 1.0f;
+ private static final float A11Y_SCALE_MIN_VALUE = 2.0f;
+ private WindowMagnificationSettingsCallback mCallback;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ MagnificationSize.NONE,
+ MagnificationSize.SMALL,
+ MagnificationSize.MEDIUM,
+ MagnificationSize.LARGE,
+ })
+ /** Denotes the Magnification size type. */
+ @interface MagnificationSize {
+ int NONE = 0;
+ int SMALL = 1;
+ int MEDIUM = 2;
+ int LARGE = 3;
+ }
+
+ @VisibleForTesting
+ WindowMagnificationSettings(Context context, WindowMagnificationSettingsCallback callback,
+ SfVsyncFrameCallbackProvider sfVsyncFrameProvider) {
+ mContext = context;
+ mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
+ mWindowManager = mContext.getSystemService(WindowManager.class);
+ mSfVsyncFrameProvider = sfVsyncFrameProvider;
+ mCallback = callback;
+
+ mAllowDiagonalScrolling = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ALLOW_DIAGONAL_SCROLLING, 0,
+ UserHandle.USER_CURRENT) == 1;
+
+ float scale = Settings.Secure.getFloatForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0,
+ UserHandle.USER_CURRENT);
+
+ mSettingView = (LinearLayout) View.inflate(context,
+ R.layout.window_magnification_settings_view, null);
+
+ mSettingView.setClickable(true);
+ mSettingView.setFocusable(true);
+ mSettingView.setOnTouchListener(this::onTouch);
+
+ mPanelView = mSettingView.findViewById(R.id.magnifier_panel_view);
+ mSmallButton = mSettingView.findViewById(R.id.magnifier_small_button);
+ mMediumButton = mSettingView.findViewById(R.id.magnifier_medium_button);
+ mLargeButton = mSettingView.findViewById(R.id.magnifier_large_button);
+ mCloseButton = mSettingView.findViewById(R.id.magnifier_close_button);
+ mEditButton = mSettingView.findViewById(R.id.magnifier_edit_button);
+ mChangeModeButton = mSettingView.findViewById(R.id.magnifier_full_button);
+
+ mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_seekbar);
+ mZoomSeekbar.setOnSeekBarChangeListener(new ZoomSeekbarChangeListener());
+ setSeekbarProgress(scale);
+ mAllowDiagonalScrollingSwitch =
+ (Switch) mSettingView.findViewById(R.id.magnifier_horizontal_lock_switch);
+ mAllowDiagonalScrollingSwitch.setChecked(mAllowDiagonalScrolling);
+ mAllowDiagonalScrollingSwitch.setOnCheckedChangeListener((view, checked) -> {
+ toggleDiagonalScrolling();
+ });
+
+ mParams = createLayoutParams(context);
+ applyResourcesValues();
+
+ mSmallButton.setAccessibilityDelegate(mButtonDelegate);
+ mSmallButton.setOnClickListener(mButtonClickListener);
+
+ mMediumButton.setAccessibilityDelegate(mButtonDelegate);
+ mMediumButton.setOnClickListener(mButtonClickListener);
+
+ mLargeButton.setAccessibilityDelegate(mButtonDelegate);
+ mLargeButton.setOnClickListener(mButtonClickListener);
+
+ mCloseButton.setAccessibilityDelegate(mButtonDelegate);
+ mCloseButton.setOnClickListener(mButtonClickListener);
+
+ mChangeModeButton.setAccessibilityDelegate(mButtonDelegate);
+ mChangeModeButton.setOnClickListener(mButtonClickListener);
+
+ mEditButton.setAccessibilityDelegate(mButtonDelegate);
+ mEditButton.setOnClickListener(mButtonClickListener);
+
+ mWindowInsetChangeRunnable = this::onWindowInsetChanged;
+ mSettingView.setOnApplyWindowInsetsListener((v, insets) -> {
+ // Adds a pending post check to avoiding redundant calculation because this callback
+ // is sent frequently when the switch icon window dragged by the users.
+ if (!mSettingView.getHandler().hasCallbacks(mWindowInsetChangeRunnable)) {
+ mSettingView.getHandler().post(mWindowInsetChangeRunnable);
+ }
+ return v.onApplyWindowInsets(insets);
+ });
+
+ mGestureDetector = new MagnificationGestureDetector(context,
+ context.getMainThreadHandler(), this);
+ }
+
+ private class ZoomSeekbarChangeListener implements SeekBar.OnSeekBarChangeListener {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ float scale = progress * A11Y_CHANGE_SCALE_DIFFERENCE + A11Y_SCALE_MIN_VALUE;
+ Settings.Secure.putFloatForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, scale,
+ UserHandle.USER_CURRENT);
+ mCallback.onMagnifierScale(scale);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ // Do nothing
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // Do nothing
+ }
+ }
+
+ private CharSequence formatContentDescription(int viewId) {
+ if (viewId == R.id.magnifier_small_button) {
+ return mContext.getResources().getString(
+ R.string.accessibility_magnification_small);
+ } else if (viewId == R.id.magnifier_medium_button) {
+ return mContext.getResources().getString(
+ R.string.accessibility_magnification_medium);
+ } else if (viewId == R.id.magnifier_large_button) {
+ return mContext.getResources().getString(
+ R.string.accessibility_magnification_large);
+ } else if (viewId == R.id.magnifier_close_button) {
+ return mContext.getResources().getString(
+ R.string.accessibility_magnification_close);
+ } else if (viewId == R.id.magnifier_edit_button) {
+ return mContext.getResources().getString(
+ R.string.accessibility_resize);
+ } else {
+ return mContext.getResources().getString(
+ R.string.magnification_mode_switch_description);
+ }
+ }
+
+ private void applyResourcesValues() {
+ final int padding = mContext.getResources().getDimensionPixelSize(
+ R.dimen.magnification_switch_button_padding);
+
+ PorterDuffColorFilter filter = new PorterDuffColorFilter(mContext.getColor(
+ R.color.accessibility_magnifier_icon_color), PorterDuff.Mode.SRC_ATOP);
+
+ mSmallButton.setImageResource(R.drawable.ic_magnification_menu_small);
+ mSmallButton.setColorFilter(filter);
+ mSmallButton.setBackgroundResource(
+ R.drawable.accessibility_magnification_setting_view_btn_bg);
+ mSmallButton.setPadding(padding, padding, padding, padding);
+
+ mMediumButton.setImageResource(R.drawable.ic_magnification_menu_medium);
+ mMediumButton.setColorFilter(filter);
+ mMediumButton.setBackgroundResource(
+ R.drawable.accessibility_magnification_setting_view_btn_bg);
+ mMediumButton.setPadding(padding, padding, padding, padding);
+
+ mLargeButton.setImageResource(R.drawable.ic_magnification_menu_large);
+ mLargeButton.setColorFilter(filter);
+ mLargeButton.setBackgroundResource(
+ R.drawable.accessibility_magnification_setting_view_btn_bg);
+ mLargeButton.setPadding(padding, padding, padding, padding);
+
+ mChangeModeButton.setImageResource(R.drawable.ic_open_in_new_fullscreen);
+ mChangeModeButton.setColorFilter(filter);
+ mChangeModeButton.setBackgroundResource(
+ R.drawable.accessibility_magnification_setting_view_btn_bg);
+ mChangeModeButton.setPadding(padding, padding, padding, padding);
+
+ mCloseButton.setBackgroundResource(
+ R.drawable.accessibility_magnification_setting_view_btn_bg);
+ mEditButton.setBackgroundResource(
+ R.drawable.accessibility_magnification_setting_view_btn_bg);
+ }
+
+ private final AccessibilityDelegate mButtonDelegate = new AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+
+ info.setContentDescription(formatContentDescription(host.getId()));
+ final AccessibilityAction clickAction = new AccessibilityAction(
+ AccessibilityAction.ACTION_CLICK.getId(), mContext.getResources().getString(
+ R.string.magnification_mode_switch_click_label));
+ info.addAction(clickAction);
+ info.setClickable(true);
+ info.addAction(new AccessibilityAction(R.id.accessibility_action_move_up,
+ mContext.getString(R.string.accessibility_control_move_up)));
+ info.addAction(new AccessibilityAction(R.id.accessibility_action_move_down,
+ mContext.getString(R.string.accessibility_control_move_down)));
+ info.addAction(new AccessibilityAction(R.id.accessibility_action_move_left,
+ mContext.getString(R.string.accessibility_control_move_left)));
+ info.addAction(new AccessibilityAction(R.id.accessibility_action_move_right,
+ mContext.getString(R.string.accessibility_control_move_right)));
+ }
+
+ @Override
+ public boolean performAccessibilityAction(View host, int action, Bundle args) {
+ if (performA11yAction(host, action)) {
+ return true;
+ }
+ return super.performAccessibilityAction(host, action, args);
+ }
+
+ private boolean performA11yAction(View view, int action) {
+ final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
+ if (action == AccessibilityAction.ACTION_CLICK.getId()) {
+ handleSingleTap(view);
+ } else if (action == R.id.accessibility_action_move_up) {
+ moveButton(0, -windowBounds.height());
+ } else if (action == R.id.accessibility_action_move_down) {
+ moveButton(0, windowBounds.height());
+ } else if (action == R.id.accessibility_action_move_left) {
+ moveButton(-windowBounds.width(), 0);
+ } else if (action == R.id.accessibility_action_move_right) {
+ moveButton(windowBounds.width(), 0);
+ } else {
+ return false;
+ }
+ return true;
+ }
+ };
+
+ private void applyResourcesValuesWithDensityChanged() {
+ if (mIsVisible) {
+ // Reset button to make its window layer always above the mirror window.
+ hideSettingPanel();
+ showSettingPanel(false);
+ }
+ }
+
+ private boolean onTouch(View v, MotionEvent event) {
+ if (!mIsVisible) {
+ return false;
+ }
+ return mGestureDetector.onTouch(v, event);
+ }
+
+ private View.OnClickListener mButtonClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ int id = view.getId();
+ if (id == R.id.magnifier_small_button) {
+ setMagnifierSize(MagnificationSize.SMALL);
+ } else if (id == R.id.magnifier_medium_button) {
+ setMagnifierSize(MagnificationSize.MEDIUM);
+ } else if (id == R.id.magnifier_large_button) {
+ setMagnifierSize(MagnificationSize.LARGE);
+ } else if (id == R.id.magnifier_edit_button) {
+ editMagnifierSizeMode(true);
+ } else if (id == R.id.magnifier_close_button) {
+ hideSettingPanel();
+ } else if (id == R.id.magnifier_full_button) {
+ hideSettingPanel();
+ toggleMagnificationMode();
+ } else {
+ hideSettingPanel();
+ }
+ }
+ };
+
+ @Override
+ public boolean onSingleTap(View view) {
+ mSingleTapDetected = true;
+ handleSingleTap(view);
+ return true;
+ }
+
+ @Override
+ public boolean onDrag(View v, float offsetX, float offsetY) {
+ moveButton(offsetX, offsetY);
+ return true;
+ }
+
+ @Override
+ public boolean onStart(float x, float y) {
+ return true;
+ }
+
+ @Override
+ public boolean onFinish(float xOffset, float yOffset) {
+ if (!mSingleTapDetected) {
+ showSettingPanel();
+ }
+ mSingleTapDetected = false;
+ return true;
+ }
+
+ @VisibleForTesting
+ public ViewGroup getSettingView() {
+ return mSettingView;
+ }
+
+ private void moveButton(float offsetX, float offsetY) {
+ mSfVsyncFrameProvider.postFrameCallback(l -> {
+ mParams.x += offsetX;
+ mParams.y += offsetY;
+ updateButtonViewLayoutIfNeeded();
+ });
+ }
+
+ public void hideSettingPanel() {
+ if (!mIsVisible) {
+ return;
+ }
+
+ // Reset button status.
+ mWindowManager.removeView(mSettingView);
+ mIsVisible = false;
+ mParams.x = 0;
+ mParams.y = 0;
+
+ mContext.unregisterReceiver(mScreenOffReceiver);
+ }
+
+ public void showSettingPanel() {
+ showSettingPanel(true);
+ }
+
+ public void setScaleSeekbar(float scale) {
+ setSeekbarProgress(scale);
+ }
+
+ private void toggleMagnificationMode() {
+ mCallback.onModeSwitch(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+ }
+
+ /**
+ * Shows magnification panel for set window magnification.
+ * When the panel is going to be visible by calling this method, the layout position can be
+ * reset depending on the flag.
+ *
+ * @param resetPosition if the button position needs be reset
+ */
+ private void showSettingPanel(boolean resetPosition) {
+ if (!mIsVisible) {
+ if (resetPosition) {
+ mDraggableWindowBounds.set(getDraggableWindowBounds());
+ mParams.x = mDraggableWindowBounds.right;
+ mParams.y = mDraggableWindowBounds.bottom;
+ }
+
+ mWindowManager.addView(mSettingView, mParams);
+
+ // Exclude magnification switch button from system gesture area.
+ setSystemGestureExclusion();
+ mIsVisible = true;
+ }
+ mContext.registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+ }
+
+ private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ hideSettingPanel();
+ }
+ };
+
+ private void setSeekbarProgress(float scale) {
+ int index = (int) ((scale - A11Y_SCALE_MIN_VALUE) / A11Y_CHANGE_SCALE_DIFFERENCE);
+ if (index < 0) {
+ index = 0;
+ }
+ mZoomSeekbar.setProgress(index);
+ }
+
+ void onConfigurationChanged(int configDiff) {
+ if ((configDiff & ActivityInfo.CONFIG_UI_MODE) != 0) {
+ applyResourcesValues();
+ return;
+ }
+ if ((configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
+ final Rect previousDraggableBounds = new Rect(mDraggableWindowBounds);
+ mDraggableWindowBounds.set(getDraggableWindowBounds());
+ // Keep the Y position with the same height ratio before the window bounds and
+ // draggable bounds are changed.
+ final float windowHeightFraction = (float) (mParams.y - previousDraggableBounds.top)
+ / previousDraggableBounds.height();
+ mParams.y = (int) (windowHeightFraction * mDraggableWindowBounds.height())
+ + mDraggableWindowBounds.top;
+ return;
+ }
+ if ((configDiff & ActivityInfo.CONFIG_DENSITY) != 0) {
+ applyResourcesValuesWithDensityChanged();
+ return;
+ }
+ if ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0) {
+ updateAccessibilityWindowTitle();
+ return;
+ }
+ }
+
+ private void onWindowInsetChanged() {
+ final Rect newBounds = getDraggableWindowBounds();
+ if (mDraggableWindowBounds.equals(newBounds)) {
+ return;
+ }
+ mDraggableWindowBounds.set(newBounds);
+ }
+
+ private void updateButtonViewLayoutIfNeeded() {
+ if (mIsVisible) {
+ mParams.x = MathUtils.constrain(mParams.x, mDraggableWindowBounds.left,
+ mDraggableWindowBounds.right);
+ mParams.y = MathUtils.constrain(mParams.y, mDraggableWindowBounds.top,
+ mDraggableWindowBounds.bottom);
+ mWindowManager.updateViewLayout(mSettingView, mParams);
+ }
+ }
+
+ private void updateAccessibilityWindowTitle() {
+ mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
+ if (mIsVisible) {
+ mWindowManager.updateViewLayout(mSettingView, mParams);
+ }
+ }
+
+ private void handleSingleTap(View view) {
+ int id = view.getId();
+ if (id == R.id.magnifier_small_button) {
+ setMagnifierSize(MagnificationSize.SMALL);
+ } else if (id == R.id.magnifier_medium_button) {
+ setMagnifierSize(MagnificationSize.MEDIUM);
+ } else if (id == R.id.magnifier_large_button) {
+ setMagnifierSize(MagnificationSize.LARGE);
+ } else if (id == R.id.magnifier_full_button) {
+ hideSettingPanel();
+ toggleMagnificationMode();
+ } else {
+ hideSettingPanel();
+ }
+ }
+
+ public void editMagnifierSizeMode(boolean enable) {
+ setEditMagnifierSizeMode(enable);
+ hideSettingPanel();
+ }
+
+ private void setMagnifierSize(@MagnificationSize int index) {
+ mCallback.onSetMagnifierSize(index);
+ }
+
+ private void toggleDiagonalScrolling() {
+ boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ALLOW_DIAGONAL_SCROLLING, 0,
+ UserHandle.USER_CURRENT) == 1;
+
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ALLOW_DIAGONAL_SCROLLING, enabled ? 0 : 1,
+ UserHandle.USER_CURRENT);
+
+ mCallback.onSetDiagonalScrolling(!enabled);
+ }
+
+ private void setEditMagnifierSizeMode(boolean enable) {
+ mCallback.onEditMagnifierSizeMode(enable);
+ }
+
+ private static LayoutParams createLayoutParams(Context context) {
+ final LayoutParams params = new LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
+ LayoutParams.FLAG_NOT_FOCUSABLE,
+ PixelFormat.TRANSPARENT);
+ params.gravity = Gravity.TOP | Gravity.START;
+ params.accessibilityTitle = getAccessibilityWindowTitle(context);
+ params.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ return params;
+ }
+
+ private Rect getDraggableWindowBounds() {
+ final int layoutMargin = mContext.getResources().getDimensionPixelSize(
+ R.dimen.magnification_switch_button_margin);
+ final WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();
+ final Insets windowInsets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
+ WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
+ final Rect boundRect = new Rect(windowMetrics.getBounds());
+ boundRect.offsetTo(0, 0);
+ boundRect.inset(0, 0, mParams.width, mParams.height);
+ boundRect.inset(windowInsets);
+ boundRect.inset(layoutMargin, layoutMargin);
+
+ return boundRect;
+ }
+
+ private static String getAccessibilityWindowTitle(Context context) {
+ return context.getString(com.android.internal.R.string.android_system_label);
+ }
+
+ private void setSystemGestureExclusion() {
+ mSettingView.post(() -> {
+ mSettingView.setSystemGestureExclusionRects(
+ Collections.singletonList(
+ new Rect(0, 0, mSettingView.getWidth(), mSettingView.getHeight())));
+ });
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java
new file mode 100644
index 000000000000..22ec65001101
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility;
+
+import static com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize;
+
+/**
+ * A callback to inform WindowMagnificationController about
+ * the setting value change or the user interaction.
+ */
+public interface WindowMagnificationSettingsCallback {
+
+ /**
+ * Called when change magnification size.
+ *
+ * @param index Magnification size index.
+ * 0 : MagnificationSize.NONE, 1 : MagnificationSize.SMALL,
+ * 2 : MagnificationSize.MEDIUM, 3: MagnificationSize.LARGE
+ */
+ void onSetMagnifierSize(@MagnificationSize int index);
+
+ /**
+ * Called when set allow diagonal scrolling.
+ *
+ * @param enable Allow diagonal scrolling enable value.
+ */
+ void onSetDiagonalScrolling(boolean enable);
+
+ /**
+ * Called when change magnification size on free mode.
+ *
+ * @param enable Free mode enable value.
+ */
+ void onEditMagnifierSizeMode(boolean enable);
+
+ /**
+ * Called when set magnification scale.
+ *
+ * @param scale Magnification scale value.
+ */
+ void onMagnifierScale(float scale);
+
+ /**
+ * Called when magnification mode changed.
+ *
+ * @param newMode Magnification mode
+ * 1 : ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, 2 : ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
+ */
+ void onModeSwitch(int newMode);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
index c334ca664c46..19caaf431e0a 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
@@ -60,4 +60,12 @@ interface WindowMagnifierCallback {
* @param displayId The logical display id.
*/
void onMove(int displayId);
+
+ /**
+ * Called when magnification mode changed.
+ *
+ * @param displayId The logical display id.
+ * @param newMode Magnification mode.
+ */
+ void onModeSwitch(int displayId, int newMode);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java
index 6f4846a601d9..36ae3c0595ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java
@@ -19,6 +19,7 @@ package com.android.systemui.accessibility;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -27,6 +28,7 @@ import android.os.Handler;
import android.os.SystemClock;
import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
+import android.view.View;
import android.view.ViewConfiguration;
import androidx.test.filters.SmallTest;
@@ -52,6 +54,7 @@ public class MagnificationGestureDetectorTest extends SysuiTestCase {
private int mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
private MagnificationGestureDetector mGestureDetector;
private MotionEventHelper mMotionEventHelper = new MotionEventHelper();
+ private View mSpyView;
@Mock
private MagnificationGestureDetector.OnGestureListener mListener;
@Mock
@@ -66,6 +69,7 @@ public class MagnificationGestureDetectorTest extends SysuiTestCase {
return null;
}).when(mHandler).postAtTime(any(Runnable.class), anyLong());
mGestureDetector = new MagnificationGestureDetector(mContext, mHandler, mListener);
+ mSpyView = Mockito.spy(new View(mContext));
}
@After
@@ -79,7 +83,7 @@ public class MagnificationGestureDetectorTest extends SysuiTestCase {
final MotionEvent downEvent = mMotionEventHelper.obtainMotionEvent(downTime, downTime,
MotionEvent.ACTION_DOWN, ACTION_DOWN_X, ACTION_DOWN_Y);
- mGestureDetector.onTouch(downEvent);
+ mGestureDetector.onTouch(mSpyView, downEvent);
mListener.onStart(ACTION_DOWN_X, ACTION_DOWN_Y);
}
@@ -92,14 +96,14 @@ public class MagnificationGestureDetectorTest extends SysuiTestCase {
final MotionEvent upEvent = mMotionEventHelper.obtainMotionEvent(downTime, downTime,
MotionEvent.ACTION_UP, ACTION_DOWN_X, ACTION_DOWN_Y);
- mGestureDetector.onTouch(downEvent);
- mGestureDetector.onTouch(upEvent);
+ mGestureDetector.onTouch(mSpyView, downEvent);
+ mGestureDetector.onTouch(mSpyView, upEvent);
InOrder inOrder = Mockito.inOrder(mListener);
inOrder.verify(mListener).onStart(ACTION_DOWN_X, ACTION_DOWN_Y);
- inOrder.verify(mListener).onSingleTap();
+ inOrder.verify(mListener).onSingleTap(mSpyView);
inOrder.verify(mListener).onFinish(ACTION_DOWN_X, ACTION_DOWN_Y);
- verify(mListener, never()).onDrag(anyFloat(), anyFloat());
+ verify(mListener, never()).onDrag(eq(mSpyView), anyFloat(), anyFloat());
}
@Test
@@ -110,10 +114,10 @@ public class MagnificationGestureDetectorTest extends SysuiTestCase {
final MotionEvent cancelEvent = mMotionEventHelper.obtainMotionEvent(downTime, downTime,
MotionEvent.ACTION_CANCEL, ACTION_DOWN_X, ACTION_DOWN_Y);
- mGestureDetector.onTouch(downEvent);
- mGestureDetector.onTouch(cancelEvent);
+ mGestureDetector.onTouch(mSpyView, downEvent);
+ mGestureDetector.onTouch(mSpyView, cancelEvent);
- verify(mListener, never()).onSingleTap();
+ verify(mListener, never()).onSingleTap(mSpyView);
}
@Test
@@ -124,10 +128,10 @@ public class MagnificationGestureDetectorTest extends SysuiTestCase {
final MotionEvent upEvent = mMotionEventHelper.obtainMotionEvent(downTime, downTime,
MotionEvent.ACTION_POINTER_DOWN, ACTION_DOWN_X, ACTION_DOWN_Y);
- mGestureDetector.onTouch(downEvent);
- mGestureDetector.onTouch(upEvent);
+ mGestureDetector.onTouch(mSpyView, downEvent);
+ mGestureDetector.onTouch(mSpyView, upEvent);
- verify(mListener, never()).onSingleTap();
+ verify(mListener, never()).onSingleTap(mSpyView);
}
@Test
@@ -138,15 +142,15 @@ public class MagnificationGestureDetectorTest extends SysuiTestCase {
final MotionEvent upEvent = mMotionEventHelper.obtainMotionEvent(downTime, downTime,
MotionEvent.ACTION_UP, ACTION_DOWN_X, ACTION_DOWN_Y);
- mGestureDetector.onTouch(downEvent);
+ mGestureDetector.onTouch(mSpyView, downEvent);
// Execute the pending message for stopping single-tap detection.
mCancelSingleTapRunnable.run();
- mGestureDetector.onTouch(upEvent);
+ mGestureDetector.onTouch(mSpyView, upEvent);
InOrder inOrder = Mockito.inOrder(mListener);
inOrder.verify(mListener).onStart(ACTION_DOWN_X, ACTION_DOWN_Y);
inOrder.verify(mListener).onFinish(ACTION_DOWN_X, ACTION_DOWN_Y);
- verify(mListener, never()).onSingleTap();
+ verify(mListener, never()).onSingleTap(mSpyView);
}
@Test
@@ -160,14 +164,14 @@ public class MagnificationGestureDetectorTest extends SysuiTestCase {
final MotionEvent upEvent = mMotionEventHelper.obtainMotionEvent(downTime, downTime,
MotionEvent.ACTION_UP, ACTION_DOWN_X, ACTION_DOWN_Y);
- mGestureDetector.onTouch(downEvent);
- mGestureDetector.onTouch(moveEvent);
- mGestureDetector.onTouch(upEvent);
+ mGestureDetector.onTouch(mSpyView, downEvent);
+ mGestureDetector.onTouch(mSpyView, moveEvent);
+ mGestureDetector.onTouch(mSpyView, upEvent);
InOrder inOrder = Mockito.inOrder(mListener);
inOrder.verify(mListener).onStart(ACTION_DOWN_X, ACTION_DOWN_Y);
- inOrder.verify(mListener).onDrag(dragOffset, 0);
+ inOrder.verify(mListener).onDrag(mSpyView, dragOffset, 0);
inOrder.verify(mListener).onFinish(ACTION_DOWN_X, ACTION_DOWN_Y);
- verify(mListener, never()).onSingleTap();
+ verify(mListener, never()).onSingleTap(mSpyView);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index bc89da7d504c..00cb49169048 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -145,7 +145,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void removeButton_buttonIsShowing_removeViewAndUnregisterComponentCallbacks() {
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
mMagnificationModeSwitch.removeButton();
@@ -167,7 +167,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void showButton_excludeSystemGestureArea() {
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
verify(mSpyImageView).setSystemGestureExclusionRects(any(List.class));
}
@@ -178,7 +178,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
when(mAccessibilityManager.getRecommendedTimeoutMillis(anyInt(), anyInt())).thenReturn(
a11yTimeout);
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
verify(mAccessibilityManager).getRecommendedTimeoutMillis(
DEFAULT_FADE_OUT_ANIMATION_DELAY_MS, AccessibilityManager.FLAG_CONTENT_ICONS
@@ -188,7 +188,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void showMagnificationButton_windowModeAndFadingOut_verifyAnimationEndAction() {
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
executeFadeOutAnimation();
// Verify the end action after fade-out.
@@ -389,15 +389,15 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void initializeA11yNode_showWindowModeButton_expectedValues() {
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
final AccessibilityNodeInfo nodeInfo = new AccessibilityNodeInfo();
mSpyImageView.onInitializeAccessibilityNodeInfo(nodeInfo);
assertEquals(mContext.getString(R.string.magnification_mode_switch_description),
nodeInfo.getContentDescription());
- assertEquals(mContext.getString(R.string.magnification_mode_switch_state_window),
- nodeInfo.getStateDescription());
+ assertEquals(mContext.getString(R.string.magnification_mode_switch_state_full_screen),
+ nodeInfo.getStateDescription().toString());
assertThat(nodeInfo.getActionList(),
hasItems(new AccessibilityNodeInfo.AccessibilityAction(
ACTION_CLICK.getId(), mContext.getResources().getString(
@@ -422,18 +422,18 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void performClickA11yActions_showWindowModeButton_verifyTapAction() {
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
resetAndStubMockImageViewAndAnimator();
mSpyImageView.performAccessibilityAction(
ACTION_CLICK.getId(), null);
- verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+ verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
}
@Test
public void performMoveLeftA11yAction_showButtonAtRightEdge_moveToLeftEdge() {
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
mSpyImageView.performAccessibilityAction(
R.id.accessibility_action_move_left, null);
@@ -456,7 +456,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void showButton_hasAccessibilityWindowTitle() {
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
final WindowManager.LayoutParams layoutPrams =
mWindowManager.getLayoutParamsFromAttachedView();
@@ -468,7 +468,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
@Test
public void showButton_registerComponentCallbacks() {
- mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
verify(mContext).registerComponentCallbacks(mMagnificationModeSwitch);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
index a56218b08224..82ae6ff1e945 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
@@ -24,6 +24,7 @@ import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Display;
+import android.view.View;
import androidx.test.filters.SmallTest;
@@ -46,6 +47,7 @@ public class ModeSwitchesControllerTest extends SysuiTestCase {
private FakeSwitchSupplier mSupplier;
private MagnificationModeSwitch mModeSwitch;
private ModeSwitchesController mModeSwitchesController;
+ private View mSpyView;
@Mock
private MagnificationModeSwitch.SwitchListener mListener;
@@ -57,6 +59,7 @@ public class ModeSwitchesControllerTest extends SysuiTestCase {
mModeSwitchesController = new ModeSwitchesController(mSupplier);
mModeSwitchesController.setSwitchListenerDelegate(mListener);
mModeSwitch = Mockito.spy(new MagnificationModeSwitch(mContext, mModeSwitchesController));
+ mSpyView = Mockito.spy(new View(mContext));
}
@After
@@ -94,12 +97,12 @@ public class ModeSwitchesControllerTest extends SysuiTestCase {
@Test
public void testOnSwitchClick_showWindowModeButton_invokeListener() {
mModeSwitchesController.showButton(Display.DEFAULT_DISPLAY,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
- mModeSwitch.onSingleTap();
+ mModeSwitch.onSingleTap(mSpyView);
verify(mListener).onSwitch(mContext.getDisplayId(),
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
}
private class FakeSwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 3d77d64a7988..69ccc8b88bd8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -19,6 +19,8 @@ package com.android.systemui.accessibility;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Choreographer.FrameCallback;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowInsets.Type.systemGestures;
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -46,6 +48,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.animation.ValueAnimator;
+import android.annotation.IdRes;
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -65,6 +68,7 @@ import android.testing.TestableResources;
import android.text.TextUtils;
import android.view.Display;
import android.view.IWindowSession;
+import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.View;
@@ -126,8 +130,13 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
private WindowMagnificationController mWindowMagnificationController;
private Instrumentation mInstrumentation;
private final ValueAnimator mValueAnimator = ValueAnimator.ofFloat(0, 1.0f).setDuration(0);
+
private IWindowSession mWindowSessionSpy;
+ private View mSpyView;
+ private View.OnTouchListener mTouchListener;
+ private MotionEventHelper mMotionEventHelper = new MotionEventHelper();
+
@Before
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
@@ -165,6 +174,12 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
verify(mMirrorWindowControl).setWindowDelegate(
any(MirrorWindowControl.MirrorWindowDelegate.class));
+ mSpyView = Mockito.spy(new View(mContext));
+ doAnswer((invocation) -> {
+ mTouchListener = invocation.getArgument(0);
+ return null;
+ }).when(mSpyView).setOnTouchListener(
+ any(View.OnTouchListener.class));
}
@After
@@ -702,7 +717,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
});
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onSingleTap();
+ mWindowMagnificationController.onSingleTap(mSpyView);
});
final View mirrorView = mWindowManager.getAttachedView();
@@ -910,6 +925,38 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
assertTrue(magnificationCenterY.get() < bounds.bottom);
}
+ @Test
+ public void performSingleTap_DragHandle() {
+ final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
+ mInstrumentation.runOnMainSync(
+ () -> {
+ mWindowMagnificationController.enableWindowMagnificationInternal(
+ 1.5f, bounds.centerX(), bounds.centerY());
+ });
+ View dragButton = getInternalView(R.id.drag_handle);
+
+ // Perform a single-tap
+ final long downTime = SystemClock.uptimeMillis();
+ dragButton.dispatchTouchEvent(
+ obtainMotionEvent(downTime, 0, ACTION_DOWN, 100, 100));
+ dragButton.dispatchTouchEvent(
+ obtainMotionEvent(downTime, downTime, ACTION_UP, 100, 100));
+
+ verify(mWindowManager).addView(any(View.class), any());
+ }
+
+ private <T extends View> T getInternalView(@IdRes int idRes) {
+ View mirrorView = mWindowManager.getAttachedView();
+ T view = mirrorView.findViewById(idRes);
+ assertNotNull(view);
+ return view;
+ }
+
+ private MotionEvent obtainMotionEvent(long downTime, long eventTime, int action, float x,
+ float y) {
+ return mMotionEventHelper.obtainMotionEvent(downTime, eventTime, action, x, y);
+ }
+
private CharSequence getAccessibilityWindowTitle() {
final View mirrorView = mWindowManager.getAttachedView();
if (mirrorView == null) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
new file mode 100644
index 000000000000..2f94b69b8189
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.IdRes;
+import android.content.Context;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.CompoundButton;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class WindowMagnificationSettingsTest extends SysuiTestCase {
+
+ private static final int MAGNIFICATION_SIZE_SMALL = 1;
+ private static final int MAGNIFICATION_SIZE_MEDIUM = 2;
+ private static final int MAGNIFICATION_SIZE_LARGE = 3;
+
+ private ViewGroup mSettingView;
+ @Mock
+ private AccessibilityManager mAccessibilityManager;
+ @Mock
+ private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
+ @Mock
+ private WindowMagnificationSettingsCallback mWindowMagnificationSettingsCallback;
+ private TestableWindowManager mWindowManager;
+ private WindowMagnificationSettings mWindowMagnificationSettings;
+ private MotionEventHelper mMotionEventHelper = new MotionEventHelper();
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mContext = getContext();
+ mContext.setTheme(android.R.style.Theme_DeviceDefault_DayNight);
+ final WindowManager wm = mContext.getSystemService(WindowManager.class);
+ mWindowManager = spy(new TestableWindowManager(wm));
+ mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
+ mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
+
+ mWindowMagnificationSettings = new WindowMagnificationSettings(mContext,
+ mWindowMagnificationSettingsCallback, mSfVsyncFrameProvider);
+
+ mSettingView = mWindowMagnificationSettings.getSettingView();
+ }
+
+ @After
+ public void tearDown() {
+ mMotionEventHelper.recycleEvents();
+ mWindowMagnificationSettings.hideSettingPanel();
+ }
+
+ @Test
+ public void showSettingPanel_hasAccessibilityWindowTitle() {
+ mWindowMagnificationSettings.showSettingPanel();
+
+ final WindowManager.LayoutParams layoutPrams =
+ mWindowManager.getLayoutParamsFromAttachedView();
+ assertNotNull(layoutPrams);
+ assertEquals(getContext().getResources()
+ .getString(com.android.internal.R.string.android_system_label),
+ layoutPrams.accessibilityTitle.toString());
+ }
+
+ @Test
+ public void performClick_smallSizeButton_changeMagnifierSizeSmall() {
+ // Open view
+ mWindowMagnificationSettings.showSettingPanel();
+
+ verifyOnSetMagnifierSize(R.id.magnifier_small_button, MAGNIFICATION_SIZE_SMALL);
+ }
+
+ @Test
+ public void performClick_mediumSizeButton_changeMagnifierSizeMedium() {
+ // Open view
+ mWindowMagnificationSettings.showSettingPanel();
+
+ verifyOnSetMagnifierSize(R.id.magnifier_medium_button, MAGNIFICATION_SIZE_MEDIUM);
+ }
+
+ @Test
+ public void performClick_largeSizeButton_changeMagnifierSizeLarge() {
+ // Open view
+ mWindowMagnificationSettings.showSettingPanel();
+
+ verifyOnSetMagnifierSize(R.id.magnifier_large_button, MAGNIFICATION_SIZE_LARGE);
+ }
+
+ private void verifyOnSetMagnifierSize(@IdRes int viewId, int expectedSizeIndex) {
+ View changeSizeButton = getInternalView(viewId);
+
+ // Perform click
+ changeSizeButton.performClick();
+
+ verify(mWindowMagnificationSettingsCallback).onSetMagnifierSize(expectedSizeIndex);
+ }
+
+
+ @Test
+ public void performClick_fullScreenModeButton_setEditMagnifierSizeMode() {
+ View fullScreenModeButton = getInternalView(R.id.magnifier_full_button);
+ getInternalView(R.id.magnifier_panel_view);
+
+ // Open view
+ mWindowMagnificationSettings.showSettingPanel();
+
+ // Perform click
+ fullScreenModeButton.performClick();
+
+ verify(mWindowManager).removeView(mSettingView);
+ verify(mWindowMagnificationSettingsCallback)
+ .onModeSwitch(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+ }
+
+ @Test
+ public void performClick_editButton_setEditMagnifierSizeMode() {
+ View editButton = getInternalView(R.id.magnifier_edit_button);
+
+ // Open view
+ mWindowMagnificationSettings.showSettingPanel();
+
+ // Perform click
+ editButton.performClick();
+
+ verify(mWindowMagnificationSettingsCallback).onEditMagnifierSizeMode(true);
+ verify(mWindowManager).removeView(mSettingView);
+ }
+
+ @Test
+ public void performClick_setDiagonalScrollingSwitch_toggleDiagonalScrollingSwitchMode() {
+ CompoundButton diagonalScrollingSwitch =
+ getInternalView(R.id.magnifier_horizontal_lock_switch);
+ final boolean currentCheckedState = diagonalScrollingSwitch.isChecked();
+
+ // Open view
+ mWindowMagnificationSettings.showSettingPanel();
+
+ // Perform click
+ diagonalScrollingSwitch.performClick();
+
+ verify(mWindowMagnificationSettingsCallback).onSetDiagonalScrolling(!currentCheckedState);
+ }
+
+ private <T extends View> T getInternalView(@IdRes int idRes) {
+ T view = mSettingView.findViewById(idRes);
+ assertNotNull(view);
+ return view;
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
index ccf2f8b16f8a..e1bd25bd17e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
@@ -158,6 +158,18 @@ public class WindowMagnificationTest extends SysuiTestCase {
}
@Test
+ public void onModeSwitch_enabled_notifyCallback() throws RemoteException {
+ final int magnificationModeFullScreen = 1;
+ mCommandQueue.requestWindowMagnificationConnection(true);
+ waitForIdleSync();
+
+ mWindowMagnification.onModeSwitch(TEST_DISPLAY, magnificationModeFullScreen);
+
+ verify(mConnectionCallback).onChangeMagnificationMode(TEST_DISPLAY,
+ magnificationModeFullScreen);
+ }
+
+ @Test
public void overviewProxyIsConnected_noController_resetFlag() {
mOverviewProxyListener.onConnectionChanged(true);
diff --git a/services/core/java/com/android/server/notification/ReviewNotificationPermissionsJobService.java b/services/core/java/com/android/server/notification/ReviewNotificationPermissionsJobService.java
index fde45f71a844..acb36a0660cb 100644
--- a/services/core/java/com/android/server/notification/ReviewNotificationPermissionsJobService.java
+++ b/services/core/java/com/android/server/notification/ReviewNotificationPermissionsJobService.java
@@ -42,10 +42,6 @@ public class ReviewNotificationPermissionsJobService extends JobService {
*/
public static void scheduleJob(Context context, long rescheduleTimeMillis) {
JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
- // if the job already exists for some reason, cancel & reschedule
- if (jobScheduler.getPendingJob(JOB_ID) != null) {
- jobScheduler.cancel(JOB_ID);
- }
ComponentName component = new ComponentName(
context, ReviewNotificationPermissionsJobService.class);
JobInfo newJob = new JobInfo.Builder(JOB_ID, component)
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsJobServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsJobServiceTest.java
index 5a4ce5da676e..3a6c0eb8fc2a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsJobServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsJobServiceTest.java
@@ -20,10 +20,8 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
@@ -75,9 +73,6 @@ public class ReviewNotificationPermissionsJobServiceTest extends UiServiceTestCa
@Test
public void testScheduleJob() {
- // if asked, the job doesn't currently exist yet
- when(mMockJobScheduler.getPendingJob(anyInt())).thenReturn(null);
-
final int rescheduleTimeMillis = 350; // arbitrary number
// attempt to schedule the job