am 51a0c90b: Merge "Add new API to take over a window\'s Surface." into kraken

This commit is contained in:
Dianne Hackborn
2010-05-18 12:22:53 -07:00
committed by Android Git Automerger
9 changed files with 223 additions and 26 deletions

View File

@ -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"

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -472,6 +472,14 @@ public abstract class Window {
return mCallback;
}
/**
* 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

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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;
@ -238,6 +246,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return mDecor != null ? mDecor.findFocus() : null;
}
@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() {