https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/accessibilityservice/AccessibilityButtonController.java?hl=zh-cn
代码如下:
package android.accessibilityservice;
import android.annotation.NonNull;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Slog;
import java.util.Objects;
public final class AccessibilityButtonController {
private static final String LOG_TAG = "A11yButtonController";
private final IAccessibilityServiceConnection mServiceConnection;
private final Object mLock;
private ArrayMap<AccessibilityButtonCallback, Handler> mCallbacks;
AccessibilityButtonController(@NonNull IAccessibilityServiceConnection serviceConnection) {
mServiceConnection = serviceConnection;
mLock = new Object();
}
public boolean isAccessibilityButtonAvailable() {
if (mServiceConnection != null) {
try {
return mServiceConnection.isAccessibilityButtonAvailable();
} catch (RemoteException re) {
Slog.w(LOG_TAG, "Failed to get accessibility button availability.", re);
re.rethrowFromSystemServer();
return false;
}
}
return false;
}
public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback) {
registerAccessibilityButtonCallback(callback, new Handler(Looper.getMainLooper()));
}
public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback,
@NonNull Handler handler) {
Objects.requireNonNull(callback);
Objects.requireNonNull(handler);
synchronized (mLock) {
if (mCallbacks == null) {
mCallbacks = new ArrayMap<>();
}
mCallbacks.put(callback, handler);
}
}
public void unregisterAccessibilityButtonCallback(
@NonNull AccessibilityButtonCallback callback) {
Objects.requireNonNull(callback);
synchronized (mLock) {
if (mCallbacks == null) {
return;
}
final int keyIndex = mCallbacks.indexOfKey(callback);
final boolean hasKey = keyIndex >= 0;
if (hasKey) {
mCallbacks.removeAt(keyIndex);
}
}
}
void dispatchAccessibilityButtonClicked() {
final ArrayMap<AccessibilityButtonCallback, Handler> entries;
synchronized (mLock) {
if (mCallbacks == null || mCallbacks.isEmpty()) {
Slog.w(LOG_TAG, "Received accessibility button click with no callbacks!");
return;
}
// Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
// modification.
entries = new ArrayMap<>(mCallbacks);
}
for (int i = 0, count = entries.size(); i < count; i++) {
final AccessibilityButtonCallback callback = entries.keyAt(i);
final Handler handler = entries.valueAt(i);
handler.post(() -> callback.onClicked(this));
}
}
void dispatchAccessibilityButtonAvailabilityChanged(boolean available) {
final ArrayMap<AccessibilityButtonCallback, Handler> entries;
synchronized (mLock) {
if (mCallbacks == null || mCallbacks.isEmpty()) {
Slog.w(LOG_TAG,
"Received accessibility button availability change with no callbacks!");
return;
}
// Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
// modification.
entries = new ArrayMap<>(mCallbacks);
}
for (int i = 0, count = entries.size(); i < count; i++) {
final AccessibilityButtonCallback callback = entries.keyAt(i);
final Handler handler = entries.valueAt(i);
handler.post(() -> callback.onAvailabilityChanged(this, available));
}
}
public static abstract class AccessibilityButtonCallback {
public void onClicked(AccessibilityButtonController controller) {}
public void onAvailabilityChanged(AccessibilityButtonController controller,
boolean available) {
}
}
}
private static final String LOG_TAG = "A11yButtonController";
private final IAccessibilityServiceConnection mServiceConnection;
private final Object mLock;
private ArrayMap<AccessibilityButtonCallback, Handler> mCallbacks;
AccessibilityButtonController(@NonNull IAccessibilityServiceConnection serviceConnection) {
mServiceConnection = serviceConnection;
mLock = new Object();
}
private static final String LOG_TAG = "A11yButtonController";
这一行定义了一个私有的、静态的、最终的字符串变量,它的值是"A11yButtonController",用于作为日志的标签。私有的意思是只有这个类自己可以访问这个变量,静态的意思是这个变量不属于任何对象,而是属于这个类,最终的意思是这个变量的值不能被修改。private final IAccessibilityServiceConnection mServiceConnection;
这一行定义了一个私有的、最终的接口类型的变量,它的值是一个实现了IAccessibilityServiceConnection接口的对象,用于表示一个无障碍服务的连接。私有的意思是只有这个类自己可以访问这个变量,最终的意思是这个变量的值不能被修改,但是这个对象的属性可以被修改。private final Object mLock;
这一行定义了一个私有的、最终的对象类型的变量,它的值是一个Object对象,用于作为一个锁对象,用于保护临界区的同步。私有的意思是只有这个类自己可以访问这个变量,最终的意思是这个变量的值不能被修改,但是这个对象的属性可以被修改。private ArrayMap mCallbacks;
这一行定义了一个私有的数组映射类型的变量,它的值是一个ArrayMap对象,用于存储无障碍按钮的回调函数和处理器的键值对。私有的意思是只有这个类自己可以访问这个变量,这个变量的值可以被修改,也就是可以添加或删除键值对。AccessibilityButtonController(@NonNull IAccessibilityServiceConnection serviceConnection) {
这一行定义了一个构造函数,它的参数是一个非空的IAccessibilityServiceConnection类型的对象,用于初始化这个类的对象。mServiceConnection = serviceConnection;
这一行是构造函数的一条语句,它的作用是将参数serviceConnection的值赋给变量mServiceConnection,也就是初始化这个类的无障碍服务连接。mLock = new Object();
这一行是构造函数的另一条语句,它的作用是创建一个新的Object对象,并将其赋给变量mLock,也就是初始化这个类的锁对象。 public boolean isAccessibilityButtonAvailable() {
if (mServiceConnection != null) {
try {
return mServiceConnection.isAccessibilityButtonAvailable();
} catch (RemoteException re) {
Slog.w(LOG_TAG, "Failed to get accessibility button availability.", re);
re.rethrowFromSystemServer();
return false;
}
}
return false;
}
总之,这个方法的作用是判断无障碍按钮是否可用,它的逻辑是先检查无障碍服务连接对象是否存在,然后尝试调用它的方法来获取无障碍按钮的可用性,如果发生异常,就打印日志,重新抛出异常,并返回false。
public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback) {
registerAccessibilityButtonCallback(callback, new Handler(Looper.getMainLooper()));
}
总之,这个方法的作用是注册一个无障碍按钮的回调函数,它的逻辑是调用另一个同名但是参数不同的方法,简化了方法的调用,让用户不需要自己创建一个Handler对象。
public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback,
@NonNull Handler handler) {
Objects.requireNonNull(callback);
Objects.requireNonNull(handler);
synchronized (mLock) {
if (mCallbacks == null) {
mCallbacks = new ArrayMap<>();
}
mCallbacks.put(callback, handler);
}
}
总之,这个方法的作用是注册一个无障碍按钮的回调函数和处理器,它的逻辑是先对参数进行非空检查,然后使用一个锁对象进行同步,再判断是否需要初始化数组映射对象,最后将参数添加到数组映射中。
public void unregisterAccessibilityButtonCallback(
@NonNull AccessibilityButtonCallback callback) {
Objects.requireNonNull(callback);
synchronized (mLock) {
if (mCallbacks == null) {
return;
}
final int keyIndex = mCallbacks.indexOfKey(callback);
final boolean hasKey = keyIndex >= 0;
if (hasKey) {
mCallbacks.removeAt(keyIndex);
}
}
}
总之,这个方法的作用是取消注册一个无障碍按钮的回调函数,它的逻辑是先对参数进行非空检查,然后使用一个锁对象进行同步,再判断是否需要从数组映射中删除对应的键值对。
void dispatchAccessibilityButtonClicked() {
final ArrayMap<AccessibilityButtonCallback, Handler> entries;
synchronized (mLock) {
if (mCallbacks == null || mCallbacks.isEmpty()) {
Slog.w(LOG_TAG, "Received accessibility button click with no callbacks!");
return;
}
// Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
// modification.
entries = new ArrayMap<>(mCallbacks);
}
for (int i = 0, count = entries.size(); i < count; i++) {
final AccessibilityButtonCallback callback = entries.keyAt(i);
final Handler handler = entries.valueAt(i);
handler.post(() -> callback.onClicked(this));
}
}
总之,这个方法的作用是分发无障碍按钮的点击事件给已注册的回调函数,它的逻辑是先检查数组映射对象是否存在或为空,然后使用一个锁对象进行同步,再对数组映射对象进行浅拷贝,最后遍历数组映射对象中的所有键值对,通过处理器对象执行回调函数对象的逻辑。
void dispatchAccessibilityButtonAvailabilityChanged(boolean available) {
final ArrayMap<AccessibilityButtonCallback, Handler> entries;
synchronized (mLock) {
if (mCallbacks == null || mCallbacks.isEmpty()) {
Slog.w(LOG_TAG,
"Received accessibility button availability change with no callbacks!");
return;
}
// Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
// modification.
entries = new ArrayMap<>(mCallbacks);
}
for (int i = 0, count = entries.size(); i < count; i++) {
final AccessibilityButtonCallback callback = entries.keyAt(i);
final Handler handler = entries.valueAt(i);
handler.post(() -> callback.onAvailabilityChanged(this, available));
}
}
总之,这个方法的作用是分发无障碍按钮的可用性变化事件给已注册的回调函数,它的逻辑是先检查数组映射对象是否存在或为空,然后使用一个锁对象进行同步,再对数组映射对象进行浅拷贝,最后遍历数组映射对象中的所有键值对,通过处理器对象执行回调函数对象的逻辑。
public static abstract class AccessibilityButtonCallback {
public void onClicked(AccessibilityButtonController controller) {}
public void onAvailabilityChanged(AccessibilityButtonController controller,
boolean available) {
}
}
总之,这个类的作用是定义一个无障碍按钮的回调函数的接口,它的逻辑是声明两个抽象的方法,让其他类可以继承它并实现它的方法,以便在无障碍按钮的事件发生时,执行相应的逻辑。
AccessibilityButtonController.java 这个文件是 Android 框架的一部分,它提供了一个控制器类,用于管理系统导航区域中的辅助功能按钮。这个类的主要逻辑和作用如下: