summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Jurka <mikejurka@google.com>2012-10-04 17:42:38 +0200
committerMichael Jurka <mikejurka@google.com>2012-10-08 15:41:51 +0200
commit22143131770f7e90be4181e88ced0cb1d7158306 (patch)
tree2bc775598be2c7966b04c898432f8401c07fc82b
parent68255cbabe1cb7fbfc0706a8a2e1b1927eae1b55 (diff)
downloadandroid_packages_apps_Trebuchet-22143131770f7e90be4181e88ced0cb1d7158306.tar.gz
android_packages_apps_Trebuchet-22143131770f7e90be4181e88ced0cb1d7158306.tar.bz2
android_packages_apps_Trebuchet-22143131770f7e90be4181e88ced0cb1d7158306.zip
Fix bug 6886990: cling accessibility
Clings should block interaction with elements below when Talkback is enabled Change-Id: Ifdcd109351fd3c2d6dc97ad75ea3ab6eea48b582
-rw-r--r--src/com/android/launcher2/HideFromAccessibilityHelper.java113
-rw-r--r--src/com/android/launcher2/Launcher.java21
2 files changed, 132 insertions, 2 deletions
diff --git a/src/com/android/launcher2/HideFromAccessibilityHelper.java b/src/com/android/launcher2/HideFromAccessibilityHelper.java
new file mode 100644
index 000000000..0b2ce5ba6
--- /dev/null
+++ b/src/com/android/launcher2/HideFromAccessibilityHelper.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2012 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.launcher2;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.OnHierarchyChangeListener;
+
+import java.util.HashMap;
+
+public class HideFromAccessibilityHelper implements OnHierarchyChangeListener {
+ private HashMap<View, Integer> mPreviousValues;
+ boolean mHide;
+ boolean mOnlyAllApps;
+
+ public HideFromAccessibilityHelper() {
+ mPreviousValues = new HashMap<View, Integer>();
+ mHide = false;
+ }
+
+ public void setImportantForAccessibilityToNo(View v, boolean onlyAllApps) {
+ mOnlyAllApps = onlyAllApps;
+ setImportantForAccessibilityToNoHelper(v);
+ mHide = true;
+ }
+
+ private void setImportantForAccessibilityToNoHelper(View v) {
+ mPreviousValues.put(v, v.getImportantForAccessibility());
+ v.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+
+ // Call method on children recursively
+ if (v instanceof ViewGroup) {
+ ViewGroup vg = (ViewGroup) v;
+ vg.setOnHierarchyChangeListener(this);
+ for (int i = 0; i < vg.getChildCount(); i++) {
+ View child = vg.getChildAt(i);
+
+ if (includeView(child)) {
+ setImportantForAccessibilityToNoHelper(child);
+ }
+ }
+ }
+ }
+
+ public void restoreImportantForAccessibility(View v) {
+ if (mHide) {
+ restoreImportantForAccessibilityHelper(v);
+ }
+ mHide = false;
+ }
+
+ private void restoreImportantForAccessibilityHelper(View v) {
+ v.setImportantForAccessibility(mPreviousValues.get(v));
+ mPreviousValues.remove(v);
+
+ // Call method on children recursively
+ if (v instanceof ViewGroup) {
+ ViewGroup vg = (ViewGroup) v;
+
+ // We assume if a class implements OnHierarchyChangeListener, it listens
+ // to changes to any of its children (happens to be the case in Launcher)
+ if (vg instanceof OnHierarchyChangeListener) {
+ vg.setOnHierarchyChangeListener((OnHierarchyChangeListener) vg);
+ } else {
+ vg.setOnHierarchyChangeListener(null);
+ }
+ for (int i = 0; i < vg.getChildCount(); i++) {
+ View child = vg.getChildAt(i);
+ if (includeView(child)) {
+ restoreImportantForAccessibilityHelper(child);
+ }
+ }
+ }
+ }
+
+ public void onChildViewAdded(View parent, View child) {
+ if (mHide && includeView(child)) {
+ setImportantForAccessibilityToNoHelper(child);
+ }
+ }
+
+ public void onChildViewRemoved(View parent, View child) {
+ if (mHide && includeView(child)) {
+ restoreImportantForAccessibilityHelper(child);
+ }
+ }
+
+ private boolean includeView(View v) {
+ return !hasAncestorOfType(v, Cling.class) &&
+ (!mOnlyAllApps || hasAncestorOfType(v, AppsCustomizeTabHost.class));
+ }
+
+ private boolean hasAncestorOfType(View v, Class c) {
+ return v != null &&
+ (v.getClass().equals(c) ||
+ (v.getParent() instanceof ViewGroup &&
+ hasAncestorOfType((ViewGroup) v.getParent(), c)));
+ }
+} \ No newline at end of file
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index fedf32460..64e382a7b 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -300,6 +300,9 @@ public final class Launcher extends Activity
private BubbleTextView mWaitingForResume;
+ private HideFromAccessibilityHelper mHideFromAccessibilityHelper
+ = new HideFromAccessibilityHelper();
+
private Runnable mBuildLayersRunnable = new Runnable() {
public void run() {
if (mWorkspace != null) {
@@ -3662,8 +3665,9 @@ public final class Launcher extends Activity
return true;
}
+
private Cling initCling(int clingId, int[] positionData, boolean animate, int delay) {
- Cling cling = (Cling) findViewById(clingId);
+ final Cling cling = (Cling) findViewById(clingId);
if (cling != null) {
cling.init(this, positionData);
cling.setVisibility(View.VISIBLE);
@@ -3680,11 +3684,21 @@ public final class Launcher extends Activity
} else {
cling.setAlpha(1f);
}
+ cling.setFocusableInTouchMode(true);
+ cling.post(new Runnable() {
+ public void run() {
+ cling.setFocusable(true);
+ cling.requestFocus();
+ }
+ });
+ mHideFromAccessibilityHelper.setImportantForAccessibilityToNo(
+ mDragLayer, clingId == R.id.all_apps_cling);
}
return cling;
}
+
private void dismissCling(final Cling cling, final String flag, int duration) {
- if (cling != null) {
+ if (cling != null && cling.getVisibility() == View.VISIBLE) {
ObjectAnimator anim = LauncherAnimUtils.ofFloat(cling, "alpha", 0f);
anim.setDuration(duration);
anim.addListener(new AnimatorListenerAdapter() {
@@ -3702,8 +3716,10 @@ public final class Launcher extends Activity
};
});
anim.start();
+ mHideFromAccessibilityHelper.restoreImportantForAccessibility(mDragLayer);
}
}
+
private void removeCling(int id) {
final View cling = findViewById(id);
if (cling != null) {
@@ -3714,6 +3730,7 @@ public final class Launcher extends Activity
parent.removeView(cling);
}
});
+ mHideFromAccessibilityHelper.restoreImportantForAccessibility(mDragLayer);
}
}