Run google-java-format over Android code

Summary: Prettier code

Reviewed By: sjkirby

Differential Revision: D10182489

fbshipit-source-id: 6a1ba4d586f49edad00f839ccd1b94857ccfccaa
This commit is contained in:
Hilal Alsibai
2018-10-06 11:31:45 -07:00
committed by Facebook Github Bot
parent 34c55262ce
commit 52e43e6ab8
50 changed files with 485 additions and 399 deletions

View File

@@ -60,7 +60,9 @@ public final class AndroidFlipperClient {
for (String permission : REQUIRED_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_DENIED) {
Log.e("Flipper", String.format("App needs permission \"%s\" to work with Flipper.", permission));
Log.e(
"Flipper",
String.format("App needs permission \"%s\" to work with Flipper.", permission));
}
}
}

View File

@@ -7,10 +7,10 @@
*/
package com.facebook.flipper.android;
import com.facebook.flipper.BuildConfig;
import com.facebook.jni.HybridClassBase;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
import com.facebook.flipper.BuildConfig;
@DoNotStrip
class EventBase extends HybridClassBase {

View File

@@ -7,14 +7,14 @@
*/
package com.facebook.flipper.android;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
import com.facebook.flipper.BuildConfig;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.core.FlipperPlugin;
import com.facebook.flipper.core.FlipperStateUpdateListener;
import com.facebook.flipper.core.StateSummary;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
@DoNotStrip
class FlipperClientImpl implements FlipperClient {

View File

@@ -7,14 +7,14 @@
*/
package com.facebook.flipper.android;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
import com.facebook.flipper.BuildConfig;
import com.facebook.flipper.core.FlipperArray;
import com.facebook.flipper.core.FlipperConnection;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.core.FlipperReceiver;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
@DoNotStrip
class FlipperConnectionImpl implements FlipperConnection {

View File

@@ -7,13 +7,13 @@
*/
package com.facebook.flipper.android;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
import com.facebook.flipper.BuildConfig;
import com.facebook.flipper.core.FlipperArray;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.core.FlipperResponder;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
@DoNotStrip
class FlipperResponderImpl implements FlipperResponder {

View File

@@ -3,16 +3,15 @@ package com.facebook.flipper.android.diagnostics;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.core.FlipperStateUpdateListener;
import com.facebook.flipper.core.StateSummary;
import com.facebook.flipper.core.StateSummary.StateElement;
import android.widget.LinearLayout;
import android.view.View;
import android.widget.TextView;
import android.widget.ScrollView;
public class FlipperDiagnosticActivity extends Activity implements FlipperStateUpdateListener {
@@ -51,32 +50,40 @@ public class FlipperDiagnosticActivity extends Activity implements FlipperStateU
scrollView.fullScroll(View.FOCUS_DOWN);
}
@Override
@Override
public void onUpdate() {
final String state = AndroidFlipperClient.getInstance(this).getState();
final String summary = getSummary();
runOnUiThread(new Runnable() {
@Override
public void run() {
summaryView.setText(summary);
logView.setText(state);
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
runOnUiThread(
new Runnable() {
@Override
public void run() {
summaryView.setText(summary);
logView.setText(state);
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
private String getSummary() {
final Context context = this;
final StateSummary summary = AndroidFlipperClient.getInstance(context).getStateSummary();
final StringBuilder stateText = new StringBuilder();
for (StateElement e: summary.mList) {
for (StateElement e : summary.mList) {
final String status;
switch(e.getState()) {
case IN_PROGRESS: status = ""; break;
case SUCCESS: status = ""; break;
case FAILED: status = ""; break;
default: status = "";
switch (e.getState()) {
case IN_PROGRESS:
status = "";
break;
case SUCCESS:
status = "";
break;
case FAILED:
status = "";
break;
default:
status = "";
}
stateText.append(status).append(e.getName()).append("\n");
}

View File

@@ -8,9 +8,9 @@
package com.facebook.flipper.core;
/**
* A connection between a FlipperPlugin and the desktop Flipper application. Register request handlers
* to respond to calls made by the desktop application or directly send messages to the desktop
* application.
* A connection between a FlipperPlugin and the desktop Flipper application. Register request
* handlers to respond to calls made by the desktop application or directly send messages to the
* desktop application.
*/
public interface FlipperConnection {

View File

@@ -9,10 +9,10 @@ package com.facebook.flipper.core;
/**
* A FlipperPlugin is an object which exposes an API to the Desktop Flipper application. When a
* connection is established the plugin is given a FlipperConnection on which it can register request
* handlers and send messages. When the FlipperConnection is invalid onDisconnect is called. onConnect
* may be called again on the same plugin object if Flipper re-connects, this will provide a new
* FlipperConnection, do not attempt to re-use the previous connection.
* connection is established the plugin is given a FlipperConnection on which it can register
* request handlers and send messages. When the FlipperConnection is invalid onDisconnect is called.
* onConnect may be called again on the same plugin object if Flipper re-connects, this will provide
* a new FlipperConnection, do not attempt to re-use the previous connection.
*/
public interface FlipperPlugin {

View File

@@ -8,9 +8,9 @@
package com.facebook.flipper.core;
/**
* FlipperResponder is used to asyncronously response to a messaged recieved from the Flipper desktop
* app. The Flipper Responder will automatically wrap the response in an approriate object depending
* on if it is an error or not.
* FlipperResponder is used to asyncronously response to a messaged recieved from the Flipper
* desktop app. The Flipper Responder will automatically wrap the response in an approriate object
* depending on if it is an error or not.
*/
public interface FlipperResponder {

View File

@@ -3,10 +3,10 @@ package com.facebook.flipper.core;
public interface FlipperStateUpdateListener {
/**
* Called when the state of the Flipper client changes.
* Typical implementations will subscribe by calling {@link com.facebook.flipper.core.FlipperClient#subscribeForUpdates()}, to start receiving update events.
* Calling {@link com.facebook.flipper.core.FlipperClient#getState()} will retrieve the updated state.
* Called when the state of the Flipper client changes. Typical implementations will subscribe by
* calling {@link com.facebook.flipper.core.FlipperClient#subscribeForUpdates()}, to start
* receiving update events. Calling {@link com.facebook.flipper.core.FlipperClient#getState()}
* will retrieve the updated state.
*/
void onUpdate();
}

View File

@@ -1,13 +1,15 @@
package com.facebook.flipper.core;
public class StateElement {
private final String mName;
private final String mState;
public StateElement(String name, String state) {
mName = name;
mState = state;
}
public String getName() {
return mName;
}
private final String mName;
private final String mState;
public StateElement(String name, String state) {
mName = name;
mState = state;
}
public String getName() {
return mName;
}
}

View File

@@ -1,24 +1,30 @@
package com.facebook.flipper.core;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
public class StateSummary {
public enum State {
IN_PROGRESS, SUCCESS, FAILED, UNKNOWN;
IN_PROGRESS,
SUCCESS,
FAILED,
UNKNOWN;
}
public static class StateElement {
private final String mName;
private final State mState;
public StateElement(String name, State state) {
mName = name;
mState = state;
}
public String getName() {
return mName;
}
public State getState() {
return mState;
}

View File

@@ -15,8 +15,8 @@ import javax.annotation.Nullable;
/**
* Flipper plugin that keeps events in a buffer until a connection is available.
*
* <p>In order to send data to the {@link FlipperConnection}, use {@link #send(String, FlipperObject)}
* instead of {@link FlipperConnection#send(String, FlipperObject)}.
* <p>In order to send data to the {@link FlipperConnection}, use {@link #send(String,
* FlipperObject)} instead of {@link FlipperConnection#send(String, FlipperObject)}.
*/
public abstract class BufferingFlipperPlugin implements FlipperPlugin {

View File

@@ -30,6 +30,5 @@ public class ConsoleFlipperPlugin implements FlipperPlugin {
ConsoleCommandReceiver.listenForCommands(connection, mJavascriptEnvironment);
}
public void onDisconnect() throws Exception {
}
public void onDisconnect() throws Exception {}
}

View File

@@ -45,8 +45,7 @@ public class JavascriptEnvironment implements ScriptingEnvironment {
public void registerGlobalObject(String name, Object object) {
if (mBoundVariables.containsKey(name)) {
throw new IllegalStateException(
String.format(
"Variable %s is already reserved for %s", name, mBoundVariables.get(name)));
String.format("Variable %s is already reserved for %s", name, mBoundVariables.get(name)));
}
mBoundVariables.put(name, object);
}

View File

@@ -17,8 +17,8 @@ import org.json.JSONObject;
/**
* Convenience class for adding console execution to a Flipper Plugin. Calling {@link
* ConsoleCommandReceiver#listenForCommands(FlipperConnection, ScriptingEnvironment, ContextProvider)}
* will add the necessary listeners for responding to command execution calls.
* ConsoleCommandReceiver#listenForCommands(FlipperConnection, ScriptingEnvironment,
* ContextProvider)} will add the necessary listeners for responding to command execution calls.
*/
public class ConsoleCommandReceiver {

View File

@@ -12,7 +12,6 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;
import android.util.Log;
/**
* A singleton instance of a overlay drawable used for highlighting node bounds. See {@link
@@ -30,46 +29,44 @@ public class HighlightedOverlay {
* @param padding A {@link Rect} containing the padding values
* @param contentBounds The {@link Rect} bounds of the content, which includes padding
*/
public static void setHighlighted(
View targetView, Rect margin, Rect padding, Rect contentBounds, boolean isAlignmentMode) {
if (!VIEW_OVERLAY_SUPPORT) {
return;
}
if (!VIEW_OVERLAY_SUPPORT) {
return;
}
contentBounds.set(
contentBounds.left + padding.left,
contentBounds.top + padding.top,
contentBounds.right - padding.right,
contentBounds.bottom - padding.bottom);
contentBounds.set(
contentBounds.left + padding.left,
contentBounds.top + padding.top,
contentBounds.right - padding.right,
contentBounds.bottom - padding.bottom);
padding = enclose(padding, contentBounds);
margin = enclose(margin, padding);
padding = enclose(padding, contentBounds);
margin = enclose(margin, padding);
final float density = targetView.getContext().getResources().getDisplayMetrics().density;
final Drawable overlay = BoundsDrawable.getInstance(density, margin, padding, contentBounds);
final float density = targetView.getContext().getResources().getDisplayMetrics().density;
final Drawable overlay = BoundsDrawable.getInstance(density, margin, padding, contentBounds);
targetView.getOverlay().add(overlay);
targetView.getOverlay().add(overlay);
if(isAlignmentMode) {
int[] coords = new int[2];
targetView.getLocationOnScreen(coords);
Rect lineContentBounds =
new Rect(
coords[0] + contentBounds.left,
coords[1] + contentBounds.top,
coords[0] + contentBounds.right,
coords[1] + contentBounds.bottom);
if (isAlignmentMode) {
int[] coords = new int[2];
targetView.getLocationOnScreen(coords);
Rect lineContentBounds =
new Rect(
coords[0] + contentBounds.left,
coords[1] + contentBounds.top,
coords[0] + contentBounds.right,
coords[1] + contentBounds.bottom);
final Drawable lineOverlay = LinesDrawable.getInstance(density, margin, padding, lineContentBounds);
final Drawable lineOverlay =
LinesDrawable.getInstance(density, margin, padding, lineContentBounds);
targetView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
targetView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
targetView.getRootView().getOverlay().add(lineOverlay);
}
}
targetView.getRootView().getOverlay().add(lineOverlay);
}
}
public static void removeHighlight(View targetView) {
if (!VIEW_OVERLAY_SUPPORT) {

View File

@@ -10,11 +10,10 @@ package com.facebook.flipper.plugins.inspector;
import android.app.Application;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.view.accessibility.AccessibilityEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import com.facebook.flipper.core.ErrorReportingRunnable;
import com.facebook.flipper.core.FlipperArray;
import com.facebook.flipper.core.FlipperConnection;
@@ -29,10 +28,8 @@ import com.facebook.flipper.plugins.console.iface.NullScriptingEnvironment;
import com.facebook.flipper.plugins.console.iface.ScriptingEnvironment;
import com.facebook.flipper.plugins.inspector.descriptors.ApplicationDescriptor;
import com.facebook.flipper.plugins.inspector.descriptors.utils.AccessibilityUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import javax.annotation.Nullable;
public class InspectorFlipperPlugin implements FlipperPlugin {
@@ -145,7 +142,8 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
connection.receive("getAXRoot", mGetAXRoot);
connection.receive("getAXNodes", mGetAXNodes);
connection.receive("onRequestAXFocus", mOnRequestAXFocus);
connection.receive("shouldShowLithoAccessibilitySettings", mShouldShowLithoAccessibilitySettings);
connection.receive(
"shouldShowLithoAccessibilitySettings", mShouldShowLithoAccessibilitySettings);
if (mExtensionCommands != null) {
for (ExtensionCommand extensionCommand : mExtensionCommands) {
@@ -174,13 +172,16 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
}
final FlipperReceiver mShouldShowLithoAccessibilitySettings =
new MainThreadFlipperReceiver(mConnection) {
@Override
public void onReceiveOnMainThread(FlipperObject params, FlipperResponder responder)
throws Exception {
responder.success(new FlipperObject.Builder().put("showLithoAccessibilitySettings", mShowLithoAccessibilitySettings).build());
}
};
new MainThreadFlipperReceiver(mConnection) {
@Override
public void onReceiveOnMainThread(FlipperObject params, FlipperResponder responder)
throws Exception {
responder.success(
new FlipperObject.Builder()
.put("showLithoAccessibilitySettings", mShowLithoAccessibilitySettings)
.build());
}
};
final FlipperReceiver mGetRoot =
new MainThreadFlipperReceiver(mConnection) {
@@ -196,7 +197,8 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
@Override
public void onReceiveOnMainThread(FlipperObject params, FlipperResponder responder)
throws Exception {
// applicationWrapper is not used by accessibility, but is a common ancestor for multiple view roots
// applicationWrapper is not used by accessibility, but is a common ancestor for multiple
// view roots
responder.success(getAXNode(trackObject(mApplication)));
}
};
@@ -204,8 +206,8 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
final FlipperReceiver mGetNodes =
new MainThreadFlipperReceiver(mConnection) {
@Override
public void onReceiveOnMainThread(final FlipperObject params, final FlipperResponder responder)
throws Exception {
public void onReceiveOnMainThread(
final FlipperObject params, final FlipperResponder responder) throws Exception {
final FlipperArray ids = params.getArray("ids");
final FlipperArray.Builder result = new FlipperArray.Builder();
@@ -231,8 +233,8 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
final FlipperReceiver mGetAXNodes =
new MainThreadFlipperReceiver(mConnection) {
@Override
public void onReceiveOnMainThread(final FlipperObject params, final FlipperResponder responder)
throws Exception {
public void onReceiveOnMainThread(
final FlipperObject params, final FlipperResponder responder) throws Exception {
final FlipperArray ids = params.getArray("ids");
final FlipperArray.Builder result = new FlipperArray.Builder();
@@ -247,16 +249,17 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
// sent request for non-existent node, potentially in error
if (node == null) {
// some nodes may be null since we are searching through all current and previous known nodes
// some nodes may be null since we are searching through all current and previous
// known nodes
if (forAccessibilityEvent) {
continue;
}
responder.error(
new FlipperObject.Builder()
.put("message", "No accessibility node with given id")
.put("id", id)
.build());
new FlipperObject.Builder()
.put("message", "No accessibility node with given id")
.put("id", id)
.build());
return;
} else {
@@ -267,7 +270,7 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
result.put(node);
}
// normal getNodes call, put any nodes in result
// normal getNodes call, put any nodes in result
} else {
result.put(node);
}
@@ -278,20 +281,20 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
};
final FlipperReceiver mOnRequestAXFocus =
new MainThreadFlipperReceiver(mConnection) {
@Override
public void onReceiveOnMainThread(final FlipperObject params, final FlipperResponder responder)
throws Exception {
final String nodeId = params.getString("id");
new MainThreadFlipperReceiver(mConnection) {
@Override
public void onReceiveOnMainThread(
final FlipperObject params, final FlipperResponder responder) throws Exception {
final String nodeId = params.getString("id");
final Object obj = mObjectTracker.get(nodeId);
if (obj == null || !(obj instanceof View)) {
return;
}
final Object obj = mObjectTracker.get(nodeId);
if (obj == null || !(obj instanceof View)) {
return;
}
((View) obj).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
};
((View) obj).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
};
final FlipperReceiver mSetData =
new MainThreadFlipperReceiver(mConnection) {
@@ -320,7 +323,7 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
}
descriptor.setValue(obj, path, value);
responder.success(ax ? getAXNode(nodeId): null);
responder.success(ax ? getAXNode(nodeId) : null);
}
};
@@ -374,13 +377,16 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
};
final FlipperReceiver mIsSearchActive =
new MainThreadFlipperReceiver(mConnection) {
@Override
public void onReceiveOnMainThread(final FlipperObject params, FlipperResponder responder)
throws Exception {
responder.success(new FlipperObject.Builder().put("isSearchActive", ApplicationDescriptor.getSearchActive()).build());
}
};
new MainThreadFlipperReceiver(mConnection) {
@Override
public void onReceiveOnMainThread(final FlipperObject params, FlipperResponder responder)
throws Exception {
responder.success(
new FlipperObject.Builder()
.put("isSearchActive", ApplicationDescriptor.getSearchActive())
.build());
}
};
final FlipperReceiver mGetSearchResults =
new MainThreadFlipperReceiver(mConnection) {
@@ -390,7 +396,8 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
final String query = params.getString("query");
final boolean axEnabled = params.getBoolean("axEnabled");
final SearchResultNode matchTree = searchTree(query.toLowerCase(), mApplication, axEnabled);
final SearchResultNode matchTree =
searchTree(query.toLowerCase(), mApplication, axEnabled);
final FlipperObject results = matchTree == null ? null : matchTree.toFlipperObject();
final FlipperObject response =
new FlipperObject.Builder().put("results", results).put("query", query).build();
@@ -407,24 +414,35 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
@Override
public boolean onHoverEvent(MotionEvent event) {
// if in layout inspector and talkback is running, override the first click to locate the clicked view
if (mConnection != null && AccessibilityUtil.isTalkbackEnabled(getContext()) && event.getPointerCount() == 1) {
FlipperObject params = new FlipperObject.Builder()
// if in layout inspector and talkback is running, override the first click to locate the
// clicked view
if (mConnection != null
&& AccessibilityUtil.isTalkbackEnabled(getContext())
&& event.getPointerCount() == 1) {
FlipperObject params =
new FlipperObject.Builder()
.put("type", "usage")
.put("eventName", "accessibility:clickToInspectTalkbackRunning").build();
.put("eventName", "accessibility:clickToInspectTalkbackRunning")
.build();
mConnection.send("track", params);
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER: {
event.setAction(MotionEvent.ACTION_DOWN);
} break;
case MotionEvent.ACTION_HOVER_MOVE: {
event.setAction(MotionEvent.ACTION_MOVE);
} break;
case MotionEvent.ACTION_HOVER_EXIT: {
event.setAction(MotionEvent.ACTION_UP);
} break;
case MotionEvent.ACTION_HOVER_ENTER:
{
event.setAction(MotionEvent.ACTION_DOWN);
}
break;
case MotionEvent.ACTION_HOVER_MOVE:
{
event.setAction(MotionEvent.ACTION_MOVE);
}
break;
case MotionEvent.ACTION_HOVER_EXIT:
{
event.setAction(MotionEvent.ACTION_UP);
}
break;
}
return onTouchEvent(event);
}
@@ -459,15 +477,14 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
int y = touchY;
Object node = mApplication;
@Override
public void finish() {
mConnection.send(ax ? "selectAX" : "select", new FlipperObject.Builder().put("path", path).build());
mConnection.send(
ax ? "selectAX" : "select", new FlipperObject.Builder().put("path", path).build());
}
@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) {
@@ -507,7 +524,8 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
descriptor.axHitTest(mApplication, createTouch(touchX, touchY, true));
}
private void setHighlighted(final String id, final boolean highlighted, final boolean isAlignmentMode) throws Exception {
private void setHighlighted(
final String id, final boolean highlighted, final boolean isAlignmentMode) throws Exception {
final Object obj = mObjectTracker.get(id);
if (obj == null) {
return;
@@ -545,7 +563,8 @@ public class InspectorFlipperPlugin implements FlipperPlugin {
if (isMatch || childTrees != null) {
final String id = trackObject(obj);
FlipperObject node = getNode(id);
return new SearchResultNode(id, isMatch, node, childTrees, axEnabled && hasAXNode(node) ? getAXNode(id) : null);
return new SearchResultNode(
id, isMatch, node, childTrees, axEnabled && hasAXNode(node) ? getAXNode(id) : null);
}
return null;
}

View File

@@ -15,8 +15,8 @@ public class InspectorValue<T> implements FlipperValue {
/**
* Descrive the type of data this value contains. This will influence how values are parsed and
* displayed by the Flipper desktop app. For example colors will be parse as integers and displayed
* using hex values and be editable using a color picker.
* displayed by the Flipper desktop app. For example colors will be parse as integers and
* displayed using hex values and be editable using a color picker.
*
* <p>Do not extends this list of types without adding support for the type in the desktop
* Inspector.

View File

@@ -9,15 +9,12 @@
package com.facebook.flipper.plugins.inspector;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import javax.annotation.Nullable;
public class LinesDrawable extends Drawable {
@@ -67,7 +64,7 @@ public class LinesDrawable extends Drawable {
dashPaint.setColor(0xFF800000);
dashPaint.setStyle(Paint.Style.STROKE);
dashPaint.setStrokeWidth(3);
dashPaint.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0));
dashPaint.setPathEffect(new DashPathEffect(new float[] {10, 10}, 0));
canvas.drawLine(mContentBounds.right, 0, mContentBounds.right, 100000, dashPaint);
canvas.drawLine(mContentBounds.left, 0, mContentBounds.left, 100000, dashPaint);

View File

@@ -44,8 +44,9 @@ public abstract class NodeDescriptor<T> {
}
/**
* Invalidate a node. This tells Flipper that this node is no longer valid and its properties and/or
* children have changed. This will trigger Flipper to re-query this node getting any new data.
* Invalidate a node. This tells Flipper that this node is no longer valid and its properties
* and/or children have changed. This will trigger Flipper to re-query this node getting any new
* data.
*/
protected final void invalidate(final T node) {
if (mConnection != null) {
@@ -64,8 +65,9 @@ public abstract class NodeDescriptor<T> {
}
/**
* Invalidate a node in the ax tree. This tells Flipper that this node is no longer valid and its properties and/or
* children have changed. This will trigger Flipper to re-query this node getting any new data.
* Invalidate a node in the ax tree. This tells Flipper that this node is no longer valid and its
* properties and/or children have changed. This will trigger Flipper to re-query this node
* getting any new data.
*/
protected final void invalidateAX(final T node) {
if (mConnection != null) {
@@ -73,9 +75,9 @@ public abstract class NodeDescriptor<T> {
@Override
protected void runOrThrow() throws Exception {
FlipperArray array =
new FlipperArray.Builder()
.put(new FlipperObject.Builder().put("id", getId(node)).build())
.build();
new FlipperArray.Builder()
.put(new FlipperObject.Builder().put("id", getId(node)).build())
.build();
FlipperObject params = new FlipperObject.Builder().put("nodes", array).build();
mConnection.send("invalidateAX", params);
}
@@ -179,22 +181,22 @@ public abstract class NodeDescriptor<T> {
/**
* Perform hit testing on the given ax node. Either continue the search in an ax child with {@link
* Touch#continueWithOffset(int, int, int, boolean)} or finish the hit testing on this ax node with {@link
* Touch#finish()}
* Touch#continueWithOffset(int, int, int, boolean)} or finish the hit testing on this ax node
* with {@link Touch#finish()}
*/
public void axHitTest(T node, Touch touch) throws Exception {
touch.finish();
}
/**
* @return A string indicating how this element should be decorated. Check with the Flipper desktop
* app to see what values are supported.
* @return A string indicating how this element should be decorated. Check with the Flipper
* desktop app to see what values are supported.
*/
public abstract String getDecoration(T node) throws Exception;
/**
* @return A string indicating how this element should be decorated in the AX tree. Check with the Flipper desktop
* app to see what values are supported.
* @return A string indicating how this element should be decorated in the AX tree. Check with the
* Flipper desktop app to see what values are supported.
*/
public String getAXDecoration(T node) throws Exception {
return null;

View File

@@ -19,11 +19,14 @@ public class SearchResultNode {
private final boolean isMatch;
private final FlipperObject element;
private final FlipperObject axElement;
@Nullable
private final List<SearchResultNode> children;
@Nullable private final List<SearchResultNode> children;
SearchResultNode(
String id, boolean isMatch, FlipperObject element, List<SearchResultNode> children, FlipperObject axElement) {
String id,
boolean isMatch,
FlipperObject element,
List<SearchResultNode> children,
FlipperObject axElement) {
this.id = id;
this.isMatch = isMatch;
this.element = element;

View File

@@ -78,7 +78,8 @@ public class ActivityDescriptor extends NodeDescriptor<Activity> {
}
@Override
public void setHighlighted(Activity node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(Activity node, boolean selected, boolean isAlignmentMode)
throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Window.class);
descriptor.setHighlighted(node.getWindow(), selected, isAlignmentMode);
}

View File

@@ -19,7 +19,6 @@ import com.facebook.flipper.plugins.inspector.ApplicationWrapper;
import com.facebook.flipper.plugins.inspector.Named;
import com.facebook.flipper.plugins.inspector.NodeDescriptor;
import com.facebook.flipper.plugins.inspector.Touch;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -79,45 +78,46 @@ public class ApplicationDescriptor extends NodeDescriptor<ApplicationWrapper> {
if (view instanceof ViewGroup && !hasDelegateAlready) {
// add delegate to root to catch accessibility events so we can update focus in Flipper
view.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
if (mConnection != null) {
view.setAccessibilityDelegate(
new View.AccessibilityDelegate() {
@Override
public boolean onRequestSendAccessibilityEvent(
ViewGroup host, View child, AccessibilityEvent event) {
if (mConnection != null) {
// the touchOverlay will handle the event in this case
if (searchActive) {
return false;
// the touchOverlay will handle the event in this case
if (searchActive) {
return false;
}
// otherwise send the necessary focus event to the plugin
int eventType = event.getEventType();
if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
mConnection.send(
"axFocusEvent", new FlipperObject.Builder().put("isFocus", true).build());
} else if (eventType
== AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED) {
mConnection.send(
"axFocusEvent", new FlipperObject.Builder().put("isFocus", false).build());
} else if (eventType == AccessibilityEvent.TYPE_VIEW_CLICKED) {
mConnection.send(
"axFocusEvent",
new FlipperObject.Builder()
.put("isFocus", false)
.put("isClick", true)
.build());
}
}
return super.onRequestSendAccessibilityEvent(host, child, event);
}
// otherwise send the necessary focus event to the plugin
int eventType = event.getEventType();
if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
mConnection.send("axFocusEvent",
new FlipperObject.Builder()
.put("isFocus", true)
.build());
} else if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED) {
mConnection.send("axFocusEvent",
new FlipperObject.Builder()
.put("isFocus", false)
.build());
} else if (eventType == AccessibilityEvent.TYPE_VIEW_CLICKED) {
mConnection.send("axFocusEvent",
new FlipperObject.Builder()
.put("isFocus", false)
.put("isClick", true)
.build());
}
}
return super.onRequestSendAccessibilityEvent(host, child, event);
}
});
});
editedDelegates.add((ViewGroup) view);
} else if (hasDelegateAlready) {
FlipperObject params = new FlipperObject.Builder()
FlipperObject params =
new FlipperObject.Builder()
.put("type", "usage")
.put("eventName", "accessibility:hasDelegateAlready").build();
.put("eventName", "accessibility:hasDelegateAlready")
.build();
mConnection.send("track", params);
}
}
@@ -218,7 +218,8 @@ public class ApplicationDescriptor extends NodeDescriptor<ApplicationWrapper> {
}
@Override
public void setHighlighted(ApplicationWrapper node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(ApplicationWrapper node, boolean selected, boolean isAlignmentMode)
throws Exception {
final int childCount = getChildCount(node);
if (childCount > 0) {
final Object topChild = getChildAt(node, childCount - 1);
@@ -242,7 +243,7 @@ public class ApplicationDescriptor extends NodeDescriptor<ApplicationWrapper> {
}
@Override
public void hitTest(ApplicationWrapper node, Touch touch) throws Exception{
public void hitTest(ApplicationWrapper node, Touch touch) throws Exception {
runHitTest(node, touch, false);
}

View File

@@ -58,7 +58,8 @@ public class DialogDescriptor extends NodeDescriptor<Dialog> {
}
@Override
public void setHighlighted(Dialog node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(Dialog node, boolean selected, boolean isAlignmentMode)
throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Window.class);
descriptor.setHighlighted(node.getWindow(), selected, isAlignmentMode);
}

View File

@@ -71,7 +71,8 @@ public class DialogFragmentDescriptor extends NodeDescriptor<DialogFragment> {
}
@Override
public void setHighlighted(DialogFragment node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(DialogFragment node, boolean selected, boolean isAlignmentMode)
throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Dialog.class);
if (node.getDialog() != null) {
descriptor.setHighlighted(node.getDialog(), selected, isAlignmentMode);

View File

@@ -94,7 +94,8 @@ public class FragmentDescriptor extends NodeDescriptor<Fragment> {
}
@Override
public void setHighlighted(Fragment node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(Fragment node, boolean selected, boolean isAlignmentMode)
throws Exception {
if (node.getView() == null) {
return;
}

View File

@@ -71,7 +71,8 @@ public class SupportDialogFragmentDescriptor extends NodeDescriptor<DialogFragme
}
@Override
public void setHighlighted(DialogFragment node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(DialogFragment node, boolean selected, boolean isAlignmentMode)
throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Dialog.class);
if (node.getDialog() != null) {
descriptor.setHighlighted(node.getDialog(), selected, isAlignmentMode);

View File

@@ -84,7 +84,8 @@ public class SupportFragmentDescriptor extends NodeDescriptor<Fragment> {
}
@Override
public void setHighlighted(Fragment node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(Fragment node, boolean selected, boolean isAlignmentMode)
throws Exception {
if (node.getView() == null) {
return;
}

View File

@@ -138,7 +138,8 @@ public class TextViewDescriptor extends NodeDescriptor<TextView> {
}
@Override
public void setHighlighted(TextView node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(TextView node, boolean selected, boolean isAlignmentMode)
throws Exception {
final NodeDescriptor descriptor = descriptorForClass(View.class);
descriptor.setHighlighted(node, selected, isAlignmentMode);
}

View File

@@ -99,7 +99,6 @@ public class ViewDescriptor extends NodeDescriptor<View> {
}
}
return "NULL NODEINFO OR CLASSNAME";
}
@Override
@@ -195,8 +194,7 @@ public class ViewDescriptor extends NodeDescriptor<View> {
viewProps.put("foreground", fromDrawable(node.getForeground()));
}
return Arrays.asList(
new Named<>("View", viewProps.build()));
return Arrays.asList(new Named<>("View", viewProps.build()));
}
@Override
@@ -442,9 +440,9 @@ public class ViewDescriptor extends NodeDescriptor<View> {
@Override
public FlipperObject getExtraInfo(View node) {
return new FlipperObject.Builder()
.put("focused", AccessibilityUtil.isAXFocused(node))
.put("hasAXNode", true)
.build();
.put("focused", AccessibilityUtil.isAXFocused(node))
.put("hasAXNode", true)
.build();
}
@Nullable

View File

@@ -243,7 +243,8 @@ public class ViewGroupDescriptor extends NodeDescriptor<ViewGroup> {
}
@Override
public void setHighlighted(ViewGroup node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(ViewGroup node, boolean selected, boolean isAlignmentMode)
throws Exception {
final NodeDescriptor descriptor = descriptorForClass(View.class);
descriptor.setHighlighted(node, selected, isAlignmentMode);
}
@@ -252,8 +253,8 @@ public class ViewGroupDescriptor extends NodeDescriptor<ViewGroup> {
for (int i = node.getChildCount() - 1; i >= 0; i--) {
final View child = node.getChildAt(i);
if (child instanceof HiddenNode
|| child.getVisibility() != View.VISIBLE
|| shouldSkip(child)) {
|| child.getVisibility() != View.VISIBLE
|| shouldSkip(child)) {
continue;
}

View File

@@ -26,9 +26,11 @@ public class AccessibilityRoleUtil {
*
* <p>https://github.com/google/talkback/blob/master/utils/src/main/java/Role.java
*
* The roles spoken by Talkback (roleStrings) should also be kept up to date and are found here:
* <p>The roles spoken by Talkback (roleStrings) should also be kept up to date and are found
* here:
*
* <p>https://github.com/google/talkback/compositor/src/main/res/values/strings.xml
*
* <p>https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json
*/
public enum AccessibilityRole {
@@ -78,7 +80,9 @@ public class AccessibilityRoleUtil {
return mValue;
}
public String getRoleString() { return mRoleString; }
public String getRoleString() {
return mRoleString;
}
public static AccessibilityRole fromValue(String value) {
for (AccessibilityRole role : AccessibilityRole.values()) {

View File

@@ -94,13 +94,15 @@ public final class AccessibilityUtil {
}
/**
* Given a {@link Context}, determine if an accessibility touch exploration service (TalkBack) is running.
* Given a {@link Context}, determine if an accessibility touch exploration service (TalkBack) is
* running.
*
* @param context The {@link Context} used to get the {@link AccessibilityManager}.
* @return {@code true} if an accessibility touch exploration service is currently running.
*/
public static boolean isTalkbackEnabled(Context context) {
return ((AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE)).isTouchExplorationEnabled();
return ((AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE))
.isTouchExplorationEnabled();
}
/**
@@ -223,15 +225,18 @@ public final class AccessibilityUtil {
}
/**
* Adds the state segments of Talkback's response to a given list. This should be kept up to date as
* much as necessary. Details can be seen in the source code here :
* Adds the state segments of Talkback's response to a given list. This should be kept up to date
* as much as necessary. Details can be seen in the source code here :
*
* https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json
* - search for "description_for_tree_status", "get_switch_state"
* <p>https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json - search for
* "description_for_tree_status", "get_switch_state"
*
* https://github.com/google/talkback/compositor/src/main/res/values/strings.xml
* <p>https://github.com/google/talkback/compositor/src/main/res/values/strings.xml
*/
private static void addStateSegments(StringBuilder talkbackSegments, AccessibilityNodeInfoCompat node, AccessibilityRoleUtil.AccessibilityRole role) {
private static void addStateSegments(
StringBuilder talkbackSegments,
AccessibilityNodeInfoCompat node,
AccessibilityRoleUtil.AccessibilityRole role) {
// selected status is always prepended
if (node.isSelected()) {
talkbackSegments.append("selected" + delimiter);
@@ -247,14 +252,17 @@ public final class AccessibilityUtil {
}
String roleString = role.getRoleString();
if (node.isCheckable() && !roleString.equals("Switch") &&
(!role.equals(AccessibilityRoleUtil.AccessibilityRole.CHECKED_TEXT_VIEW) || node.isChecked())) {
if (node.isCheckable()
&& !roleString.equals("Switch")
&& (!role.equals(AccessibilityRoleUtil.AccessibilityRole.CHECKED_TEXT_VIEW)
|| node.isChecked())) {
talkbackSegments.append((node.isChecked() ? "checked" : "not checked") + delimiter);
}
if (roleString.equals("Switch")) {
CharSequence switchState = node.getText();
if (TextUtils.isEmpty(switchState) || role == AccessibilityRoleUtil.AccessibilityRole.TOGGLE_BUTTON) {
if (TextUtils.isEmpty(switchState)
|| role == AccessibilityRoleUtil.AccessibilityRole.TOGGLE_BUTTON) {
talkbackSegments.append((node.isChecked() ? "checked" : "not checked") + delimiter);
} else {
talkbackSegments.append(switchState + delimiter);
@@ -271,6 +279,7 @@ public final class AccessibilityUtil {
}
private static final int SYSTEM_ACTION_MAX = 0x01FFFFFF;
private static String getHintForCustomActions(AccessibilityNodeInfoCompat node) {
StringBuilder customActions = new StringBuilder();
for (AccessibilityNodeInfoCompat.AccessibilityActionCompat action : node.getActionList()) {
@@ -294,15 +303,18 @@ public final class AccessibilityUtil {
return actions.length() > 0 ? "Actions: " + actions : "";
}
// currently this is not used because the Talkback source logic seems erroneous resulting in get_hint_for_actions never
// currently this is not used because the Talkback source logic seems erroneous resulting in
// get_hint_for_actions never
// returning any strings - see the TO DO in getTalkbackHint below once source is fixed
private static String getHintForActions(AccessibilityNodeInfoCompat node) {
StringBuilder actions = new StringBuilder();
for (AccessibilityNodeInfoCompat.AccessibilityActionCompat action : node.getActionList()) {
int id = action.getId();
CharSequence label = action.getLabel();
if (id != AccessibilityNodeInfoCompat.ACTION_CLICK && id != AccessibilityNodeInfoCompat.ACTION_LONG_CLICK &&
!TextUtils.isEmpty(label) && id <= SYSTEM_ACTION_MAX) {
if (id != AccessibilityNodeInfoCompat.ACTION_CLICK
&& id != AccessibilityNodeInfoCompat.ACTION_LONG_CLICK
&& !TextUtils.isEmpty(label)
&& id <= SYSTEM_ACTION_MAX) {
actions.append(label + delimiter);
}
}
@@ -346,19 +358,18 @@ public final class AccessibilityUtil {
return "";
}
/**
* Creates the text that Google's TalkBack screen reader will read aloud for a given {@link View}'s hint.
* This hint is generally ported over from Google's TalkBack screen reader, and this should be kept up to
* date with their implementation (as much as necessary). Hints can be turned off by user, so it may not
* actually be spoken and this method assumes the selection style is double tapping (it can also be set to
* keyboard or single tap but the general idea for the hint is the same). Details can be seen in their
* source code here:
* Creates the text that Google's TalkBack screen reader will read aloud for a given {@link
* View}'s hint. This hint is generally ported over from Google's TalkBack screen reader, and this
* should be kept up to date with their implementation (as much as necessary). Hints can be turned
* off by user, so it may not actually be spoken and this method assumes the selection style is
* double tapping (it can also be set to keyboard or single tap but the general idea for the hint
* is the same). Details can be seen in their source code here:
*
* https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json
* - search for "get_hint_from_node"
* <p>https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json - search for
* "get_hint_from_node"
*
* https://github.com/google/talkback/compositor/src/main/res/values/strings.xml
* <p>https://github.com/google/talkback/compositor/src/main/res/values/strings.xml
*
* @param view The {@link View} to evaluate for a hint.
* @return {@code String} representing the hint talkback will say when a {@link View} is focused.
@@ -378,24 +389,31 @@ public final class AccessibilityUtil {
if (role == AccessibilityRoleUtil.AccessibilityRole.DROP_DOWN_LIST) {
return "Double tap to change";
} else if (role == AccessibilityRoleUtil.AccessibilityRole.PAGER) {
if (supportsAction(node, AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD) || supportsAction(node, AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD)) {
if (supportsAction(node, AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD)
|| supportsAction(node, AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD)) {
return "Swipe with two fingers to switch pages";
} else {
return "No more pages";
}
} else if (role == AccessibilityRoleUtil.AccessibilityRole.SEEK_CONTROL &&
(supportsAction(node, AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD) || supportsAction(node, AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD))) {
} else if (role == AccessibilityRoleUtil.AccessibilityRole.SEEK_CONTROL
&& (supportsAction(node, AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD)
|| supportsAction(node, AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD))) {
return "Use volume keys to adjust";
} else {
// first custom actions
String segmentToAdd = getHintForCustomActions(node);
if (segmentToAdd.length() > 0) { hint.append(segmentToAdd + delimiter); }
if (segmentToAdd.length() > 0) {
hint.append(segmentToAdd + delimiter);
}
// TODO: add getHintForActions(node) here if Talkback source gets fixed.
// Currently the "get_hint_for_actions" in the compositor source never adds to Talkback output
// because of a mismatched if condition/body. If this changes, we should also add a getHintForActions
// method here. Source at https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json
// Currently the "get_hint_for_actions" in the compositor source never adds to Talkback
// output
// because of a mismatched if condition/body. If this changes, we should also add a
// getHintForActions
// method here. Source at
// https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json
// then normal tap (special case for EditText)
if (role == AccessibilityRoleUtil.AccessibilityRole.EDIT_TEXT) {
@@ -404,12 +422,16 @@ public final class AccessibilityUtil {
}
} else {
segmentToAdd = getHintForClick(node);
if (segmentToAdd.length() > 0) { hint.append(segmentToAdd + delimiter); }
if (segmentToAdd.length() > 0) {
hint.append(segmentToAdd + delimiter);
}
}
// then long press
segmentToAdd = getHintForLongClick(node);
if (segmentToAdd.length() > 0) { hint.append(segmentToAdd + delimiter); }
if (segmentToAdd.length() > 0) {
hint.append(segmentToAdd + delimiter);
}
}
}
node.recycle();
@@ -421,11 +443,12 @@ public final class AccessibilityUtil {
* This may be any combination of the {@link View}'s {@code text}, {@code contentDescription}, and
* the {@code text} and {@code contentDescription} of any ancestor {@link View}.
*
* This description is generally ported over from Google's TalkBack screen reader, and this should be kept up to
* date with their implementation (as much as necessary). Details can be seen in their source code here:
* <p>This description is generally ported over from Google's TalkBack screen reader, and this
* should be kept up to date with their implementation (as much as necessary). Details can be seen
* in their source code here:
*
* https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json
* - search for "get_description_for_tree", "append_description_for_tree", "description_for_tree_nodes"
* <p>https://github.com/google/talkback/compositor/src/main/res/raw/compositor.json - search for
* "get_description_for_tree", "append_description_for_tree", "description_for_tree_nodes"
*
* @param view The {@link View} to evaluate.
* @return {@code String} representing what talkback will say when a {@link View} is focused.
@@ -449,7 +472,8 @@ public final class AccessibilityUtil {
if (roleString == null) {
roleString = role.getRoleString();
}
boolean disabled = AccessibilityEvaluationUtil.isActionableForAccessibility(node) && !node.isEnabled();
boolean disabled =
AccessibilityEvaluationUtil.isActionableForAccessibility(node) && !node.isEnabled();
// EditText's prioritize their own text content over a contentDescription so skip this
if (!TextUtils.isEmpty(contentDescription) && (!isEditText || !hasNodeText)) {
@@ -461,10 +485,14 @@ public final class AccessibilityUtil {
talkbackSegments.append(contentDescription + delimiter);
// then role
if (roleString.length() > 0) { talkbackSegments.append(roleString + delimiter); }
if (roleString.length() > 0) {
talkbackSegments.append(roleString + delimiter);
}
// lastly disabled is appended if applicable
if (disabled) { talkbackSegments.append("disabled" + delimiter); }
if (disabled) {
talkbackSegments.append("disabled" + delimiter);
}
return removeFinalDelimiter(talkbackSegments);
}
@@ -473,8 +501,12 @@ public final class AccessibilityUtil {
if (hasNodeText) {
// skip status checks for EditText, but description, role, and disabled are included
talkbackSegments.append(nodeText + delimiter);
if (roleString.length() > 0) { talkbackSegments.append(roleString + delimiter); }
if (disabled) { talkbackSegments.append("disabled" + delimiter); }
if (roleString.length() > 0) {
talkbackSegments.append(roleString + delimiter);
}
if (disabled) {
talkbackSegments.append("disabled" + delimiter);
}
return removeFinalDelimiter(talkbackSegments);
}
@@ -511,9 +543,9 @@ public final class AccessibilityUtil {
}
/**
* Creates a {@link FlipperObject} of useful properties of AccessibilityNodeInfo, to be shown in the
* Flipper Layout Inspector accessibility extension. All properties are immutable since they are all derived from
* various {@link View} properties. This is a more complete list than
* Creates a {@link FlipperObject} of useful properties of AccessibilityNodeInfo, to be shown in
* the Flipper Layout Inspector accessibility extension. All properties are immutable since they
* are all derived from various {@link View} properties. This is a more complete list than
* getAccessibilityNodeInfoProperties returns.
*
* @param view The {@link View} to derive the AccessibilityNodeInfo properties from.
@@ -597,7 +629,7 @@ public final class AccessibilityUtil {
public static boolean isAXFocused(View view) {
final AccessibilityNodeInfoCompat nodeInfo =
ViewAccessibilityHelper.createNodeInfoFromView(view);
ViewAccessibilityHelper.createNodeInfoFromView(view);
if (nodeInfo == null) {
return false;
} else {
@@ -608,8 +640,8 @@ public final class AccessibilityUtil {
}
/**
* Modifies a {@link FlipperObject.Builder} to add Talkback-specific Accessibiltiy properties to be
* shown in the Flipper Layout Inspector.
* Modifies a {@link FlipperObject.Builder} to add Talkback-specific Accessibiltiy properties to
* be shown in the Flipper Layout Inspector.
*
* @param props The {@link FlipperObject.Builder} to add the properties to.
* @param view The {@link View} to derive the properties from.
@@ -634,13 +666,14 @@ public final class AccessibilityUtil {
// This needs to be an empty string to be mutable. See t20470623.
CharSequence contentDescription =
view.getContentDescription() != null ? view.getContentDescription() : "";
props.put("content-description", InspectorValue.mutable(contentDescription))
.put("focusable", InspectorValue.mutable(view.isFocusable()))
.put("selected", InspectorValue.mutable(view.isSelected()))
.put("enabled", InspectorValue.mutable(view.isEnabled()))
.put("long-clickable", InspectorValue.mutable(view.isLongClickable()))
.put("clickable", InspectorValue.mutable(view.isClickable()))
.put("focused", view.isFocused());
props
.put("content-description", InspectorValue.mutable(contentDescription))
.put("focusable", InspectorValue.mutable(view.isFocusable()))
.put("selected", InspectorValue.mutable(view.isSelected()))
.put("enabled", InspectorValue.mutable(view.isEnabled()))
.put("long-clickable", InspectorValue.mutable(view.isLongClickable()))
.put("clickable", InspectorValue.mutable(view.isClickable()))
.put("focused", view.isFocused());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
props.put("accessibility-focused", view.isAccessibilityFocused());
@@ -660,19 +693,19 @@ public final class AccessibilityUtil {
if (!AccessibilityEvaluationUtil.isTalkbackFocusable(view)) {
String reason = getTalkbackIgnoredReasons(view);
return new FlipperObject.Builder()
.put("talkback-focusable", false)
.put("talkback-ignored-reasons", reason == null ? "" : reason)
.build();
.put("talkback-focusable", false)
.put("talkback-ignored-reasons", reason == null ? "" : reason)
.build();
} else {
String reason = getTalkbackFocusableReasons(view);
CharSequence description = getTalkbackDescription(view);
CharSequence hint = getTalkbackHint(view);
return new FlipperObject.Builder()
.put("talkback-focusable", true)
.put("talkback-focusable-reasons", reason)
.put("talkback-output", description)
.put("talkback-hint", hint)
.build();
.put("talkback-focusable", true)
.put("talkback-focusable-reasons", reason)
.put("talkback-output", description)
.put("talkback-hint", hint)
.build();
}
}
}

View File

@@ -96,7 +96,12 @@ public final class AndroidRootResolver {
viewsField.setAccessible(true);
paramsField = clazz.getDeclaredField(WINDOW_PARAMS_FIELD);
paramsField.setAccessible(true);
} catch (InvocationTargetException | IllegalAccessException | RuntimeException | NoSuchMethodException | NoSuchFieldException | ClassNotFoundException ignored) {
} catch (InvocationTargetException
| IllegalAccessException
| RuntimeException
| NoSuchMethodException
| NoSuchFieldException
| ClassNotFoundException ignored) {
}
}
}

View File

@@ -44,5 +44,4 @@ public final class ViewAccessibilityHelper {
return nodeInfo;
}
}

View File

@@ -11,6 +11,14 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.v4.util.Pair;
import android.view.View;
import com.facebook.flipper.core.FlipperDynamic;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.plugins.inspector.HighlightedOverlay;
import com.facebook.flipper.plugins.inspector.InspectorValue;
import com.facebook.flipper.plugins.inspector.Named;
import com.facebook.flipper.plugins.inspector.NodeDescriptor;
import com.facebook.flipper.plugins.inspector.Touch;
import com.facebook.flipper.plugins.inspector.descriptors.ObjectDescriptor;
import com.facebook.litho.Component;
import com.facebook.litho.ComponentContext;
import com.facebook.litho.DebugComponent;
@@ -20,14 +28,6 @@ import com.facebook.litho.StateContainer;
import com.facebook.litho.annotations.Prop;
import com.facebook.litho.annotations.State;
import com.facebook.litho.reference.Reference;
import com.facebook.flipper.core.FlipperDynamic;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.plugins.inspector.HighlightedOverlay;
import com.facebook.flipper.plugins.inspector.InspectorValue;
import com.facebook.flipper.plugins.inspector.Named;
import com.facebook.flipper.plugins.inspector.NodeDescriptor;
import com.facebook.flipper.plugins.inspector.Touch;
import com.facebook.flipper.plugins.inspector.descriptors.ObjectDescriptor;
import com.facebook.yoga.YogaAlign;
import com.facebook.yoga.YogaDirection;
import com.facebook.yoga.YogaEdge;
@@ -63,8 +63,7 @@ public class DebugComponentDescriptor extends NodeDescriptor<DebugComponent> {
}
@Override
public void applyStateOverrides(
String key, StateContainer stateContainer) {
public void applyStateOverrides(String key, StateContainer stateContainer) {
final List<Pair<String[], FlipperDynamic>> overrides = mOverrides.get(key);
if (overrides == null) {
return;
@@ -497,7 +496,8 @@ public class DebugComponentDescriptor extends NodeDescriptor<DebugComponent> {
return descriptor.matches(query, node);
}
private static void applyLayoutOverride(DebugLayoutNode node, String[] path, FlipperDynamic value) {
private static void applyLayoutOverride(
DebugLayoutNode node, String[] path, FlipperDynamic value) {
switch (path[0]) {
case "background":
node.setBackgroundColor(value.asInt());

View File

@@ -4,7 +4,6 @@ package com.facebook.flipper.plugins.litho;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.litho.LithoView;
import com.facebook.flipper.core.FlipperConnection;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.core.FlipperReceiver;
@@ -13,72 +12,74 @@ import com.facebook.flipper.plugins.common.MainThreadFlipperReceiver;
import com.facebook.flipper.plugins.inspector.ApplicationWrapper;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.inspector.ObjectTracker;
import com.facebook.litho.LithoView;
import java.util.Stack;
public final class GenerateLithoAccessibilityRenderExtensionCommand implements InspectorFlipperPlugin.ExtensionCommand {
public final class GenerateLithoAccessibilityRenderExtensionCommand
implements InspectorFlipperPlugin.ExtensionCommand {
@Override
public String command() {
return "forceLithoAXRender";
}
@Override
public String command() {
return "forceLithoAXRender";
}
@Override
public FlipperReceiver receiver(final ObjectTracker tracker, final FlipperConnection connection) {
return new MainThreadFlipperReceiver(connection) {
@Override
public void onReceiveOnMainThread(final FlipperObject params, final FlipperResponder responder)
throws Exception {
final String applicationId = params.getString("applicationId");
@Override
public FlipperReceiver receiver(final ObjectTracker tracker, final FlipperConnection connection) {
return new MainThreadFlipperReceiver(connection) {
@Override
public void onReceiveOnMainThread(
final FlipperObject params, final FlipperResponder responder) throws Exception {
final String applicationId = params.getString("applicationId");
// check that the application is valid
if (applicationId == null) {
return;
}
final Object obj = tracker.get(applicationId);
if (obj != null && !(obj instanceof ApplicationWrapper)) {
return;
}
final ApplicationWrapper applicationWrapper = ((ApplicationWrapper) obj);
final boolean forceLithoAXRender = params.getBoolean("forceLithoAXRender");
final boolean prevForceLithoAXRender = Boolean.getBoolean("is_accessibility_enabled");
// nothing has changed, so return
if (forceLithoAXRender == prevForceLithoAXRender) {
return;
}
// change property and rerender
System.setProperty("is_accessibility_enabled", forceLithoAXRender + "");
forceRerenderAllLithoViews(forceLithoAXRender, applicationWrapper);
}
};
}
private void forceRerenderAllLithoViews(boolean forceLithoAXRender, ApplicationWrapper applicationWrapper) {
// iterate through tree and rerender all litho views
Stack<ViewGroup> lithoViewSearchStack = new Stack<>();
for (View root : applicationWrapper.getViewRoots()) {
if (root instanceof ViewGroup) {
lithoViewSearchStack.push((ViewGroup) root);
}
// check that the application is valid
if (applicationId == null) {
return;
}
final Object obj = tracker.get(applicationId);
if (obj != null && !(obj instanceof ApplicationWrapper)) {
return;
}
while (!lithoViewSearchStack.isEmpty()) {
ViewGroup v = lithoViewSearchStack.pop();
if (v instanceof LithoView) {
// TODO: uncomment once Litho open source updates
// ((LithoView) v).rerenderForAccessibility(forceLithoAXRender);
} else {
for (int i = 0; i < v.getChildCount(); i++) {
View child = v.getChildAt(i);
if (child instanceof ViewGroup) {
lithoViewSearchStack.push((ViewGroup) child);
}
}
}
final ApplicationWrapper applicationWrapper = ((ApplicationWrapper) obj);
final boolean forceLithoAXRender = params.getBoolean("forceLithoAXRender");
final boolean prevForceLithoAXRender = Boolean.getBoolean("is_accessibility_enabled");
// nothing has changed, so return
if (forceLithoAXRender == prevForceLithoAXRender) {
return;
}
// change property and rerender
System.setProperty("is_accessibility_enabled", forceLithoAXRender + "");
forceRerenderAllLithoViews(forceLithoAXRender, applicationWrapper);
}
};
}
private void forceRerenderAllLithoViews(
boolean forceLithoAXRender, ApplicationWrapper applicationWrapper) {
// iterate through tree and rerender all litho views
Stack<ViewGroup> lithoViewSearchStack = new Stack<>();
for (View root : applicationWrapper.getViewRoots()) {
if (root instanceof ViewGroup) {
lithoViewSearchStack.push((ViewGroup) root);
}
}
}
while (!lithoViewSearchStack.isEmpty()) {
ViewGroup v = lithoViewSearchStack.pop();
if (v instanceof LithoView) {
// TODO: uncomment once Litho open source updates
// ((LithoView) v).rerenderForAccessibility(forceLithoAXRender);
} else {
for (int i = 0; i < v.getChildCount(); i++) {
View child = v.getChildAt(i);
if (child instanceof ViewGroup) {
lithoViewSearchStack.push((ViewGroup) child);
}
}
}
}
}
}

View File

@@ -2,9 +2,9 @@
package com.facebook.flipper.plugins.litho;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.litho.DebugComponent;
import com.facebook.litho.LithoView;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
public final class LithoFlipperDescriptors {

View File

@@ -4,13 +4,13 @@ package com.facebook.flipper.plugins.litho;
import android.graphics.Rect;
import android.view.ViewGroup;
import com.facebook.litho.DebugComponent;
import com.facebook.litho.LithoView;
import com.facebook.flipper.core.FlipperDynamic;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.plugins.inspector.Named;
import com.facebook.flipper.plugins.inspector.NodeDescriptor;
import com.facebook.flipper.plugins.inspector.Touch;
import com.facebook.litho.DebugComponent;
import com.facebook.litho.LithoView;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
@@ -125,7 +125,8 @@ public class LithoViewDescriptor extends NodeDescriptor<LithoView> {
}
@Override
public void setHighlighted(LithoView node, boolean selected, boolean isAlignmentMode) throws Exception {
public void setHighlighted(LithoView node, boolean selected, boolean isAlignmentMode)
throws Exception {
final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class);
descriptor.setHighlighted(node, selected, isAlignmentMode);
}

View File

@@ -13,7 +13,6 @@ import com.facebook.flipper.plugins.network.NetworkReporter.ResponseInfo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;

View File

@@ -86,16 +86,18 @@ public class SharedPreferencesFlipperPlugin implements FlipperPlugin {
* Creates a {@link android.content.SharedPreferences} plugin for Flipper
*
* @param context The context to retrieve the preferences from.
* @param descriptors A list of {@link SharedPreferencesDescriptor}s
* that describe the list of preferences to retrieve.
* @param descriptors A list of {@link SharedPreferencesDescriptor}s that describe the list of
* preferences to retrieve.
*/
public SharedPreferencesFlipperPlugin(Context context, List<SharedPreferencesDescriptor> descriptors) {
public SharedPreferencesFlipperPlugin(
Context context, List<SharedPreferencesDescriptor> descriptors) {
if (context == null) {
throw new IllegalArgumentException("Given null context");
}
mSharedPreferences = new HashMap<>(descriptors.size());
for (SharedPreferencesDescriptor descriptor : descriptors) {
SharedPreferences preferences = context.getSharedPreferences(descriptor.name, descriptor.mode);
SharedPreferences preferences =
context.getSharedPreferences(descriptor.name, descriptor.mode);
preferences.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
mSharedPreferences.put(preferences, descriptor);
}
@@ -107,12 +109,13 @@ public class SharedPreferencesFlipperPlugin implements FlipperPlugin {
}
private SharedPreferences getSharedPreferencesFor(String name) {
for (Map.Entry<SharedPreferences, SharedPreferencesDescriptor> entry : mSharedPreferences.entrySet()) {
for (Map.Entry<SharedPreferences, SharedPreferencesDescriptor> entry :
mSharedPreferences.entrySet()) {
if (entry.getValue().name.equals(name)) {
return entry.getKey();
}
}
throw new IllegalStateException("Unknown shared preferences " +name);
throw new IllegalStateException("Unknown shared preferences " + name);
}
private FlipperObject getFlipperObjectFor(String name) {
@@ -139,7 +142,8 @@ public class SharedPreferencesFlipperPlugin implements FlipperPlugin {
@Override
public void onReceive(FlipperObject params, FlipperResponder responder) {
FlipperObject.Builder builder = new FlipperObject.Builder();
for (Map.Entry<SharedPreferences, SharedPreferencesDescriptor> entry : mSharedPreferences.entrySet()) {
for (Map.Entry<SharedPreferences, SharedPreferencesDescriptor> entry :
mSharedPreferences.entrySet()) {
builder.put(entry.getValue().name, getFlipperObjectFor(entry.getKey()));
}
responder.success(builder.build());

View File

@@ -13,10 +13,10 @@ import static org.hamcrest.MatcherAssert.assertThat;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.testing.FlipperConnectionMock;
import com.facebook.flipper.testing.FlipperResponderMock;
import org.robolectric.RobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class ConsoleFlipperPluginTest {

View File

@@ -13,10 +13,10 @@ import static org.hamcrest.MatcherAssert.assertThat;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.testing.FlipperConnectionMock;
import com.facebook.flipper.testing.FlipperResponderMock;
import org.robolectric.RobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class ConsoleSonarPluginTest {

View File

@@ -9,7 +9,6 @@ package com.facebook.flipper.plugins.console;
import static org.junit.Assert.assertEquals;
import org.robolectric.RobolectricTestRunner;
import com.google.common.collect.ImmutableMap;
import java.util.Collections;
import java.util.HashMap;
@@ -17,6 +16,7 @@ import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mozilla.javascript.ContextFactory;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class JavascriptSessionTest {

View File

@@ -14,13 +14,13 @@ import android.app.Activity;
import android.app.Application;
import android.app.Application.ActivityLifecycleCallbacks;
import android.os.Bundle;
import org.robolectric.RobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class ApplicationWrapperTest {

View File

@@ -14,10 +14,10 @@ import com.facebook.flipper.core.FlipperConnection;
import com.facebook.flipper.core.FlipperDynamic;
import com.facebook.flipper.core.FlipperObject;
import com.facebook.flipper.testing.FlipperConnectionMock;
import org.robolectric.RobolectricTestRunner;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class DescriptorMappingTest {

View File

@@ -26,19 +26,18 @@ import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin.TouchOverla
import com.facebook.flipper.plugins.inspector.descriptors.ApplicationDescriptor;
import com.facebook.flipper.testing.FlipperConnectionMock;
import com.facebook.flipper.testing.FlipperResponderMock;
import org.robolectric.RobolectricTestRunner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import javax.annotation.Nullable;
@RunWith(RobolectricTestRunner.class)
public class InspectorFlipperPluginTest {
@@ -270,7 +269,8 @@ public class InspectorFlipperPluginTest {
hasItem(
new FlipperObject.Builder()
.put(
"path", new FlipperArray.Builder().put("com.facebook.flipper").put("test").put("3"))
"path",
new FlipperArray.Builder().put("com.facebook.flipper").put("test").put("3"))
.build()));
}

View File

@@ -26,19 +26,18 @@ import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin.TouchOverla
import com.facebook.flipper.plugins.inspector.descriptors.ApplicationDescriptor;
import com.facebook.flipper.testing.FlipperConnectionMock;
import com.facebook.flipper.testing.FlipperResponderMock;
import org.robolectric.RobolectricTestRunner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import javax.annotation.Nullable;
@RunWith(RobolectricTestRunner.class)
public class InspectorSonarPluginTest {
@@ -270,7 +269,8 @@ public class InspectorSonarPluginTest {
hasItem(
new FlipperObject.Builder()
.put(
"path", new FlipperArray.Builder().put("com.facebook.flipper").put("test").put("3"))
"path",
new FlipperArray.Builder().put("com.facebook.flipper").put("test").put("3"))
.build()));
}

View File

@@ -15,10 +15,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.facebook.flipper.plugins.inspector.Touch;
import org.robolectric.RobolectricTestRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)