summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-07-13 18:55:52 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2010-07-13 18:55:52 -0700
commitf8d9379bd834573feca085284970cf686993c330 (patch)
treed603a4c197ba91ab2103a04d244e3f1004bef9e3 /core/java
parent89ee578b7053d27a50922f82feb94bf6054b330c (diff)
parentd76b67c340d1564abf8d14d976fdaf83bf2b3320 (diff)
downloadframeworks_base-f8d9379bd834573feca085284970cf686993c330.zip
frameworks_base-f8d9379bd834573feca085284970cf686993c330.tar.gz
frameworks_base-f8d9379bd834573feca085284970cf686993c330.tar.bz2
am d76b67c3: IME events are now dispatched to native applications.
Merge commit 'd76b67c340d1564abf8d14d976fdaf83bf2b3320' into gingerbread-plus-aosp * commit 'd76b67c340d1564abf8d14d976fdaf83bf2b3320': IME events are now dispatched to native applications.
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/NativeActivity.java101
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java47
-rw-r--r--core/java/android/view/SurfaceHolder.java17
-rw-r--r--core/java/android/view/SurfaceView.java37
-rw-r--r--core/java/android/view/ViewRoot.java14
-rw-r--r--core/java/android/view/Window.java2
-rw-r--r--core/java/com/android/internal/view/RootViewSurfaceTaker.java2
7 files changed, 183 insertions, 37 deletions
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index d72dda7..ccc9ae3 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -2,6 +2,7 @@ package android.app;
import dalvik.system.PathClassLoader;
+import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -11,12 +12,16 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Looper;
import android.os.MessageQueue;
+import android.util.AttributeSet;
import android.view.InputChannel;
import android.view.InputQueue;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
+import android.view.WindowManager;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.inputmethod.InputMethodManager;
import java.io.File;
@@ -24,15 +29,26 @@ import java.io.File;
* Convenience for implementing an activity that will be implemented
* purely in native code. That is, a game (or game-like thing).
*/
-public class NativeActivity extends Activity implements SurfaceHolder.Callback,
- InputQueue.Callback {
+public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
+ InputQueue.Callback, OnGlobalLayoutListener {
public static final String META_DATA_LIB_NAME = "android.app.lib_name";
+ private NativeContentView mNativeContentView;
+ private InputMethodManager mIMM;
+
private int mNativeHandle;
private InputQueue mCurInputQueue;
private SurfaceHolder mCurSurfaceHolder;
+ final int[] mLocation = new int[2];
+ int mLastContentX;
+ int mLastContentY;
+ int mLastContentWidth;
+ int mLastContentHeight;
+
+ private boolean mDispatchingUnhandledKey;
+
private boolean mDestroyed;
private native int loadNativeCode(String path, MessageQueue queue,
@@ -49,18 +65,44 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback,
private native void onSurfaceCreatedNative(int handle, Surface surface);
private native void onSurfaceChangedNative(int handle, Surface surface,
int format, int width, int height);
+ private native void onSurfaceRedrawNeededNative(int handle, Surface surface);
private native void onSurfaceDestroyedNative(int handle);
private native void onInputChannelCreatedNative(int handle, InputChannel channel);
private native void onInputChannelDestroyedNative(int handle, InputChannel channel);
+ private native void onContentRectChangedNative(int handle, int x, int y, int w, int h);
+ private native void dispatchKeyEventNative(int handle, KeyEvent event);
+
+ static class NativeContentView extends View {
+ NativeActivity mActivity;
+
+ public NativeContentView(Context context) {
+ super(context);
+ }
+
+ public NativeContentView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
String libname = "main";
ActivityInfo ai;
+ mIMM = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+
getWindow().takeSurface(this);
getWindow().takeInputQueue(this);
getWindow().setFormat(PixelFormat.RGB_565);
+ getWindow().setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+
+ mNativeContentView = new NativeContentView(this);
+ mNativeContentView.mActivity = this;
+ setContentView(mNativeContentView);
+ mNativeContentView.requestFocus();
+ mNativeContentView.getViewTreeObserver().addOnGlobalLayoutListener(this);
try {
ai = getPackageManager().getActivityInfo(
@@ -165,6 +207,18 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback,
}
}
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (mDispatchingUnhandledKey) {
+ return super.dispatchKeyEvent(event);
+ } else {
+ // Key events from the IME do not go through the input channel;
+ // we need to intercept them here to hand to the application.
+ dispatchKeyEventNative(mNativeHandle, event);
+ return true;
+ }
+ }
+
public void surfaceCreated(SurfaceHolder holder) {
if (!mDestroyed) {
mCurSurfaceHolder = holder;
@@ -179,6 +233,13 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback,
}
}
+ public void surfaceRedrawNeeded(SurfaceHolder holder) {
+ if (!mDestroyed) {
+ mCurSurfaceHolder = holder;
+ onSurfaceRedrawNeededNative(mNativeHandle, holder.getSurface());
+ }
+ }
+
public void surfaceDestroyed(SurfaceHolder holder) {
mCurSurfaceHolder = null;
if (!mDestroyed) {
@@ -200,10 +261,32 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback,
}
}
+ public void onGlobalLayout() {
+ mNativeContentView.getLocationInWindow(mLocation);
+ int w = mNativeContentView.getWidth();
+ int h = mNativeContentView.getHeight();
+ if (mLocation[0] != mLastContentX || mLocation[1] != mLastContentY
+ || w != mLastContentWidth || h != mLastContentHeight) {
+ mLastContentX = mLocation[0];
+ mLastContentY = mLocation[1];
+ mLastContentWidth = w;
+ mLastContentHeight = h;
+ if (!mDestroyed) {
+ onContentRectChangedNative(mNativeHandle, mLastContentX,
+ mLastContentY, mLastContentWidth, mLastContentHeight);
+ }
+ }
+ }
+
void dispatchUnhandledKeyEvent(KeyEvent event) {
- View decor = getWindow().getDecorView();
- if (decor != null) {
- decor.dispatchKeyEvent(event);
+ try {
+ mDispatchingUnhandledKey = true;
+ View decor = getWindow().getDecorView();
+ if (decor != null) {
+ decor.dispatchKeyEvent(event);
+ }
+ } finally {
+ mDispatchingUnhandledKey = false;
}
}
@@ -214,4 +297,12 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback,
void setWindowFormat(int format) {
getWindow().setFormat(format);
}
+
+ void showIme(int mode) {
+ mIMM.showSoftInput(mNativeContentView, mode);
+ }
+
+ void hideIme(int mode) {
+ mIMM.hideSoftInputFromWindow(mNativeContentView.getWindowToken(), mode);
+ }
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 6f12f19..2d120e8 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -336,7 +336,7 @@ public abstract class WallpaperService extends Service {
? (mWindowFlags&~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
: (mWindowFlags|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
if (mCreated) {
- updateSurface(false, false);
+ updateSurface(false, false, false);
}
}
@@ -421,6 +421,13 @@ public abstract class WallpaperService extends Service {
}
/**
+ * Convenience for {@link SurfaceHolder.Callback#surfaceRedrawNeeded
+ * SurfaceHolder.Callback.surfaceRedrawNeeded()}.
+ */
+ public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
+ }
+
+ /**
* Convenience for {@link SurfaceHolder.Callback#surfaceCreated
* SurfaceHolder.Callback.surfaceCreated()}.
*/
@@ -450,7 +457,7 @@ public abstract class WallpaperService extends Service {
}
}
- void updateSurface(boolean forceRelayout, boolean forceReport) {
+ void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNeeded) {
if (mDestroyed) {
Log.w(TAG, "Ignoring updateSurface: destroyed");
}
@@ -467,7 +474,7 @@ public abstract class WallpaperService extends Service {
final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
final boolean flagsChanged = mCurWindowFlags != mWindowFlags;
if (forceRelayout || creating || surfaceCreating || formatChanged || sizeChanged
- || typeChanged || flagsChanged) {
+ || typeChanged || flagsChanged || redrawNeeded) {
if (DEBUG) Log.v(TAG, "Changes: creating=" + creating
+ " format=" + formatChanged + " size=" + sizeChanged);
@@ -555,6 +562,10 @@ public abstract class WallpaperService extends Service {
}
}
}
+
+ redrawNeeded |= creating
+ || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0;
+
if (forceReport || creating || surfaceCreating
|| formatChanged || sizeChanged) {
if (DEBUG) {
@@ -578,10 +589,24 @@ public abstract class WallpaperService extends Service {
}
}
}
+
+ if (redrawNeeded) {
+ onSurfaceRedrawNeeded(mSurfaceHolder);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ if (c instanceof SurfaceHolder.Callback2) {
+ ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
+ mSurfaceHolder);
+ }
+ }
+ }
+ }
+
} finally {
mIsCreating = false;
mSurfaceCreated = true;
- if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
+ if (redrawNeeded) {
mSession.finishDrawing(mWindow);
}
}
@@ -618,7 +643,7 @@ public abstract class WallpaperService extends Service {
onCreate(mSurfaceHolder);
mInitializing = false;
- updateSurface(false, false);
+ updateSurface(false, false, false);
}
void doDesiredSizeChanged(int desiredWidth, int desiredHeight) {
@@ -647,7 +672,7 @@ public abstract class WallpaperService extends Service {
// If becoming visible, in preview mode the surface
// may have been destroyed so now we need to make
// sure it is re-created.
- updateSurface(false, false);
+ updateSurface(false, false, false);
}
onVisibilityChanged(visible);
}
@@ -852,7 +877,7 @@ public abstract class WallpaperService extends Service {
return;
}
case MSG_UPDATE_SURFACE:
- mEngine.updateSurface(true, false);
+ mEngine.updateSurface(true, false, false);
break;
case MSG_VISIBILITY_CHANGED:
if (DEBUG) Log.v(TAG, "Visibility change in " + mEngine
@@ -868,14 +893,8 @@ public abstract class WallpaperService extends Service {
} break;
case MSG_WINDOW_RESIZED: {
final boolean reportDraw = message.arg1 != 0;
- mEngine.updateSurface(true, false);
+ mEngine.updateSurface(true, false, reportDraw);
mEngine.doOffsetsChanged();
- if (reportDraw) {
- try {
- mEngine.mSession.finishDrawing(mEngine.mWindow);
- } catch (RemoteException e) {
- }
- }
} break;
case MSG_TOUCH_EVENT: {
MotionEvent ev = (MotionEvent)message.obj;
diff --git a/core/java/android/view/SurfaceHolder.java b/core/java/android/view/SurfaceHolder.java
index 34e4638..0d38f7b 100644
--- a/core/java/android/view/SurfaceHolder.java
+++ b/core/java/android/view/SurfaceHolder.java
@@ -119,6 +119,23 @@ public interface SurfaceHolder {
}
/**
+ * Additional callbacks that can be received for {@link Callback}.
+ */
+ public interface Callback2 extends Callback {
+ /**
+ * Called when the application needs to redraw the content of its
+ * surface, after it is resized or for some other reason. By not
+ * returning here until the redraw is complete, you can ensure that
+ * the user will not see your surface in a bad state (at its new
+ * size before it has been correctly drawn that way). This will
+ * typically be preceeded by a call to {@link #surfaceChanged}.
+ *
+ * @param holder The SurfaceHolder whose surface has changed.
+ */
+ public void surfaceRedrawNeeded(SurfaceHolder holder);
+ }
+
+ /**
* Add a Callback interface for this holder. There can several Callback
* interfaces associated to a holder.
*
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index e4d1ae1..c469bcc 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -123,7 +123,7 @@ public class SurfaceView extends View {
handleGetNewSurface();
} break;
case UPDATE_WINDOW_MSG: {
- updateWindow(false);
+ updateWindow(false, false);
} break;
}
}
@@ -132,7 +132,7 @@ public class SurfaceView extends View {
final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
= new ViewTreeObserver.OnScrollChangedListener() {
public void onScrollChanged() {
- updateWindow(false);
+ updateWindow(false, false);
}
};
@@ -210,7 +210,7 @@ public class SurfaceView extends View {
super.onWindowVisibilityChanged(visibility);
mWindowVisibility = visibility == VISIBLE;
mRequestedVisible = mWindowVisibility && mViewVisibility;
- updateWindow(false);
+ updateWindow(false, false);
}
@Override
@@ -218,7 +218,7 @@ public class SurfaceView extends View {
super.setVisibility(visibility);
mViewVisibility = visibility == VISIBLE;
mRequestedVisible = mWindowVisibility && mViewVisibility;
- updateWindow(false);
+ updateWindow(false, false);
}
/**
@@ -232,7 +232,7 @@ public class SurfaceView extends View {
*/
protected void showSurface() {
if (mSession != null) {
- updateWindow(true);
+ updateWindow(true, false);
}
}
@@ -265,7 +265,7 @@ public class SurfaceView extends View {
protected void onDetachedFromWindow() {
getViewTreeObserver().removeOnScrollChangedListener(mScrollChangedListener);
mRequestedVisible = false;
- updateWindow(false);
+ updateWindow(false, false);
mHaveFrame = false;
if (mWindow != null) {
try {
@@ -290,7 +290,7 @@ public class SurfaceView extends View {
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- updateWindow(false);
+ updateWindow(false, false);
}
@Override
@@ -343,7 +343,7 @@ public class SurfaceView extends View {
}
// reposition ourselves where the surface is
mHaveFrame = true;
- updateWindow(false);
+ updateWindow(false, false);
super.dispatchDraw(canvas);
}
@@ -397,7 +397,7 @@ public class SurfaceView extends View {
mWindowType = type;
}
- private void updateWindow(boolean force) {
+ private void updateWindow(boolean force, boolean redrawNeeded) {
if (!mHaveFrame) {
return;
}
@@ -425,7 +425,7 @@ public class SurfaceView extends View {
final boolean typeChanged = mType != mRequestedType;
if (force || creating || formatChanged || sizeChanged || visibleChanged
|| typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]
- || mUpdateWindowNeeded || mReportDrawNeeded) {
+ || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
+ " format=" + formatChanged + " size=" + sizeChanged
@@ -524,6 +524,8 @@ public class SurfaceView extends View {
}
try {
+ redrawNeeded |= creating | reportDrawNeeded;
+
if (visible) {
mDestroyReportNeeded = true;
@@ -541,8 +543,13 @@ public class SurfaceView extends View {
}
if (creating || formatChanged || sizeChanged
|| visibleChanged || realSizeChanged) {
+ }
+ if (redrawNeeded) {
for (SurfaceHolder.Callback c : callbacks) {
- c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
+ if (c instanceof SurfaceHolder.Callback2) {
+ ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
+ mSurfaceHolder);
+ }
}
}
} else {
@@ -550,7 +557,7 @@ public class SurfaceView extends View {
}
} finally {
mIsCreating = false;
- if (creating || reportDrawNeeded) {
+ if (redrawNeeded) {
mSession.finishDrawing(mWindow);
}
}
@@ -580,7 +587,7 @@ public class SurfaceView extends View {
void handleGetNewSurface() {
mNewSurfaceNeeded = true;
- updateWindow(false);
+ updateWindow(false, false);
}
/**
@@ -696,7 +703,7 @@ public class SurfaceView extends View {
mRequestedFormat = format;
if (mWindow != null) {
- updateWindow(false);
+ updateWindow(false, false);
}
}
@@ -713,7 +720,7 @@ public class SurfaceView extends View {
case SURFACE_TYPE_PUSH_BUFFERS:
mRequestedType = type;
if (mWindow != null) {
- updateWindow(false);
+ updateWindow(false, false);
}
break;
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index fb45971..260bf7bc 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -137,7 +137,7 @@ public final class ViewRoot extends Handler implements ViewParent,
int mViewVisibility;
boolean mAppVisible = true;
- SurfaceHolder.Callback mSurfaceHolderCallback;
+ SurfaceHolder.Callback2 mSurfaceHolderCallback;
BaseSurfaceHolder mSurfaceHolder;
boolean mIsCreating;
boolean mDrawingAllowed;
@@ -1263,6 +1263,18 @@ public final class ViewRoot extends Handler implements ViewParent,
Log.v("ViewRoot", "FINISHED DRAWING: " + mWindowAttributes.getTitle());
}
mReportNextDraw = false;
+ if (mSurfaceHolder != null && mSurface.isValid()) {
+ mSurfaceHolderCallback.surfaceRedrawNeeded(mSurfaceHolder);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ if (c instanceof SurfaceHolder.Callback2) {
+ ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
+ mSurfaceHolder);
+ }
+ }
+ }
+ }
try {
sWindowSession.finishDrawing(mWindow);
} catch (RemoteException e) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index f40734b..11c09c1 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -478,7 +478,7 @@ public abstract class Window {
* to operate (such as for receiving input events). The given SurfaceHolder
* callback will be used to tell you about state changes to the surface.
*/
- public abstract void takeSurface(SurfaceHolder.Callback callback);
+ public abstract void takeSurface(SurfaceHolder.Callback2 callback);
/**
* Take ownership of this window's InputQueue. The window will no
diff --git a/core/java/com/android/internal/view/RootViewSurfaceTaker.java b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
index 7ff8d4c..9c1b558 100644
--- a/core/java/com/android/internal/view/RootViewSurfaceTaker.java
+++ b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
@@ -5,7 +5,7 @@ import android.view.SurfaceHolder;
/** hahahah */
public interface RootViewSurfaceTaker {
- SurfaceHolder.Callback willYouTakeTheSurface();
+ SurfaceHolder.Callback2 willYouTakeTheSurface();
void setSurfaceType(int type);
void setSurfaceFormat(int format);
void setSurfaceKeepScreenOn(boolean keepOn);