下面列出了android.view.accessibility.AccessibilityWindowInfo#getId ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public CharSequence getWindowTitle(int windowId) {
// Try to get window title from the map.
CharSequence windowTitle = windowTitlesMap.get(windowId);
if (windowTitle != null) {
return windowTitle;
}
if (!BuildVersionUtils.isAtLeastN()) {
return null;
}
// Do not try to get system window title from AccessibilityWindowInfo.getTitle, it can
// return non-translated value.
if (isSystemWindow(windowId)) {
return null;
}
// Try to get window title from AccessibilityWindowInfo.
for (AccessibilityWindowInfo window : AccessibilityServiceCompatUtils.getWindows(service)) {
if (window.getId() == windowId) {
return window.getTitle();
}
}
return null;
}
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;
}
public int getWindowType(int windowId) {
if (mWindows != null) {
for (AccessibilityWindowInfo window : mWindows) {
if (window != null && window.getId() == windowId) {
return window.getType();
}
}
}
return WRONG_WINDOW_TYPE;
}
private boolean hasValidAccessibilityFocusInWindow(AccessibilityWindowInfo window) {
AccessibilityNodeInfoCompat currentFocus = null;
try {
currentFocus =
accessibilityFocusMonitor.getAccessibilityFocus(/* useInputFocusIfEmpty= */ false);
return (currentFocus != null)
&& AccessibilityNodeInfoUtils.isVisible(currentFocus)
&& (currentFocus.getWindowId() == window.getId());
} finally {
AccessibilityNodeInfoUtils.recycleNodes(currentFocus);
}
}
@Nullable
private AccessibilityWindowInfo getWindowInfoById(
List<AccessibilityWindowInfo> windows, int windowId) {
if (windowId < 0) {
return null;
}
for (AccessibilityWindowInfo window : windows) {
if (window.getId() == windowId) {
return window;
}
}
return null;
}
private WindowHierarchyElementAndroid construct(
int id,
@Nullable WindowHierarchyElementAndroid parent,
AccessibilityWindowInfo fromWindow,
Map<ViewHierarchyElementAndroid, AccessibilityNodeInfo> elementToNodeInfoMap) {
// Bookkeeping
this.parentId = (parent != null) ? parent.getId() : null;
// Window properties
this.windowId = fromWindow.getId();
this.layer = fromWindow.getLayer();
this.type = fromWindow.getType();
this.focused = fromWindow.isFocused();
this.accessibilityFocused = fromWindow.isAccessibilityFocused();
this.active = fromWindow.isActive();
android.graphics.Rect tempRect = new android.graphics.Rect();
fromWindow.getBoundsInScreen(tempRect);
this.boundsInScreen = new Rect(tempRect.left, tempRect.top, tempRect.right, tempRect.bottom);
// Build the window's view hierarchy
AccessibilityNodeInfo rootInfo = fromWindow.getRoot();
this.viewHierarchyElements = new ArrayList<>(); // The ultimate size is unknown
if (rootInfo != null) {
buildViewHierarchy(
rootInfo, viewHierarchyElements, null /* no parent */, elementToNodeInfoMap);
rootInfo.recycle();
} else {
// This could occur in the case where the application state changes between the time that
// the AccessibilityWindowInfo object is obtained and when its root AccessibilityNodeInfo is
// extracted.
LogUtils.w(TAG, "Constructed WindowHierarchyElement with no valid root.");
}
return new WindowHierarchyElementAndroid(
id,
parentId,
childIds,
windowId,
layer,
type,
focused,
accessibilityFocused,
active,
boundsInScreen,
viewHierarchyElements);
}
public boolean onScreenStateChanged(
@Nullable ScreenState oldScreenState,
@NonNull ScreenState newScreenState,
long startTime,
EventId eventId) {
try {
primesController.startTimer(Timer.INITIALIZE_FOCUS);
if (oldScreenState == null) {
// We don't have old ScreenState when TalkBack starts.
return false;
}
AccessibilityWindowInfo currentActiveWindow = newScreenState.getActiveWindow();
if (currentActiveWindow == null) {
LogUtils.w(TAG, "Cannot find active window.");
return false;
}
int activeWindowId = currentActiveWindow.getId();
CharSequence activeWindowTitle = newScreenState.getWindowTitle(activeWindowId);
AccessibilityFocusActionHistory.Reader history = actorState.getFocusHistory();
// Fix , initial focus will be skipped if user interacts on old window. So we only
// skip initial focus if the interaction is happened on active window to ensure it can grant
// focus.
FocusActionRecord lastRecordOnActiveWindow =
history.getLastFocusActionRecordInWindow(activeWindowId, activeWindowTitle);
if ((lastRecordOnActiveWindow != null)
&& (lastRecordOnActiveWindow.getActionTime() > startTime)) {
int sourceAction = lastRecordOnActiveWindow.getExtraInfo().sourceAction;
if ((sourceAction == FocusActionInfo.TOUCH_EXPLORATION)
|| (sourceAction == FocusActionInfo.LOGICAL_NAVIGATION)) {
LogUtils.v(
TAG,
"User changes accessibility focus on active window during window transition, "
+ "don't set initial focus here.");
return false;
}
}
AccessibilityWindowInfo previousActiveWindow = oldScreenState.getActiveWindow();
if (AccessibilityWindowInfoUtils.equals(currentActiveWindow, previousActiveWindow)
&& TextUtils.equals(
newScreenState.getActiveWindowTitle(), oldScreenState.getActiveWindowTitle())) {
LogUtils.v(TAG, "Do not reassign initial focus when active window is not changed.");
return false;
}
if (isActiveWindowShiftingWithIdenticalWindowSet(oldScreenState, newScreenState)) {
LogUtils.v(
TAG,
"Do not assign initial focus when active window shifts with window set unchanged.");
return false;
}
if (hasValidAccessibilityFocusInWindow(currentActiveWindow)) {
return false;
}
if (actorState.getOverrideFocusRestoreUptimeMs() > handledOverrideFocusRestoreUptimeMs) {
if (pipeline.returnFeedback(eventId, Feedback.focus(RESTORE))) {
return true;
}
}
return assignFocusOnWindow(currentActiveWindow, activeWindowTitle, eventId);
} finally {
/**
* Refresh the update-time whenever window transition finished. Sometimes focus won't restore
* in special cases, like dismiss dialog when screen off. If we don't refresh the flag, it
* won't restore focus at screen off stage but restore focus at next visible window transition
* instead.
*/
handledOverrideFocusRestoreUptimeMs = actorState.getOverrideFocusRestoreUptimeMs();
primesController.stopTimer(Timer.INITIALIZE_FOCUS);
}
}