Merge "Resolve 3 inconsistencies in accessibility button API - Unify logic for detecting availability of the accessibility button - Ensure the initial visibility state is propagated to A11yMS - Ensure services only receive availability callbacks for changes" into oc-dev

am: 4ab690a50d

Change-Id: I38798fabc99c8db5618a6bd39c8eb6953dbf2bbb
This commit is contained in:
Casey Burkhardt
2017-06-17 00:52:46 +00:00
committed by android-build-merger
5 changed files with 88 additions and 36 deletions

View File

@@ -912,14 +912,14 @@ public final class AccessibilityManager {
}
/**
* Notifies that the availability of the accessibility button in the system's navigation area
* Notifies that the visibility of the accessibility button in the system's navigation area
* has changed.
*
* @param available {@code true} if the accessibility button is available within the system
* @param shown {@code true} if the accessibility button is visible within the system
* navigation area, {@code false} otherwise
* @hide
*/
public void notifyAccessibilityButtonAvailabilityChanged(boolean available) {
public void notifyAccessibilityButtonVisibilityChanged(boolean shown) {
final IAccessibilityManager service;
synchronized (mLock) {
service = getServiceLocked();
@@ -928,9 +928,9 @@ public final class AccessibilityManager {
}
}
try {
service.notifyAccessibilityButtonAvailabilityChanged(available);
service.notifyAccessibilityButtonVisibilityChanged(shown);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error while dispatching accessibility button availability change", re);
Log.e(LOG_TAG, "Error while dispatching accessibility button visibility change", re);
}
}

View File

@@ -64,7 +64,7 @@ interface IAccessibilityManager {
void notifyAccessibilityButtonClicked();
void notifyAccessibilityButtonAvailabilityChanged(boolean available);
void notifyAccessibilityButtonVisibilityChanged(boolean available);
// Requires WRITE_SECURE_SETTINGS
void performAccessibilityShortcut();

View File

@@ -243,6 +243,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private WindowsForAccessibilityCallback mWindowsForAccessibilityCallback;
private boolean mIsAccessibilityButtonShown;
private UserState getCurrentUserStateLocked() {
return getUserStateLocked(mCurrentUserId);
}
@@ -881,21 +883,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
/**
* Invoked remotely over AIDL by SysUi when the availability of the accessibility
* Invoked remotely over AIDL by SysUi when the visibility of the accessibility
* button within the system's navigation area has changed.
*
* @param available {@code true} if the accessibility button is available to the
* @param shown {@code true} if the accessibility button is shown to the
* user, {@code false} otherwise
*/
@Override
public void notifyAccessibilityButtonAvailabilityChanged(boolean available) {
public void notifyAccessibilityButtonVisibilityChanged(boolean shown) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Caller does not hold permission "
+ android.Manifest.permission.STATUS_BAR_SERVICE);
}
synchronized (mLock) {
notifyAccessibilityButtonAvailabilityChangedLocked(available);
notifyAccessibilityButtonVisibilityChangedLocked(shown);
}
}
@@ -1200,13 +1202,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
private void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
private void notifyAccessibilityButtonVisibilityChangedLocked(boolean available) {
final UserState state = getCurrentUserStateLocked();
state.mIsAccessibilityButtonAvailable = available;
mIsAccessibilityButtonShown = available;
for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
final Service service = state.mBoundServices.get(i);
if (service.mRequestAccessibilityButton) {
service.notifyAccessibilityButtonAvailabilityChangedLocked(available);
service.notifyAccessibilityButtonAvailabilityChangedLocked(
service.isAccessibilityButtonAvailableLocked(state));
}
}
}
@@ -1733,7 +1736,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
scheduleUpdateInputFilter(userState);
scheduleUpdateClientsIfNeededLocked(userState);
updateRelevantEventsLocked(userState);
updateAccessibilityButtonTargets(userState);
updateAccessibilityButtonTargetsLocked(userState);
}
private void updateAccessibilityFocusBehaviorLocked(UserState userState) {
@@ -2183,18 +2186,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
private void updateAccessibilityButtonTargets(UserState userState) {
final List<Service> services;
synchronized (mLock) {
services = userState.mBoundServices;
int numServices = services.size();
for (int i = 0; i < numServices; i++) {
final Service service = services.get(i);
if (service.mRequestAccessibilityButton) {
boolean available = service.mComponentName.equals(
userState.mServiceAssignedToAccessibilityButton);
service.notifyAccessibilityButtonAvailabilityChangedLocked(available);
}
private void updateAccessibilityButtonTargetsLocked(UserState userState) {
for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
final Service service = userState.mBoundServices.get(i);
if (service.mRequestAccessibilityButton) {
service.notifyAccessibilityButtonAvailabilityChangedLocked(
service.isAccessibilityButtonAvailableLocked(userState));
}
}
}
@@ -2501,7 +2498,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
case MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER: {
showAccessibilityButtonTargetSelection();
}
} break;
}
}
@@ -2656,6 +2653,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
boolean mRequestAccessibilityButton;
boolean mReceivedAccessibilityButtonCallbackSinceBind;
boolean mLastAccessibilityButtonCallbackState;
int mFetchFlags;
long mNotificationTimeout;
@@ -3596,9 +3597,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return false;
}
userState = getCurrentUserStateLocked();
return isAccessibilityButtonAvailableLocked(userState);
}
return mRequestAccessibilityButton && userState.mIsAccessibilityButtonAvailable;
}
@Override
@@ -3656,6 +3656,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mService = null;
}
mServiceInterface = null;
mReceivedAccessibilityButtonCallbackSinceBind = false;
}
public boolean isConnectedLocked() {
@@ -3728,6 +3729,48 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
private boolean isAccessibilityButtonAvailableLocked(UserState userState) {
// If the service does not request the accessibility button, it isn't available
if (!mRequestAccessibilityButton) {
return false;
}
// If the accessibility button isn't currently shown, it cannot be available to services
if (!mIsAccessibilityButtonShown) {
return false;
}
// If magnification is on and assigned to the accessibility button, services cannot be
if (userState.mIsNavBarMagnificationEnabled
&& userState.mIsNavBarMagnificationAssignedToAccessibilityButton) {
return false;
}
int requestingServices = 0;
for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
final Service service = userState.mBoundServices.get(i);
if (service.mRequestAccessibilityButton) {
requestingServices++;
}
}
if (requestingServices == 1) {
// If only a single service is requesting, it must be this service, and the
// accessibility button is available to it
return true;
} else {
// With more than one active service, we derive the target from the user's settings
if (userState.mServiceAssignedToAccessibilityButton == null) {
// If the user has not made an assignment, we treat the button as available to
// all services until the user interacts with the button to make an assignment
return true;
} else {
// If an assignment was made, it defines availability
return mComponentName.equals(userState.mServiceAssignedToAccessibilityButton);
}
}
}
/**
* Notifies an accessibility service client for a scheduled event given the event type.
*
@@ -3875,6 +3918,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
private void notifyAccessibilityButtonAvailabilityChangedInternal(boolean available) {
// Only notify the service if it's not been notified or the state has changed
if (mReceivedAccessibilityButtonCallbackSinceBind
&& (mLastAccessibilityButtonCallbackState == available)) {
return;
}
mReceivedAccessibilityButtonCallbackSinceBind = true;
mLastAccessibilityButtonCallbackState = available;
final IAccessibilityServiceClient listener;
synchronized (mLock) {
listener = mServiceInterface;
@@ -4874,7 +4924,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
public int mSoftKeyboardShowMode = 0;
public boolean mIsAccessibilityButtonAvailable;
public boolean mIsNavBarMagnificationAssignedToAccessibilityButton;
public ComponentName mServiceAssignedToAccessibilityButton;
@@ -4954,9 +5003,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mIsNavBarMagnificationAssignedToAccessibilityButton = false;
mIsAutoclickEnabled = false;
mSoftKeyboardShowMode = 0;
// Clear state tracked from system UI
mIsAccessibilityButtonAvailable = false;
}
public void destroyUiAutomationService() {

View File

@@ -166,8 +166,14 @@ public class BarController {
return change || stateChanged;
}
void setOnBarVisibilityChangedListener(OnBarVisibilityChangedListener listener) {
void setOnBarVisibilityChangedListener(OnBarVisibilityChangedListener listener,
boolean invokeWithState) {
mVisibilityChangeListener = listener;
if (invokeWithState) {
// Optionally report the initial window state for initialization purposes
mHandler.obtainMessage(MSG_NAV_BAR_VISIBILITY_CHANGED,
(mState == StatusBarManager.WINDOW_STATE_SHOWING) ? 1 : 0, 0).sendToTarget();
}
}
protected boolean skipAnimation() {

View File

@@ -1045,7 +1045,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
new BarController.OnBarVisibilityChangedListener() {
@Override
public void onBarVisibilityChanged(boolean visible) {
mAccessibilityManager.notifyAccessibilityButtonAvailabilityChanged(visible);
mAccessibilityManager.notifyAccessibilityButtonVisibilityChanged(visible);
}
};
@@ -3037,7 +3037,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mNavigationBar = win;
mNavigationBarController.setWindow(win);
mNavigationBarController.setOnBarVisibilityChangedListener(
mNavBarVisibilityListener);
mNavBarVisibilityListener, true);
if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break;
case TYPE_NAVIGATION_BAR_PANEL: