Improve handling of crashing a11y services.

am: a8cfb3733d

Change-Id: I303d1dfdb328b787b4315d846dfb4d9bbc747b75
This commit is contained in:
Phil Weaver
2016-08-05 23:44:40 +00:00
committed by android-build-merger

View File

@@ -1111,9 +1111,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private void addServiceLocked(Service service, UserState userState) { private void addServiceLocked(Service service, UserState userState) {
try { try {
if (!userState.mBoundServices.contains(service)) {
service.onAdded(); service.onAdded();
userState.mBoundServices.add(service); userState.mBoundServices.add(service);
userState.mComponentNameToServiceMap.put(service.mComponentName, service); userState.mComponentNameToServiceMap.put(service.mComponentName, service);
}
} catch (RemoteException re) { } catch (RemoteException re) {
/* do nothing */ /* do nothing */
} }
@@ -1126,8 +1128,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
*/ */
private void removeServiceLocked(Service service, UserState userState) { private void removeServiceLocked(Service service, UserState userState) {
userState.mBoundServices.remove(service); userState.mBoundServices.remove(service);
userState.mComponentNameToServiceMap.remove(service.mComponentName);
service.onRemoved(); service.onRemoved();
// It may be possible to bind a service twice, which confuses the map. Rebuild the map
// to make sure we can still reach a service
userState.mComponentNameToServiceMap.clear();
for (int i = 0; i < userState.mBoundServices.size(); i++) {
Service boundService = userState.mBoundServices.get(i);
userState.mComponentNameToServiceMap.put(boundService.mComponentName, boundService);
}
} }
/** /**
@@ -2324,15 +2332,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} }
/** /**
* Unbinds form the accessibility service and removes it from the data * Unbinds from the accessibility service and removes it from the data
* structures for service management. * structures for service management.
* *
* @return True if unbinding is successful. * @return True if unbinding is successful.
*/ */
public boolean unbindLocked() { public boolean unbindLocked() {
if (mService == null) {
return false;
}
UserState userState = getUserStateLocked(mUserId); UserState userState = getUserStateLocked(mUserId);
getKeyEventDispatcher().flush(this); getKeyEventDispatcher().flush(this);
if (!mIsAutomation) { if (!mIsAutomation) {
@@ -3033,7 +3038,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
@Override @Override
public void onServiceDisconnected(ComponentName componentName) { public void onServiceDisconnected(ComponentName componentName) {
/* do nothing - #binderDied takes care */ binderDied();
} }
public void onAdded() throws RemoteException { public void onAdded() throws RemoteException {
@@ -3062,14 +3067,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} }
public void unlinkToOwnDeathLocked() { public void unlinkToOwnDeathLocked() {
if (mService != null) {
mService.unlinkToDeath(this, 0); mService.unlinkToDeath(this, 0);
} }
}
public void resetLocked() { public void resetLocked() {
try { try {
// Clear the proxy in the other process so this // Clear the proxy in the other process so this
// IAccessibilityServiceConnection can be garbage collected. // IAccessibilityServiceConnection can be garbage collected.
if (mServiceInterface != null) {
mServiceInterface.init(null, mId, null); mServiceInterface.init(null, mId, null);
}
} catch (RemoteException re) { } catch (RemoteException re) {
/* ignore */ /* ignore */
} }
@@ -3093,10 +3102,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mWasConnectedAndDied = true; mWasConnectedAndDied = true;
getKeyEventDispatcher().flush(this); getKeyEventDispatcher().flush(this);
UserState userState = getUserStateLocked(mUserId); UserState userState = getUserStateLocked(mUserId);
// The death recipient is unregistered in removeServiceLocked
removeServiceLocked(this, userState);
resetLocked(); resetLocked();
if (mIsAutomation) { if (mIsAutomation) {
// This is typically done when unbinding, but UiAutomation isn't bound.
removeServiceLocked(this, userState);
// We no longer have an automation service, so restore // We no longer have an automation service, so restore
// the state based on values in the settings database. // the state based on values in the settings database.
userState.mInstalledServices.remove(mAccessibilityServiceInfo); userState.mInstalledServices.remove(mAccessibilityServiceInfo);