diff options
Diffstat (limited to 'services/java/com/android')
16 files changed, 433 insertions, 106 deletions
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index eb024e9..bf958a5 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -28,6 +28,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.Pair; @@ -260,6 +261,16 @@ class AppWidgetService extends IAppWidgetService.Stub return getImplForUser().getAppWidgetViews(appWidgetId); } + @Override + public void updateAppWidgetExtras(int appWidgetId, Bundle extras) { + getImplForUser().updateAppWidgetExtras(appWidgetId, extras); + } + + @Override + public Bundle getAppWidgetExtras(int appWidgetId) { + return getImplForUser().getAppWidgetExtras(appWidgetId); + } + static int[] getAppWidgetIds(Provider p) { int instancesSize = p.instances.size(); int appWidgetIds[] = new int[instancesSize]; diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index b24823e..3b43b9b 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -113,6 +113,7 @@ class AppWidgetServiceImpl { int appWidgetId; Provider provider; RemoteViews views; + Bundle extras; Host host; } @@ -760,6 +761,38 @@ class AppWidgetServiceImpl { } } + public void updateAppWidgetExtras(int appWidgetId, Bundle extras) { + synchronized (mAppWidgetIds) { + ensureStateLoadedLocked(); + AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); + + if (id == null) { + return; + } + Provider p = id.provider; + id.extras = extras; + + // send the broacast saying that this appWidgetId has been deleted + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_EXTRAS_CHANGED); + intent.setComponent(p.info.provider); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS, extras); + mContext.sendBroadcast(intent, mUserId); + } + } + + public Bundle getAppWidgetExtras(int appWidgetId) { + synchronized (mAppWidgetIds) { + ensureStateLoadedLocked(); + AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); + if (id != null && id.extras != null) { + return id.extras; + } else { + return Bundle.EMPTY; + } + } + } + public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views) { if (appWidgetIds == null) { return; diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java index d8e3d59..eb33060 100644 --- a/services/java/com/android/server/DevicePolicyManagerService.java +++ b/services/java/com/android/server/DevicePolicyManagerService.java @@ -451,7 +451,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public DevicePolicyManagerService(Context context) { mContext = context; mMonitor = new MyPackageMonitor(); - mMonitor.register(context, true); + mMonitor.register(context, null, true); mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)) .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM"); IntentFilter filter = new IntentFilter(); diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index a474cec..43c2292 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -594,7 +594,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } mImListManager = new InputMethodAndSubtypeListManager(context, this); - (new MyPackageMonitor()).register(mContext, true); + (new MyPackageMonitor()).register(mContext, null, true); IntentFilter screenOnOffFilt = new IntentFilter(); screenOnOffFilt.addAction(Intent.ACTION_SCREEN_ON); diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 8cb9d99b..d651111 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -511,7 +511,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run com.android.internal.R.string.config_networkLocationProvider); mGeocodeProviderPackageName = resources.getString( com.android.internal.R.string.config_geocodeProvider); - mPackageMonitor.register(context, true); + mPackageMonitor.register(context, null, true); if (LOCAL_LOGV) { Slog.v(TAG, "Constructed LocationManager Service"); diff --git a/services/java/com/android/server/RecognitionManagerService.java b/services/java/com/android/server/RecognitionManagerService.java index 85224d8..3567cfc 100644 --- a/services/java/com/android/server/RecognitionManagerService.java +++ b/services/java/com/android/server/RecognitionManagerService.java @@ -65,7 +65,7 @@ public class RecognitionManagerService extends Binder { RecognitionManagerService(Context context) { mContext = context; mMonitor = new MyPackageMonitor(); - mMonitor.register(context, true); + mMonitor.register(context, null, true); } public void systemReady() { diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java index 106bb3e..499ff7a 100644 --- a/services/java/com/android/server/TextServicesManagerService.java +++ b/services/java/com/android/server/TextServicesManagerService.java @@ -77,7 +77,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { mSystemReady = false; mContext = context; mMonitor = new TextServicesMonitor(); - mMonitor.register(context, true); + mMonitor.register(context, null, true); synchronized (mSpellCheckerMap) { buildSpellCheckerMapLocked(context, mSpellCheckerList, mSpellCheckerMap); } diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java index 6d83f30..d97d335 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/java/com/android/server/WallpaperManagerService.java @@ -295,7 +295,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub { || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) { continue; } - doPackagesChanged(true, wallpaper); + doPackagesChangedLocked(true, wallpaper); } } } @@ -315,66 +315,68 @@ class WallpaperManagerService extends IWallpaperManager.Stub { @Override public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { - boolean changed = false; - for (int i = 0; i < mWallpaperMap.size(); i++) { - WallpaperData wallpaper = mWallpaperMap.valueAt(i); - boolean res = doPackagesChanged(doit, wallpaper); - changed |= res; + synchronized (mLock) { + boolean changed = false; + for (int i = 0; i < mWallpaperMap.size(); i++) { + WallpaperData wallpaper = mWallpaperMap.valueAt(i); + boolean res = doPackagesChangedLocked(doit, wallpaper); + changed |= res; + } + return changed; } - return changed; } @Override public void onSomePackagesChanged() { - for (int i = 0; i < mWallpaperMap.size(); i++) { - WallpaperData wallpaper = mWallpaperMap.valueAt(i); - doPackagesChanged(true, wallpaper); + synchronized (mLock) { + for (int i = 0; i < mWallpaperMap.size(); i++) { + WallpaperData wallpaper = mWallpaperMap.valueAt(i); + doPackagesChangedLocked(true, wallpaper); + } } } - boolean doPackagesChanged(boolean doit, WallpaperData wallpaper) { + boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) { boolean changed = false; - synchronized (mLock) { - if (wallpaper.wallpaperComponent != null) { - int change = isPackageDisappearing(wallpaper.wallpaperComponent - .getPackageName()); - if (change == PACKAGE_PERMANENT_CHANGE - || change == PACKAGE_TEMPORARY_CHANGE) { - changed = true; - if (doit) { - Slog.w(TAG, "Wallpaper uninstalled, removing: " - + wallpaper.wallpaperComponent); - clearWallpaperLocked(false, wallpaper.userId); - } - } - } - if (wallpaper.nextWallpaperComponent != null) { - int change = isPackageDisappearing(wallpaper.nextWallpaperComponent - .getPackageName()); - if (change == PACKAGE_PERMANENT_CHANGE - || change == PACKAGE_TEMPORARY_CHANGE) { - wallpaper.nextWallpaperComponent = null; - } - } - if (wallpaper.wallpaperComponent != null - && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) { - try { - mContext.getPackageManager().getServiceInfo( - wallpaper.wallpaperComponent, 0); - } catch (NameNotFoundException e) { - Slog.w(TAG, "Wallpaper component gone, removing: " + if (wallpaper.wallpaperComponent != null) { + int change = isPackageDisappearing(wallpaper.wallpaperComponent + .getPackageName()); + if (change == PACKAGE_PERMANENT_CHANGE + || change == PACKAGE_TEMPORARY_CHANGE) { + changed = true; + if (doit) { + Slog.w(TAG, "Wallpaper uninstalled, removing: " + wallpaper.wallpaperComponent); clearWallpaperLocked(false, wallpaper.userId); } } - if (wallpaper.nextWallpaperComponent != null - && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) { - try { - mContext.getPackageManager().getServiceInfo( - wallpaper.nextWallpaperComponent, 0); - } catch (NameNotFoundException e) { - wallpaper.nextWallpaperComponent = null; - } + } + if (wallpaper.nextWallpaperComponent != null) { + int change = isPackageDisappearing(wallpaper.nextWallpaperComponent + .getPackageName()); + if (change == PACKAGE_PERMANENT_CHANGE + || change == PACKAGE_TEMPORARY_CHANGE) { + wallpaper.nextWallpaperComponent = null; + } + } + if (wallpaper.wallpaperComponent != null + && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) { + try { + mContext.getPackageManager().getServiceInfo( + wallpaper.wallpaperComponent, 0); + } catch (NameNotFoundException e) { + Slog.w(TAG, "Wallpaper component gone, removing: " + + wallpaper.wallpaperComponent); + clearWallpaperLocked(false, wallpaper.userId); + } + } + if (wallpaper.nextWallpaperComponent != null + && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) { + try { + mContext.getPackageManager().getServiceInfo( + wallpaper.nextWallpaperComponent, 0); + } catch (NameNotFoundException e) { + wallpaper.nextWallpaperComponent = null; } } return changed; @@ -387,7 +389,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub { mIWindowManager = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); mMonitor = new MyPackageMonitor(); - mMonitor.register(context, true); + mMonitor.register(context, null, true); WALLPAPER_BASE_DIR.mkdirs(); loadSettingsLocked(0); } diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 6675816..648e4d5 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -23,6 +23,7 @@ import android.Manifest; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; +import android.accessibilityservice.IAccessibilityServiceClientCallback; import android.accessibilityservice.IAccessibilityServiceConnection; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -40,8 +41,10 @@ import android.hardware.input.InputManager; import android.net.Uri; import android.os.Binder; import android.os.Build; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; @@ -55,7 +58,9 @@ import android.view.IWindow; import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; +import android.view.View; import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityInteractionConnection; @@ -64,6 +69,8 @@ import android.view.accessibility.IAccessibilityManager; import android.view.accessibility.IAccessibilityManagerClient; import com.android.internal.content.PackageMonitor; +import com.android.internal.os.HandlerCaller; +import com.android.internal.os.HandlerCaller.Callback; import com.android.server.accessibility.TouchExplorer.GestureListener; import com.android.server.wm.WindowManagerService; @@ -78,6 +85,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; /** * This class is instantiated by the system as a system level service and can be @@ -97,10 +105,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE = "registerUiTestAutomationService"; - private static int sIdCounter = 0; - private static final int OWN_PROCESS_ID = android.os.Process.myPid(); + private static final int UNDEFINED = -1; + + private static int sIdCounter = 0; + private static int sNextWindowId; final Context mContext; @@ -145,6 +155,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private Service mUiAutomationService; + private GestureHandler mGestureHandler; + + private int mDefaultGestureHandlingHelperServiceId = UNDEFINED; + /** * Handler for delayed event dispatch. */ @@ -269,11 +283,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub }; // package changes - monitor.register(context, true); + monitor.register(context, null, true); // boot completed IntentFilter bootFiler = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); - mContext.registerReceiver(monitor, bootFiler); + mContext.registerReceiver(monitor, bootFiler, null, monitor.getRegisteredHandler()); } /** @@ -471,26 +485,60 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } @Override - public void onGesture(int gestureId) { + public boolean onGesture(int gestureId) { + // Lazily instantiate the gesture handler. + if (mGestureHandler == null) { + mGestureHandler = new GestureHandler(); + } synchronized (mLock) { - final boolean dispatched = notifyGestureLocked(gestureId, false); - if (!dispatched) { - notifyGestureLocked(gestureId, true); + boolean handled = notifyGestureLocked(gestureId, false); + if (!handled) { + handled = notifyGestureLocked(gestureId, true); + } + if (!handled) { + mGestureHandler.scheduleHandleGestureDefault(gestureId); } + return handled; + } + } + + private Service getDefaultGestureHandlingHelperService() { + // Since querying of screen content is done through the + // AccessibilityInteractionClient which talks to an + // IAccessibilityServiceConnection implementation we create a proxy + // Service when necessary to enable interaction with the remote + // view tree. Note that this service is just a stateless proxy + // that does not get any events or interrupts. + if (mDefaultGestureHandlingHelperServiceId == UNDEFINED) { + ComponentName name = new ComponentName("android", + "DefaultGestureHandlingHelperService"); + AccessibilityServiceInfo info = new AccessibilityServiceInfo(); + Service service = new Service(name, info, true); + mDefaultGestureHandlingHelperServiceId = service.mId; + AccessibilityInteractionClient.getInstance().addConnection( + mDefaultGestureHandlingHelperServiceId, service); + return service; + } else { + return (Service) AccessibilityInteractionClient.getInstance() + .getConnection(mDefaultGestureHandlingHelperServiceId); } } private boolean notifyGestureLocked(int gestureId, boolean isDefault) { - final int serviceCount = mServices.size(); - for (int i = 0; i < serviceCount; i++) { + // TODO: Now we are giving the gestures to the last enabled + // service that can handle them which is the last one + // in our list since we write the last enabled as the + // last record in the enabled services setting. Ideally, + // the user should make the call which service handles + // gestures. However, only one service should handle + // gestrues to avoid user frustration when different + // bahiour is observed from different combinations of + // enabled accessibility services. + for (int i = mServices.size() - 1; i >= 0; i--) { Service service = mServices.get(i); - if (service.mIsDefault == isDefault) { - try { - service.mServiceInterface.onGesture(gestureId); - return true; - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error dispatching gesture."); - } + if (service.mCanHandleGestures && service.mIsDefault == isDefault) { + mGestureHandler.scheduleHandleGesture(gestureId, service.mServiceInterface); + return true; } } return false; @@ -935,6 +983,212 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } + class GestureHandler extends IAccessibilityServiceClientCallback.Stub + implements Runnable, Callback { + + private static final String THREAD_NAME = "AccessibilityGestureHandler"; + + private static final long TIMEOUT_INTERACTION_MILLIS = 5000; + + private static final int MSG_HANDLE_GESTURE = 1; + + private static final int MSG_HANDLE_GESTURE_DEFAULT = 2; + + private final AtomicInteger mInteractionCounter = new AtomicInteger(); + + private final Object mGestureLock = new Object(); + + private HandlerCaller mHandlerCaller; + + private volatile int mInteractionId = -1; + + private volatile boolean mGestureResult; + + public GestureHandler() { + synchronized (mGestureLock) { + Thread worker = new Thread(this, THREAD_NAME); + worker.start(); + while (mHandler == null) { + try { + mGestureLock.wait(); + } catch (InterruptedException ie) { + /* ignore */ + } + } + } + } + + @Override + public void run() { + Looper.prepare(); + synchronized (mGestureLock) { + mHandlerCaller = new HandlerCaller(mContext, Looper.myLooper(), this); + mGestureLock.notifyAll(); + } + Looper.loop(); + } + + @Override + public void setGestureResult(int gestureId, boolean handled, int interactionId) { + synchronized (mGestureLock) { + if (interactionId > mInteractionId) { + mGestureResult = handled; + mInteractionId = interactionId; + } + mGestureLock.notifyAll(); + } + } + + @Override + public void executeMessage(Message message) { + final int type = message.what; + switch (type) { + case MSG_HANDLE_GESTURE: { + IAccessibilityServiceClient service = + (IAccessibilityServiceClient) message.obj; + final int gestureId = message.arg1; + final int interactionId = message.arg2; + + try { + service.onGesture(gestureId, this, interactionId); + } catch (RemoteException re) { + Slog.e(LOG_TAG, "Error dispatching a gesture to a client.", re); + return; + } + + long waitTimeMillis = 0; + final long startTimeMillis = SystemClock.uptimeMillis(); + synchronized (mGestureLock) { + while (true) { + try { + // Did we get the expected callback? + if (mInteractionId == interactionId) { + break; + } + // Did we get an obsolete callback? + if (mInteractionId > interactionId) { + break; + } + // Did we time out? + final long elapsedTimeMillis = + SystemClock.uptimeMillis() - startTimeMillis; + waitTimeMillis = TIMEOUT_INTERACTION_MILLIS - elapsedTimeMillis; + if (waitTimeMillis <= 0) { + break; + } + mGestureLock.wait(waitTimeMillis); + } catch (InterruptedException ie) { + /* ignore */ + } + } + handleGestureIfNeededAndResetLocked(gestureId); + } + } break; + case MSG_HANDLE_GESTURE_DEFAULT: { + final int gestureId = message.arg1; + handleGestureDefault(gestureId); + } break; + default: { + throw new IllegalArgumentException("Unknown message type: " + type); + } + } + } + + private void handleGestureIfNeededAndResetLocked(int gestureId) { + if (!mGestureResult) { + handleGestureDefault(gestureId); + } + mGestureResult = false; + mInteractionId = -1; + } + + public void scheduleHandleGesture(int gestureId, IAccessibilityServiceClient service) { + final int interactionId = mInteractionCounter.incrementAndGet(); + mHandlerCaller.obtainMessageIIO(MSG_HANDLE_GESTURE, gestureId, interactionId, + service).sendToTarget(); + } + + public void scheduleHandleGestureDefault(int gestureId) { + final int interactionId = mInteractionCounter.incrementAndGet(); + mHandlerCaller.obtainMessageI(MSG_HANDLE_GESTURE_DEFAULT, gestureId).sendToTarget(); + } + + private void handleGestureDefault(int gestureId) { + Service service = getDefaultGestureHandlingHelperService(); + + // Global actions. + switch (gestureId) { + case AccessibilityService.GESTURE_SWIPE_DOWN_AND_LEFT: { + service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK); + } return; + case AccessibilityService.GESTURE_SWIPE_DOWN_AND_RIGHT: { + service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME); + } return; + case AccessibilityService.GESTURE_SWIPE_UP_AND_LEFT: { + service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS); + } return; + case AccessibilityService.GESTURE_SWIPE_UP_AND_RIGHT: { + service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS); + } return; + } + + AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance(); + + AccessibilityNodeInfo root = client.getRootInActiveWindow(service.mId); + if (root == null) { + return; + } + + AccessibilityNodeInfo current = root.findFocus( + AccessibilityNodeInfo.FOCUS_ACCESSIBILITY); + if (current == null) { + current = root; + } + + // Local actions. + AccessibilityNodeInfo next = null; + switch (gestureId) { + case AccessibilityService.GESTURE_SWIPE_UP: { + next = current.focusSearch(View.ACCESSIBILITY_FOCUS_OUT); + } break; + case AccessibilityService.GESTURE_SWIPE_DOWN: { + next = current.focusSearch(View.ACCESSIBILITY_FOCUS_IN); + } break; + case AccessibilityService.GESTURE_SWIPE_LEFT: { + // TODO: Implement the RTL support. +// if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) { + next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD); +// } else { // LAYOUT_DIRECTION_RTL +// next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD); +// } + } break; + case AccessibilityService.GESTURE_SWIPE_RIGHT: { + // TODO: Implement the RTL support. +// if (mLayoutDirection == View.LAYOUT_DIRECTION_LTR) { + next = current.focusSearch(View.ACCESSIBILITY_FOCUS_FORWARD); +// } else { // LAYOUT_DIRECTION_RTL +// next = current.focusSearch(View.ACCESSIBILITY_FOCUS_BACKWARD); +// } + } break; + case AccessibilityService.GESTURE_SWIPE_UP_AND_DOWN: { + next = current.focusSearch(View.ACCESSIBILITY_FOCUS_UP); + } break; + case AccessibilityService.GESTURE_SWIPE_DOWN_AND_UP: { + next = current.focusSearch(View.ACCESSIBILITY_FOCUS_DOWN); + } break; + case AccessibilityService.GESTURE_SWIPE_LEFT_AND_RIGHT: { + next = current.focusSearch(View.ACCESSIBILITY_FOCUS_LEFT); + } break; + case AccessibilityService.GESTURE_SWIPE_RIGHT_AND_LEFT: { + next = current.focusSearch(View.ACCESSIBILITY_FOCUS_RIGHT); + } break; + } + if (next != null && !next.equals(current)) { + next.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + } + } + } + /** * This class represents an accessibility service. It stores all per service * data required for the service management, provides API for starting/stopping the @@ -971,6 +1225,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub boolean mCanRetrieveScreenContent; + boolean mCanHandleGestures; + boolean mIsAutomation; final Rect mTempBounds = new Rect(); @@ -987,6 +1243,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mIsAutomation = isAutomation; if (!isAutomation) { mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent(); + mCanHandleGestures = accessibilityServiceInfo.getCanHandleGestures(); mIntent = new Intent().setComponent(mComponentName); mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL, com.android.internal.R.string.accessibility_binding_label); @@ -995,6 +1252,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } else { mCanRetrieveScreenContent = true; mIncludeNotImportantViews = true; + mCanHandleGestures = true; } setDynamicallyConfigurableProperties(accessibilityServiceInfo); } @@ -1290,7 +1548,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub @Override public boolean performAccessibilityAction(int accessibilityWindowId, - long accessibilityNodeId, int action, int interactionId, + long accessibilityNodeId, int action, Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) { final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId); IAccessibilityInteractionConnection connection = null; @@ -1311,8 +1569,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int flags = (mIncludeNotImportantViews) ? AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS : 0; final int interrogatingPid = Binder.getCallingPid(); - connection.performAccessibilityAction(accessibilityNodeId, action, interactionId, - callback, flags, interrogatingPid, interrogatingTid); + connection.performAccessibilityAction(accessibilityNodeId, action, arguments, + interactionId, callback, flags, interrogatingPid, interrogatingTid); } catch (RemoteException re) { if (DEBUG) { Slog.e(LOG_TAG, "Error calling performAccessibilityAction()"); @@ -1323,7 +1581,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return true; } - public boolean perfromGlobalAction(int action) { + public boolean performGlobalAction(int action) { switch (action) { case AccessibilityService.GLOBAL_ACTION_BACK: { sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK); @@ -1441,7 +1699,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub | AccessibilityNodeInfo.ACTION_SELECT | AccessibilityNodeInfo.ACTION_CLEAR_SELECTION | AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS - | AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS; + | AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS + | AccessibilityNodeInfo.ACTION_NEXT_AT_GRANULARITY + | AccessibilityNodeInfo.ACTION_PREVIOUS_AT_GRANULARITY; private static final int RETRIEVAL_ALLOWING_EVENT_TYPES = AccessibilityEvent.TYPE_VIEW_CLICKED diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java index 5d01c77..39012e6 100644 --- a/services/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/java/com/android/server/accessibility/TouchExplorer.java @@ -152,7 +152,7 @@ public class TouchExplorer { * * @param gestureId The gesture id. */ - public void onGesture(int gestureId); + public boolean onGesture(int gestureId); } /** diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java index e810e3c..ba65f39 100644 --- a/services/java/com/android/server/am/UsageStatsService.java +++ b/services/java/com/android/server/am/UsageStatsService.java @@ -656,7 +656,7 @@ public final class UsageStatsService extends IUsageStats.Stub { } } }; - mPackageMonitor.register(mContext, true); + mPackageMonitor.register(mContext, null, true); filterHistoryStats(); } diff --git a/services/java/com/android/server/usb/UsbSettingsManager.java b/services/java/com/android/server/usb/UsbSettingsManager.java index 0baafbb..7dde340 100644 --- a/services/java/com/android/server/usb/UsbSettingsManager.java +++ b/services/java/com/android/server/usb/UsbSettingsManager.java @@ -370,7 +370,7 @@ class UsbSettingsManager { synchronized (mLock) { readSettingsLocked(); } - mPackageMonitor.register(context, true); + mPackageMonitor.register(context, null, true); } private void readPreference(XmlPullParser parser) diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java index b08c864..f9f9d1a 100644 --- a/services/java/com/android/server/wm/DimAnimator.java +++ b/services/java/com/android/server/wm/DimAnimator.java @@ -42,10 +42,17 @@ class DimAnimator { DimAnimator (SurfaceSession session) { if (mDimSurface == null) { try { - mDimSurface = new Surface(session, 0, + if (WindowManagerService.DEBUG_SURFACE_TRACE) { + mDimSurface = new WindowStateAnimator.SurfaceTrace(session, 0, "DimAnimator", -1, 16, 16, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM); + } else { + mDimSurface = new Surface(session, 0, + "DimAnimator", + -1, 16, 16, PixelFormat.OPAQUE, + Surface.FX_SURFACE_DIM); + } if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface + ": CREATE"); diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index 7611a0f..f946f6c 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -75,6 +75,9 @@ public class WindowAnimator { DimAnimator mDimAnimator = null; DimAnimator.Parameters mDimParams = null; + static final int WALLPAPER_ACTION_PENDING = 1; + int mPendingActions; + WindowAnimator(final WindowManagerService service, final Context context, final WindowManagerPolicy policy) { mService = service; @@ -364,7 +367,9 @@ public class WindowAnimator { for (int i=unForceHiding.size()-1; i>=0; i--) { Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding); if (a != null) { - unForceHiding.get(i).setAnimation(a); + final WindowStateAnimator winAnimator = unForceHiding.get(i); + winAnimator.setAnimation(a); + winAnimator.mAnimationIsEntrance = true; } } } @@ -421,13 +426,16 @@ public class WindowAnimator { mWindowAnimationBackgroundColor = 0; updateWindowsAndWallpaperLocked(); + if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { + mPendingActions |= WALLPAPER_ACTION_PENDING; + } if (mTokenMayBeDrawn) { testTokenMayBeDrawnLocked(); } } - void animate() { + synchronized void animate() { mPendingLayoutChanges = 0; mCurrentTime = SystemClock.uptimeMillis(); mBulkUpdateParams = 0; @@ -554,4 +562,8 @@ public class WindowAnimator { mAnimDh = animDh; } } + + synchronized void clearPendingActions() { + mPendingActions = 0; + } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index f698fbc..f64ad12 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -1629,9 +1629,7 @@ public class WindowManagerService extends IWindowManager.Stub "Found wallpaper activity: #" + i + "=" + w); foundW = w; foundI = i; - if (w == mWallpaperTarget && ((w.mAppToken != null - && w.mAppToken.mAppAnimator.animation != null) - || w.mWinAnimator.mAnimation != null)) { + if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) { // The current wallpaper target is animating, so we'll // look behind it for another possible target and figure // out what is going on below. @@ -6618,6 +6616,7 @@ public class WindowManagerService extends IWindowManager.Stub public static final int SET_WALLPAPER_OFFSET = ANIMATOR_WHAT_OFFSET + 2; public static final int SET_DIM_PARAMETERS = ANIMATOR_WHAT_OFFSET + 3; public static final int SET_MOVE_ANIMATION = ANIMATOR_WHAT_OFFSET + 4; + public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 5; private Session mLastReportedHold; @@ -7070,7 +7069,8 @@ public class WindowManagerService extends IWindowManager.Stub } if (doRequest) { - requestTraversalLocked(); + mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS); + performLayoutAndPlaceSurfacesLocked(); } } break; @@ -7111,6 +7111,11 @@ public class WindowManagerService extends IWindowManager.Stub scheduleAnimationLocked(); break; } + + case CLEAR_PENDING_ACTIONS: { + mAnimator.clearPendingActions(); + break; + } } if (DEBUG_WINDOW_TRACE) { Slog.v(TAG, "handleMessage: exit"); diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 0cebee7..74e3304 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -186,6 +186,7 @@ class WindowStateAnimator { if (mAnimation != null) { mAnimation.cancel(); mAnimation = null; + mLocalAnimating = false; destroySurfaceLocked(); } } @@ -262,9 +263,6 @@ class WindowStateAnimator { // If the display is frozen, and there is a pending animation, // clear it and make sure we run the cleanup code. mAnimating = true; - mLocalAnimating = true; - mAnimation.cancel(); - mAnimation = null; } if (!mAnimating && !mLocalAnimating) { @@ -878,11 +876,14 @@ class WindowStateAnimator { ": " + mWin.mShownFrame + ", alpha=" + mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha); return; + } else if (mWin.mIsWallpaper && + (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) { + return; } if (WindowManagerService.localLOGV) Slog.v( - TAG, "computeShownFrameLocked: " + this + - " not attached, mAlpha=" + mAlpha); + TAG, "computeShownFrameLocked: " + this + + " not attached, mAlpha=" + mAlpha); mWin.mShownFrame.set(mWin.mFrame); if (mWin.mXOffset != 0 || mWin.mYOffset != 0) { mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset); @@ -920,19 +921,19 @@ class WindowStateAnimator { mSurfaceH = height; } - if (mSurfaceX != w.mShownFrame.left - || mSurfaceY != w.mShownFrame.top) { + final float left = w.mShownFrame.left; + final float top = w.mShownFrame.top; + if (mSurfaceX != left || mSurfaceY != top) { try { if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, - "POS " + w.mShownFrame.left - + ", " + w.mShownFrame.top, null); - mSurfaceX = w.mShownFrame.left; - mSurfaceY = w.mShownFrame.top; - mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top); + "POS " + left + ", " + top, null); + mSurfaceX = left; + mSurfaceY = top; + mSurface.setPosition(left, top); } catch (RuntimeException e) { Slog.w(TAG, "Error positioning surface of " + w - + " pos=(" + w.mShownFrame.left - + "," + w.mShownFrame.top + ")", e); + + " pos=(" + left + + "," + top + ")", e); if (!recoveringMemory) { mService.reclaimSomeSurfaceMemoryLocked(this, "position", true); } @@ -1177,12 +1178,7 @@ class WindowStateAnimator { // will do an animation to reveal it from behind the // starting window, so there is no need for it to also // be doing its own stuff. - if (mAnimation != null) { - mAnimation.cancel(); - mAnimation = null; - // Make sure we clean up the animation. - mAnimating = true; - } + clearAnimation(); mService.mFinishedStarting.add(mWin.mAppToken); mService.mH.sendEmptyMessage(H.FINISHED_STARTING); } @@ -1286,6 +1282,7 @@ class WindowStateAnimator { if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + this + " anim=" + anim + " attr=0x" + Integer.toHexString(attr) + + " a=" + a + " mAnimation=" + mAnimation + " isEntrance=" + isEntrance); if (a != null) { |
