// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.view;

import android.annotation.SuppressLint;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.accessibility.AccessibilityRecord;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.Log;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Facilitates embedding of platform views in the accessibility tree generated by the accessibility
 * bridge.
 *
 * <p>Embedding is done by mirroring the accessibility tree of the platform view as a subtree of the
 * flutter accessibility tree.
 *
 * <p>This class relies on hidden system APIs to extract the accessibility information and does not
 * work starting Android P; If the reflection accessors are not available we fail silently by
 * embedding a null node, the app continues working but the accessibility information for the
 * platform view will not be embedded.
 *
 * <p>We use the term `flutterId` for virtual accessibility node IDs in the FlutterView tree, and
 * the term `originId` for the virtual accessibility node IDs in the platform view's tree.
 * Internally this class maintains a bidirectional mapping between `flutterId`s and the
 * corresponding platform view and `originId`.
 */
@Keep
class AccessibilityViewEmbedder {
  private static final String TAG = "AccessibilityBridge";

  private final ReflectionAccessors reflectionAccessors;

  // The view to which the platform view is embedded, this is typically FlutterView.
  private final View rootAccessibilityView;

  // Maps a flutterId to the corresponding platform view and originId.
  private final SparseArray<ViewAndId> flutterIdToOrigin;

  // Maps a platform view and originId to a corresponding flutterID.
  private final Map<ViewAndId, Integer> originToFlutterId;

  // Maps an embedded view to it's screen bounds.
  // This is used to translate the coordinates of the accessibility node subtree to the main
  // display's coordinate
  // system.
  private final Map<View, Rect> embeddedViewToDisplayBounds;

  private int nextFlutterId;

  AccessibilityViewEmbedder(@NonNull View rootAccessibiiltyView, int firstVirtualNodeId) {
    reflectionAccessors = new ReflectionAccessors();
    flutterIdToOrigin = new SparseArray<>();
    this.rootAccessibilityView = rootAccessibiiltyView;
    nextFlutterId = firstVirtualNodeId;
    originToFlutterId = new HashMap<>();
    embeddedViewToDisplayBounds = new HashMap<>();
  }

  /**
   * Returns the root accessibility node for an embedded platform view.
   *
   * @param flutterId the virtual accessibility ID for the node in flutter accessibility tree
   * @param displayBounds the display bounds for the node in screen coordinates
   */
  public AccessibilityNodeInfo getRootNode(
      @NonNull View embeddedView, int flutterId, @NonNull Rect displayBounds) {
    AccessibilityNodeInfo originNode = embeddedView.createAccessibilityNodeInfo();
    Long originPackedId = reflectionAccessors.getSourceNodeId(originNode);
    if (originPackedId == null) {
      return null;
    }
    embeddedViewToDisplayBounds.put(embeddedView, displayBounds);
    int originId = ReflectionAccessors.getVirtualNodeId(originPackedId);
    cacheVirtualIdMappings(embeddedView, originId, flutterId);
    return convertToFlutterNode(originNode, flutterId, embeddedView);
  }

  /** Creates the accessibility node info for the node identified with `flutterId`. */
  @Nullable
  public AccessibilityNodeInfo createAccessibilityNodeInfo(int flutterId) {
    ViewAndId origin = flutterIdToOrigin.get(flutterId);
    if (origin == null) {
      return null;
    }
    if (!embeddedViewToDisplayBounds.containsKey(origin.view)) {
      // This might happen if the embedded view is sending accessibility event before the first
      // Flutter semantics
      // tree was sent to the accessibility bridge. In this case we don't return a node as we do not
      // know the
      // bounds yet.
      // https://github.com/flutter/flutter/issues/30068
      return null;
    }
    AccessibilityNodeProvider provider = origin.view.getAccessibilityNodeProvider();
    if (provider == null) {
      // The provider is null for views that don't have a virtual accessibility tree.
      // We currently only support embedding virtual hierarchies in the Flutter tree.
      // TODO(amirh): support embedding non virtual hierarchies.
      // https://github.com/flutter/flutter/issues/29717
      return null;
    }
    AccessibilityNodeInfo originNode =
        origin.view.getAccessibilityNodeProvider().createAccessibilityNodeInfo(origin.id);
    if (originNode == null) {
      return null;
    }
    return convertToFlutterNode(originNode, flutterId, origin.view);
  }

