OSDN Git Service

Cannot click on partially visible views in touch exploration.
authorSvetoslav Ganov <svetoslavganov@google.com>
Thu, 1 Nov 2012 01:28:49 +0000 (18:28 -0700)
committerSvetoslav Ganov <svetoslavganov@google.com>
Thu, 1 Nov 2012 23:27:05 +0000 (16:27 -0700)
1. In touch exploration mode the system clicks in the center of the
   accessibility focus rectangle. However, if this rectangle is only
   partially shown on the window or on the screen the system may not
   be able to perform the click, if the accessibility focus center
   is not on the screen, or click on the wrong window, if the access
   focus center is outside of the window.

   This change clips the rectangle to the window bounds which and the
   display bounds. This will ensure no clicks are sent to the wrong
   window and no clicks are sent outside of the screen.

bug:7453839

Change-Id: I79f98971e7ebcbb391c37284467dc76076172c5f

core/java/android/view/ViewRootImpl.java
services/java/com/android/server/accessibility/AccessibilityManagerService.java

index a3360bc..b6016e9 100644 (file)
@@ -2338,6 +2338,7 @@ public final class ViewRootImpl implements ViewParent,
             mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
         }
         bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop);
+        bounds.intersect(0, 0, mAttachInfo.mViewRootImpl.mWidth, mAttachInfo.mViewRootImpl.mHeight);
         drawable.setBounds(bounds);
         drawable.draw(canvas);
     }
index 6b277c7..4953f48 100644 (file)
@@ -40,7 +40,9 @@ import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.database.ContentObserver;
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
 import android.hardware.input.InputManager;
 import android.net.Uri;
 import android.os.Binder;
@@ -62,6 +64,7 @@ import android.text.TextUtils;
 import android.text.TextUtils.SimpleStringSplitter;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.IWindow;
 import android.view.IWindowManager;
 import android.view.InputDevice;
@@ -137,6 +140,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
     private final List<AccessibilityServiceInfo> mEnabledServicesForFeedbackTempList =
             new ArrayList<AccessibilityServiceInfo>();
 
+    private final Rect mTempRect = new Rect();
+
+    private final Point mTempPoint = new Point();
+
+    private final Display mDefaultDisplay;
+
     private final PackageManager mPackageManager;
 
     private final IWindowManager mWindowManagerService;
@@ -194,6 +203,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
         mWindowManagerService = (IWindowManager) ServiceManager.getService(Context.WINDOW_SERVICE);
         mSecurityPolicy = new SecurityPolicy();
         mMainHandler = new MainHandler(mContext.getMainLooper());
+        //TODO: (multi-display) We need to support multiple displays.
+        DisplayManager displayManager = (DisplayManager)
+                mContext.getSystemService(Context.DISPLAY_SERVICE);
+        mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
         registerBroadcastReceivers();
         new AccessibilityContentObserver(mMainHandler).register(
                 context.getContentResolver());
@@ -582,6 +595,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
      * @param outBounds The output to which to write the focus bounds.
      * @return Whether accessibility focus was found and the bounds are populated.
      */
+    // TODO: (multi-display) Make sure this works for multiple displays. 
     boolean getAccessibilityFocusBoundsInActiveWindow(Rect outBounds) {
         // Instead of keeping track of accessibility focus events per
         // window to be able to find the focus in the active window,
@@ -603,6 +617,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
                 return false;
             }
             focus.getBoundsInScreen(outBounds);
+            // Clip to the window rectangle.
+            Rect windowBounds = mTempRect;
+            getActiveWindowBounds(windowBounds);
+            outBounds.intersect(windowBounds);
+            // Clip to the screen rectangle.
+            mDefaultDisplay.getRealSize(mTempPoint);
+            outBounds.intersect(0,  0,  mTempPoint.x, mTempPoint.y);
             return true;
         } finally {
             client.removeConnection(connectionId);