summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml13
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java25
-rw-r--r--core/java/android/view/SurfaceHolder.java1
-rw-r--r--core/java/android/view/ViewRoot.java123
-rw-r--r--core/java/android/view/Window.java8
-rw-r--r--core/java/com/android/internal/view/BaseSurfaceHolder.java31
-rw-r--r--core/java/com/android/internal/view/RootViewSurfaceTaker.java11
-rw-r--r--native/include/android/native_activity.h5
-rw-r--r--policy/com/android/internal/policy/impl/PhoneWindow.java32
9 files changed, 223 insertions, 26 deletions
diff --git a/api/current.xml b/api/current.xml
index e17e31d..b141ad1 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -186070,6 +186070,19 @@
<parameter name="get" type="boolean">
</parameter>
</method>
+<method name="takeSurface"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callback" type="android.view.SurfaceHolder.Callback">
+</parameter>
+</method>
<method name="togglePanel"
return="void"
abstract="true"
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 3d1d7d6..2ade44e 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -522,20 +522,14 @@ public abstract class WallpaperService extends Service {
}
try {
- SurfaceHolder.Callback callbacks[] = null;
- synchronized (mSurfaceHolder.mCallbacks) {
- final int N = mSurfaceHolder.mCallbacks.size();
- if (N > 0) {
- callbacks = new SurfaceHolder.Callback[N];
- mSurfaceHolder.mCallbacks.toArray(callbacks);
- }
- }
+ mSurfaceHolder.ungetCallbacks();
if (surfaceCreating) {
mIsCreating = true;
if (DEBUG) Log.v(TAG, "onSurfaceCreated("
+ mSurfaceHolder + "): " + this);
onSurfaceCreated(mSurfaceHolder);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
if (callbacks != null) {
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceCreated(mSurfaceHolder);
@@ -557,6 +551,7 @@ public abstract class WallpaperService extends Service {
+ "): " + this);
onSurfaceChanged(mSurfaceHolder, mFormat,
mCurWidth, mCurHeight);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
if (callbacks != null) {
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceChanged(mSurfaceHolder, mFormat,
@@ -698,14 +693,12 @@ public abstract class WallpaperService extends Service {
void reportSurfaceDestroyed() {
if (mSurfaceCreated) {
mSurfaceCreated = false;
- SurfaceHolder.Callback callbacks[];
- synchronized (mSurfaceHolder.mCallbacks) {
- callbacks = new SurfaceHolder.Callback[
- mSurfaceHolder.mCallbacks.size()];
- mSurfaceHolder.mCallbacks.toArray(callbacks);
- }
- for (SurfaceHolder.Callback c : callbacks) {
- c.surfaceDestroyed(mSurfaceHolder);
+ mSurfaceHolder.ungetCallbacks();
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceDestroyed(mSurfaceHolder);
+ }
}
if (DEBUG) Log.v(TAG, "onSurfaceDestroyed("
+ mSurfaceHolder + "): " + this);
diff --git a/core/java/android/view/SurfaceHolder.java b/core/java/android/view/SurfaceHolder.java
index 64a10d1..34e4638 100644
--- a/core/java/android/view/SurfaceHolder.java
+++ b/core/java/android/view/SurfaceHolder.java
@@ -182,7 +182,6 @@ public interface SurfaceHolder {
/**
* Enable or disable option to keep the screen turned on while this
* surface is displayed. The default is false, allowing it to turn off.
- * Enabling the option effectivelty.
* This is safe to call from any thread.
*
* @param screenOn Supply to true to force the screen to stay on, false
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index a9dd844..aa124e6 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -16,8 +16,10 @@
package android.view;
+import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
+import com.android.internal.view.RootViewSurfaceTaker;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
@@ -135,6 +137,11 @@ public final class ViewRoot extends Handler implements ViewParent,
int mViewVisibility;
boolean mAppVisible = true;
+ SurfaceHolder.Callback mSurfaceHolderCallback;
+ BaseSurfaceHolder mSurfaceHolder;
+ boolean mIsCreating;
+ boolean mDrawingAllowed;
+
final Region mTransparentRegion;
final Region mPreviousTransparentRegion;
@@ -440,6 +447,13 @@ public final class ViewRoot extends Handler implements ViewParent,
mView = view;
mWindowAttributes.copyFrom(attrs);
attrs = mWindowAttributes;
+ if (view instanceof RootViewSurfaceTaker) {
+ mSurfaceHolderCallback =
+ ((RootViewSurfaceTaker)view).willYouTakeTheSurface();
+ if (mSurfaceHolderCallback != null) {
+ mSurfaceHolder = new TakenSurfaceHolder();
+ }
+ }
Resources resources = mView.getContext().getResources();
CompatibilityInfo compatibilityInfo = resources.getCompatibilityInfo();
mTranslator = compatibilityInfo.getTranslator();
@@ -695,6 +709,7 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean windowResizesToFitContent = false;
boolean fullRedrawNeeded = mFullRedrawNeeded;
boolean newSurface = false;
+ boolean surfaceChanged = false;
WindowManager.LayoutParams lp = mWindowAttributes;
int desiredWindowWidth;
@@ -713,6 +728,7 @@ public final class ViewRoot extends Handler implements ViewParent,
WindowManager.LayoutParams params = null;
if (mWindowAttributesChanged) {
mWindowAttributesChanged = false;
+ surfaceChanged = true;
params = lp;
}
Rect frame = mWinFrame;
@@ -899,11 +915,18 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
+ if (mSurfaceHolder != null) {
+ mSurfaceHolder.mSurfaceLock.lock();
+ mDrawingAllowed = true;
+ lp.format = mSurfaceHolder.getRequestedFormat();
+ lp.type = mSurfaceHolder.getRequestedType();
+ }
+
boolean initialized = false;
boolean contentInsetsChanged = false;
boolean visibleInsetsChanged;
+ boolean hadSurface = mSurface.isValid();
try {
- boolean hadSurface = mSurface.isValid();
int fl = 0;
if (params != null) {
fl = params.flags;
@@ -978,6 +1001,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
} catch (RemoteException e) {
}
+
if (DEBUG_ORIENTATION) Log.v(
"ViewRoot", "Relayout returned: frame=" + frame + ", surface=" + mSurface);
@@ -990,6 +1014,57 @@ public final class ViewRoot extends Handler implements ViewParent,
mWidth = frame.width();
mHeight = frame.height();
+ if (mSurfaceHolder != null) {
+ // The app owns the surface; tell it about what is going on.
+ if (mSurface.isValid()) {
+ // XXX .copyFrom() doesn't work!
+ //mSurfaceHolder.mSurface.copyFrom(mSurface);
+ mSurfaceHolder.mSurface = mSurface;
+ }
+ mSurfaceHolder.mSurfaceLock.unlock();
+ if (mSurface.isValid()) {
+ if (!hadSurface) {
+ mSurfaceHolder.ungetCallbacks();
+
+ mIsCreating = true;
+ mSurfaceHolderCallback.surfaceCreated(mSurfaceHolder);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceCreated(mSurfaceHolder);
+ }
+ }
+ surfaceChanged = true;
+ }
+ if (surfaceChanged) {
+ mSurfaceHolderCallback.surfaceChanged(mSurfaceHolder,
+ lp.format, mWidth, mHeight);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceChanged(mSurfaceHolder, lp.format,
+ mWidth, mHeight);
+ }
+ }
+ }
+ mIsCreating = false;
+ } else if (hadSurface) {
+ mSurfaceHolder.ungetCallbacks();
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ mSurfaceHolderCallback.surfaceDestroyed(mSurfaceHolder);
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceDestroyed(mSurfaceHolder);
+ }
+ }
+ mSurfaceHolder.mSurfaceLock.lock();
+ // Make surface invalid.
+ //mSurfaceHolder.mSurface.copyFrom(mSurface);
+ mSurfaceHolder.mSurface = new Surface();
+ mSurfaceHolder.mSurfaceLock.unlock();
+ }
+ }
+
if (initialized) {
mGlCanvas.setViewport((int) (mWidth * appScale + 0.5f),
(int) (mHeight * appScale + 0.5f));
@@ -1281,6 +1356,12 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean scalingRequired = mAttachInfo.mScalingRequired;
Rect dirty = mDirty;
+ if (mSurfaceHolder != null) {
+ // The app owns the surface, we won't draw.
+ dirty.setEmpty();
+ return;
+ }
+
if (mUseGL) {
if (!dirty.isEmpty()) {
Canvas canvas = mGlCanvas;
@@ -2828,6 +2909,46 @@ public final class ViewRoot extends Handler implements ViewParent,
return scrollToRectOrFocus(rectangle, immediate);
}
+ class TakenSurfaceHolder extends BaseSurfaceHolder {
+ @Override
+ public boolean onAllowLockCanvas() {
+ return mDrawingAllowed;
+ }
+
+ @Override
+ public void onRelayoutContainer() {
+ // Not currently interesting -- from changing between fixed and layout size.
+ }
+
+ public void setFormat(int format) {
+ ((RootViewSurfaceTaker)mView).setSurfaceFormat(format);
+ }
+
+ public void setType(int type) {
+ ((RootViewSurfaceTaker)mView).setSurfaceType(type);
+ }
+
+ @Override
+ public void onUpdateSurface() {
+ // We take care of format and type changes on our own.
+ throw new IllegalStateException("Shouldn't be here");
+ }
+
+ public boolean isCreating() {
+ return mIsCreating;
+ }
+
+ @Override
+ public void setFixedSize(int width, int height) {
+ throw new UnsupportedOperationException(
+ "Currently only support sizing from layout");
+ }
+
+ public void setKeepScreenOn(boolean screenOn) {
+ ((RootViewSurfaceTaker)mView).setSurfaceKeepScreenOn(screenOn);
+ }
+ }
+
static class InputMethodCallback extends IInputMethodCallback.Stub {
private WeakReference<ViewRoot> mViewRoot;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 7dd5085..234deba 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -473,6 +473,14 @@ public abstract class Window {
}
/**
+ * Take ownership of this window's surface. The window's view hierarchy
+ * will no longer draw into the surface, though it will otherwise continue
+ * 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);
+
+ /**
* Return whether this window is being displayed with a floating style
* (based on the {@link android.R.attr#windowIsFloating} attribute in
* the style/theme).
diff --git a/core/java/com/android/internal/view/BaseSurfaceHolder.java b/core/java/com/android/internal/view/BaseSurfaceHolder.java
index e0d3a5f..3a04993 100644
--- a/core/java/com/android/internal/view/BaseSurfaceHolder.java
+++ b/core/java/com/android/internal/view/BaseSurfaceHolder.java
@@ -33,9 +33,11 @@ public abstract class BaseSurfaceHolder implements SurfaceHolder {
public final ArrayList<SurfaceHolder.Callback> mCallbacks
= new ArrayList<SurfaceHolder.Callback>();
-
+ SurfaceHolder.Callback[] mGottenCallbacks;
+ boolean mHaveGottenCallbacks;
+
public final ReentrantLock mSurfaceLock = new ReentrantLock();
- public final Surface mSurface = new Surface();
+ public Surface mSurface = new Surface();
int mRequestedWidth = -1;
int mRequestedHeight = -1;
@@ -83,6 +85,31 @@ public abstract class BaseSurfaceHolder implements SurfaceHolder {
}
}
+ public SurfaceHolder.Callback[] getCallbacks() {
+ if (mHaveGottenCallbacks) {
+ return mGottenCallbacks;
+ }
+
+ synchronized (mCallbacks) {
+ final int N = mCallbacks.size();
+ if (N > 0) {
+ if (mGottenCallbacks == null || mGottenCallbacks.length != N) {
+ mGottenCallbacks = new SurfaceHolder.Callback[N];
+ }
+ mCallbacks.toArray(mGottenCallbacks);
+ } else {
+ mGottenCallbacks = null;
+ }
+ mHaveGottenCallbacks = true;
+ }
+
+ return mGottenCallbacks;
+ }
+
+ public void ungetCallbacks() {
+ mHaveGottenCallbacks = false;
+ }
+
public void setFixedSize(int width, int height) {
if (mRequestedWidth != width || mRequestedHeight != height) {
mRequestedWidth = width;
diff --git a/core/java/com/android/internal/view/RootViewSurfaceTaker.java b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
new file mode 100644
index 0000000..fcb1645
--- /dev/null
+++ b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
@@ -0,0 +1,11 @@
+package com.android.internal.view;
+
+import android.view.SurfaceHolder;
+
+/** hahahah */
+public interface RootViewSurfaceTaker {
+ SurfaceHolder.Callback willYouTakeTheSurface();
+ void setSurfaceType(int type);
+ void setSurfaceFormat(int format);
+ void setSurfaceKeepScreenOn(boolean keepOn);
+}
diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h
index 8b09461..c0f35f8 100644
--- a/native/include/android/native_activity.h
+++ b/native/include/android/native_activity.h
@@ -55,11 +55,6 @@ typedef void android_activity_create_t(android_activity_t* activity,
extern android_activity_create_t android_onCreateActivity;
-#if 0
-extern android_onCreateActivity(android_activity_t activity,
- void* savedState, size_t savedStateSize);
-#endif
-
#ifdef __cplusplus
};
#endif
diff --git a/policy/com/android/internal/policy/impl/PhoneWindow.java b/policy/com/android/internal/policy/impl/PhoneWindow.java
index 5592b6d..0cb0efc 100644
--- a/policy/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,6 +22,8 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import com.android.internal.view.BaseSurfaceHolder;
+import com.android.internal.view.RootViewSurfaceTaker;
import com.android.internal.view.menu.ContextMenuBuilder;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuDialogHelper;
@@ -42,6 +44,7 @@ import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -59,6 +62,8 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewManager;
@@ -100,6 +105,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// mDecor itself, or a child of mDecor where the contents go.
private ViewGroup mContentParent;
+ SurfaceHolder.Callback mTakeSurfaceCallback;
+ BaseSurfaceHolder mSurfaceHolder;
+
private boolean mIsFloating;
private LayoutInflater mLayoutInflater;
@@ -239,6 +247,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
+ public void takeSurface(SurfaceHolder.Callback callback) {
+ mTakeSurfaceCallback = callback;
+ }
+
+ @Override
public boolean isFloating() {
return mIsFloating;
}
@@ -1554,7 +1567,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
- private final class DecorView extends FrameLayout {
+ private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
/* package */int mDefaultOpacity = PixelFormat.OPAQUE;
/** The feature ID of the panel, or -1 if this is the application's DecorView */
@@ -2019,6 +2032,23 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
closeAllPanels();
}
}
+
+ public android.view.SurfaceHolder.Callback willYouTakeTheSurface() {
+ return mFeatureId < 0 ? mTakeSurfaceCallback : null;
+ }
+
+ public void setSurfaceType(int type) {
+ PhoneWindow.this.setType(type);
+ }
+
+ public void setSurfaceFormat(int format) {
+ PhoneWindow.this.setFormat(format);
+ }
+
+ public void setSurfaceKeepScreenOn(boolean keepOn) {
+ if (keepOn) PhoneWindow.this.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ else PhoneWindow.this.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
}
protected DecorView generateDecor() {