1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package com.yourcompany.platforminteraction; 6 7 import java.util.HashMap; 8 import java.util.Map; 9 import java.util.List; 10 import java.util.ArrayList; 11 import java.lang.StringBuilder; 12 13 import android.graphics.Rect; 14 import android.os.Bundle; 15 import android.util.DisplayMetrics; 16 import android.view.WindowManager; 17 import android.content.Context; 18 19 import io.flutter.app.FlutterActivity; 20 import io.flutter.plugin.common.MethodCall; 21 import io.flutter.plugin.common.MethodChannel; 22 import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 23 import io.flutter.plugins.GeneratedPluginRegistrant; 24 import io.flutter.view.FlutterView; 25 26 import android.view.accessibility.AccessibilityManager; 27 import android.view.accessibility.AccessibilityNodeProvider; 28 import android.view.accessibility.AccessibilityNodeInfo; 29 30 public class MainActivity extends FlutterActivity { 31 @Override onCreate(Bundle savedInstanceState)32 protected void onCreate(Bundle savedInstanceState) { 33 super.onCreate(savedInstanceState); 34 GeneratedPluginRegistrant.registerWith(this); 35 new MethodChannel(getFlutterView(), "semantics").setMethodCallHandler(new SemanticsTesterMethodHandler()); 36 } 37 38 class SemanticsTesterMethodHandler implements MethodCallHandler { 39 Float mScreenDensity = 1.0f; 40 41 @Override onMethodCall(MethodCall methodCall, MethodChannel.Result result)42 public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { 43 FlutterView flutterView = getFlutterView(); 44 AccessibilityNodeProvider provider = flutterView.getAccessibilityNodeProvider(); 45 DisplayMetrics displayMetrics = new DisplayMetrics(); 46 WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); 47 wm.getDefaultDisplay().getMetrics(displayMetrics); 48 mScreenDensity = displayMetrics.density; 49 if (methodCall.method.equals("getSemanticsNode")) { 50 Map<String, Object> data = methodCall.arguments(); 51 @SuppressWarnings("unchecked") 52 Integer id = (Integer) data.get("id"); 53 if (id == null) { 54 result.error("No ID provided", "", null); 55 return; 56 } 57 if (provider == null) { 58 result.error("Semantics not enabled", "", null); 59 return; 60 } 61 AccessibilityNodeInfo node = provider.createAccessibilityNodeInfo(id); 62 result.success(convertSemantics(node, id)); 63 return; 64 } 65 result.notImplemented(); 66 } 67 68 @SuppressWarnings("unchecked") convertSemantics(AccessibilityNodeInfo node, int id)69 private Map<String, Object> convertSemantics(AccessibilityNodeInfo node, int id) { 70 if (node == null) 71 return null; 72 Map<String, Object> result = new HashMap<>(); 73 Map<String, Object> flags = new HashMap<>(); 74 Map<String, Object> rect = new HashMap<>(); 75 result.put("id", id); 76 result.put("text", node.getText()); 77 result.put("contentDescription", node.getContentDescription()); 78 flags.put("isChecked", node.isChecked()); 79 flags.put("isCheckable", node.isCheckable()); 80 flags.put("isDismissable", node.isDismissable()); 81 flags.put("isEditable", node.isEditable()); 82 flags.put("isEnabled", node.isEnabled()); 83 flags.put("isFocusable", node.isFocusable()); 84 flags.put("isFocused", node.isFocused()); 85 flags.put("isPassword", node.isPassword()); 86 flags.put("isLongClickable", node.isLongClickable()); 87 result.put("flags", flags); 88 Rect nodeRect = new Rect(); 89 node.getBoundsInScreen(nodeRect); 90 rect.put("left", nodeRect.left / mScreenDensity); 91 rect.put("top", nodeRect.top/ mScreenDensity); 92 rect.put("right", nodeRect.right / mScreenDensity); 93 rect.put("bottom", nodeRect.bottom/ mScreenDensity); 94 rect.put("width", nodeRect.width()); 95 rect.put("height", nodeRect.height()); 96 result.put("rect", rect); 97 result.put("className", node.getClassName()); 98 result.put("contentDescription", node.getContentDescription()); 99 result.put("liveRegion", node.getLiveRegion()); 100 List<AccessibilityNodeInfo.AccessibilityAction> actionList = node.getActionList(); 101 if (actionList.size() > 0) { 102 ArrayList<Integer> actions = new ArrayList<>(); 103 for (AccessibilityNodeInfo.AccessibilityAction action : actionList) { 104 actions.add(action.getId()); 105 } 106 result.put("actions", actions); 107 } 108 return result; 109 } 110 } 111 } 112