下面列出了android.view.accessibility.AccessibilityWindowInfo#TYPE_SYSTEM 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private boolean isSystemWindow(int windowId) {
if (systemWindowIdsSet.contains(windowId)) {
return true;
}
if (!isSplitScreenModeAvailable) {
return false;
}
for (AccessibilityWindowInfo window : AccessibilityServiceCompatUtils.getWindows(service)) {
if (window.getId() == windowId && window.getType() == AccessibilityWindowInfo.TYPE_SYSTEM) {
return true;
}
}
return false;
}
private static String windowTypeToString(int type) {
switch (type) {
case AccessibilityWindowInfo.TYPE_APPLICATION:
return "TYPE_APPLICATION";
case AccessibilityWindowInfo.TYPE_INPUT_METHOD:
return "TYPE_INPUT_METHOD";
case AccessibilityWindowInfo.TYPE_SYSTEM:
return "TYPE_SYSTEM";
case AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY:
return "TYPE_ACCESSIBILITY_OVERLAY";
case AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER:
return "TYPE_SPLIT_SCREEN_DIVIDER";
default:
return "UNKNOWN";
}
}
private void removeStatusBarButtonsFromWindowList(List<SwitchAccessWindowInfo> windowList) {
int statusBarHeight = DisplayUtils.getStatusBarHeightInPixel(service);
final Iterator<SwitchAccessWindowInfo> windowIterator = windowList.iterator();
while (windowIterator.hasNext()) {
SwitchAccessWindowInfo window = windowIterator.next();
/* Keep all non-system buttons */
if (window.getType() != AccessibilityWindowInfo.TYPE_SYSTEM) {
continue;
}
final Rect windowBounds = new Rect();
window.getBoundsInScreen(windowBounds);
/* Filter out items in the status bar */
if ((windowBounds.bottom <= statusBarHeight)) {
windowIterator.remove();
}
}
}
/**
* Returns title of window with given window ID.
*
* <p><strong>Note: </strong> This method returns null if the window has no title, or the window
* is not visible, or the window is IME or system window.
*/
@Nullable
public CharSequence getWindowTitle(int windowId) {
AccessibilityWindowInfo window = idToWindowInfoMap.get(windowId);
if ((window == null)
|| (window.getType() == AccessibilityWindowInfo.TYPE_INPUT_METHOD)
|| (window.getType() == AccessibilityWindowInfo.TYPE_SYSTEM)
|| (window.getType() == AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER)) {
// Only return title for application or accessibility windows.
return null;
}
CharSequence eventTitle = overriddenWindowTitles.get(windowId);
if (!TextUtils.isEmpty(eventTitle)) {
return eventTitle;
}
if (BuildVersionUtils.isAtLeastN()) {
// AccessibilityWindowInfo.getTitle() is available since API 24.
CharSequence infoTitle = window.getTitle();
if (!TextUtils.isEmpty(infoTitle)) {
return infoTitle;
}
}
return null;
}
public boolean isStatusBar(int windowId) {
if (mWindows == null || mWindows.size() == 0) {
return false;
}
return mWindows.get(0).getId() == windowId
&& mWindows.get(0).getType() == AccessibilityWindowInfo.TYPE_SYSTEM;
}
public boolean isNavigationBar(int windowId) {
if (mWindows == null || mWindows.size() < 2) {
return false;
}
int lastIndex = mWindows.size() - 1;
return mWindows.get(lastIndex).getId() == windowId
&& mWindows.get(lastIndex).getType() == AccessibilityWindowInfo.TYPE_SYSTEM;
}
@Override
public boolean accept(AccessibilityWindowInfo window) {
if (window == null) {
return false;
}
int type = window.getType();
return (type == AccessibilityWindowInfo.TYPE_APPLICATION)
|| (type == AccessibilityWindowInfo.TYPE_SYSTEM);
}
/**
* Restores last focus from {@link AccessibilityFocusActionHistory} to the active window. Caller
* should recycle {@code root}.
*
* @param root root node in the active window
* @param windowType current active window type
* @param windowId current active window id
* @param windowTitle current active window title
* @param eventId event id
* @return {@code true} if successfully restore and set accessibility focus on the node.
*/
protected boolean restoreLastFocusedNode(
AccessibilityNodeInfoCompat root,
int windowType,
int windowId,
@Nullable CharSequence windowTitle,
EventId eventId) {
if (windowType == AccessibilityWindowInfo.TYPE_SYSTEM) {
// Don't restore focus in system window. A exemption is when context menu closes, we might
// restore focus in a system window in restoreFocusForContextMenu().
LogUtils.d(TAG, "Do not restore focus in system ui window.");
return false;
}
AccessibilityFocusActionHistory.Reader history = actorState.getFocusHistory();
final FocusActionRecord lastFocusAction =
history.getLastFocusActionRecordInWindow(windowId, windowTitle);
if (lastFocusAction == null) {
return false;
}
AccessibilityNodeInfoCompat nodeToRestoreFocus = getNodeToRestoreFocus(root, lastFocusAction);
try {
return (nodeToRestoreFocus != null)
&& nodeToRestoreFocus.isVisibleToUser()
// When a pane changes, the nodes not in the pane become out of the window even though
// they are still visible to user. The window id and title don't change, so the last
// focused node, which searches from getFocusHistory(), may not be in the window.
&& AccessibilityNodeInfoUtils.isInWindow(nodeToRestoreFocus, root.getWindow())
&& pipeline.returnFeedback(
eventId, Feedback.focus(nodeToRestoreFocus, FOCUS_ACTION_INFO_RESTORED));
} finally {
AccessibilityNodeInfoUtils.recycleNodes(nodeToRestoreFocus);
}
}
/**
* Starts the SummaryActivity, passing it the application window which will be used to generate
* the screen summary.
*/
public static void showOutput(AccessibilityService service) {
List<AccessibilityWindowInfo> windows = AccessibilityServiceCompatUtils.getWindows(service);
ArrayList<ArrayList<NodeData>> nodeDataList = new ArrayList<ArrayList<NodeData>>();
for (int i = 0; i < TreeTraversal.ZONE_COUNT; i++) {
nodeDataList.add(new ArrayList<NodeData>());
}
// Collect summary info from all windows of type application to account for split screen mode.
// Also collect info if the window is an active system window, such as notification shade.
for (AccessibilityWindowInfo window : windows) {
int windowType = window.getType();
if (windowType == AccessibilityWindowInfo.TYPE_APPLICATION
|| (window.getType() == AccessibilityWindowInfo.TYPE_SYSTEM && window.isActive())) {
ArrayList<ArrayList<NodeData>> windowSummary = TreeTraversal.checkRootNode(window, service);
for (int i = 0; i < TreeTraversal.ZONE_COUNT; i++) {
nodeDataList.get(i).addAll(windowSummary.get(i));
}
}
}
// Attach summary elements to their location names in LocationData. Only add to the LocationData
// list if the list of summary items is non empty.
ArrayList<LocationData> locationDataList = new ArrayList<LocationData>();
String[] locationNames = getLocationNames(service);
for (int i = 0; i < TreeTraversal.ZONE_COUNT; i++) {
ArrayList<NodeData> nodeDataSubList = nodeDataList.get(i);
if (!nodeDataSubList.isEmpty()) {
locationDataList.add(new LocationData(locationNames[i], nodeDataList.get(i)));
}
}
showDialog(service, locationDataList);
}
private static boolean isSystemOrImeWindow(AccessibilityWindowInfo window) {
return (window.getType() == AccessibilityWindowInfo.TYPE_INPUT_METHOD)
|| (window.getType() == AccessibilityWindowInfo.TYPE_SYSTEM);
}