summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java70
1 files changed, 59 insertions, 11 deletions
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 33595f2b9b37..7ad88ca6b1b2 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -115,6 +115,8 @@ import android.util.SparseArray;
import android.util.TypedValue;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -2000,6 +2002,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
static private final String FOCUSED_ID_TAG = "android:focusedViewId";
+ static private final String ACCESSIBILITY_FOCUSED_ID_TAG = "android:accessibilityFocusedViewId";
+ static private final String ACCESSIBILITY_FOCUSED_VIRTUAL_ID_TAG =
+ "android:accessibilityFocusedVirtualViewId";
static private final String VIEWS_TAG = "android:views";
static private final String PANELS_TAG = "android:Panels";
static private final String ACTION_BAR_TAG = "android:ActionBar";
@@ -2016,16 +2021,25 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mContentParent.saveHierarchyState(states);
outState.putSparseParcelableArray(VIEWS_TAG, states);
- // save the focused view id
- View focusedView = mContentParent.findFocus();
- if (focusedView != null) {
- if (focusedView.getId() != View.NO_ID) {
- outState.putInt(FOCUSED_ID_TAG, focusedView.getId());
- } else {
- if (false) {
- Log.d(TAG, "couldn't save which view has focus because the focused view "
- + focusedView + " has no id.");
- }
+ // Save the focused view ID.
+ final View focusedView = mContentParent.findFocus();
+ if (focusedView != null && focusedView.getId() != View.NO_ID) {
+ outState.putInt(FOCUSED_ID_TAG, focusedView.getId());
+ }
+
+ // Save the accessibility focused view ID.
+ final ViewRootImpl viewRootImpl = mContentParent.getViewRootImpl();
+ final View accessFocusHost = viewRootImpl.getAccessibilityFocusedHost();
+ if (accessFocusHost != null && accessFocusHost.getId() != View.NO_ID) {
+ outState.putInt(ACCESSIBILITY_FOCUSED_ID_TAG, accessFocusHost.getId());
+
+ // If we have a focused virtual node ID, save that too.
+ final AccessibilityNodeInfo accessFocusedNode =
+ viewRootImpl.getAccessibilityFocusedVirtualView();
+ if (accessFocusedNode != null) {
+ final int virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
+ accessFocusedNode.getSourceNodeId());
+ outState.putInt(ACCESSIBILITY_FOCUSED_VIRTUAL_ID_TAG, virtualNodeId);
}
}
@@ -2071,7 +2085,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
- // restore the panels
+ // Restore the accessibility focused view.
+ final int accessFocusHostViewId = savedInstanceState.getInt(
+ ACCESSIBILITY_FOCUSED_ID_TAG, View.NO_ID);
+ final int accessFocusVirtualViewId = savedInstanceState.getInt(
+ ACCESSIBILITY_FOCUSED_VIRTUAL_ID_TAG, AccessibilityNodeInfo.UNDEFINED_ITEM_ID);
+ tryRestoreAccessibilityFocus(accessFocusHostViewId, accessFocusVirtualViewId);
+
+ // Restore the panels.
SparseArray<Parcelable> panelStates = savedInstanceState.getSparseParcelableArray(PANELS_TAG);
if (panelStates != null) {
restorePanelState(panelStates);
@@ -2090,6 +2111,33 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
+ private void tryRestoreAccessibilityFocus(int hostViewId, int virtualViewId) {
+ if (hostViewId != View.NO_ID) {
+ final View needsAccessFocus = mContentParent.findViewById(hostViewId);
+ if (needsAccessFocus != null) {
+ if (!tryFocusingVirtualView(needsAccessFocus, virtualViewId)
+ && !needsAccessFocus.requestAccessibilityFocus()) {
+ Log.w(TAG, "Failed to restore focus to previously accessibility"
+ + " focused view with id " + hostViewId);
+ }
+ } else {
+ Log.w(TAG, "Previously accessibility focused view reported id " + hostViewId
+ + " during save, but can't be found during restore.");
+ }
+ }
+ }
+
+ private boolean tryFocusingVirtualView(View host, int virtualViewId) {
+ if (virtualViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+ final AccessibilityNodeProvider nodeProvider = host.getAccessibilityNodeProvider();
+ if (nodeProvider != null) {
+ return nodeProvider.performAction(virtualViewId,
+ AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
+ }
+ }
+ return false;
+ }
+
/**
* Invoked when the panels should freeze their state.
*