Android Embedding PR 17: Clarify AccessibilityBridge and move logic out of FlutterView. (flutter/engine#8061)
This commit is contained in:
@@ -20,6 +20,8 @@ import io.flutter.embedding.engine.dart.PlatformMessageHandler;
|
||||
import io.flutter.embedding.engine.FlutterEngine.EngineLifecycleListener;
|
||||
import io.flutter.embedding.engine.renderer.FlutterRenderer;
|
||||
import io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener;
|
||||
import io.flutter.plugin.common.StandardMessageCodec;
|
||||
import io.flutter.view.AccessibilityBridge;
|
||||
|
||||
/**
|
||||
* Interface between Flutter embedding's Java code and Flutter engine's C/C++ code.
|
||||
@@ -323,6 +325,22 @@ public class FlutterJNI {
|
||||
ByteBuffer buffer,
|
||||
int position);
|
||||
|
||||
public void dispatchSemanticsAction(int id, @NonNull AccessibilityBridge.Action action) {
|
||||
dispatchSemanticsAction(id, action, null);
|
||||
}
|
||||
|
||||
public void dispatchSemanticsAction(int id, @NonNull AccessibilityBridge.Action action, @Nullable Object args) {
|
||||
ensureAttachedToNative();
|
||||
|
||||
ByteBuffer encodedArgs = null;
|
||||
int position = 0;
|
||||
if (args != null) {
|
||||
encodedArgs = StandardMessageCodec.INSTANCE.encodeMessage(args);
|
||||
position = encodedArgs.position();
|
||||
}
|
||||
dispatchSemanticsAction(id, action.value, encodedArgs, position);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void dispatchSemanticsAction(int id, int action, ByteBuffer args, int argsPosition) {
|
||||
ensureAttachedToNative();
|
||||
|
||||
@@ -103,17 +103,17 @@ public class AccessibilityChannel {
|
||||
void announce(@NonNull String message);
|
||||
|
||||
/**
|
||||
* The user has tapped on the artifact with the given {@code nodeId}.
|
||||
* The user has tapped on the widget with the given {@code nodeId}.
|
||||
*/
|
||||
void onTap(int nodeId);
|
||||
|
||||
/**
|
||||
* The user has long pressed on the artifact with the given {@code nodeId}.
|
||||
* The user has long pressed on the widget with the given {@code nodeId}.
|
||||
*/
|
||||
void onLongPress(int nodeId);
|
||||
|
||||
/**
|
||||
* The user has opened a popup window, menu, dialog, etc.
|
||||
* The user has opened a tooltip.
|
||||
*/
|
||||
void onTooltip(@NonNull String message);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,12 +8,10 @@ import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.LocaleList;
|
||||
@@ -52,8 +50,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
/**
|
||||
* An Android view containing a Flutter app.
|
||||
*/
|
||||
public class FlutterView extends SurfaceView
|
||||
implements BinaryMessenger, TextureRegistry, AccessibilityManager.AccessibilityStateChangeListener {
|
||||
public class FlutterView extends SurfaceView implements BinaryMessenger, TextureRegistry {
|
||||
/**
|
||||
* Interface for those objects that maintain and expose a reference to a
|
||||
* {@code FlutterView} (such as a full-screen Flutter activity).
|
||||
@@ -91,7 +88,6 @@ public class FlutterView extends SurfaceView
|
||||
}
|
||||
|
||||
private final DartExecutor dartExecutor;
|
||||
private final AccessibilityChannel accessibilityChannel;
|
||||
private final NavigationChannel navigationChannel;
|
||||
private final KeyEventChannel keyEventChannel;
|
||||
private final LifecycleChannel lifecycleChannel;
|
||||
@@ -105,14 +101,19 @@ public class FlutterView extends SurfaceView
|
||||
private AccessibilityBridge mAccessibilityNodeProvider;
|
||||
private final SurfaceHolder.Callback mSurfaceCallback;
|
||||
private final ViewportMetrics mMetrics;
|
||||
private final AccessibilityManager mAccessibilityManager;
|
||||
private final List<ActivityLifecycleListener> mActivityLifecycleListeners;
|
||||
private final List<FirstFrameListener> mFirstFrameListeners;
|
||||
private final AtomicLong nextTextureId = new AtomicLong(0L);
|
||||
private FlutterNativeView mNativeView;
|
||||
private final AnimationScaleObserver mAnimationScaleObserver;
|
||||
private boolean mIsSoftwareRenderingEnabled = false; // using the software renderer or not
|
||||
|
||||
private final AccessibilityBridge.OnAccessibilityChangeListener onAccessibilityChangeListener = new AccessibilityBridge.OnAccessibilityChangeListener() {
|
||||
@Override
|
||||
public void onAccessibilityChanged(boolean isAccessibilityEnabled, boolean isTouchExplorationEnabled) {
|
||||
resetWillNotDraw(isAccessibilityEnabled, isTouchExplorationEnabled);
|
||||
}
|
||||
};
|
||||
|
||||
public FlutterView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -133,7 +134,6 @@ public class FlutterView extends SurfaceView
|
||||
|
||||
dartExecutor = mNativeView.getDartExecutor();
|
||||
mIsSoftwareRenderingEnabled = FlutterJNI.nativeGetIsSoftwareRenderingEnabled();
|
||||
mAnimationScaleObserver = new AnimationScaleObserver(new Handler());
|
||||
mMetrics = new ViewportMetrics();
|
||||
mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density;
|
||||
setFocusable(true);
|
||||
@@ -162,13 +162,10 @@ public class FlutterView extends SurfaceView
|
||||
};
|
||||
getHolder().addCallback(mSurfaceCallback);
|
||||
|
||||
mAccessibilityManager = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
|
||||
mActivityLifecycleListeners = new ArrayList<>();
|
||||
mFirstFrameListeners = new ArrayList<>();
|
||||
|
||||
// Create all platform channels
|
||||
accessibilityChannel = new AccessibilityChannel(dartExecutor);
|
||||
navigationChannel = new NavigationChannel(dartExecutor);
|
||||
keyEventChannel = new KeyEventChannel(dartExecutor);
|
||||
lifecycleChannel = new LifecycleChannel(dartExecutor);
|
||||
@@ -236,7 +233,6 @@ public class FlutterView extends SurfaceView
|
||||
}
|
||||
|
||||
public void onPostResume() {
|
||||
updateAccessibilityFeatures();
|
||||
for (ActivityLifecycleListener listener : mActivityLifecycleListeners) {
|
||||
listener.onPostResume();
|
||||
}
|
||||
@@ -573,7 +569,7 @@ public class FlutterView extends SurfaceView
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean handled = handleAccessibilityHoverEvent(event);
|
||||
boolean handled = mAccessibilityNodeProvider.onAccessibilityHoverEvent(event);
|
||||
if (!handled) {
|
||||
// TODO(ianh): Expose hover events to the platform,
|
||||
// implementing ADD, REMOVE, etc.
|
||||
@@ -746,6 +742,12 @@ public class FlutterView extends SurfaceView
|
||||
resetAccessibilityTree();
|
||||
}
|
||||
|
||||
void resetAccessibilityTree() {
|
||||
if (mAccessibilityNodeProvider != null) {
|
||||
mAccessibilityNodeProvider.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private void postRun() {
|
||||
}
|
||||
|
||||
@@ -844,206 +846,52 @@ public class FlutterView extends SurfaceView
|
||||
}
|
||||
}
|
||||
|
||||
// ACCESSIBILITY
|
||||
|
||||
private boolean mAccessibilityEnabled = false;
|
||||
private boolean mTouchExplorationEnabled = false;
|
||||
private int mAccessibilityFeatureFlags = 0;
|
||||
private TouchExplorationListener mTouchExplorationListener;
|
||||
|
||||
protected void dispatchSemanticsAction(int id, AccessibilityBridge.Action action) {
|
||||
dispatchSemanticsAction(id, action, null);
|
||||
}
|
||||
|
||||
protected void dispatchSemanticsAction(int id, AccessibilityBridge.Action action, Object args) {
|
||||
if (!isAttached())
|
||||
return;
|
||||
ByteBuffer encodedArgs = null;
|
||||
int position = 0;
|
||||
if (args != null) {
|
||||
encodedArgs = StandardMessageCodec.INSTANCE.encodeMessage(args);
|
||||
position = encodedArgs.position();
|
||||
}
|
||||
mNativeView.getFlutterJNI().dispatchSemanticsAction(id, action.value, encodedArgs, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mAccessibilityEnabled = mAccessibilityManager.isEnabled();
|
||||
mTouchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
Uri transitionUri = Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE);
|
||||
getContext().getContentResolver().registerContentObserver(transitionUri, false, mAnimationScaleObserver);
|
||||
}
|
||||
|
||||
if (mAccessibilityEnabled || mTouchExplorationEnabled) {
|
||||
ensureAccessibilityEnabled();
|
||||
}
|
||||
if (mTouchExplorationEnabled) {
|
||||
mAccessibilityFeatureFlags |= AccessibilityFeature.ACCESSIBLE_NAVIGATION.value;
|
||||
} else {
|
||||
mAccessibilityFeatureFlags &= ~AccessibilityFeature.ACCESSIBLE_NAVIGATION.value;
|
||||
}
|
||||
// Apply additional accessibility settings
|
||||
updateAccessibilityFeatures();
|
||||
resetWillNotDraw();
|
||||
mAccessibilityManager.addAccessibilityStateChangeListener(this);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
if (mTouchExplorationListener == null) {
|
||||
mTouchExplorationListener = new TouchExplorationListener();
|
||||
}
|
||||
mAccessibilityManager.addTouchExplorationStateChangeListener(mTouchExplorationListener);
|
||||
}
|
||||
}
|
||||
mAccessibilityNodeProvider = new AccessibilityBridge(
|
||||
this,
|
||||
getFlutterNativeView().getFlutterJNI(),
|
||||
new AccessibilityChannel(dartExecutor),
|
||||
(AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE),
|
||||
getContext().getContentResolver()
|
||||
);
|
||||
mAccessibilityNodeProvider.setOnAccessibilityChangeListener(onAccessibilityChangeListener);
|
||||
|
||||
private void updateAccessibilityFeatures() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
String transitionAnimationScale = Settings.Global.getString(getContext().getContentResolver(),
|
||||
Settings.Global.TRANSITION_ANIMATION_SCALE);
|
||||
if (transitionAnimationScale != null && transitionAnimationScale.equals("0")) {
|
||||
mAccessibilityFeatureFlags |= AccessibilityFeature.DISABLE_ANIMATIONS.value;
|
||||
} else {
|
||||
mAccessibilityFeatureFlags &= ~AccessibilityFeature.DISABLE_ANIMATIONS.value;
|
||||
}
|
||||
}
|
||||
mNativeView.getFlutterJNI().setAccessibilityFeatures(mAccessibilityFeatureFlags);
|
||||
resetWillNotDraw(
|
||||
mAccessibilityNodeProvider.isAccessibilityEnabled(),
|
||||
mAccessibilityNodeProvider.isTouchExplorationEnabled()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
getContext().getContentResolver().unregisterContentObserver(mAnimationScaleObserver);
|
||||
mAccessibilityManager.removeAccessibilityStateChangeListener(this);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
mAccessibilityManager.removeTouchExplorationStateChangeListener(mTouchExplorationListener);
|
||||
}
|
||||
|
||||
mAccessibilityNodeProvider.release();
|
||||
mAccessibilityNodeProvider = null;
|
||||
}
|
||||
|
||||
private void resetWillNotDraw() {
|
||||
// TODO(mattcarroll): Confer with Ian as to why we need this method. Delete if possible, otherwise add comments.
|
||||
private void resetWillNotDraw(boolean isAccessibilityEnabled, boolean isTouchExplorationEnabled) {
|
||||
if (!mIsSoftwareRenderingEnabled) {
|
||||
setWillNotDraw(!(mAccessibilityEnabled || mTouchExplorationEnabled));
|
||||
setWillNotDraw(!(isAccessibilityEnabled || isTouchExplorationEnabled));
|
||||
} else {
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityStateChanged(boolean enabled) {
|
||||
if (enabled) {
|
||||
ensureAccessibilityEnabled();
|
||||
} else {
|
||||
mAccessibilityEnabled = false;
|
||||
if (mAccessibilityNodeProvider != null) {
|
||||
mAccessibilityNodeProvider.setAccessibilityEnabled(false);
|
||||
}
|
||||
mNativeView.getFlutterJNI().setSemanticsEnabled(false);
|
||||
}
|
||||
resetWillNotDraw();
|
||||
}
|
||||
|
||||
/// Must match the enum defined in window.dart.
|
||||
private enum AccessibilityFeature {
|
||||
ACCESSIBLE_NAVIGATION(1 << 0),
|
||||
INVERT_COLORS(1 << 1), // NOT SUPPORTED
|
||||
DISABLE_ANIMATIONS(1 << 2);
|
||||
|
||||
AccessibilityFeature(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
final int value;
|
||||
}
|
||||
|
||||
// Listens to the global TRANSITION_ANIMATION_SCALE property and notifies us so
|
||||
// that we can disable animations in Flutter.
|
||||
private class AnimationScaleObserver extends ContentObserver {
|
||||
public AnimationScaleObserver(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
this.onChange(selfChange, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
String value = Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1 ? null
|
||||
: Settings.Global.getString(getContext().getContentResolver(),
|
||||
Settings.Global.TRANSITION_ANIMATION_SCALE);
|
||||
if (value != null && value.equals("0")) {
|
||||
mAccessibilityFeatureFlags |= AccessibilityFeature.DISABLE_ANIMATIONS.value;
|
||||
} else {
|
||||
mAccessibilityFeatureFlags &= ~AccessibilityFeature.DISABLE_ANIMATIONS.value;
|
||||
}
|
||||
mNativeView.getFlutterJNI().setAccessibilityFeatures(mAccessibilityFeatureFlags);
|
||||
}
|
||||
}
|
||||
|
||||
// This is guarded at instantiation time.
|
||||
@TargetApi(19)
|
||||
@RequiresApi(19)
|
||||
class TouchExplorationListener implements AccessibilityManager.TouchExplorationStateChangeListener {
|
||||
@Override
|
||||
public void onTouchExplorationStateChanged(boolean enabled) {
|
||||
if (enabled) {
|
||||
mTouchExplorationEnabled = true;
|
||||
ensureAccessibilityEnabled();
|
||||
mAccessibilityFeatureFlags |= AccessibilityFeature.ACCESSIBLE_NAVIGATION.value;
|
||||
mNativeView.getFlutterJNI().setAccessibilityFeatures(mAccessibilityFeatureFlags);
|
||||
} else {
|
||||
mTouchExplorationEnabled = false;
|
||||
if (mAccessibilityNodeProvider != null) {
|
||||
mAccessibilityNodeProvider.handleTouchExplorationExit();
|
||||
}
|
||||
mAccessibilityFeatureFlags &= ~AccessibilityFeature.ACCESSIBLE_NAVIGATION.value;
|
||||
mNativeView.getFlutterJNI().setAccessibilityFeatures(mAccessibilityFeatureFlags);
|
||||
}
|
||||
resetWillNotDraw();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
|
||||
if (mAccessibilityEnabled)
|
||||
if (mAccessibilityNodeProvider.isAccessibilityEnabled()) {
|
||||
return mAccessibilityNodeProvider;
|
||||
// TODO(goderbauer): when a11y is off this should return a one-off snapshot of
|
||||
// the a11y
|
||||
// tree.
|
||||
return null;
|
||||
}
|
||||
|
||||
void ensureAccessibilityEnabled() {
|
||||
if (!isAttached())
|
||||
return;
|
||||
mAccessibilityEnabled = true;
|
||||
if (mAccessibilityNodeProvider == null) {
|
||||
mAccessibilityNodeProvider = new AccessibilityBridge(this, accessibilityChannel);
|
||||
}
|
||||
mNativeView.getFlutterJNI().setSemanticsEnabled(true);
|
||||
mAccessibilityNodeProvider.setAccessibilityEnabled(true);
|
||||
}
|
||||
|
||||
void resetAccessibilityTree() {
|
||||
if (mAccessibilityNodeProvider != null) {
|
||||
mAccessibilityNodeProvider.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleAccessibilityHoverEvent(MotionEvent event) {
|
||||
if (!mTouchExplorationEnabled) {
|
||||
return false;
|
||||
}
|
||||
if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER || event.getAction() == MotionEvent.ACTION_HOVER_MOVE) {
|
||||
mAccessibilityNodeProvider.handleTouchExploration(event.getX(), event.getY());
|
||||
} else if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
|
||||
mAccessibilityNodeProvider.handleTouchExplorationExit();
|
||||
} else {
|
||||
Log.d("flutter", "unexpected accessibility hover event: " + event);
|
||||
return false;
|
||||
// TODO(goderbauer): when a11y is off this should return a one-off snapshot of
|
||||
// the a11y
|
||||
// tree.
|
||||
return null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
<issue
|
||||
id="Assert"
|
||||
message="Assertions are unreliable in Dalvik and unimplemented in ART. Use `BuildConfig.DEBUG` conditional checks instead."
|
||||
errorLine1=" assert object.id > ROOT_NODE_ID;"
|
||||
errorLine1=" assert semanticsNode.id > ROOT_NODE_ID;"
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="273"
|
||||
line="537"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="Assert"
|
||||
message="Assertions are unreliable in Dalvik and unimplemented in ART. Use `BuildConfig.DEBUG` conditional checks instead."
|
||||
errorLine1=" assert object.id == ROOT_NODE_ID;"
|
||||
errorLine1=" assert semanticsNode.id == ROOT_NODE_ID;"
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="276"
|
||||
line="540"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@@ -30,18 +30,18 @@
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="378"
|
||||
line="649"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="Assert"
|
||||
message="Assertions are unreliable in Dalvik and unimplemented in ART. Use `BuildConfig.DEBUG` conditional checks instead."
|
||||
errorLine1=" assert objects.containsKey(0);"
|
||||
errorLine1=" assert flutterSemanticsTree.containsKey(0);"
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="644"
|
||||
line="984"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="824"
|
||||
line="1240"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="825"
|
||||
line="1241"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
@@ -74,29 +74,29 @@
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="919"
|
||||
line="1393"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="Assert"
|
||||
message="Assertions are unreliable in Dalvik and unimplemented in ART. Use `BuildConfig.DEBUG` conditional checks instead."
|
||||
errorLine1=" assert objects.containsKey(object.id);"
|
||||
errorLine1=" assert flutterSemanticsTree.containsKey(semanticsNodeToBeRemoved.id);"
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="953"
|
||||
line="1405"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="Assert"
|
||||
message="Assertions are unreliable in Dalvik and unimplemented in ART. Use `BuildConfig.DEBUG` conditional checks instead."
|
||||
errorLine1=" assert objects.get(object.id) == object;"
|
||||
errorLine1=" assert flutterSemanticsTree.get(semanticsNodeToBeRemoved.id) == semanticsNodeToBeRemoved;"
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="954"
|
||||
line="1406"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="1098"
|
||||
line="1701"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="1227"
|
||||
line="1830"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="1249"
|
||||
line="1852"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@@ -305,7 +305,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/ResourceExtractor.java"
|
||||
line="47"
|
||||
line="48"
|
||||
column="19"/>
|
||||
</issue>
|
||||
|
||||
@@ -327,7 +327,7 @@
|
||||
errorLine2=" ^">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="1115"
|
||||
line="1718"
|
||||
column="13"/>
|
||||
</issue>
|
||||
|
||||
@@ -360,7 +360,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/ResourceExtractor.java"
|
||||
line="200"
|
||||
line="201"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
@@ -371,7 +371,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/ResourceExtractor.java"
|
||||
line="327"
|
||||
line="328"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
@@ -432,24 +432,24 @@
|
||||
|
||||
<issue
|
||||
id="UseSparseArrays"
|
||||
message="Use `new SparseArray<SemanticsObject>(...)` instead for better performance"
|
||||
errorLine1=" objects = new HashMap<>();"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~">
|
||||
message="Use `new SparseArray<SemanticsNode>(...)` instead for better performance"
|
||||
errorLine1=" private final Map<Integer, SemanticsNode> flutterSemanticsTree = new HashMap<>();"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="142"
|
||||
column="19"/>
|
||||
line="135"
|
||||
column="70"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="UseSparseArrays"
|
||||
message="Use `new SparseArray<CustomAccessibilityAction>(...)` instead for better performance"
|
||||
errorLine1=" customAccessibilityActions = new HashMap<>();"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~">
|
||||
errorLine1=" private final Map<Integer, CustomAccessibilityAction> customAccessibilityActions = new HashMap<>();"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java"
|
||||
line="143"
|
||||
column="38"/>
|
||||
line="160"
|
||||
column="88"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
@@ -492,7 +492,7 @@
|
||||
errorLine2=" ~~~~~~~~~~~~">
|
||||
<location
|
||||
file="../../../flutter/shell/platform/android/io/flutter/view/FlutterView.java"
|
||||
line="511"
|
||||
line="508"
|
||||
column="20"/>
|
||||
</issue>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user