(client) Return Tree instead of Path

Summary:
- Add return parameter to `createTouch` method: stack of node. This reference will be used to retrieve the final tree structure to be sent back to desktop app.
- `Touch` now keeps every step in component tree (I have concerned for app performance here)
- Edit test to reflect changes

Note:
- `path` will also be returned to keep backward compatibility with older server (desktop) side

Reviewed By: adityasharat

Differential Revision: D21040429

fbshipit-source-id: 6c2b9792378bf08b19fbbda1d2381df8c357170c
This commit is contained in:
Chaiwat Ekkaewnumchai
2020-05-07 03:37:49 -07:00
committed by Facebook GitHub Bot
parent f275ee00c5
commit d593409ec4
2 changed files with 109 additions and 44 deletions

View File

@@ -9,6 +9,7 @@ package com.facebook.flipper.plugins.inspector;
import android.app.Application;
import android.content.Context;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -25,7 +26,9 @@ import com.facebook.flipper.plugins.common.MainThreadFlipperReceiver;
import com.facebook.flipper.plugins.inspector.descriptors.ApplicationDescriptor;
import com.facebook.flipper.plugins.inspector.descriptors.utils.AccessibilityUtil;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import javax.annotation.Nullable;
public class InspectorFlipperPlugin implements FlipperPlugin {
@@ -473,45 +476,60 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
}
}
private Touch createTouch(final int touchX, final int touchY, final boolean ax) throws Exception {
final FlipperArray.Builder path = new FlipperArray.Builder();
path.put(trackObject(mApplication));
private Pair<Touch, Stack<FlipperObject.Builder>> createTouch(
final int touchX, final int touchY, final boolean ax) throws Exception {
final Stack<FlipperObject.Builder> objStack = new Stack<>();
objStack.push(new FlipperObject.Builder());
return new Touch() {
final Stack<Object> nodes = new Stack<>();
nodes.push(mApplication);
final Touch touch =
new Touch() {
int x = touchX;
int y = touchY;
Object node = mApplication;
@Override
public void finish() {
mConnection.send(
ax ? "selectAX" : "select", new FlipperObject.Builder().put("path", path).build());
}
public void finish() {}
@Override
public void continueWithOffset(final int childIndex, final int offsetX, final int offsetY) {
public void continueWithOffset(
final int childIndex, final int offsetX, final int offsetY) {
final Touch touch = this;
new ErrorReportingRunnable(mConnection) {
@Override
protected void runOrThrow() throws Exception {
Object nextNode;
final Object currNode = nodes.peek();
x -= offsetX;
y -= offsetY;
if (ax) {
node = assertNotNull(descriptorForObject(node).getAXChildAt(node, childIndex));
nextNode =
assertNotNull(
descriptorForObject(currNode).getAXChildAt(currNode, childIndex));
} else {
node = assertNotNull(descriptorForObject(node).getChildAt(node, childIndex));
nextNode =
assertNotNull(descriptorForObject(currNode).getChildAt(currNode, childIndex));
}
path.put(trackObject(node));
final NodeDescriptor<Object> descriptor = descriptorForObject(node);
nodes.push(nextNode);
final String nodeID = trackObject(nextNode);
final NodeDescriptor<Object> descriptor = descriptorForObject(nextNode);
objStack.push(new FlipperObject.Builder());
if (ax) {
descriptor.axHitTest(node, touch);
descriptor.axHitTest(nextNode, touch);
} else {
descriptor.hitTest(node, touch);
descriptor.hitTest(nextNode, touch);
}
x += offsetX;
y += offsetY;
nodes.pop();
final FlipperObject objTree = objStack.pop().build();
objStack.peek().put(nodeID, objTree);
}
}.run();
}
@@ -521,12 +539,47 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
return x >= l && x <= r && y >= t && y <= b;
}
};
return new Pair<>(touch, objStack);
}
// This is mainly for backward compatibility
private FlipperArray getPathFromTree(FlipperObject tree) {
final FlipperArray.Builder pathBuilder = new FlipperArray.Builder();
FlipperObject subtree = tree;
Iterator<String> it = subtree.keys();
while (it.hasNext()) {
final String key = it.next();
pathBuilder.put(key);
subtree = subtree.getObject(key);
it = subtree.keys();
}
return pathBuilder.build();
}
void hitTest(final int touchX, final int touchY) throws Exception {
final NodeDescriptor<Object> descriptor = descriptorForObject(mApplication);
descriptor.hitTest(mApplication, createTouch(touchX, touchY, false));
descriptor.axHitTest(mApplication, createTouch(touchX, touchY, true));
FlipperObject treeObj;
Pair<Touch, Stack<FlipperObject.Builder>> pair = createTouch(touchX, touchY, false);
descriptor.hitTest(mApplication, pair.first);
treeObj = new FlipperObject.Builder().put(trackObject(mApplication), pair.second.pop()).build();
mConnection.send(
"select",
new FlipperObject.Builder()
.put("tree", treeObj)
.put("path", getPathFromTree(treeObj))
.build());
pair = createTouch(touchX, touchY, true);
descriptor.axHitTest(mApplication, pair.first);
treeObj = new FlipperObject.Builder().put(trackObject(mApplication), pair.second.pop()).build();
mConnection.send(
"selectAX",
new FlipperObject.Builder()
.put("tree", treeObj)
.put("path", getPathFromTree(treeObj))
.build());
}
private void setHighlighted(

View File

@@ -269,9 +269,20 @@ public class InspectorFlipperPluginTest {
connection.sent.get("select"),
hasItem(
new FlipperObject.Builder()
.put(
"tree",
new FlipperObject.Builder()
.put(
"com.facebook.flipper",
new FlipperObject.Builder()
.put(
"test",
new FlipperObject.Builder()
.put("3", new FlipperObject.Builder())
.put("1", new FlipperObject.Builder()))))
.put(
"path",
new FlipperArray.Builder().put("com.facebook.flipper").put("test").put("3"))
new FlipperArray.Builder().put("com.facebook.flipper").put("test").put("1"))
.build()));
}
@@ -391,16 +402,17 @@ public class InspectorFlipperPluginTest {
@Override
public void hitTest(TestNode node, Touch touch) {
boolean finish = true;
for (int i = node.children.size() - 1; i >= 0; i--) {
final TestNode child = node.children.get(i);
final Rect bounds = child.bounds;
if (touch.containedIn(bounds.left, bounds.top, bounds.right, bounds.bottom)) {
touch.continueWithOffset(i, bounds.left, bounds.top);
return;
finish = false;
}
}
touch.finish();
if (finish) touch.finish();
}
@Override