  /*
   * Creates an AccessibilityNodeInfo that can be attached to the Flutter accessibility tree and is equivalent to
   * originNode(which belongs to embeddedView). The virtual ID for the created node will be flutterId.
   */
  @NonNull
  private AccessibilityNodeInfo convertToFlutterNode(
      @NonNull AccessibilityNodeInfo originNode, int flutterId, @NonNull View embeddedView) {
    AccessibilityNodeInfo result = AccessibilityNodeInfo.obtain(rootAccessibilityView, flutterId);
    result.setPackageName(rootAccessibilityView.getContext().getPackageName());
    result.setSource(rootAccessibilityView, flutterId);
    result.setClassName(originNode.getClassName());

    Rect displayBounds = embeddedViewToDisplayBounds.get(embeddedView);

    copyAccessibilityFields(originNode, result);
    setFlutterNodesTranslateBounds(originNode, displayBounds, result);
    addChildrenToFlutterNode(originNode, embeddedView, result);
    setFlutterNodeParent(originNode, embeddedView, result);

    return result;
  }

  private void setFlutterNodeParent(
      @NonNull AccessibilityNodeInfo originNode,
      @NonNull View embeddedView,
      @NonNull AccessibilityNodeInfo result) {
    Long parentOriginPackedId = reflectionAccessors.getParentNodeId(originNode);
    if (parentOriginPackedId == null) {
      return;
    }
    int parentOriginId = ReflectionAccessors.getVirtualNodeId(parentOriginPackedId);
    Integer parentFlutterId = originToFlutterId.get(new ViewAndId(embeddedView, parentOriginId));
    if (parentFlutterId != null) {
      result.setParent(rootAccessibilityView, parentFlutterId);
    }
  }

  private void addChildrenToFlutterNode(
      @NonNull AccessibilityNodeInfo originNode,
      @NonNull View embeddedView,
      @NonNull AccessibilityNodeInfo resultNode) {
    for (int i = 0; i < originNode.getChildCount(); i++) {
      Long originPackedId = reflectionAccessors.getChildId(originNode, i);
      if (originPackedId == null) {
        continue;
      }
      int originId = ReflectionAccessors.getVirtualNodeId(originPackedId);
      ViewAndId origin = new ViewAndId(embeddedView, originId);
      int childFlutterId;
      if (originToFlutterId.containsKey(origin)) {
        childFlutterId = originToFlutterId.get(origin);
      } else {
        childFlutterId = nextFlutterId++;
        cacheVirtualIdMappings(embeddedView, originId, childFlutterId);
      }
      resultNode.addChild(rootAccessibilityView, childFlutterId);
    }
  }

  // Caches a bidirectional mapping of (embeddedView, originId)<-->flutterId.
  // Where originId is a virtual node ID in the embeddedView's tree, and flutterId is the ID
  // of the corresponding node in the Flutter virtual accessibility nodes tree.
  private void cacheVirtualIdMappings(@NonNull View embeddedView, int originId, int flutterId) {
    ViewAndId origin = new ViewAndId(embeddedView, originId);
    originToFlutterId.put(origin, flutterId);
    flutterIdToOrigin.put(flutterId, origin);
  }

  // Suppressing deprecation warning for AccessibilityNodeInfo#getBoundsinParent and
  // AccessibilityNodeInfo#getBoundsinParent as we are copying the platform view's
  // accessibility node and we should not lose any available bounds information.
  @SuppressWarnings("deprecation")
  private void setFlutterNodesTranslateBounds(
      @NonNull AccessibilityNodeInfo originNode,
      @NonNull Rect displayBounds,
      @NonNull AccessibilityNodeInfo resultNode) {
    Rect boundsInParent = new Rect();
    originNode.getBoundsInParent(boundsInParent);
    resultNode.setBoundsInParent(boundsInParent);

    Rect boundsInScreen = new Rect();
    originNode.getBoundsInScreen(boundsInScreen);
    boundsInScreen.offset(displayBounds.left, displayBounds.top);
    resultNode.setBoundsInScreen(boundsInScreen);
  }

