summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2009-10-20 20:15:20 -0700
committerDianne Hackborn <hackbod@google.com>2009-10-22 20:10:53 -0700
commit7580493b014a2c7ea883cd291255798dc72ebbff (patch)
tree22bffa58ac973192ea8b06ea747e1582526c1249
parent86dc4d312216be0b4c2847a1e79d94efaf4b9559 (diff)
downloadframeworks_base-7580493b014a2c7ea883cd291255798dc72ebbff.zip
frameworks_base-7580493b014a2c7ea883cd291255798dc72ebbff.tar.gz
frameworks_base-7580493b014a2c7ea883cd291255798dc72ebbff.tar.bz2
Implement feature #2117336: Create event communication APIs for live wallpaper
Note: currently only implements an async version (no result), and not yet actually tested. Change-Id: Id47ed045a4b0eb309ea8c58daf41a0e03eff1d3a
-rw-r--r--api/current.xml23
-rw-r--r--core/java/android/app/WallpaperManager.java25
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java70
-rw-r--r--core/java/android/view/IWindow.aidl7
-rw-r--r--core/java/android/view/IWindowSession.aidl6
-rw-r--r--core/java/android/view/ViewRoot.java10
-rw-r--r--core/java/com/android/internal/view/BaseIWindow.java11
-rw-r--r--services/java/com/android/server/WindowManagerService.java106
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java19
9 files changed, 249 insertions, 28 deletions
diff --git a/api/current.xml b/api/current.xml
index 6148047..8f83e39 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -24659,6 +24659,29 @@
visibility="public"
>
</method>
+<method name="sendWallpaperCommand"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="windowToken" type="android.os.IBinder">
+</parameter>
+<parameter name="action" type="java.lang.String">
+</parameter>
+<parameter name="x" type="int">
+</parameter>
+<parameter name="y" type="int">
+</parameter>
+<parameter name="z" type="int">
+</parameter>
+<parameter name="extras" type="android.os.Bundle">
+</parameter>
+</method>
<method name="setBitmap"
return="void"
abstract="false"
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 69c87ee..5881694 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -592,6 +592,31 @@ public class WallpaperManager {
}
/**
+ * Send an arbitrary command to the current active wallpaper.
+ *
+ * @param windowToken The window who these offsets should be associated
+ * with, as returned by {@link android.view.View#getWindowToken()
+ * View.getWindowToken()}.
+ * @param action Name of the command to perform. This must be a scoped
+ * name to avoid collisions, such as "com.mycompany.wallpaper.DOIT".
+ * @param x Arbitrary integer argument based on command.
+ * @param y Arbitrary integer argument based on command.
+ * @param z Arbitrary integer argument based on command.
+ * @param extras Optional additional information for the command, or null.
+ */
+ public void sendWallpaperCommand(IBinder windowToken, String action,
+ int x, int y, int z, Bundle extras) {
+ try {
+ //Log.v(TAG, "Sending new wallpaper offsets from app...");
+ ViewRoot.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand(
+ windowToken, action, x, y, z, extras, false);
+ //Log.v(TAG, "...app returning after sending offsets!");
+ } catch (RemoteException e) {
+ // Ignore.
+ }
+ }
+
+ /**
* Clear the offsets previously associated with this window through
* {@link #setWallpaperOffsets(IBinder, float, float)}. This reverts
* the window to its default state, where it does not cause the wallpaper
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index da8d62c0..dfd6af9 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -73,11 +74,21 @@ public abstract class WallpaperService extends Service {
private static final int MSG_UPDATE_SURFACE = 10000;
private static final int MSG_VISIBILITY_CHANGED = 10010;
private static final int MSG_WALLPAPER_OFFSETS = 10020;
+ private static final int MSG_WALLPAPER_COMMAND = 10025;
private static final int MSG_WINDOW_RESIZED = 10030;
private static final int MSG_TOUCH_EVENT = 10040;
private Looper mCallbackLooper;
+ static final class WallpaperCommand {
+ String action;
+ int x;
+ int y;
+ int z;
+ Bundle extras;
+ boolean sync;
+ }
+
/**
* The actual implementation of a wallpaper. A wallpaper service may
* have multiple instances running (for example as a real wallpaper
@@ -233,6 +244,22 @@ public abstract class WallpaperService extends Service {
}
}
+ public void dispatchWallpaperCommand(String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ synchronized (mLock) {
+ if (DEBUG) Log.v(TAG, "Dispatch wallpaper command: " + x + ", " + y);
+ WallpaperCommand cmd = new WallpaperCommand();
+ cmd.action = action;
+ cmd.x = x;
+ cmd.y = y;
+ cmd.z = z;
+ cmd.extras = extras;
+ cmd.sync = sync;
+ Message msg = mCaller.obtainMessage(MSG_WALLPAPER_COMMAND);
+ msg.obj = cmd;
+ mCaller.sendMessage(msg);
+ }
+ }
};
/**
@@ -338,6 +365,28 @@ public abstract class WallpaperService extends Service {
}
/**
+ * Process a command that was sent to the wallpaper with
+ * {@link WallpaperManager#sendWallpaperCommand(String, int, int, int, Bundle)}.
+ * The default implementation does nothing, and always returns null
+ * as the result.
+ *
+ * @param action The name of the command to perform. This tells you
+ * what to do and how to interpret the rest of the arguments.
+ * @param x Generic integer parameter.
+ * @param y Generic integer parameter.
+ * @param z Generic integer parameter.
+ * @param extras Any additional parameters.
+ * @param resultRequested If true, the caller is requesting that
+ * a result, appropriate for the command, be returned back.
+ * @return If returning a result, create a Bundle and place the
+ * result data in to it. Otherwise return null.
+ */
+ public Bundle onCommand(String action, int x, int y, int z,
+ Bundle extras, boolean resultRequested) {
+ return null;
+ }
+
+ /**
* Called when an application has changed the desired virtual size of
* the wallpaper.
*/
@@ -585,6 +634,23 @@ public abstract class WallpaperService extends Service {
}
}
+ void doCommand(WallpaperCommand cmd) {
+ Bundle result;
+ if (!mDestroyed) {
+ result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z,
+ cmd.extras, cmd.sync);
+ } else {
+ result = null;
+ }
+ if (cmd.sync) {
+ try {
+ if (DEBUG) Log.v(TAG, "Reporting command complete");
+ mSession.wallpaperCommandComplete(mWindow.asBinder(), result);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
void detach() {
mDestroyed = true;
@@ -709,6 +775,10 @@ public abstract class WallpaperService extends Service {
case MSG_WALLPAPER_OFFSETS: {
mEngine.doOffsetsChanged();
} break;
+ case MSG_WALLPAPER_COMMAND: {
+ WallpaperCommand cmd = (WallpaperCommand)message.obj;
+ mEngine.doCommand(cmd);
+ } break;
case MSG_WINDOW_RESIZED: {
final boolean reportDraw = message.arg1 != 0;
mEngine.updateSurface(true, false);
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 7977578..6bfc8b5 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -18,11 +18,11 @@
package android.view;
import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
import android.view.KeyEvent;
import android.view.MotionEvent;
-import android.os.ParcelFileDescriptor;
-
/**
* API back to a client window that the Window Manager uses to inform it of
* interesting things happening.
@@ -63,4 +63,7 @@ oneway interface IWindow {
* Called for wallpaper windows when their offsets change.
*/
void dispatchWallpaperOffsets(float x, float y, boolean sync);
+
+ void dispatchWallpaperCommand(String action, int x, int y,
+ int z, in Bundle extras, boolean sync);
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 9b8b6d4..7e7a38f 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -19,6 +19,7 @@ package android.view;
import android.graphics.Rect;
import android.graphics.Region;
+import android.os.Bundle;
import android.view.IWindow;
import android.view.MotionEvent;
import android.view.WindowManager;
@@ -116,4 +117,9 @@ interface IWindowSession {
void setWallpaperPosition(IBinder windowToken, float x, float y);
void wallpaperOffsetsComplete(IBinder window);
+
+ Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
+ int z, in Bundle extras, boolean sync);
+
+ void wallpaperCommandComplete(IBinder window, in Bundle result);
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 3b83044..f4593f5 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2903,6 +2903,16 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
+
+ public void dispatchWallpaperCommand(String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ if (sync) {
+ try {
+ sWindowSession.wallpaperCommandComplete(asBinder(), null);
+ } catch (RemoteException e) {
+ }
+ }
+ }
}
/**
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 38ef0c2..2674262 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -1,6 +1,7 @@
package com.android.internal.view;
import android.graphics.Rect;
+import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.view.IWindow;
@@ -101,4 +102,14 @@ public class BaseIWindow extends IWindow.Stub {
}
}
}
+
+ public void dispatchWallpaperCommand(String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ if (sync) {
+ try {
+ mSession.wallpaperCommandComplete(asBinder(), null);
+ } catch (RemoteException e) {
+ }
+ }
+ }
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index e743513..cd6a371 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -63,6 +63,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.BatteryStats;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
@@ -432,8 +433,6 @@ public class WindowManagerService extends IWindowManager.Stub
int mWallpaperAnimLayerAdjustment;
float mLastWallpaperX = -1;
float mLastWallpaperY = -1;
- // Lock for waiting for the wallpaper.
- final Object mWaitingOnWallpaperLock = new Object();
// This is set when we are waiting for a wallpaper to tell us it is done
// changing its scroll position.
WindowState mWaitingOnWallpaper;
@@ -1604,34 +1603,30 @@ public class WindowManagerService extends IWindowManager.Stub
+ wallpaperWin + " x=" + wallpaperWin.mWallpaperX
+ " y=" + wallpaperWin.mWallpaperY);
if (sync) {
- synchronized (mWaitingOnWallpaperLock) {
- mWaitingOnWallpaper = wallpaperWin;
- }
+ mWaitingOnWallpaper = wallpaperWin;
}
wallpaperWin.mClient.dispatchWallpaperOffsets(
wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY, sync);
if (sync) {
- synchronized (mWaitingOnWallpaperLock) {
- if (mWaitingOnWallpaper != null) {
- long start = SystemClock.uptimeMillis();
- if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
- < start) {
- try {
- if (DEBUG_WALLPAPER) Log.v(TAG,
- "Waiting for offset complete...");
- mWaitingOnWallpaperLock.wait(WALLPAPER_TIMEOUT);
- } catch (InterruptedException e) {
- }
- if (DEBUG_WALLPAPER) Log.v(TAG, "Offset complete!");
- if ((start+WALLPAPER_TIMEOUT)
- < SystemClock.uptimeMillis()) {
- Log.i(TAG, "Timeout waiting for wallpaper to offset: "
- + wallpaperWin);
- mLastWallpaperTimeoutTime = start;
- }
+ if (mWaitingOnWallpaper != null) {
+ long start = SystemClock.uptimeMillis();
+ if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
+ < start) {
+ try {
+ if (DEBUG_WALLPAPER) Log.v(TAG,
+ "Waiting for offset complete...");
+ mWindowMap.wait(WALLPAPER_TIMEOUT);
+ } catch (InterruptedException e) {
+ }
+ if (DEBUG_WALLPAPER) Log.v(TAG, "Offset complete!");
+ if ((start+WALLPAPER_TIMEOUT)
+ < SystemClock.uptimeMillis()) {
+ Log.i(TAG, "Timeout waiting for wallpaper to offset: "
+ + wallpaperWin);
+ mLastWallpaperTimeoutTime = start;
}
- mWaitingOnWallpaper = null;
}
+ mWaitingOnWallpaper = null;
}
}
} catch (RemoteException e) {
@@ -1642,11 +1637,11 @@ public class WindowManagerService extends IWindowManager.Stub
}
void wallpaperOffsetsComplete(IBinder window) {
- synchronized (mWaitingOnWallpaperLock) {
+ synchronized (mWindowMap) {
if (mWaitingOnWallpaper != null &&
mWaitingOnWallpaper.mClient.asBinder() == window) {
mWaitingOnWallpaper = null;
- mWaitingOnWallpaperLock.notifyAll();
+ mWindowMap.notifyAll();
}
}
}
@@ -2196,6 +2191,47 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ void wallpaperCommandComplete(IBinder window, Bundle result) {
+ synchronized (mWindowMap) {
+ if (mWaitingOnWallpaper != null &&
+ mWaitingOnWallpaper.mClient.asBinder() == window) {
+ mWaitingOnWallpaper = null;
+ mWindowMap.notifyAll();
+ }
+ }
+ }
+
+ public Bundle sendWindowWallpaperCommandLocked(WindowState window,
+ String action, int x, int y, int z, Bundle extras, boolean sync) {
+ if (window == mWallpaperTarget || window == mLowerWallpaperTarget
+ || window == mUpperWallpaperTarget) {
+ boolean doWait = sync;
+ int curTokenIndex = mWallpaperTokens.size();
+ while (curTokenIndex > 0) {
+ curTokenIndex--;
+ WindowToken token = mWallpaperTokens.get(curTokenIndex);
+ int curWallpaperIndex = token.windows.size();
+ while (curWallpaperIndex > 0) {
+ curWallpaperIndex--;
+ WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ try {
+ wallpaper.mClient.dispatchWallpaperCommand(action,
+ x, y, z, extras, sync);
+ // We only want to be synchronous with one wallpaper.
+ sync = false;
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ if (doWait) {
+ // XXX Need to wait for result.
+ }
+ }
+
+ return null;
+ }
+
public int relayoutWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, boolean insetsPending,
@@ -6565,6 +6601,24 @@ public class WindowManagerService extends IWindowManager.Stub
WindowManagerService.this.wallpaperOffsetsComplete(window);
}
+ public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ synchronized(mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return sendWindowWallpaperCommandLocked(
+ windowForClientLocked(this, window),
+ action, x, y, z, extras, sync);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ public void wallpaperCommandComplete(IBinder window, Bundle result) {
+ WindowManagerService.this.wallpaperCommandComplete(window, result);
+ }
+
void windowAddedLocked() {
if (mSurfaceSession == null) {
if (localLOGV) Log.v(
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index d28a151..f0223e8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -36,6 +36,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -1069,6 +1070,18 @@ public final class Bridge implements ILayoutBridge {
}
@SuppressWarnings("unused")
+ public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ // pass for now.
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ public void wallpaperCommandComplete(IBinder window, Bundle result) {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
public void closeSystemDialogs(String reason) {
// pass for now.
}
@@ -1132,6 +1145,12 @@ public final class Bridge implements ILayoutBridge {
}
@SuppressWarnings("unused")
+ public void dispatchWallpaperCommand(String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ // pass for now.
+ }
+
+ @SuppressWarnings("unused")
public void closeSystemDialogs(String reason) {
// pass for now.
}