summaryrefslogtreecommitdiffstats
path: root/services/java/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android')
-rw-r--r--services/java/com/android/server/AppWidgetService.java11
-rw-r--r--services/java/com/android/server/AppWidgetServiceImpl.java33
-rw-r--r--services/java/com/android/server/DevicePolicyManagerService.java2
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java2
-rw-r--r--services/java/com/android/server/LocationManagerService.java2
-rw-r--r--services/java/com/android/server/RecognitionManagerService.java2
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java2
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java100
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java304
-rw-r--r--services/java/com/android/server/accessibility/TouchExplorer.java2
-rw-r--r--services/java/com/android/server/am/UsageStatsService.java2
-rw-r--r--services/java/com/android/server/usb/UsbSettingsManager.java2
-rw-r--r--services/java/com/android/server/wm/DimAnimator.java9
-rw-r--r--services/java/com/android/server/wm/WindowAnimator.java16
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java13
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java37
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) {