@Override
    protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfo node) {
      final boolean hasBounds = getBoundsForDay(virtualViewId, mTempRect);

      if (!hasBounds) {
        // The day is invalid, kill the node.
        mTempRect.setEmpty();
        node.setContentDescription("");
        node.setBoundsInParent(mTempRect);
        node.setVisibleToUser(false);
        return;
      }

      node.setText(getDayText(virtualViewId));
      node.setContentDescription(getDayDescription(virtualViewId));
      node.setBoundsInParent(mTempRect);

      final boolean isDayEnabled = isDayEnabled(virtualViewId);
      if (isDayEnabled) {
        node.addAction(AccessibilityAction.ACTION_CLICK);
      }

      node.setEnabled(isDayEnabled);

      if (virtualViewId == mActivatedDay) {
        // TODO: This should use activated once that's supported.
        node.setChecked(true);
      }
    }
 public void c(Object paramObject, Rect paramRect) {
   ((AccessibilityNodeInfo) paramObject).setBoundsInParent(paramRect);
 }
Example #3
0
  public static void sendAccessibilityEvent(final JSONObject message) {
    if (!sEnabled) return;

    final int eventType = message.optInt("eventType", -1);
    if (eventType < 0) {
      Log.e(LOGTAG, "No accessibility event type provided");
      return;
    }

    if (Versions.preJB) {
      // Before Jelly Bean we send events directly from here while spoofing the source by setting
      // the package and class name manually.
      ThreadUtils.postToBackgroundThread(
          new Runnable() {
            @Override
            public void run() {
              sendDirectAccessibilityEvent(eventType, message);
            }
          });
    } else {
      // In Jelly Bean we populate an AccessibilityNodeInfo with the minimal amount of data to have
      // it work with TalkBack.
      final LayerView view = GeckoAppShell.getLayerView();
      if (view == null) return;

      if (sVirtualCursorNode == null)
        sVirtualCursorNode = AccessibilityNodeInfo.obtain(view, VIRTUAL_CURSOR_POSITION);
      sVirtualCursorNode.setEnabled(message.optBoolean("enabled", true));
      sVirtualCursorNode.setClickable(message.optBoolean("clickable"));
      sVirtualCursorNode.setCheckable(message.optBoolean("checkable"));
      sVirtualCursorNode.setChecked(message.optBoolean("checked"));
      sVirtualCursorNode.setPassword(message.optBoolean("password"));

      final JSONArray textArray = message.optJSONArray("text");
      StringBuilder sb = new StringBuilder();
      if (textArray != null && textArray.length() > 0) {
        sb.append(textArray.optString(0));
        for (int i = 1; i < textArray.length(); i++) {
          sb.append(" ").append(textArray.optString(i));
        }
      }
      sVirtualCursorNode.setText(sb.toString());
      sVirtualCursorNode.setContentDescription(message.optString("description"));

      JSONObject bounds = message.optJSONObject("bounds");
      if (bounds != null) {
        Rect relativeBounds =
            new Rect(
                bounds.optInt("left"), bounds.optInt("top"),
                bounds.optInt("right"), bounds.optInt("bottom"));
        sVirtualCursorNode.setBoundsInParent(relativeBounds);
        int[] locationOnScreen = new int[2];
        view.getLocationOnScreen(locationOnScreen);
        Rect screenBounds = new Rect(relativeBounds);
        screenBounds.offset(locationOnScreen[0], locationOnScreen[1]);
        sVirtualCursorNode.setBoundsInScreen(screenBounds);
      }

      final JSONObject braille = message.optJSONObject("brailleOutput");
      if (braille != null) {
        sendBrailleText(
            view,
            braille.optString("text"),
            braille.optInt("selectionStart"),
            braille.optInt("selectionEnd"));
      }

      ThreadUtils.postToUiThread(
          new Runnable() {
            @Override
            public void run() {
              // If this is an accessibility focus, a lot of internal voodoo happens so we perform
              // an
              // accessibility focus action on the view, and it in turn sends the right events.
              switch (eventType) {
                case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
                  sEventMessage = message;
                  view.performAccessibilityAction(
                      AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
                  break;
                case AccessibilityEvent.TYPE_ANNOUNCEMENT:
                case AccessibilityEvent.TYPE_VIEW_SCROLLED:
                  sEventMessage = null;
                  final AccessibilityEvent accEvent = AccessibilityEvent.obtain(eventType);
                  view.onInitializeAccessibilityEvent(accEvent);
                  populateEventFromJSON(accEvent, message);
                  view.getParent().requestSendAccessibilityEvent(view, accEvent);
                  break;
                default:
                  sEventMessage = message;
                  view.sendAccessibilityEvent(eventType);
                  break;
              }
            }
          });
    }
  }