Home | History | Annotate | Download | only in tree
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.uiautomator.tree;
     18 
     19 import java.util.ArrayList;
     20 import java.util.Collections;
     21 import java.util.List;
     22 
     23 public class BasicTreeNode {
     24 
     25     private static final BasicTreeNode[] CHILDREN_TEMPLATE = new BasicTreeNode[] {};
     26 
     27     protected BasicTreeNode mParent;
     28 
     29     protected final List<BasicTreeNode> mChildren = new ArrayList<BasicTreeNode>();
     30 
     31     public int x, y, width, height;
     32 
     33     // whether the boundary fields are applicable for the node or not
     34     // RootWindowNode has no bounds, but UiNodes should
     35     protected boolean mHasBounds = false;
     36 
     37     public void addChild(BasicTreeNode child) {
     38         if (child == null) {
     39             throw new NullPointerException("Cannot add null child");
     40         }
     41         if (mChildren.contains(child)) {
     42             throw new IllegalArgumentException("node already a child");
     43         }
     44         mChildren.add(child);
     45         child.mParent = this;
     46     }
     47 
     48     public List<BasicTreeNode> getChildrenList() {
     49         return Collections.unmodifiableList(mChildren);
     50     }
     51 
     52     public BasicTreeNode[] getChildren() {
     53         return mChildren.toArray(CHILDREN_TEMPLATE);
     54     }
     55 
     56     public BasicTreeNode getParent() {
     57         return mParent;
     58     }
     59 
     60     public boolean hasChild() {
     61         return mChildren.size() != 0;
     62     }
     63 
     64     public int getChildCount() {
     65         return mChildren.size();
     66     }
     67 
     68     public void clearAllChildren() {
     69         for (BasicTreeNode child : mChildren) {
     70             child.clearAllChildren();
     71         }
     72         mChildren.clear();
     73     }
     74 
     75     /**
     76      *
     77      * Find nodes in the tree containing the coordinate
     78      *
     79      * The found node should have bounds covering the coordinate, and none of its children's
     80      * bounds covers it. Depending on the layout, some app may have multiple nodes matching it,
     81      * the caller must provide a {@link IFindNodeListener} to receive all found nodes
     82      *
     83      * @param px
     84      * @param py
     85      * @return
     86      */
     87     public boolean findLeafMostNodesAtPoint(int px, int py, IFindNodeListener listener) {
     88         boolean foundInChild = false;
     89         for (BasicTreeNode node : mChildren) {
     90             foundInChild |= node.findLeafMostNodesAtPoint(px, py, listener);
     91         }
     92         // checked all children, if at least one child covers the point, return directly
     93         if (foundInChild) return true;
     94         // check self if the node has no children, or no child nodes covers the point
     95         if (mHasBounds) {
     96             if (x <= px && px <= x + width && y <= py && py <= y + height) {
     97                 listener.onFoundNode(this);
     98                 return true;
     99             } else {
    100                 return false;
    101             }
    102         } else {
    103             return false;
    104         }
    105     }
    106 
    107     public Object[] getAttributesArray () {
    108         return null;
    109     };
    110 
    111     public static interface IFindNodeListener {
    112         void onFoundNode(BasicTreeNode node);
    113     }
    114 }
    115