  private void copyAccessibilityFields(
      @NonNull AccessibilityNodeInfo input, @NonNull AccessibilityNodeInfo output) {
    output.setAccessibilityFocused(input.isAccessibilityFocused());
    output.setCheckable(input.isCheckable());
    output.setChecked(input.isChecked());
    output.setContentDescription(input.getContentDescription());
    output.setEnabled(input.isEnabled());
    output.setClickable(input.isClickable());
    output.setFocusable(input.isFocusable());
    output.setFocused(input.isFocused());
    output.setLongClickable(input.isLongClickable());
    output.setMovementGranularities(input.getMovementGranularities());
    output.setPassword(input.isPassword());
    output.setScrollable(input.isScrollable());
    output.setSelected(input.isSelected());
    output.setText(input.getText());
    output.setVisibleToUser(input.isVisibleToUser());

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
      output.setEditable(input.isEditable());
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      output.setCanOpenPopup(input.canOpenPopup());
      output.setCollectionInfo(input.getCollectionInfo());
      output.setCollectionItemInfo(input.getCollectionItemInfo());
      output.setContentInvalid(input.isContentInvalid());
      output.setDismissable(input.isDismissable());
      output.setInputType(input.getInputType());
      output.setLiveRegion(input.getLiveRegion());
      output.setMultiLine(input.isMultiLine());
      output.setRangeInfo(input.getRangeInfo());
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      output.setError(input.getError());
      output.setMaxTextLength(input.getMaxTextLength());
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      output.setContextClickable(input.isContextClickable());
      // TODO(amirh): copy traversal before and after.
      // https://github.com/flutter/flutter/issues/29718
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      output.setDrawingOrder(input.getDrawingOrder());
      output.setImportantForAccessibility(input.isImportantForAccessibility());
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      output.setAvailableExtraData(input.getAvailableExtraData());
      output.setHintText(input.getHintText());
      output.setShowingHintText(input.isShowingHintText());
    }
  }

  /**
   * Delegates an AccessibilityNodeProvider#requestSendAccessibilityEvent from the
   * AccessibilityBridge to the embedded view.
   *
   * @return True if the event was sent.
   */
  public boolean requestSendAccessibilityEvent(
      @NonNull View embeddedView, @NonNull View eventOrigin, @NonNull AccessibilityEvent event) {
    AccessibilityEvent translatedEvent = AccessibilityEvent.obtain(event);
    Long originPackedId = reflectionAccessors.getRecordSourceNodeId(event);
    if (originPackedId == null) {
      return false;
    }
    int originVirtualId = ReflectionAccessors.getVirtualNodeId(originPackedId);
    Integer flutterId = originToFlutterId.get(new ViewAndId(embeddedView, originVirtualId));
    if (flutterId == null) {
      flutterId = nextFlutterId++;
      cacheVirtualIdMappings(embeddedView, originVirtualId, flutterId);
    }
    translatedEvent.setSource(rootAccessibilityView, flutterId);
    translatedEvent.setClassName(event.getClassName());
    translatedEvent.setPackageName(event.getPackageName());

    for (int i = 0; i < translatedEvent.getRecordCount(); i++) {
      AccessibilityRecord record = translatedEvent.getRecord(i);
      Long recordOriginPackedId = reflectionAccessors.getRecordSourceNodeId(record);
      if (recordOriginPackedId == null) {
        return false;
      }
      int recordOriginVirtualID = ReflectionAccessors.getVirtualNodeId(recordOriginPackedId);
      ViewAndId originViewAndId = new ViewAndId(embeddedView, recordOriginVirtualID);
      if (!originToFlutterId.containsKey(originViewAndId)) {
        return false;
      }
      int recordFlutterId = originToFlutterId.get(originViewAndId);
      record.setSource(rootAccessibilityView, recordFlutterId);
    }

    return rootAccessibilityView
        .getParent()
        .requestSendAccessibilityEvent(eventOrigin, translatedEvent);
  }

  /**
   * Delegates an @{link AccessibilityNodeProvider#performAction} from the AccessibilityBridge to
   * the embedded view's accessibility node provider.
   *
   * @return True if the action was performed.
   */
  public boolean performAction(int flutterId, int accessibilityAction, @Nullable Bundle arguments) {
    ViewAndId origin = flutterIdToOrigin.get(flutterId);
    if (origin == null) {
      return false;
    }
    View embeddedView = origin.view;
    AccessibilityNodeProvider provider = embeddedView.getAccessibilityNodeProvider();
    if (provider == null) {
      return false;
    }
    return provider.performAction(origin.id, accessibilityAction, arguments);
  }

  /**
   * Returns a flutterID for an accessibility record, or null if no mapping exists.
   *
   * @param embeddedView the embedded view that the record is associated with.
   */
  @Nullable
  public Integer getRecordFlutterId(
      @NonNull View embeddedView, @NonNull AccessibilityRecord record) {
    Long originPackedId = reflectionAccessors.getRecordSourceNodeId(record);
    if (originPackedId == null) {
      return null;
    }
    int originVirtualId = ReflectionAccessors.getVirtualNodeId(originPackedId);
    return originToFlutterId.get(new ViewAndId(embeddedView, originVirtualId));
  }

  /**
   * Delegates a View#onHoverEvent event from the AccessibilityBridge to an embedded view.
   *
   * <p>The pointer coordinates are translated to the embedded view's coordinate system.
   */
  public boolean onAccessibilityHoverEvent(int rootFlutterId, @NonNull MotionEvent event) {
    ViewAndId origin = flutterIdToOrigin.get(rootFlutterId);
    if (origin == null) {
      return false;
    }
    Rect displayBounds = embeddedViewToDisplayBounds.get(origin.view);
    int pointerCount = event.getPointerCount();
    MotionEvent.PointerProperties[] pointerProperties =
        new MotionEvent.PointerProperties[pointerCount];
    MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[pointerCount];
    for (int i = 0; i < event.getPointerCount(); i++) {
      pointerProperties[i] = new MotionEvent.PointerProperties();
      event.getPointerProperties(i, pointerProperties[i]);

      MotionEvent.PointerCoords originCoords = new MotionEvent.PointerCoords();
      event.getPointerCoords(i, originCoords);

      pointerCoords[i] = new MotionEvent.PointerCoords(originCoords);
      pointerCoords[i].x -= displayBounds.left;
      pointerCoords[i].y -= displayBounds.top;
    }
    MotionEvent translatedEvent =
        MotionEvent.obtain(
            event.getDownTime(),
            event.getEventTime(),
            event.getAction(),
            event.getPointerCount(),
            pointerProperties,
            pointerCoords,
            event.getMetaState(),
            event.getButtonState(),
            event.getXPrecision(),
            event.getYPrecision(),
            event.getDeviceId(),
            event.getEdgeFlags(),
            event.getSource(),
            event.getFlags());
    return origin.view.dispatchGenericMotionEvent(translatedEvent);
  }

  /**
   * Returns the View that contains the accessibility node identified by the provided flutterId or
   * null if it doesn't belong to a view.
   */
  public View platformViewOfNode(int flutterId) {
    ViewAndId viewAndId = flutterIdToOrigin.get(flutterId);
    if (viewAndId == null) {
      return null;
    }
    return viewAndId.view;
  }

  private static class ViewAndId {
    final View view;
    final int id;

    private ViewAndId(View view, int id) {
      this.view = view;
      this.id = id;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof ViewAndId)) return false;
      ViewAndId viewAndId = (ViewAndId) o;
      return id == viewAndId.id && view.equals(viewAndId.view);
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + view.hashCode();
      result = prime * result + id;
      return result;
    }
  }

  private static class ReflectionAccessors {
    private @Nullable final Method getSourceNodeId;
    private @Nullable final Method getParentNodeId;
    private @Nullable final Method getRecordSourceNodeId;
    private @Nullable final Method getChildId;
    private @Nullable final Field childNodeIdsField;
    private @Nullable final Method longArrayGetIndex;

    @SuppressLint("PrivateApi")
    private ReflectionAccessors() {
      Method getSourceNodeId = null;
      Method getParentNodeId = null;
      Method getRecordSourceNodeId = null;
      Method getChildId = null;
      Field childNodeIdsField = null;
      Method longArrayGetIndex = null;
      try {
        getSourceNodeId = AccessibilityNodeInfo.class.getMethod("getSourceNodeId");
      } catch (NoSuchMethodException e) {
        Log.w(TAG, "can't invoke AccessibilityNodeInfo#getSourceNodeId with reflection");
      }
      try {
        getRecordSourceNodeId = AccessibilityRecord.class.getMethod("getSourceNodeId");
      } catch (NoSuchMethodException e) {
        Log.w(TAG, "can't invoke AccessibiiltyRecord#getSourceNodeId with reflection");
      }
      // Reflection access is not allowed starting Android P on these methods.
      if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O) {
        try {
          getParentNodeId = AccessibilityNodeInfo.class.getMethod("getParentNodeId");
        } catch (NoSuchMethodException e) {
          Log.w(TAG, "can't invoke getParentNodeId with reflection");
        }
        // Starting P we extract the child id from the mChildNodeIds field (see getChildId
        // below).
        try {
          getChildId = AccessibilityNodeInfo.class.getMethod("getChildId", int.class);
        } catch (NoSuchMethodException e) {
          Log.w(TAG, "can't invoke getChildId with reflection");
        }
      } else {
        try {
          childNodeIdsField = AccessibilityNodeInfo.class.getDeclaredField("mChildNodeIds");
          childNodeIdsField.setAccessible(true);
          // The private member is a private utility class to Android. We need to use
          // reflection to actually handle the data too.
          longArrayGetIndex = Class.forName("android.util.LongArray").getMethod("get", int.class);
        } catch (NoSuchFieldException
            | ClassNotFoundException
            | NoSuchMethodException
            | NullPointerException e) {
          Log.w(TAG, "can't access childNodeIdsField with reflection");
          childNodeIdsField = null;
        }
      }
      this.getSourceNodeId = getSourceNodeId;
      this.getParentNodeId = getParentNodeId;
      this.getRecordSourceNodeId = getRecordSourceNodeId;
      this.getChildId = getChildId;
      this.childNodeIdsField = childNodeIdsField;
      this.longArrayGetIndex = longArrayGetIndex;
    }

    /** Returns virtual node ID given packed node ID used internally in accessibility API. */
    private static int getVirtualNodeId(long nodeId) {
      return (int) (nodeId >> 32);
    }

    @Nullable
    private Long getSourceNodeId(@NonNull AccessibilityNodeInfo node) {
      if (getSourceNodeId == null) {
        return null;
      }
      try {
        return (Long) getSourceNodeId.invoke(node);
      } catch (IllegalAccessException e) {
        Log.w(TAG, "Failed to access getSourceNodeId method.", e);
      } catch (InvocationTargetException e) {
        Log.w(TAG, "The getSourceNodeId method threw an exception when invoked.", e);
      }
      return null;
    }

    @Nullable
    private Long getChildId(@NonNull AccessibilityNodeInfo node, int child) {
      if (getChildId == null && (childNodeIdsField == null || longArrayGetIndex == null)) {
        return null;
      }
      if (getChildId != null) {
        try {
          return (Long) getChildId.invoke(node, child);
          // Using identical separate catch blocks to comply with the following lint:
          // Error: Multi-catch with these reflection exceptions requires API level 19
          // (current min is 16) because they get compiled to the common but new super
          // type ReflectiveOperationException. As a workaround either create individual
          // catch statements, or catch Exception. [NewApi]
        } catch (IllegalAccessException e) {
          Log.w(TAG, "Failed to access getChildId method.", e);
        } catch (InvocationTargetException e) {
          Log.w(TAG, "The getChildId method threw an exception when invoked.", e);
        }
      } else {
        try {
          return (long) longArrayGetIndex.invoke(childNodeIdsField.get(node), child);
          // Using identical separate catch blocks to comply with the following lint:
          // Error: Multi-catch with these reflection exceptions requires API level 19
          // (current min is 16) because they get compiled to the common but new super
          // type ReflectiveOperationException. As a workaround either create individual
          // catch statements, or catch Exception. [NewApi]
        } catch (IllegalAccessException e) {
          Log.w(TAG, "Failed to access longArrayGetIndex method or the childNodeId field.", e);
        } catch (InvocationTargetException | ArrayIndexOutOfBoundsException e) {
          Log.w(TAG, "The longArrayGetIndex method threw an exception when invoked.", e);
        }
      }
      return null;
    }

    @Nullable
    private Long getParentNodeId(@NonNull AccessibilityNodeInfo node) {
      if (getParentNodeId != null) {
        try {
          return (long) getParentNodeId.invoke(node);
          // Using identical separate catch blocks to comply with the following lint:
          // Error: Multi-catch with these reflection exceptions requires API level 19
          // (current min is 16) because they get compiled to the common but new super
          // type ReflectiveOperationException. As a workaround either create individual
          // catch statements, or catch Exception. [NewApi]
        } catch (IllegalAccessException e) {
          Log.w(TAG, "Failed to access getParentNodeId method.", e);
        } catch (InvocationTargetException e) {
          Log.w(TAG, "The getParentNodeId method threw an exception when invoked.", e);
        }
      }

      // Fall back on reading the ID from a serialized data if we absolutely have to.
      return yoinkParentIdFromParcel(node);
    }

    // If this looks like it's failing, that's because it probably is. This method is relying on
    // the implementation details of `AccessibilityNodeInfo#writeToParcel` in order to find the
    // particular bit in the opaque parcel that represents mParentNodeId. If the implementation
    // details change from our assumptions in this method, this will silently break.
    @Nullable
    private static Long yoinkParentIdFromParcel(AccessibilityNodeInfo node) {
      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        Log.w(TAG, "Unexpected Android version. Unable to find the parent ID.");
        return null;
      }

      // We're creating a copy here because writing a node to a parcel recycles it. Objects
      // are passed by reference in Java. So even though this method doesn't seem to use the
      // node again, it's really used in other methods that would throw exceptions if we
      // recycle it here.
      AccessibilityNodeInfo copy = AccessibilityNodeInfo.obtain(node);
      final Parcel parcel = Parcel.obtain();
      parcel.setDataPosition(0);
      copy.writeToParcel(parcel, /*flags=*/ 0);
      Long parentNodeId = null;
      // Match the internal logic that sets where mParentId actually ends up finally living.
      // This logic should match
      // https://android.googlesource.com/platform/frameworks/base/+/0b5ca24a4/core/java/android/view/accessibility/AccessibilityNodeInfo.java#3524.
      parcel.setDataPosition(0);
      long nonDefaultFields = parcel.readLong();
      int fieldIndex = 0;
      if (isBitSet(nonDefaultFields, fieldIndex++)) {
        parcel.readInt(); // mIsSealed
      }
      if (isBitSet(nonDefaultFields, fieldIndex++)) {
        parcel.readLong(); // mSourceNodeId
      }
      if (isBitSet(nonDefaultFields, fieldIndex++)) {
        parcel.readInt(); // mWindowId
      }
      if (isBitSet(nonDefaultFields, fieldIndex++)) {
        parentNodeId = parcel.readLong();
      }

      parcel.recycle();
      return parentNodeId;
    }

    private static boolean isBitSet(long flags, int bitIndex) {
      return (flags & (1L << bitIndex)) != 0;
    }

    @Nullable
    private Long getRecordSourceNodeId(@NonNull AccessibilityRecord node) {
      if (getRecordSourceNodeId == null) {
        return null;
      }
      try {
        return (Long) getRecordSourceNodeId.invoke(node);
      } catch (IllegalAccessException e) {
        Log.w(TAG, "Failed to access the getRecordSourceNodeId method.", e);
      } catch (InvocationTargetException e) {
        Log.w(TAG, "The getRecordSourceNodeId method threw an exception when invoked.", e);
      }
      return null;
    }
  }
}
