diff options
84 files changed, 1003 insertions, 441 deletions
@@ -199955,6 +199955,25 @@ > </field> </class> +<class name="Base64DataException" + extends="java.io.IOException" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="Base64DataException" + type="android.util.Base64DataException" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="detailMessage" type="java.lang.String"> +</parameter> +</constructor> +</class> <class name="Base64InputStream" extends="java.io.FilterInputStream" abstract="false" @@ -214823,6 +214842,19 @@ <parameter name="selected" type="boolean"> </parameter> </method> +<method name="dispatchSystemUiVisibilityChanged" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="visibility" type="int"> +</parameter> +</method> <method name="dispatchTouchEvent" return="boolean" abstract="false" @@ -215876,6 +215908,17 @@ visibility="protected" > </method> +<method name="getSystemUiVisibility" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getTag" return="java.lang.Object" abstract="false" @@ -218126,6 +218169,19 @@ <parameter name="l" type="android.view.View.OnLongClickListener"> </parameter> </method> +<method name="setOnSystemUiVisibilityChangeListener" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="l" type="android.view.View.OnSystemUiVisibilityChangeListener"> +</parameter> +</method> <method name="setOnTouchListener" return="void" abstract="false" @@ -218379,6 +218435,19 @@ <parameter name="soundEffectsEnabled" type="boolean"> </parameter> </method> +<method name="setSystemUiVisibility" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="visibility" type="int"> +</parameter> +</method> <method name="setTag" return="void" abstract="false" @@ -219386,6 +219455,28 @@ visibility="public" > </field> +<field name="STATUS_BAR_HIDDEN" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="STATUS_BAR_VISIBLE" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="VIEW_LOG_TAG" type="java.lang.String" transient="false" @@ -219804,6 +219895,27 @@ </parameter> </method> </interface> +<interface name="View.OnSystemUiVisibilityChangeListener" + abstract="true" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<method name="onSystemUiVisibilityChange" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="visibility" type="int"> +</parameter> +</method> +</interface> <interface name="View.OnTouchListener" abstract="true" static="true" diff --git a/api/current.xml b/api/current.xml index 3bcac93..b7d7b3a 100644 --- a/api/current.xml +++ b/api/current.xml @@ -29889,6 +29889,17 @@ visibility="public" > </method> +<method name="isRemoving" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="isResumed" return="boolean" abstract="false" @@ -199955,6 +199966,25 @@ > </field> </class> +<class name="Base64DataException" + extends="java.io.IOException" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="Base64DataException" + type="android.util.Base64DataException" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="detailMessage" type="java.lang.String"> +</parameter> +</constructor> +</class> <class name="Base64InputStream" extends="java.io.FilterInputStream" abstract="false" diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 511ddc1..960b943 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2385,7 +2385,9 @@ public final class ActivityThread { performPauseActivity(token, finished, r.isPreHoneycomb()); // Make sure any pending writes are now committed. - QueuedWork.waitToFinish(); + if (r.isPreHoneycomb()) { + QueuedWork.waitToFinish(); + } // Tell the activity manager we have paused. try { @@ -2583,6 +2585,11 @@ public final class ActivityThread { updateVisibility(r, show); + // Make sure any pending writes are now committed. + if (!r.isPreHoneycomb()) { + QueuedWork.waitToFinish(); + } + // Tell activity manager we have been stopped. try { ActivityManagerNative.getDefault().activityStopped( @@ -2647,6 +2654,12 @@ public final class ActivityThread { } r.stopped = true; } + + // Make sure any pending writes are now committed. + if (!r.isPreHoneycomb()) { + QueuedWork.waitToFinish(); + } + // Tell activity manager we slept. try { ActivityManagerNative.getDefault().activitySlept(r.token); diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 3280b22..b3d111a 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -357,6 +357,9 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener // True if the fragment is in the list of added fragments. boolean mAdded; + // If set this fragment is being removed from its activity. + boolean mRemoving; + // True if the fragment is in the resumed state. boolean mResumed; @@ -638,6 +641,9 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener * Return <code>getActivity().getResources()</code>. */ final public Resources getResources() { + if (mActivity == null) { + throw new IllegalStateException("Fragment " + this + " not attached to Activity"); + } return mActivity.getResources(); } @@ -689,7 +695,16 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener * Return true if the fragment is currently added to its activity. */ final public boolean isAdded() { - return mActivity != null && mActivity.mFragments.mAdded.contains(this); + return mActivity != null && mAdded; + } + + /** + * Return true if this fragment is currently being removed from its + * activity. This is <em>not</em> whether its activity is finishing, but + * rather whether it is in the process of being removed from its activity. + */ + final public boolean isRemoving() { + return mRemoving; } /** @@ -787,6 +802,9 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener if (mLoaderManager != null) { return mLoaderManager; } + if (mActivity == null) { + throw new IllegalStateException("Fragment " + this + " not attached to Activity"); + } mCheckedForLoaderManager = true; mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, true); return mLoaderManager; @@ -797,6 +815,9 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener * containing Activity. */ public void startActivity(Intent intent) { + if (mActivity == null) { + throw new IllegalStateException("Fragment " + this + " not attached to Activity"); + } mActivity.startActivityFromFragment(this, intent, -1); } @@ -805,6 +826,9 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener * containing Activity. */ public void startActivityForResult(Intent intent, int requestCode) { + if (mActivity == null) { + throw new IllegalStateException("Fragment " + this + " not attached to Activity"); + } mActivity.startActivityFromFragment(this, intent, requestCode); } @@ -1217,6 +1241,7 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener writer.print(" mWho="); writer.print(mWho); writer.print(" mBackStackNesting="); writer.println(mBackStackNesting); writer.print(prefix); writer.print("mAdded="); writer.print(mAdded); + writer.print(" mRemoving="); writer.print(mRemoving); writer.print(" mResumed="); writer.print(mResumed); writer.print(" mFromLayout="); writer.print(mFromLayout); writer.print(" mInLayout="); writer.println(mInLayout); diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index e729805..2c9c85b 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -28,6 +28,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.DebugUtils; import android.util.Log; +import android.util.LogWriter; +import android.util.Slog; import android.util.SparseArray; import android.view.Menu; import android.view.MenuInflater; @@ -968,6 +970,7 @@ final class FragmentManagerImpl extends FragmentManager { makeActive(fragment); if (DEBUG) Log.v(TAG, "add: " + fragment); fragment.mAdded = true; + fragment.mRemoving = false; if (fragment.mHasMenu) { mNeedMenuInvalidate = true; } @@ -984,6 +987,7 @@ final class FragmentManagerImpl extends FragmentManager { mNeedMenuInvalidate = true; } fragment.mAdded = false; + fragment.mRemoving = true; moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED, transition, transitionStyle); if (inactive) { @@ -1376,6 +1380,14 @@ final class FragmentManagerImpl extends FragmentManager { } if (f.mTarget != null) { + if (f.mTarget.mIndex < 0) { + String msg = "Failure saving state: " + f + + " has target not in fragment manager: " + f.mTarget; + Slog.e(TAG, msg); + dump(" ", null, new PrintWriter(new LogWriter( + Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { }); + throw new IllegalStateException(msg); + } if (fs.mSavedFragmentState == null) { fs.mSavedFragmentState = new Bundle(); } diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 60213f8..c406524 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -567,6 +567,7 @@ final class LoadedApk { } else { rd.validate(context, handler); } + rd.mForgotten = false; return rd.getIIntentReceiver(); } } @@ -596,6 +597,7 @@ final class LoadedApk { rd.setUnregisterLocation(ex); holder.put(r, rd); } + rd.mForgotten = true; return rd.getIIntentReceiver(); } } @@ -666,6 +668,7 @@ final class LoadedApk { final boolean mRegistered; final IntentReceiverLeaked mLocation; RuntimeException mUnregisterLocation; + boolean mForgotten; final class Args extends BroadcastReceiver.PendingResult implements Runnable { private Intent mCurIntent; @@ -696,7 +699,7 @@ final class LoadedApk { final Intent intent = mCurIntent; mCurIntent = null; - if (receiver == null || !mRegistered) { + if (receiver == null || mForgotten) { if (mRegistered && ordered) { if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, "Finishing null broadcast to " + mReceiver); diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java index 3d6182b..a7dd5fb 100644 --- a/core/java/android/content/AsyncTaskLoader.java +++ b/core/java/android/content/AsyncTaskLoader.java @@ -195,7 +195,7 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> { } } if (DEBUG) Slog.v(TAG, "Executing: " + mTask); - mTask.execute((Void[]) null); + mTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } } diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 5467a30..1764e11 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -899,7 +899,7 @@ public abstract class ContentProvider implements ComponentCallbacks { return null; } }; - task.execute((Object[])null); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null); return fds[0]; } catch (IOException e) { diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index 01fc010..df8cf9a 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -76,6 +76,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub } public void executeMessage(Message msg) { + if (mInputMethodSession == null) return; + switch (msg.what) { case DO_FINISH_INPUT: mInputMethodSession.finishInput(); diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java index 6a54846..343242e 100644 --- a/core/java/android/inputmethodservice/SoftInputWindow.java +++ b/core/java/android/inputmethodservice/SoftInputWindow.java @@ -19,11 +19,16 @@ package android.inputmethodservice; import android.app.Dialog; import android.content.Context; import android.content.pm.ActivityInfo; +import android.graphics.Rect; import android.os.IBinder; import android.view.Gravity; import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; import android.view.WindowManager; +import java.lang.Math; + /** * A SoftInputWindow is a Dialog that is intended to be used for a top-level input * method window. It will be displayed along the edge of the screen, moving @@ -32,6 +37,7 @@ import android.view.WindowManager; */ class SoftInputWindow extends Dialog { final KeyEvent.DispatcherState mDispatcherState; + private final Rect mBounds = new Rect(); public void setToken(IBinder token) { WindowManager.LayoutParams lp = getWindow().getAttributes(); @@ -64,6 +70,13 @@ class SoftInputWindow extends Dialog { mDispatcherState.reset(); } + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + getWindow().getDecorView().getHitRect(mBounds); + final MotionEvent event = clipMotionEvent(ev, mBounds); + return super.dispatchTouchEvent(event); + } + /** * Get the size of the DockWindow. * @@ -150,4 +163,48 @@ class SoftInputWindow extends Dialog { WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_DIM_BEHIND); } + + private static MotionEvent clipMotionEvent(MotionEvent me, Rect bounds) { + final int pointerCount = me.getPointerCount(); + boolean shouldClip = false; + for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) { + final int x = (int)me.getX(pointerIndex); + final int y = (int)me.getY(pointerIndex); + if (!bounds.contains(x, y)) { + shouldClip = true; + break; + } + } + if (!shouldClip) + return me; + + if (pointerCount == 1) { + final int x = (int)me.getX(); + final int y = (int)me.getY(); + me.setLocation( + Math.max(bounds.left, Math.min(x, bounds.right - 1)), + Math.max(bounds.top, Math.min(y, bounds.bottom - 1))); + return me; + } + + final int[] pointerIds = new int[pointerCount]; + final MotionEvent.PointerCoords[] pointerCoords = + new MotionEvent.PointerCoords[pointerCount]; + for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) { + pointerIds[pointerIndex] = me.getPointerId(pointerIndex); + final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); + me.getPointerCoords(pointerIndex, coords); + pointerCoords[pointerIndex] = coords; + final int x = (int)coords.x; + final int y = (int)coords.y; + if (!bounds.contains(x, y)) { + coords.x = Math.max(bounds.left, Math.min(x, bounds.right - 1)); + coords.y = Math.max(bounds.top, Math.min(y, bounds.bottom - 1)); + } + } + return MotionEvent.obtain( + me.getDownTime(), me.getEventTime(), me.getAction(), pointerCount, pointerIds, + pointerCoords, me.getMetaState(), me.getXPrecision(), me.getYPrecision(), + me.getDeviceId(), me.getEdgeFlags(), me.getSource(), me.getFlags()); + } } diff --git a/core/java/android/util/Base64DataException.java b/core/java/android/util/Base64DataException.java new file mode 100644 index 0000000..de12ee1 --- /dev/null +++ b/core/java/android/util/Base64DataException.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.io.IOException; + +/** + * This exception is thrown by {@link Base64InputStream} or {@link Base64OutputStream} + * when an error is detected in the data being decoded. This allows problems with the base64 data + * to be disambiguated from errors in the underlying streams (e.g. actual connection errors.) + */ +public class Base64DataException extends IOException { + public Base64DataException(String detailMessage) { + super(detailMessage); + } +} diff --git a/core/java/android/util/Base64InputStream.java b/core/java/android/util/Base64InputStream.java index e9dac24..9eba5b5 100644 --- a/core/java/android/util/Base64InputStream.java +++ b/core/java/android/util/Base64InputStream.java @@ -145,7 +145,7 @@ public class Base64InputStream extends FilterInputStream { success = coder.process(inputBuffer, 0, bytesRead, false); } if (!success) { - throw new IOException("bad base-64"); + throw new Base64DataException("bad base-64"); } outputEnd = coder.op; outputStart = 0; diff --git a/core/java/android/util/Base64OutputStream.java b/core/java/android/util/Base64OutputStream.java index 30d632d..4535d1c 100644 --- a/core/java/android/util/Base64OutputStream.java +++ b/core/java/android/util/Base64OutputStream.java @@ -136,7 +136,7 @@ public class Base64OutputStream extends FilterOutputStream { private void internalWrite(byte[] b, int off, int len, boolean finish) throws IOException { coder.output = embiggen(coder.output, coder.maxOutputSize(len)); if (!coder.process(b, off, len, finish)) { - throw new IOException("bad base-64"); + throw new Base64DataException("bad base-64"); } out.write(coder.output, 0, coder.op); } diff --git a/core/java/android/util/LogWriter.java b/core/java/android/util/LogWriter.java new file mode 100644 index 0000000..ce30631 --- /dev/null +++ b/core/java/android/util/LogWriter.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.io.Writer; + +/** @hide */ +public class LogWriter extends Writer { + private final int mPriority; + private final String mTag; + private final int mBuffer; + private StringBuilder mBuilder = new StringBuilder(128); + + /** + * Create a new Writer that sends to the log with the given priority + * and tag. + * + * @param priority The desired log priority: + * {@link android.util.Log#VERBOSE Log.VERBOSE}, + * {@link android.util.Log#DEBUG Log.DEBUG}, + * {@link android.util.Log#INFO Log.INFO}, + * {@link android.util.Log#WARN Log.WARN}, or + * {@link android.util.Log#ERROR Log.ERROR}. + * @param tag A string tag to associate with each printed log statement. + */ + public LogWriter(int priority, String tag) { + mPriority = priority; + mTag = tag; + mBuffer = Log.LOG_ID_MAIN; + } + + /** + * @hide + * Same as above, but buffer is one of the LOG_ID_ constants from android.util.Log. + */ + public LogWriter(int priority, String tag, int buffer) { + mPriority = priority; + mTag = tag; + mBuffer = buffer; + } + + @Override public void close() { + flushBuilder(); + } + + @Override public void flush() { + flushBuilder(); + } + + @Override public void write(char[] buf, int offset, int count) { + for(int i = 0; i < count; i++) { + char c = buf[offset + i]; + if ( c == '\n') { + flushBuilder(); + } + else { + mBuilder.append(c); + } + } + } + + private void flushBuilder() { + if (mBuilder.length() > 0) { + Log.println_native(mBuffer, mPriority, mTag, mBuilder.toString()); + mBuilder.delete(0, mBuilder.length()); + } + } +} diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index dce1a6c..dac3135 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -192,21 +192,36 @@ class GLES20Canvas extends HardwareCanvas { nSetViewport(mRenderer, width, height); } - private native void nSetViewport(int renderer, int width, int height); + private static native void nSetViewport(int renderer, int width, int height); + /** + * @hide + */ + public static boolean preserveBackBuffer() { + return nPreserveBackBuffer(); + } + + private static native boolean nPreserveBackBuffer(); + @Override - void onPreDraw() { - nPrepare(mRenderer, mOpaque); + void onPreDraw(Rect dirty) { + if (dirty != null) { + nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom, mOpaque); + } else { + nPrepare(mRenderer, mOpaque); + } } - private native void nPrepare(int renderer, boolean opaque); + private static native void nPrepare(int renderer, boolean opaque); + private static native void nPrepareDirty(int renderer, int left, int top, int right, int bottom, + boolean opaque); @Override void onPostDraw() { nFinish(mRenderer); } - private native void nFinish(int renderer); + private static native void nFinish(int renderer); @Override public boolean acquireContext() { @@ -217,14 +232,14 @@ class GLES20Canvas extends HardwareCanvas { return mContextLocked; } - private native void nAcquireContext(int renderer); + private static native void nAcquireContext(int renderer); @Override public boolean callDrawGLFunction(int drawGLFunction) { return nCallDrawGLFunction(mRenderer, drawGLFunction); } - private native boolean nCallDrawGLFunction(int renderer, int drawGLFunction); + private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction); @Override public void releaseContext() { @@ -234,7 +249,7 @@ class GLES20Canvas extends HardwareCanvas { } } - private native void nReleaseContext(int renderer); + private static native void nReleaseContext(int renderer); /////////////////////////////////////////////////////////////////////////// // Display list @@ -244,7 +259,7 @@ class GLES20Canvas extends HardwareCanvas { return nGetDisplayList(mRenderer); } - private native int nGetDisplayList(int renderer); + private static native int nGetDisplayList(int renderer); static void destroyDisplayList(int displayList) { nDestroyDisplayList(displayList); @@ -257,7 +272,7 @@ class GLES20Canvas extends HardwareCanvas { return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList); } - private native boolean nDrawDisplayList(int renderer, int displayList); + private static native boolean nDrawDisplayList(int renderer, int displayList); /////////////////////////////////////////////////////////////////////////// // Hardware layer @@ -271,7 +286,7 @@ class GLES20Canvas extends HardwareCanvas { if (hasColorFilter) nResetModifiers(mRenderer); } - private native void nDrawLayer(int renderer, int layer, float x, float y, int paint); + private static native void nDrawLayer(int renderer, int layer, float x, float y, int paint); void interrupt() { nInterrupt(mRenderer); @@ -281,8 +296,8 @@ class GLES20Canvas extends HardwareCanvas { nResume(mRenderer); } - private native void nInterrupt(int renderer); - private native void nResume(int renderer); + private static native void nInterrupt(int renderer); + private static native void nResume(int renderer); /////////////////////////////////////////////////////////////////////////// // Clipping @@ -303,7 +318,7 @@ class GLES20Canvas extends HardwareCanvas { return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt); } - private native boolean nClipRect(int renderer, float left, float top, + private static native boolean nClipRect(int renderer, float left, float top, float right, float bottom, int op); @Override @@ -316,7 +331,8 @@ class GLES20Canvas extends HardwareCanvas { return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt); } - private native boolean nClipRect(int renderer, int left, int top, int right, int bottom, int op); + private static native boolean nClipRect(int renderer, int left, int top, int right, int bottom, + int op); @Override public boolean clipRect(Rect rect) { @@ -355,14 +371,14 @@ class GLES20Canvas extends HardwareCanvas { return nGetClipBounds(mRenderer, bounds); } - private native boolean nGetClipBounds(int renderer, Rect bounds); + private static native boolean nGetClipBounds(int renderer, Rect bounds); @Override public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) { return nQuickReject(mRenderer, left, top, right, bottom, type.nativeInt); } - private native boolean nQuickReject(int renderer, float left, float top, + private static native boolean nQuickReject(int renderer, float left, float top, float right, float bottom, int edge); @Override @@ -384,56 +400,56 @@ class GLES20Canvas extends HardwareCanvas { if (dx != 0.0f || dy != 0.0f) nTranslate(mRenderer, dx, dy); } - private native void nTranslate(int renderer, float dx, float dy); + private static native void nTranslate(int renderer, float dx, float dy); @Override public void skew(float sx, float sy) { nSkew(mRenderer, sx, sy); } - private native void nSkew(int renderer, float sx, float sy); + private static native void nSkew(int renderer, float sx, float sy); @Override public void rotate(float degrees) { nRotate(mRenderer, degrees); } - private native void nRotate(int renderer, float degrees); + private static native void nRotate(int renderer, float degrees); @Override public void scale(float sx, float sy) { nScale(mRenderer, sx, sy); } - private native void nScale(int renderer, float sx, float sy); + private static native void nScale(int renderer, float sx, float sy); @Override public void setMatrix(Matrix matrix) { nSetMatrix(mRenderer, matrix.native_instance); } - private native void nSetMatrix(int renderer, int matrix); + private static native void nSetMatrix(int renderer, int matrix); @Override public int getNativeMatrix() { return nGetMatrix(mRenderer); } - private native int nGetMatrix(int renderer); + private static native int nGetMatrix(int renderer); @Override public void getMatrix(Matrix matrix) { nGetMatrix(mRenderer, matrix.native_instance); } - private native void nGetMatrix(int renderer, int matrix); + private static native void nGetMatrix(int renderer, int matrix); @Override public void concat(Matrix matrix) { nConcatMatrix(mRenderer, matrix.native_instance); } - private native void nConcatMatrix(int renderer, int matrix); + private static native void nConcatMatrix(int renderer, int matrix); /////////////////////////////////////////////////////////////////////////// // State management @@ -449,7 +465,7 @@ class GLES20Canvas extends HardwareCanvas { return nSave(mRenderer, saveFlags); } - private native int nSave(int renderer, int flags); + private static native int nSave(int renderer, int flags); @Override public int saveLayer(RectF bounds, Paint paint, int saveFlags) { @@ -469,8 +485,8 @@ class GLES20Canvas extends HardwareCanvas { return save(saveFlags); } - private native int nSaveLayer(int renderer, float left, float top, float right, float bottom, - int paint, int saveFlags); + private static native int nSaveLayer(int renderer, float left, float top, + float right, float bottom, int paint, int saveFlags); @Override public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) { @@ -487,7 +503,7 @@ class GLES20Canvas extends HardwareCanvas { return save(saveFlags); } - private native int nSaveLayerAlpha(int renderer, float left, float top, float right, + private static native int nSaveLayerAlpha(int renderer, float left, float top, float right, float bottom, int alpha, int saveFlags); @Override @@ -495,21 +511,21 @@ class GLES20Canvas extends HardwareCanvas { nRestore(mRenderer); } - private native void nRestore(int renderer); + private static native void nRestore(int renderer); @Override public void restoreToCount(int saveCount) { nRestoreToCount(mRenderer, saveCount); } - private native void nRestoreToCount(int renderer, int saveCount); + private static native void nRestoreToCount(int renderer, int saveCount); @Override public int getSaveCount() { return nGetSaveCount(mRenderer); } - private native int nGetSaveCount(int renderer); + private static native int nGetSaveCount(int renderer); /////////////////////////////////////////////////////////////////////////// // Filtering @@ -538,8 +554,9 @@ class GLES20Canvas extends HardwareCanvas { if (hasModifier) nResetModifiers(mRenderer); } - private native void nDrawArc(int renderer, float left, float top, float right, float bottom, - float startAngle, float sweepAngle, boolean useCenter, int paint); + private static native void nDrawArc(int renderer, float left, float top, + float right, float bottom, float startAngle, float sweepAngle, + boolean useCenter, int paint); @Override public void drawARGB(int a, int r, int g, int b) { @@ -556,7 +573,7 @@ class GLES20Canvas extends HardwareCanvas { if (hasColorFilter) nResetModifiers(mRenderer); } - private native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks, + private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks, float left, float top, float right, float bottom, int paint); @Override @@ -568,7 +585,7 @@ class GLES20Canvas extends HardwareCanvas { if (hasColorFilter) nResetModifiers(mRenderer); } - private native void nDrawBitmap( + private static native void nDrawBitmap( int renderer, int bitmap, byte[] buffer, float left, float top, int paint); @Override @@ -581,7 +598,8 @@ class GLES20Canvas extends HardwareCanvas { if (hasColorFilter) nResetModifiers(mRenderer); } - private native void nDrawBitmap(int renderer, int bitmap, byte[] buff, int matrix, int paint); + private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff, + int matrix, int paint); @Override public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { @@ -616,7 +634,7 @@ class GLES20Canvas extends HardwareCanvas { if (hasColorFilter) nResetModifiers(mRenderer); } - private native void nDrawBitmap(int renderer, int bitmap, byte[] buffer, + private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer, float srcLeft, float srcTop, float srcRight, float srcBottom, float left, float top, float right, float bottom, int paint); @@ -665,7 +683,7 @@ class GLES20Canvas extends HardwareCanvas { if (hasColorFilter) nResetModifiers(mRenderer); } - private native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer, + private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, int paint); @@ -676,7 +694,8 @@ class GLES20Canvas extends HardwareCanvas { if (hasModifier) nResetModifiers(mRenderer); } - private native void nDrawCircle(int renderer, float cx, float cy, float radius, int paint); + private static native void nDrawCircle(int renderer, float cx, float cy, + float radius, int paint); @Override public void drawColor(int color) { @@ -688,7 +707,7 @@ class GLES20Canvas extends HardwareCanvas { nDrawColor(mRenderer, color, mode.nativeInt); } - private native void nDrawColor(int renderer, int color, int mode); + private static native void nDrawColor(int renderer, int color, int mode); @Override public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) { @@ -709,7 +728,8 @@ class GLES20Canvas extends HardwareCanvas { if (hasModifier) nResetModifiers(mRenderer); } - private native void nDrawLines(int renderer, float[] points, int offset, int count, int paint); + private static native void nDrawLines(int renderer, float[] points, + int offset, int count, int paint); @Override public void drawLines(float[] pts, Paint paint) { @@ -723,8 +743,8 @@ class GLES20Canvas extends HardwareCanvas { if (hasModifier) nResetModifiers(mRenderer); } - private native void nDrawOval(int renderer, float left, float top, float right, float bottom, - int paint); + private static native void nDrawOval(int renderer, float left, float top, + float right, float bottom, int paint); @Override public void drawPaint(Paint paint) { @@ -746,8 +766,8 @@ class GLES20Canvas extends HardwareCanvas { if (hasModifier) nResetModifiers(mRenderer); } - private native void nDrawPath(int renderer, int path, int paint); - private native void nDrawRects(int renderer, int region, int paint); + private static native void nDrawPath(int renderer, int path, int paint); + private static native void nDrawRects(int renderer, int region, int paint); @Override public void drawPicture(Picture picture) { @@ -798,8 +818,8 @@ class GLES20Canvas extends HardwareCanvas { if (hasModifier) nResetModifiers(mRenderer); } - private native void nDrawRect(int renderer, float left, float top, float right, float bottom, - int paint); + private static native void nDrawRect(int renderer, float left, float top, + float right, float bottom, int paint); @Override public void drawRect(Rect r, Paint paint) { @@ -824,7 +844,7 @@ class GLES20Canvas extends HardwareCanvas { if (hasModifier) nResetModifiers(mRenderer); } - private native void nDrawRoundRect(int renderer, float left, float top, + private static native void nDrawRoundRect(int renderer, float left, float top, float right, float bottom, float rx, float y, int paint); @Override @@ -841,8 +861,8 @@ class GLES20Canvas extends HardwareCanvas { } } - private native void nDrawText(int renderer, char[] text, int index, int count, float x, float y, - int bidiFlags, int paint); + private static native void nDrawText(int renderer, char[] text, int index, int count, + float x, float y, int bidiFlags, int paint); @Override public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { @@ -858,7 +878,8 @@ class GLES20Canvas extends HardwareCanvas { } else { char[] buf = TemporaryBuffer.obtain(end - start); TextUtils.getChars(text, start, end, buf, 0); - nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint); + nDrawText(mRenderer, buf, 0, end - start, x, y, + paint.mBidiFlags, paint.mNativePaint); TemporaryBuffer.recycle(buf); } } finally { @@ -880,8 +901,8 @@ class GLES20Canvas extends HardwareCanvas { } } - private native void nDrawText(int renderer, String text, int start, int end, float x, float y, - int bidiFlags, int paint); + private static native void nDrawText(int renderer, String text, int start, int end, + float x, float y, int bidiFlags, int paint); @Override public void drawText(String text, float x, float y, Paint paint) { @@ -924,7 +945,7 @@ class GLES20Canvas extends HardwareCanvas { } } - private native void nDrawTextRun(int renderer, char[] text, int index, int count, + private static native void nDrawTextRun(int renderer, char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, int dir, int nativePaint); @Override @@ -958,7 +979,7 @@ class GLES20Canvas extends HardwareCanvas { } } - private native void nDrawTextRun(int renderer, String text, int start, int end, + private static native void nDrawTextRun(int renderer, String text, int start, int end, int contextStart, int contextEnd, float x, float y, int flags, int nativePaint); @Override @@ -1001,9 +1022,10 @@ class GLES20Canvas extends HardwareCanvas { return false; } - private native void nSetupShader(int renderer, int shader); - private native void nSetupColorFilter(int renderer, int colorFilter); - private native void nSetupShadow(int renderer, float radius, float dx, float dy, int color); + private static native void nSetupShader(int renderer, int shader); + private static native void nSetupColorFilter(int renderer, int colorFilter); + private static native void nSetupShadow(int renderer, float radius, + float dx, float dy, int color); - private native void nResetModifiers(int renderer); + private static native void nResetModifiers(int renderer); } diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java index a4d36b7..e6fecc8 100644 --- a/core/java/android/view/HardwareCanvas.java +++ b/core/java/android/view/HardwareCanvas.java @@ -19,6 +19,7 @@ package android.view; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Rect; /** * Hardware accelerated canvas. @@ -38,8 +39,10 @@ public abstract class HardwareCanvas extends Canvas { /** * Invoked before any drawing operation is performed in this canvas. + * + * @param dirty The dirty rectangle to update, can be null. */ - abstract void onPreDraw(); + abstract void onPreDraw(Rect dirty); /** * Invoked after all drawing operation have been performed. diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index c82184a..48f40c3 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -18,6 +18,8 @@ package android.view; import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; import android.os.SystemClock; import android.util.EventLog; import android.util.Log; @@ -39,6 +41,16 @@ public abstract class HardwareRenderer { static final String LOG_TAG = "HardwareRenderer"; /** + * Turn on to only refresh the parts of the screen that need updating. + */ + public static final boolean RENDER_DIRTY_REGIONS = true; + + /** + * Turn on to draw dirty regions every other frame. + */ + private static final boolean DEBUG_DIRTY_REGION = false; + + /** * A process can set this flag to false to prevent the use of hardware * rendering. * @@ -108,11 +120,14 @@ public abstract class HardwareRenderer { /** * Draws the specified view. - * + * * @param view The view to draw. * @param attachInfo AttachInfo tied to the specified view. + * @param callbacks Callbacks invoked when drawing happens. + * @param dirty The dirty rectangle to update, can be null. */ - abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks); + abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks, + Rect dirty); /** * Creates a new display list that can be used to record batches of @@ -214,7 +229,13 @@ public abstract class HardwareRenderer { @SuppressWarnings({"deprecation"}) static abstract class GlRenderer extends HardwareRenderer { private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + private static final int EGL_SURFACE_TYPE = 0x3033; + private static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400; + private static final int SURFACE_STATE_ERROR = 0; + private static final int SURFACE_STATE_SUCCESS = 1; + private static final int SURFACE_STATE_UPDATED = 2; + static EGLContext sEglContext; static EGL10 sEgl; static EGLDisplay sEglDisplay; @@ -226,6 +247,9 @@ public abstract class HardwareRenderer { GL mGl; HardwareCanvas mCanvas; + int mFrameCount; + Paint mDebugPaint; + final int mGlVersion; final boolean mTranslucent; @@ -412,7 +436,7 @@ public abstract class HardwareRenderer { if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) { int error = sEgl.eglGetError(); if (error == EGL10.EGL_BAD_NATIVE_WINDOW) { - Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); + Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); return null; } throw new RuntimeException("createWindowSurface failed " @@ -427,6 +451,12 @@ public abstract class HardwareRenderer { throw new RuntimeException("eglMakeCurrent failed " + getEGLErrorString(sEgl.eglGetError())); } + + if (RENDER_DIRTY_REGIONS) { + if (!GLES20Canvas.preserveBackBuffer()) { + Log.w(LOG_TAG, "Backbuffer cannot be preserved"); + } + } return sEglContext.getGL(); } @@ -471,12 +501,12 @@ public abstract class HardwareRenderer { void setup(int width, int height) { mCanvas.setViewport(width, height); } - + boolean canDraw() { return mGl != null && mCanvas != null; } - void onPreDraw() { + void onPreDraw(Rect dirty) { } void onPostDraw() { @@ -492,8 +522,14 @@ public abstract class HardwareRenderer { } @Override - void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks) { + void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks, + Rect dirty) { if (canDraw()) { + //noinspection PointlessBooleanExpression,ConstantConditions + if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { + dirty = null; + } + attachInfo.mDrawingTime = SystemClock.uptimeMillis(); attachInfo.mIgnoreDirtyState = true; view.mPrivateFlags |= View.DRAWN; @@ -503,11 +539,18 @@ public abstract class HardwareRenderer { startTime = SystemClock.elapsedRealtime(); } - if (checkCurrent()) { - onPreDraw(); + final int surfaceState = checkCurrent(); + if (surfaceState != SURFACE_STATE_ERROR) { + // We had to change the current surface and/or context, redraw everything + if (surfaceState == SURFACE_STATE_UPDATED) { + dirty = null; + } + + onPreDraw(dirty); HardwareCanvas canvas = mCanvas; attachInfo.mHardwareCanvas = canvas; + int saveCount = canvas.save(); callbacks.onHardwarePreDraw(canvas); @@ -515,6 +558,7 @@ public abstract class HardwareRenderer { view.mRecreateDisplayList = (view.mPrivateFlags & View.INVALIDATED) == View.INVALIDATED; view.mPrivateFlags &= ~View.INVALIDATED; + DisplayList displayList = view.getDisplayList(); if (displayList != null) { if (canvas.drawDisplayList(displayList)) { @@ -524,6 +568,16 @@ public abstract class HardwareRenderer { // Shouldn't reach here view.draw(canvas); } + + if (DEBUG_DIRTY_REGION) { + if (mDebugPaint == null) { + mDebugPaint = new Paint(); + mDebugPaint.setColor(0x7fff0000); + } + if (dirty != null && (mFrameCount++ & 1) == 0) { + canvas.drawRect(dirty, mDebugPaint); + } + } } finally { callbacks.onHardwarePostDraw(canvas); canvas.restoreToCount(saveCount); @@ -543,8 +597,8 @@ public abstract class HardwareRenderer { } } } - - private boolean checkCurrent() { + + private int checkCurrent() { // TODO: Don't check the current context when we have one per UI thread // TODO: Use a threadlocal flag to know whether the surface has changed if (sEgl.eglGetCurrentContext() != sEglContext || @@ -553,10 +607,12 @@ public abstract class HardwareRenderer { fallback(true); Log.e(LOG_TAG, "eglMakeCurrent failed " + getEGLErrorString(sEgl.eglGetError())); - return false; + return SURFACE_STATE_ERROR; + } else { + return SURFACE_STATE_UPDATED; } } - return true; + return SURFACE_STATE_SUCCESS; } static abstract class EglConfigChooser { @@ -629,6 +685,7 @@ public abstract class HardwareRenderer { ComponentSizeChooser(int glVersion, int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize) { + //noinspection PointlessBitwiseExpression super(glVersion, new int[] { EGL10.EGL_RED_SIZE, redSize, EGL10.EGL_GREEN_SIZE, greenSize, @@ -636,6 +693,8 @@ public abstract class HardwareRenderer { EGL10.EGL_ALPHA_SIZE, alphaSize, EGL10.EGL_DEPTH_SIZE, depthSize, EGL10.EGL_STENCIL_SIZE, stencilSize, + EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT | + (RENDER_DIRTY_REGIONS ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0), EGL10.EGL_NONE }); mValue = new int[1]; mRedSize = redSize; @@ -656,7 +715,16 @@ public abstract class HardwareRenderer { int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0); int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0); int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0); - if (r >= mRedSize && g >= mGreenSize && b >= mBlueSize && a >= mAlphaSize) { + boolean backBuffer; + if (RENDER_DIRTY_REGIONS) { + int surfaceType = findConfigAttrib(egl, display, config, + EGL_SURFACE_TYPE, 0); + backBuffer = (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) != 0; + } else { + backBuffer = true; + } + if (r >= mRedSize && g >= mGreenSize && b >= mBlueSize && a >= mAlphaSize + && backBuffer) { return config; } } @@ -696,8 +764,8 @@ public abstract class HardwareRenderer { } @Override - void onPreDraw() { - mGlCanvas.onPreDraw(); + void onPreDraw(Rect dirty) { + mGlCanvas.onPreDraw(dirty); } @Override diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index aa69aea..65d2e11 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6730,11 +6730,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mPrivateFlags |= INVALIDATED; final ViewParent p = mParent; final AttachInfo ai = mAttachInfo; - if (p != null && ai != null && ai.mHardwareAccelerated) { - // fast-track for GL-enabled applications; just invalidate the whole hierarchy - // with a null dirty rect, which tells the ViewRoot to redraw everything - p.invalidateChild(this, null); - return; + //noinspection PointlessBooleanExpression,ConstantConditions + if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { + if (p != null && ai != null && ai.mHardwareAccelerated) { + // fast-track for GL-enabled applications; just invalidate the whole hierarchy + // with a null dirty rect, which tells the ViewRoot to redraw everything + p.invalidateChild(this, null); + return; + } } if (p != null && ai != null) { final int scrollX = mScrollX; @@ -6770,11 +6773,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mPrivateFlags |= INVALIDATED; final ViewParent p = mParent; final AttachInfo ai = mAttachInfo; - if (p != null && ai != null && ai.mHardwareAccelerated) { - // fast-track for GL-enabled applications; just invalidate the whole hierarchy - // with a null dirty rect, which tells the ViewRoot to redraw everything - p.invalidateChild(this, null); - return; + //noinspection PointlessBooleanExpression,ConstantConditions + if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { + if (p != null && ai != null && ai.mHardwareAccelerated) { + // fast-track for GL-enabled applications; just invalidate the whole hierarchy + // with a null dirty rect, which tells the ViewRoot to redraw everything + p.invalidateChild(this, null); + return; + } } if (p != null && ai != null && l < r && t < b) { final int scrollX = mScrollX; @@ -6823,11 +6829,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } final AttachInfo ai = mAttachInfo; final ViewParent p = mParent; - if (p != null && ai != null && ai.mHardwareAccelerated) { - // fast-track for GL-enabled applications; just invalidate the whole hierarchy - // with a null dirty rect, which tells the ViewRoot to redraw everything - p.invalidateChild(this, null); - return; + //noinspection PointlessBooleanExpression,ConstantConditions + if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { + if (p != null && ai != null && ai.mHardwareAccelerated) { + // fast-track for GL-enabled applications; just invalidate the whole hierarchy + // with a null dirty rect, which tells the ViewRoot to redraw everything + p.invalidateChild(this, null); + return; + } } if (p != null && ai != null) { @@ -8078,7 +8087,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility * * @return A HardwareLayer ready to render, or null if an error occurred. */ - HardwareLayer getHardwareLayer(Canvas currentCanvas) { + HardwareLayer getHardwareLayer() { if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) { return null; } @@ -8098,10 +8107,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mHardwareLayer.resize(width, height); } - final HardwareCanvas canvas = mHardwareLayer.start(mAttachInfo.mHardwareCanvas); + Canvas currentCanvas = mAttachInfo.mHardwareCanvas; + final HardwareCanvas canvas = mHardwareLayer.start(currentCanvas); + mAttachInfo.mHardwareCanvas = canvas; try { canvas.setViewport(width, height); - canvas.onPreDraw(); + // TODO: We should pass the dirty rect + canvas.onPreDraw(null); computeScroll(); canvas.translate(-mScrollX, -mScrollY); @@ -8121,7 +8133,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility canvas.restoreToCount(restoreCount); } finally { canvas.onPostDraw(); - mHardwareLayer.end(mAttachInfo.mHardwareCanvas); + mHardwareLayer.end(currentCanvas); + mAttachInfo.mHardwareCanvas = currentCanvas; } } @@ -8190,7 +8203,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility ViewGroup parent = (ViewGroup) this; final int count = parent.getChildCount(); for (int i = 0; i < count; i++) { - final View child = (View) parent.getChildAt(i); + final View child = parent.getChildAt(i); child.outputDirtyFlags(indent + " ", clear, clearMask); } } @@ -8251,7 +8264,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility int height = mBottom - mTop; canvas.setViewport(width, height); - canvas.onPreDraw(); + // The dirty rect should always be null for a display list + canvas.onPreDraw(null); final int restoreCount = canvas.save(); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index c73cbe6..f198c46 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2395,8 +2395,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager canvas.scale(scale, scale); } } - - boolean layerSaved = false; if (transformToApply != null || alpha < 1.0f || !child.hasIdentityMatrix()) { if (transformToApply != null || !childHasIdentityMatrix) { @@ -2477,7 +2475,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (hasNoCache) { boolean layerRendered = false; if (layerType == LAYER_TYPE_HARDWARE) { - final HardwareLayer layer = child.getHardwareLayer(canvas); + final HardwareLayer layer = child.getHardwareLayer(); if (layer != null && layer.isValid()) { ((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, child.mLayerPaint); layerRendered = true; @@ -3357,7 +3355,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager addInArray(child, index); child.mParent = this; - child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK & ~DRAWING_CACHE_VALID) | DRAWN; + child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK & ~DRAWING_CACHE_VALID) | + DRAWN | INVALIDATED; + this.mPrivateFlags |= INVALIDATED; if (child.hasFocus()) { requestChildFocus(child, child.findFocus()); @@ -3527,10 +3527,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager (int) (boundingRect.bottom + 0.5f)); } + if (child.mLayerType != LAYER_TYPE_NONE) { + mPrivateFlags |= INVALIDATED; + mPrivateFlags &= ~DRAWING_CACHE_VALID; + } do { View view = null; if (parent instanceof View) { view = (View) parent; + if (view.mLayerType != LAYER_TYPE_NONE && + view.getParent() instanceof View) { + final View grandParent = (View) view.getParent(); + grandParent.mPrivateFlags |= INVALIDATED; + grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID; + } } if (drawAnimation) { diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index ba671c0..19d7811 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -160,7 +160,9 @@ public final class ViewRoot extends Handler implements ViewParent, int mWidth; int mHeight; - Rect mDirty; // will be a graphics.Region soon + Rect mDirty; + final Rect mCurrentDirty = new Rect(); + final Rect mPreviousDirty = new Rect(); boolean mIsAnimating; CompatibilityInfo.Translator mTranslator; @@ -1055,6 +1057,7 @@ public final class ViewRoot extends Handler implements ViewParent, disposeResizeBitmap(); } else if (surfaceGenerationId != mSurface.getGenerationId() && mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) { + fullRedrawNeeded = true; mAttachInfo.mHardwareRenderer.updateSurface(mHolder); } } catch (RemoteException e) { @@ -1488,10 +1491,15 @@ public final class ViewRoot extends Handler implements ViewParent, if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) { if (!dirty.isEmpty() || mIsAnimating) { mIsAnimating = false; - dirty.setEmpty(); mHardwareYOffset = yoff; mResizeAlpha = resizeAlpha; - mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this); + + mCurrentDirty.set(dirty); + mCurrentDirty.union(mPreviousDirty); + mPreviousDirty.set(dirty); + dirty.setEmpty(); + + mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this, mCurrentDirty); } if (animating) { @@ -1986,6 +1994,7 @@ public final class ViewRoot extends Handler implements ViewParent, if (mAttachInfo.mHardwareRenderer != null && mSurface != null && mSurface.isValid()) { + mFullRedrawNeeded = true; mAttachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight, mAttachInfo, mHolder); } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 796af55..a107c60 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -2706,7 +2706,7 @@ public class ListView extends AbsListView { int startPos = (mSelectedPosition != INVALID_POSITION) ? mSelectedPosition - 1 : firstPosition + getChildCount() - 1; - if (startPos < 0) { + if (startPos < 0 || startPos >= mAdapter.getCount()) { return INVALID_POSITION; } if (startPos > last) { diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java index ff59950..14d0ac5 100644 --- a/core/java/com/android/internal/view/menu/MenuBuilder.java +++ b/core/java/com/android/internal/view/menu/MenuBuilder.java @@ -215,6 +215,11 @@ public class MenuBuilder implements Menu { private ViewGroup mMeasureActionButtonParent; + private final WeakReference<MenuAdapter>[] mAdapterCache = + new WeakReference[NUM_TYPES]; + private final WeakReference<OverflowMenuAdapter>[] mOverflowAdapterCache = + new WeakReference[NUM_TYPES]; + // Group IDs that have been added as actions - used temporarily, allocated here for reuse. private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); @@ -1004,6 +1009,12 @@ public class MenuBuilder implements Menu { MenuView menuView = menuTypes[i].mMenuView.get(); menuView.updateChildren(cleared); } + + MenuAdapter adapter = mAdapterCache[i] == null ? null : mAdapterCache[i].get(); + if (adapter != null) adapter.notifyDataSetChanged(); + + adapter = mOverflowAdapterCache[i] == null ? null : mOverflowAdapterCache[i].get(); + if (adapter != null) adapter.notifyDataSetChanged(); } } } @@ -1358,7 +1369,13 @@ public class MenuBuilder implements Menu { * @return A {@link MenuAdapter} for this menu with the given menu type. */ public MenuAdapter getMenuAdapter(int menuType) { - return new MenuAdapter(menuType); + MenuAdapter adapter = mAdapterCache[menuType] == null ? + null : mAdapterCache[menuType].get(); + if (adapter != null) return adapter; + + adapter = new MenuAdapter(menuType); + mAdapterCache[menuType] = new WeakReference<MenuAdapter>(adapter); + return adapter; } /** @@ -1368,7 +1385,13 @@ public class MenuBuilder implements Menu { * @return A {@link MenuAdapter} for this menu with the given menu type. */ public MenuAdapter getOverflowMenuAdapter(int menuType) { - return new OverflowMenuAdapter(menuType); + OverflowMenuAdapter adapter = mOverflowAdapterCache[menuType] == null ? + null : mOverflowAdapterCache[menuType].get(); + if (adapter != null) return adapter; + + adapter = new OverflowMenuAdapter(menuType); + mOverflowAdapterCache[menuType] = new WeakReference<OverflowMenuAdapter>(adapter); + return adapter; } void setOptionalIconsVisible(boolean visible) { @@ -1469,21 +1492,18 @@ public class MenuBuilder implements Menu { * source for overflow menu items that do not fit in the list of action items. */ private class OverflowMenuAdapter extends MenuAdapter { - private ArrayList<MenuItemImpl> mOverflowItems; - public OverflowMenuAdapter(int menuType) { super(menuType); - mOverflowItems = getNonActionItems(true); } @Override public MenuItemImpl getItem(int position) { - return mOverflowItems.get(position); + return getNonActionItems(true).get(position); } @Override public int getCount() { - return mOverflowItems.size(); + return getNonActionItems(true).size(); } } } diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index e4a89d7..9de270d 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "OpenGLRenderer" +#include <EGL/egl.h> + #include "jni.h" #include "GraphicsJNI.h" #include <nativehelper/JNIHelp.h> @@ -75,6 +77,23 @@ static struct { } gRectClassInfo; // ---------------------------------------------------------------------------- +// Misc +// ---------------------------------------------------------------------------- + +static jboolean android_view_GLES20Canvas_preserveBackBuffer(JNIEnv* env, jobject clazz) { + EGLDisplay display = eglGetCurrentDisplay(); + EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); + + eglGetError(); + eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); + + EGLint error = eglGetError(); + RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error); + + return error == EGL_SUCCESS; +} + +// ---------------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------------- @@ -97,32 +116,38 @@ static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz // Setup // ---------------------------------------------------------------------------- -static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jint width, jint height) { renderer->setViewport(width, height); } -static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jboolean opaque) { renderer->prepare(opaque); } -static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz, + OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom, + jboolean opaque) { + renderer->prepareDirty(left, top, right, bottom, opaque); +} + +static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer) { renderer->finish(); } -static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer) { renderer->acquireContext(); } -static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject canvas, +static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, Functor *functor) { return renderer->callDrawGLFunction(functor); } -static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer) { renderer->releaseContext(); } @@ -131,22 +156,22 @@ static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject canvas // State // ---------------------------------------------------------------------------- -static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, +static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jint flags) { return renderer->save(flags); } -static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject canvas, +static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer) { return renderer->getSaveCount(); } -static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer) { renderer->restore(); } -static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jint saveCount) { renderer->restoreToCount(saveCount); } @@ -155,13 +180,13 @@ static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas // Layers // ---------------------------------------------------------------------------- -static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject canvas, +static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, SkPaint* paint, jint saveFlags) { return renderer->saveLayer(left, top, right, bottom, paint, saveFlags); } -static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas, +static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, jint alpha, jint saveFlags) { return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags); @@ -171,25 +196,25 @@ static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas // Clipping // ---------------------------------------------------------------------------- -static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject canvas, +static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, SkCanvas::EdgeType edge) { return renderer->quickReject(left, top, right, bottom); } -static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject canvas, +static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, SkRegion::Op op) { return renderer->clipRect(left, top, right, bottom, op); } -static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject canvas, +static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom, SkRegion::Op op) { return renderer->clipRect(float(left), float(top), float(right), float(bottom), op); } -static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas, +static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jobject rect) { const android::uirenderer::Rect& bounds(renderer->getClipBounds()); @@ -203,42 +228,42 @@ static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas, // Transforms // ---------------------------------------------------------------------------- -static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat dx, jfloat dy) { renderer->translate(dx, dy); } -static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat degrees) { renderer->rotate(degrees); } -static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat sx, jfloat sy) { renderer->scale(sx, sy); } -static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat sx, jfloat sy) { renderer->skew(sx, sy); } -static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkMatrix* matrix) { renderer->setMatrix(matrix); } static const float* android_view_GLES20Canvas_getNativeMatrix(JNIEnv* env, - jobject canvas, OpenGLRenderer* renderer) { + jobject clazz, OpenGLRenderer* renderer) { return renderer->getMatrix(); } -static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkMatrix* matrix) { renderer->getMatrix(matrix); } -static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkMatrix* matrix) { renderer->concatMatrix(matrix); } @@ -247,7 +272,7 @@ static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas, // Drawing // ---------------------------------------------------------------------------- -static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, float left, float top, SkPaint* paint) { // This object allows the renderer to allocate a global JNI ref to the buffer object. @@ -256,7 +281,7 @@ static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject canvas, renderer->drawBitmap(bitmap, left, top, paint); } -static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) { @@ -267,7 +292,7 @@ static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject canvas dstLeft, dstTop, dstRight, dstBottom, paint); } -static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, SkMatrix* matrix, SkPaint* paint) { // This object allows the renderer to allocate a global JNI ref to the buffer object. @@ -276,7 +301,7 @@ static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject canv renderer->drawBitmap(bitmap, matrix, paint); } -static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, SkPaint* paint) { @@ -292,7 +317,7 @@ static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject canvas if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0); } -static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, jbyteArray chunks, float left, float top, float right, float bottom, SkPaint* paint) { // This object allows the renderer to allocate a global JNI ref to the buffer object. @@ -309,41 +334,41 @@ static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas, env->ReleaseByteArrayElements(chunks, storage, 0); } -static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jint color, SkXfermode::Mode mode) { renderer->drawColor(color, mode); } -static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, SkPaint* paint) { renderer->drawRect(left, top, right, bottom, paint); } -static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat rx, jfloat ry, SkPaint* paint) { renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint); } -static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat x, jfloat y, jfloat radius, SkPaint* paint) { renderer->drawCircle(x, y, radius, paint); } -static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, SkPaint* paint) { renderer->drawOval(left, top, right, bottom, paint); } -static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle, jboolean useCenter, SkPaint* paint) { renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint); } -static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) { SkRegion::Iterator it(*region); while (!it.done()) { @@ -353,12 +378,12 @@ static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas, } } -static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkPath* path, SkPaint* paint) { renderer->drawPath(path, paint); } -static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloatArray points, jint offset, jint count, SkPaint* paint) { jfloat* storage = env->GetFloatArrayElements(points, NULL); @@ -371,24 +396,24 @@ static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject canvas, // Shaders and color filters // ---------------------------------------------------------------------------- -static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer) { renderer->resetShader(); renderer->resetColorFilter(); renderer->resetShadow(); } -static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkiaShader* shader) { renderer->setupShader(shader); } -static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkiaColorFilter* filter) { renderer->setupColorFilter(filter); } -static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jfloat radius, jfloat dx, jfloat dy, jint color) { renderer->setupShadow(radius, dx, dy, color); } @@ -425,7 +450,7 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, } } -static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jcharArray text, jint index, jint count, jfloat x, jfloat y, jint flags, SkPaint* paint) { jchar* textArray = env->GetCharArrayElements(text, NULL); @@ -433,7 +458,7 @@ static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas, env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); } -static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jstring text, jint start, jint end, jfloat x, jfloat y, jint flags, SkPaint* paint) { const jchar* textArray = env->GetStringChars(text, NULL); @@ -441,7 +466,7 @@ static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas, env->ReleaseStringChars(text, textArray); } -static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags, SkPaint* paint) { @@ -451,7 +476,7 @@ static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject canv env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); } -static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jstring text, jint start, jint end, jint contextStart, int contextEnd, jfloat x, jfloat y, jint dirFlags, SkPaint* paint) { @@ -468,7 +493,7 @@ static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject canvas, // ---------------------------------------------------------------------------- static DisplayList* android_view_GLES20Canvas_getDisplayList(JNIEnv* env, - jobject canvas, DisplayListRenderer* renderer) { + jobject clazz, DisplayListRenderer* renderer) { return renderer->getDisplayList(); } @@ -488,7 +513,7 @@ static void android_view_GLES20Canvas_destroyDisplayList(JNIEnv* env, } static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env, - jobject canvas, OpenGLRenderer* renderer, DisplayList* displayList) { + jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList) { return renderer->drawDisplayList(displayList); } @@ -496,12 +521,12 @@ static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env, // Layers // ---------------------------------------------------------------------------- -static void android_view_GLES20Canvas_interrupt(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_interrupt(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer) { renderer->interrupt(); } -static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer) { renderer->resume(); } @@ -547,7 +572,7 @@ static void android_view_GLES20Canvas_destroyLayerDeferred(JNIEnv* env, LayerRenderer::destroyLayerDeferred(layer); } -static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject canvas, +static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) { renderer->drawLayer(layer, x, y, paint); } @@ -576,16 +601,20 @@ static JNINativeMethod gMethods[] = { { "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable }, #ifdef USE_OPENGL_RENDERER + { "nPreserveBackBuffer", "()Z", (void*) android_view_GLES20Canvas_preserveBackBuffer }, + { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer }, { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer }, { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport }, { "nPrepare", "(IZ)V", (void*) android_view_GLES20Canvas_prepare }, + { "nPrepareDirty", "(IIIIIZ)V", (void*) android_view_GLES20Canvas_prepareDirty }, { "nFinish", "(I)V", (void*) android_view_GLES20Canvas_finish }, { "nAcquireContext", "(I)V", (void*) android_view_GLES20Canvas_acquireContext }, - { "nCallDrawGLFunction", "(II)Z", - (void*) android_view_GLES20Canvas_callDrawGLFunction }, { "nReleaseContext", "(I)V", (void*) android_view_GLES20Canvas_releaseContext }, + { "nCallDrawGLFunction", "(II)Z", + (void*) android_view_GLES20Canvas_callDrawGLFunction }, + { "nSave", "(II)I", (void*) android_view_GLES20Canvas_save }, { "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore }, { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Canvas_restoreToCount }, diff --git a/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png Binary files differindex bd353ae..00e8f06 100644 --- a/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png Binary files differindex d127b3c..997ccb2 100644 --- a/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_holo_dark.9.png Binary files differdeleted file mode 100644 index b86c65a..0000000 --- a/core/res/res/drawable-hdpi/btn_group_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_group_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_holo_light.9.png Binary files differdeleted file mode 100644 index 1248e88..0000000 --- a/core/res/res/drawable-hdpi/btn_group_holo_light.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/btn_group_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_normal_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..b2120f4 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_normal_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_normal_holo_light.9.png Binary files differnew file mode 100644 index 0000000..782d36b --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_normal_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/overscroll_edge.png b/core/res/res/drawable-hdpi/overscroll_edge.png Binary files differindex 6d3c26d..7eb615b 100644 --- a/core/res/res/drawable-hdpi/overscroll_edge.png +++ b/core/res/res/drawable-hdpi/overscroll_edge.png diff --git a/core/res/res/drawable-hdpi/overscroll_glow.png b/core/res/res/drawable-hdpi/overscroll_glow.png Binary files differindex 0b0b936..a800d8e 100644 --- a/core/res/res/drawable-hdpi/overscroll_glow.png +++ b/core/res/res/drawable-hdpi/overscroll_glow.png diff --git a/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png Binary files differindex aa04cc9..5894afe 100644 --- a/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png Binary files differindex 25aefd2..1dfc7d3 100644 --- a/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_holo_dark.9.png Binary files differdeleted file mode 100644 index 9541252..0000000 --- a/core/res/res/drawable-mdpi/btn_group_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_group_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_holo_light.9.png Binary files differdeleted file mode 100644 index bf4f9b2..0000000 --- a/core/res/res/drawable-mdpi/btn_group_holo_light.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/btn_group_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_normal_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..c6257bb --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_normal_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_normal_holo_light.9.png Binary files differnew file mode 100644 index 0000000..7e25ad3 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_normal_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/overscroll_edge.png b/core/res/res/drawable-mdpi/overscroll_edge.png Binary files differindex 6d3c26d..86d9454 100644 --- a/core/res/res/drawable-mdpi/overscroll_edge.png +++ b/core/res/res/drawable-mdpi/overscroll_edge.png diff --git a/core/res/res/drawable-mdpi/overscroll_glow.png b/core/res/res/drawable-mdpi/overscroll_glow.png Binary files differindex 0b0b936..d96b9be 100644 --- a/core/res/res/drawable-mdpi/overscroll_glow.png +++ b/core/res/res/drawable-mdpi/overscroll_glow.png diff --git a/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png Binary files differdeleted file mode 100644 index 137923b..0000000 --- a/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png Binary files differdeleted file mode 100644 index 62b1deb..0000000 --- a/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png Binary files differdeleted file mode 100644 index ab30a77..0000000 --- a/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png Binary files differdeleted file mode 100644 index 9274bc7..0000000 --- a/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png Binary files differdeleted file mode 100644 index e46155e..0000000 --- a/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_activated_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_activated_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..a233b0d --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_activated_holo_dark.9.png diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_default_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_default_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..403f502 --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_default_holo_dark.9.png diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..0ded801 --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..27237b8 --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_focused_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..0e451f1 --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_focused_holo_dark.9.png diff --git a/core/res/res/drawable/btn_group_holo_dark.xml b/core/res/res/drawable/btn_group_holo_dark.xml new file mode 100644 index 0000000..553f023 --- /dev/null +++ b/core/res/res/drawable/btn_group_holo_dark.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="true" + android:drawable="@drawable/btn_group_normal_holo_dark" /> + <item + android:drawable="@drawable/btn_group_disabled_holo_dark" /> +</selector> diff --git a/core/res/res/drawable/btn_group_holo_light.xml b/core/res/res/drawable/btn_group_holo_light.xml new file mode 100644 index 0000000..9c89eef --- /dev/null +++ b/core/res/res/drawable/btn_group_holo_light.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="true" + android:drawable="@drawable/btn_group_normal_holo_light" /> + <item + android:drawable="@drawable/btn_group_disabled_holo_light" /> +</selector> diff --git a/core/res/res/drawable/group_button_background_holo_dark.xml b/core/res/res/drawable/group_button_background_holo_dark.xml deleted file mode 100644 index fa00785..0000000 --- a/core/res/res/drawable/group_button_background_holo_dark.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2010 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - - <item android:state_window_focused="false" android:drawable="@color/transparent" /> - - <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> - <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/btn_group_disabled_holo_dark" /> - <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/btn_group_disabled_holo_dark" /> - <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_dark" /> - <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_dark" /> - <item android:state_focused="true" android:drawable="@drawable/btn_group_focused_holo_dark" /> - <item android:drawable="@color/transparent" /> -</selector> diff --git a/core/res/res/drawable/group_button_background_holo_light.xml b/core/res/res/drawable/group_button_background_holo_light.xml deleted file mode 100644 index 1e74ec7..0000000 --- a/core/res/res/drawable/group_button_background_holo_light.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2010 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - - <item android:state_window_focused="false" android:drawable="@color/transparent" /> - - <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> - <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/btn_group_disabled_holo_light" /> - <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/btn_group_disabled_holo_light" /> - <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_light" /> - <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_light" /> - <item android:state_focused="true" android:drawable="@drawable/btn_group_focused_holo_light" /> - <item android:drawable="@color/transparent" /> -</selector> diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml index fab69d8..e4a1b81 100644 --- a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml +++ b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml @@ -74,6 +74,7 @@ android:layout_height="230dip" android:background="#00000000" android:keyBackground="@drawable/btn_keyboard_key_fulltrans" + android:visibility="gone" /> <!-- emergency call button --> diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml index d22f74a..fef017d 100644 --- a/core/res/res/layout/popup_menu_item_layout.xml +++ b/core/res/res/layout/popup_menu_item_layout.xml @@ -16,7 +16,7 @@ <com.android.internal.view.menu.ListMenuItemView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="48dip" + android:layout_height="?android:attr/dropdownListPreferredItemHeight" android:minWidth="196dip" android:paddingLeft="16dip" android:paddingRight="16dip"> diff --git a/core/res/res/layout/simple_spinner_dropdown_item.xml b/core/res/res/layout/simple_spinner_dropdown_item.xml index 5fd7a09..cb999b6 100644 --- a/core/res/res/layout/simple_spinner_dropdown_item.xml +++ b/core/res/res/layout/simple_spinner_dropdown_item.xml @@ -22,5 +22,5 @@ style="?android:attr/spinnerDropDownItemStyle" android:singleLine="true" android:layout_width="match_parent" - android:layout_height="?android:attr/listPreferredItemHeight" + android:layout_height="?android:attr/dropdownListPreferredItemHeight" android:ellipsize="marquee" /> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index c808a07..a404fba 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -223,6 +223,9 @@ <!-- The preferred right bound for an expandable list child's indicator. --> <attr name="expandableListPreferredChildIndicatorRight" format="dimension" /> + <!-- The preferred item height for dropdown lists. --> + <attr name="dropdownListPreferredItemHeight" format="dimension" /> + <!-- ============= --> <!-- Window styles --> <!-- ============= --> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 08542bf..1f9085e 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -95,6 +95,8 @@ <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> + <item name="dropdownListPreferredItemHeight">64dip</item> + <!-- @hide --> <item name="searchResultListItemHeight">58dip</item> <item name="listDivider">@drawable/divider_horizontal_dark</item> @@ -813,6 +815,8 @@ <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> + <item name="dropdownListPreferredItemHeight">48dip</item> + <!-- @hide --> <item name="searchResultListItemHeight">58dip</item> <item name="listDivider">@drawable/list_divider_holo_dark</item> @@ -1084,6 +1088,8 @@ <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> + <item name="dropdownListPreferredItemHeight">48dip</item> + <!-- @hide --> <item name="searchResultListItemHeight">58dip</item> <item name="listDivider">@drawable/list_divider_holo_light</item> diff --git a/data/fonts/AndroidClock-Solid.ttf b/data/fonts/AndroidClock-Solid.ttf Binary files differnew file mode 100644 index 0000000..108839e --- /dev/null +++ b/data/fonts/AndroidClock-Solid.ttf diff --git a/data/fonts/AndroidClock.ttf b/data/fonts/AndroidClock.ttf Binary files differindex 03e36cb..7b550ee 100644 --- a/data/fonts/AndroidClock.ttf +++ b/data/fonts/AndroidClock.ttf diff --git a/data/fonts/AndroidClock_Highlight.ttf b/data/fonts/AndroidClock_Highlight.ttf Binary files differindex 8fb31ba..a95d548 100644 --- a/data/fonts/AndroidClock_Highlight.ttf +++ b/data/fonts/AndroidClock_Highlight.ttf diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index a768efe..c2106d4 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -629,7 +629,8 @@ void DisplayListRenderer::setViewport(int width, int height) { mHeight = height; } -void DisplayListRenderer::prepare(bool opaque) { +void DisplayListRenderer::prepareDirty(float left, float top, + float right, float bottom, bool opaque) { mSnapshot = new Snapshot(mFirstSnapshot, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); mSaveCount = 1; @@ -848,7 +849,7 @@ void DisplayListRenderer::drawOval(float left, float top, float right, float bot void DisplayListRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { - addOp(DisplayList::DrawOval); + addOp(DisplayList::DrawArc); addBounds(left, top, right, bottom); addPoint(startAngle, sweepAngle); addInt(useCenter ? 1 : 0); diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 6c8e8f5..bab5149 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -28,7 +28,7 @@ #include <SkTSearch.h> #include "OpenGLRenderer.h" -#include "Functor.h" +#include "utils/Functor.h" namespace android { namespace uirenderer { @@ -241,7 +241,7 @@ public: DisplayList* getDisplayList(); void setViewport(int width, int height); - void prepare(bool opaque); + void prepareDirty(float left, float top, float right, float bottom, bool opaque); void finish(); bool callDrawGLFunction(Functor *functor); diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index 1c89577..36709dc 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -26,7 +26,7 @@ namespace uirenderer { // Rendering /////////////////////////////////////////////////////////////////////////////// -void LayerRenderer::prepare(bool opaque) { +void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo); #if RENDER_LAYERS_AS_REGIONS @@ -35,7 +35,7 @@ void LayerRenderer::prepare(bool opaque) { glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo); - OpenGLRenderer::prepare(opaque); + OpenGLRenderer::prepareDirty(0.0f, 0.0f, mLayer->width, mLayer->height, opaque); } void LayerRenderer::finish() { diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h index 1e39847..d2f565e 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -46,7 +46,7 @@ public: ~LayerRenderer() { } - void prepare(bool opaque); + void prepareDirty(float left, float top, float right, float bottom, bool opaque); void finish(); bool hasLayer(); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 98f8fc5..4813e93 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -136,6 +136,10 @@ void OpenGLRenderer::setViewport(int width, int height) { } void OpenGLRenderer::prepare(bool opaque) { + prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque); +} + +void OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { mCaches.clearGarbage(); mSnapshot = new Snapshot(mFirstSnapshot, @@ -146,15 +150,14 @@ void OpenGLRenderer::prepare(bool opaque) { glDisable(GL_DITHER); + glEnable(GL_SCISSOR_TEST); + glScissor(left, mSnapshot->height - bottom, right - left, bottom - top); + mSnapshot->setClip(left, top, right, bottom); + if (!opaque) { - glDisable(GL_SCISSOR_TEST); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); } - - glEnable(GL_SCISSOR_TEST); - glScissor(0, 0, mWidth, mHeight); - mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); } void OpenGLRenderer::finish() { @@ -1210,8 +1213,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int const bool pureTranslate = mSnapshot->transform->isPureTranslate(); #if RENDER_LAYERS_AS_REGIONS // Mark the current layer dirty where we are going to draw the patch - if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && - mSnapshot->region && mesh->hasEmptyQuads) { + if (hasLayer() && mesh->hasEmptyQuads) { const size_t count = mesh->quads.size(); for (size_t i = 0; i < count; i++) { const Rect& bounds = mesh->quads.itemAt(i); @@ -1607,6 +1609,7 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { layer->alpha = alpha; layer->mode = mode; + LOGD("Drawing layer with alpha = %d", alpha); #if RENDER_LAYERS_AS_REGIONS if (!layer->region.isEmpty()) { @@ -1614,11 +1617,12 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight()); composeLayerRect(layer, r); } else if (layer->mesh) { + const float a = alpha / 255.0f; const Rect& rect = layer->layer; setupDraw(); setupDrawWithTexture(); - setupDrawColor(alpha, alpha, alpha, alpha); + setupDrawColor(a, a, a, a); setupDrawColorFilter(); setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false); setupDrawProgram(); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index bd29609..77de1d2 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -62,7 +62,8 @@ public: virtual void setViewport(int width, int height); - virtual void prepare(bool opaque); + void prepare(bool opaque); + virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque); virtual void finish(); // These two calls must not be recorded in display lists diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 3acb624..40cb5c7 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -201,9 +201,9 @@ bool Context::initGLThread() { mGL.mExtensions = glGetString(GL_EXTENSIONS); //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); - LOGV("GL Version %s", mGL.mVersion); + //LOGV("GL Version %s", mGL.mVersion); //LOGV("GL Vendor %s", mGL.mVendor); - LOGV("GL Renderer %s", mGL.mRenderer); + //LOGV("GL Renderer %s", mGL.mRenderer); //LOGV("GL Extensions %s", mGL.mExtensions); const char *verptr = NULL; @@ -468,7 +468,6 @@ void * Context::threadProc(void *vrsc) { return NULL; } - rsc->mScriptC.init(rsc); if (rsc->mIsGraphicsContext) { rsc->mStateRaster.init(rsc); rsc->setProgramRaster(NULL); @@ -528,7 +527,7 @@ void * Context::threadProc(void *vrsc) { } void Context::destroyWorkerThreadResources() { - LOGV("destroyWorkerThreadResources 1"); + //LOGV("destroyWorkerThreadResources 1"); if (mIsGraphicsContext) { mRaster.clear(); mFragment.clear(); @@ -544,7 +543,7 @@ void Context::destroyWorkerThreadResources() { mShaderCache.cleanupAll(); } ObjectBase::zeroAllUserRef(this); - LOGV("destroyWorkerThreadResources 2"); + //LOGV("destroyWorkerThreadResources 2"); mExit = true; } @@ -552,7 +551,7 @@ void * Context::helperThreadProc(void *vrsc) { Context *rsc = static_cast<Context *>(vrsc); uint32_t idx = (uint32_t)android_atomic_inc(&rsc->mWorkers.mLaunchCount); - LOGV("RS helperThread starting %p idx=%i", rsc, idx); + //LOGV("RS helperThread starting %p idx=%i", rsc, idx); rsc->mWorkers.mLaunchSignals[idx].init(); rsc->mWorkers.mNativeThreadId[idx] = gettid(); @@ -573,7 +572,7 @@ void * Context::helperThreadProc(void *vrsc) { LOGE("pthread_setspecific %i", status); } - while (rsc->mRunning) { + while (!rsc->mExit) { rsc->mWorkers.mLaunchSignals[idx].wait(); if (rsc->mWorkers.mLaunchCallback) { rsc->mWorkers.mLaunchCallback(rsc->mWorkers.mLaunchData, idx); @@ -582,7 +581,7 @@ void * Context::helperThreadProc(void *vrsc) { rsc->mWorkers.mCompleteSignal.set(); } - LOGV("RS helperThread exiting %p idx=%i", rsc, idx); + //LOGV("RS helperThread exited %p idx=%i", rsc, idx); return NULL; } @@ -730,6 +729,18 @@ Context::~Context() { mIO.shutdown(); int status = pthread_join(mThreadId, &res); + // Cleanup compute threads. + mWorkers.mLaunchData = NULL; + mWorkers.mLaunchCallback = NULL; + mWorkers.mRunningCount = (int)mWorkers.mCount; + for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) { + mWorkers.mLaunchSignals[ct].set(); + } + for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) { + int status = pthread_join(mWorkers.mThreadId[ct], &res); + } + rsAssert(!mWorkers.mRunningCount); + // Global structure cleanup. pthread_mutex_lock(&gInitMutex); if (mDev) { diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp index eb2af1c..3f88543 100644 --- a/libs/rs/rsLocklessFifo.cpp +++ b/libs/rs/rsLocklessFifo.cpp @@ -76,7 +76,8 @@ uint32_t LocklessCommandFifo::getFreeSpace() const { } bool LocklessCommandFifo::isEmpty() const { - return mPut == mGet; + uint32_t p = android_atomic_acquire_load((int32_t *)&mPut); + return ((uint8_t *)p) == mGet; } @@ -155,7 +156,9 @@ const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) { void LocklessCommandFifo::next() { uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1]; - mGet += ((bytes + 3) & ~3) + 4; + + android_atomic_add(((bytes + 3) & ~3) + 4, (int32_t *)&mGet); + //mGet += ((bytes + 3) & ~3) + 4; if (isEmpty()) { mSignalToControl.set(); } diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index eecfa16..3858e1c 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -421,21 +421,9 @@ void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, uint32_t len } ScriptCState::ScriptCState() { - mScript.clear(); } ScriptCState::~ScriptCState() { - mScript.clear(); -} - -void ScriptCState::init(Context *rsc) { - clear(rsc); -} - -void ScriptCState::clear(Context *rsc) { - rsAssert(rsc); - mScript.clear(); - mScript.set(new ScriptC(rsc)); } static void* symbolLookup(void* pContext, char const* name) { @@ -608,8 +596,6 @@ namespace android { namespace renderscript { void rsi_ScriptCBegin(Context * rsc) { - ScriptCState *ss = &rsc->mScriptC; - ss->clear(rsc); } void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) { @@ -618,8 +604,8 @@ void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) { char *t = (char *)malloc(len + 1); memcpy(t, text, len); t[len] = 0; - ss->mScript->mEnviroment.mScriptText = t; - ss->mScript->mEnviroment.mScriptTextLength = len; + ss->mScriptText = t; + ss->mScriptLen = len; } @@ -630,17 +616,19 @@ RsScript rsi_ScriptCCreate(Context *rsc, { ScriptCState *ss = &rsc->mScriptC; - ObjectBaseRef<ScriptC> s(ss->mScript); - ss->mScript.clear(); + ScriptC *s = new ScriptC(rsc); + s->mEnviroment.mScriptText = ss->mScriptText; + s->mEnviroment.mScriptTextLength = ss->mScriptLen; + ss->mScriptText = NULL; + ss->mScriptLen = 0; s->incUserRef(); - if (!ss->runCompiler(rsc, s.get(), resName, cacheDir)) { + if (!ss->runCompiler(rsc, s, resName, cacheDir)) { // Error during compile, destroy s and return null. - s->zeroUserRef(); + delete s; return NULL; } - ss->clear(rsc); - return s.get(); + return s; } } diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h index 612e38a..7143c67 100644 --- a/libs/rs/rsScriptC.h +++ b/libs/rs/rsScriptC.h @@ -76,11 +76,9 @@ public: ScriptCState(); ~ScriptCState(); - ObjectBaseRef<ScriptC> mScript; + char * mScriptText; + size_t mScriptLen; - void init(Context *rsc); - - void clear(Context *rsc); bool runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir); struct SymbolTable_t { @@ -88,7 +86,6 @@ public: void * mPtr; bool threadable; }; - //static SymbolTable_t gSyms[]; static const SymbolTable_t * lookupSymbol(const char *); static const SymbolTable_t * lookupSymbolCL(const char *); static const SymbolTable_t * lookupSymbolGL(const char *); diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 11e27a9..925f965 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -299,12 +299,16 @@ public class ExifInterface { String lngRef = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE_REF); if (latValue != null && latRef != null && lngValue != null && lngRef != null) { - output[0] = convertRationalLatLonToFloat(latValue, latRef); - output[1] = convertRationalLatLonToFloat(lngValue, lngRef); - return true; - } else { - return false; + try { + output[0] = convertRationalLatLonToFloat(latValue, latRef); + output[1] = convertRationalLatLonToFloat(lngValue, lngRef); + return true; + } catch (IllegalArgumentException e) { + // if values are not parseable + } } + + return false; } /** @@ -373,12 +377,12 @@ public class ExifInterface { String [] pair; pair = parts[0].split("/"); - int degrees = (int) (Float.parseFloat(pair[0].trim()) - / Float.parseFloat(pair[1].trim())); + double degrees = Double.parseDouble(pair[0].trim()) + / Double.parseDouble(pair[1].trim()); pair = parts[1].split("/"); - int minutes = (int) ((Float.parseFloat(pair[0].trim()) - / Float.parseFloat(pair[1].trim()))); + double minutes = Double.parseDouble(pair[0].trim()) + / Double.parseDouble(pair[1].trim()); pair = parts[2].split("/"); double seconds = Double.parseDouble(pair[0].trim()) @@ -389,10 +393,12 @@ public class ExifInterface { return (float) -result; } return (float) result; - } catch (RuntimeException ex) { - // if for whatever reason we can't parse the lat long then return - // null - return 0f; + } catch (NumberFormatException e) { + // Some of the nubmers are not valid + throw new IllegalArgumentException(); + } catch (ArrayIndexOutOfBoundsException e) { + // Some of the rational does not follow the correct format + throw new IllegalArgumentException(); } } diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java index 54db8cd..8156439 100755 --- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java +++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java @@ -30,6 +30,9 @@ import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener; import android.util.Log; import android.util.Pair; import android.view.Surface; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; /** *This class provide Native methods to be used by MediaArtist {@hide} @@ -67,7 +70,10 @@ class MediaArtistNativeHelper { private boolean mExportDone = false; private int mProgressToApp; - + /** + * The resize paint + */ + private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG); public static final int TASK_LOADING_SETTINGS = 1; @@ -3838,11 +3844,39 @@ class MediaArtistNativeHelper { throw new IllegalArgumentException(); } - IntBuffer rgb888 = IntBuffer.allocate(width * height * 4); + int newWidth = 0; + int newHeight = 0; + Bitmap tempBitmap = null; + + /* Make width and height as even */ + newWidth = (width + 1) & 0xFFFFFFFE; + newHeight = (height + 1) & 0xFFFFFFFE; + + /* Create a temp bitmap for resized thumbnails */ + if ((newWidth != width) || (newHeight != height)) { + tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888); + } + + IntBuffer rgb888 = IntBuffer.allocate(newWidth * newHeight * 4); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - nativeGetPixels(inputFile, rgb888.array(), width, height, timeMS); - bitmap.copyPixelsFromBuffer(rgb888); + nativeGetPixels(inputFile, rgb888.array(), newWidth, newHeight, timeMS); + + if ((newWidth == width) && (newHeight == height)) { + bitmap.copyPixelsFromBuffer(rgb888); + } else { + /* Create a temp bitmap to be used for resize */ + tempBitmap.copyPixelsFromBuffer(rgb888); + + /* Create a canvas to resize */ + final Canvas canvas = new Canvas(bitmap); + canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight), + new Rect(0, 0, width, height), + sResizePaint); + } + if (tempBitmap != null) { + tempBitmap.recycle(); + } return bitmap; } @@ -3863,11 +3897,24 @@ class MediaArtistNativeHelper { public Bitmap[] getPixelsList(String filename, int width, int height, long startMs, long endMs, int thumbnailCount) { int[] rgb888 = null; - int thumbnailSize = width * height * 4; - + int thumbnailSize = 0; + int newWidth = 0; + int newHeight = 0; + Bitmap tempBitmap = null; + + /* Make width and height as even */ + newWidth = (width + 1) & 0xFFFFFFFE; + newHeight = (height + 1) & 0xFFFFFFFE; + thumbnailSize = newWidth * newHeight * 4; + + /* Create a temp bitmap for resized thumbnails */ + if ((newWidth != width) || (newHeight != height)) { + tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888); + } int i = 0; int deltaTime = (int)(endMs - startMs) / thumbnailCount; Bitmap[] bitmap = null; + try { // This may result in out of Memory Error rgb888 = new int[thumbnailSize * thumbnailCount]; @@ -3880,19 +3927,35 @@ class MediaArtistNativeHelper { bitmap = new Bitmap[MAX_THUMBNAIL_PERMITTED]; thumbnailCount = MAX_THUMBNAIL_PERMITTED; } catch (Throwable ex) { - throw new RuntimeException("Memory allocation fails,reduce nos of thumbanail count"); + throw new RuntimeException("Memory allocation fails, thumbnail count too large: "+thumbnailCount); } } IntBuffer tmpBuffer = IntBuffer.allocate(thumbnailSize); - nativeGetPixelsList(filename, rgb888, width, height, deltaTime, thumbnailCount, startMs, + nativeGetPixelsList(filename, rgb888, newWidth, newHeight, deltaTime, thumbnailCount, startMs, endMs); + for (; i < thumbnailCount; i++) { bitmap[i] = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); tmpBuffer.put(rgb888, (i * thumbnailSize), thumbnailSize); tmpBuffer.rewind(); - bitmap[i].copyPixelsFromBuffer(tmpBuffer); + + if ((newWidth == width) && (newHeight == height)) { + bitmap[i].copyPixelsFromBuffer(tmpBuffer); + } else { + /* Copy the out rgb buffer to temp bitmap */ + tempBitmap.copyPixelsFromBuffer(tmpBuffer); + + /* Create a canvas to resize */ + final Canvas canvas = new Canvas(bitmap[i]); + canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight), + new Rect(0, 0, width, height), + sResizePaint); + } } + if (tempBitmap != null) { + tempBitmap.recycle(); + } return bitmap; } @@ -3942,12 +4005,11 @@ class MediaArtistNativeHelper { } } - public void clearPreviewSurface(Surface surface, int width, int height) { - nativeClearSurface(surface,width,height); + public void clearPreviewSurface(Surface surface) { + nativeClearSurface(surface); } /** Native Methods */ - - public native Properties getMediaProperties(String file) throws IllegalArgumentException, + native Properties getMediaProperties(String file) throws IllegalArgumentException, IllegalStateException, RuntimeException, Exception; /** @@ -3957,7 +4019,7 @@ class MediaArtistNativeHelper { * @throws RuntimeException if an error occurred * @see Version */ - public static native Version getVersion() throws RuntimeException; + private static native Version getVersion() throws RuntimeException; /** * Returns the video thumbnail in an array of integers. Output format is @@ -3974,10 +4036,10 @@ class MediaArtistNativeHelper { * negative * @throws RuntimeException on runtime errors in native code */ - public native int nativeGetPixels(String fileName, int[] pixelArray, int width, int height, + private native int nativeGetPixels(String fileName, int[] pixelArray, int width, int height, long timeMS); - public native int nativeGetPixelsList(String fileName, int[] pixelArray, int width, int height, + private native int nativeGetPixelsList(String fileName, int[] pixelArray, int width, int height, int timeMS, int nosofTN, long startTimeMs, long endTimeMs); /** @@ -3986,12 +4048,12 @@ class MediaArtistNativeHelper { * * @throws IllegalStateException if the method could not be called */ - public native void release() throws IllegalStateException, RuntimeException; + private native void release() throws IllegalStateException, RuntimeException; /* * Clear the preview surface */ - public native void nativeClearSurface(Surface surface, int width, int height); + private native void nativeClearSurface(Surface surface); /** @@ -4000,7 +4062,7 @@ class MediaArtistNativeHelper { * * @throws IllegalStateException if the method could not be called */ - public native void stopEncoding() throws IllegalStateException, RuntimeException; + private native void stopEncoding() throws IllegalStateException, RuntimeException; @@ -4026,12 +4088,12 @@ class MediaArtistNativeHelper { private native void nativeStopPreview(); - public native int nativeGenerateAudioGraph(String pcmFilePath, String outGraphPath, + private native int nativeGenerateAudioGraph(String pcmFilePath, String outGraphPath, int frameDuration, int channels, int sampleCount); - public native int nativeGenerateRawAudio(String InFileName, String PCMFileName); + private native int nativeGenerateRawAudio(String InFileName, String PCMFileName); - public native int nativeGenerateClip(EditSettings editSettings) + private native int nativeGenerateClip(EditSettings editSettings) throws IllegalArgumentException, IllegalStateException, RuntimeException; } diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java index 1c02878..a977b8e 100755 --- a/media/java/android/media/videoeditor/MediaImageItem.java +++ b/media/java/android/media/videoeditor/MediaImageItem.java @@ -1013,9 +1013,20 @@ public class MediaImageItem extends MediaItem { if (dx > dy) { bitmapWidth = width; - bitmapHeight = Math.round(nativeHeight / dx); + + if (((float)nativeHeight / dx) < (float)height) { + bitmapHeight = (float)Math.ceil(nativeHeight / dx); + } else { // value equals the requested height + bitmapHeight = (float)Math.floor(nativeHeight / dx); + } + } else { - bitmapWidth = Math.round(nativeWidth / dy); + if (((float)nativeWidth / dy) > (float)width) { + bitmapWidth = (float)Math.floor(nativeWidth / dy); + } else { // value equals the requested width + bitmapWidth = (float)Math.ceil(nativeWidth / dy); + } + bitmapHeight = height; } diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java index 5b87d16..c19725c 100755 --- a/media/java/android/media/videoeditor/VideoEditorImpl.java +++ b/media/java/android/media/videoeditor/VideoEditorImpl.java @@ -1828,9 +1828,6 @@ public class VideoEditorImpl implements VideoEditor { if (surfaceHolder == null) { throw new IllegalArgumentException(); } - Rect frame; - int surfaceWidth; - int surfaceHeight; Surface surface = surfaceHolder.getSurface(); if (surface == null) { @@ -1838,10 +1835,7 @@ public class VideoEditorImpl implements VideoEditor { "Surface could not be retrieved from surface holder"); throw new RuntimeException(); } - frame = surfaceHolder.getSurfaceFrame(); - surfaceWidth = frame.width(); - surfaceHeight = frame.height(); - mMANativeHelper.clearPreviewSurface(surface,surfaceWidth,surfaceHeight); + mMANativeHelper.clearPreviewSurface(surface); } } diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp index 1751396..8ce788b 100755 --- a/media/jni/mediaeditor/VideoEditorMain.cpp +++ b/media/jni/mediaeditor/VideoEditorMain.cpp @@ -261,9 +261,7 @@ videoEditor_generateClip( static void videoEditor_clearSurface(JNIEnv* pEnv, jobject thiz, - jobject surface, - jint width, - jint height); + jobject surface); static JNINativeMethod gManualEditMethods[] = { {"getVersion", "()L"VERSION_CLASS_NAME";", @@ -300,7 +298,7 @@ static JNINativeMethod gManualEditMethods[] = { (int *)videoEditor_generateAudioRawFile }, {"nativeGenerateClip", "(L"EDIT_SETTINGS_CLASS_NAME";)I", (void *)videoEditor_generateClip }, - {"nativeClearSurface", "(Landroid/view/Surface;II)V", + {"nativeClearSurface", "(Landroid/view/Surface;)V", (void *)videoEditor_clearSurface }, }; @@ -428,16 +426,15 @@ static void videoEditor_stopPreview(JNIEnv* pEnv, static void videoEditor_clearSurface(JNIEnv* pEnv, jobject thiz, - jobject surface, - jint width, - jint height) + jobject surface) { bool needToBeLoaded = true; - M4OSA_UInt32 framesizeYuv =0; M4OSA_ERR result = M4NO_ERROR; VideoEditor_renderPreviewFrameStr frameStr; const char* pMessage = NULL; - M4VIFI_ImagePlane *yuvPlane; + // Let the size be QVGA + int width = 320; + int height = 240; ManualEditContext* pContext = M4OSA_NULL; // Get the context. @@ -474,62 +471,7 @@ static void videoEditor_clearSurface(JNIEnv* pEnv, Surface* const p = (Surface*)pEnv->GetIntField(surface, surface_native); sp<Surface> previewSurface = sp<Surface>(p); - /** - * Allocate output YUV planes - */ - yuvPlane = (M4VIFI_ImagePlane*)M4OSA_malloc(3*sizeof(M4VIFI_ImagePlane), M4VS, - (M4OSA_Char*)"videoEditor_clearSurface Output plane YUV"); - if (yuvPlane == M4OSA_NULL) { - VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", - "videoEditor_clearSurface() malloc error for yuv plane"); - pMessage = videoEditJava_getErrorName(M4ERR_ALLOC); - jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); - return ; - } - - framesizeYuv = width * height * 1.5; - yuvPlane[0].u_width = width; - yuvPlane[0].u_height = height; - yuvPlane[0].u_topleft = 0; - yuvPlane[0].u_stride = width; - yuvPlane[0].pac_data = (M4VIFI_UInt8 *)M4OSA_malloc(framesizeYuv, M4VS, - (M4OSA_Char*)"videoEditor pixelArray"); - if (yuvPlane[0].pac_data == M4OSA_NULL) { - VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR", - "videoEditor_renderPreviewFrame() malloc error"); - pMessage = videoEditJava_getErrorName(M4ERR_ALLOC); - jniThrowException(pEnv, "java/lang/RuntimeException", pMessage); - return; - } - - /* memset yuvPlane[0].pac_data with 0 for black frame */ - M4OSA_memset((M4OSA_MemAddr8)yuvPlane[0].pac_data,framesizeYuv,0x00); - FILE *p1 = fopen("/mnt/sdcard/black.raw","wb"); - fwrite(yuvPlane[0].pac_data,1,framesizeYuv,p1); - fclose(p1); - - yuvPlane[1].u_width = width>>1; - yuvPlane[1].u_height = height>>1; - yuvPlane[1].u_topleft = 0; - yuvPlane[1].u_stride = width>>1; - yuvPlane[1].pac_data = yuvPlane[0].pac_data - + yuvPlane[0].u_width * yuvPlane[0].u_height; - - M4OSA_memset((M4OSA_MemAddr8)yuvPlane[1].pac_data,yuvPlane[1].u_width * - yuvPlane[1].u_height,128); - yuvPlane[2].u_width = (width)>>1; - yuvPlane[2].u_height = (height)>>1; - yuvPlane[2].u_topleft = 0; - yuvPlane[2].u_stride = (width)>>1; - yuvPlane[2].pac_data = yuvPlane[1].pac_data - + yuvPlane[1].u_width * yuvPlane[1].u_height; - - M4OSA_memset((M4OSA_MemAddr8)yuvPlane[2].pac_data,yuvPlane[2].u_width * - yuvPlane[2].u_height,128); - - /* Fill up the render structure*/ - frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data; - + frameStr.pBuffer = M4OSA_NULL; frameStr.timeMs = 0; frameStr.uiSurfaceWidth = width; frameStr.uiSurfaceHeight = height; @@ -539,19 +481,11 @@ static void videoEditor_clearSurface(JNIEnv* pEnv, frameStr.clipBeginCutTime = 0; frameStr.clipEndCutTime = 0; - /*pContext->mPreviewController->setPreviewFrameRenderingMode( - pContext->pEditSettings->\ - pClipList[iCurrentClipIndex]->xVSS.MediaRendering, - pContext->pEditSettings->xVSS.outputVideoSize); - */ - - result = pContext->mPreviewController->renderPreviewFrame(previewSurface, + result = pContext->mPreviewController->clearSurface(previewSurface, &frameStr); videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, (M4NO_ERROR != result), result); - M4OSA_free((M4OSA_MemAddr32)yuvPlane[0].pac_data); - M4OSA_free((M4OSA_MemAddr32)yuvPlane); } static int videoEditor_renderPreviewFrame(JNIEnv* pEnv, diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_item.xml b/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_item.xml index 3028a42..3fef7e0 100644 --- a/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_item.xml +++ b/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_item.xml @@ -47,12 +47,11 @@ android:id="@+id/item_radio" android:layout_width="30dip" android:layout_height="wrap_content" - android:layout_marginRight="11dip" android:focusable="false" android:clickable="false" /> <ImageView android:id="@+id/item_icon" - android:layout_width="wrap_content" + android:layout_width="@android:dimen/app_icon_size" android:layout_height="wrap_content" android:scaleType="fitCenter" /> <LinearLayout diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java index a3ccef9..06c789c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java @@ -36,9 +36,12 @@ import android.widget.LinearLayout; import android.widget.RadioButton; import android.widget.TextView; +import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.TreeMap; import com.android.systemui.R; @@ -47,9 +50,10 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel, O private static final String TAG = "InputMethodsPanel"; private final InputMethodManager mImm; - private final HashMap<InputMethodInfo, List<InputMethodSubtype>> + private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mEnabledInputMethodAndSubtypesCache = - new HashMap<InputMethodInfo, List<InputMethodSubtype>>(); + new TreeMap<InputMethodInfo, List<InputMethodSubtype>>( + new InputMethodComparator()); private final HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>> mRadioViewAndImiMap = new HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>>(); @@ -61,6 +65,21 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel, O private String mEnabledInputMethodAndSubtypesCacheStr; private View mConfigureImeShortcut; + private class InputMethodComparator implements Comparator<InputMethodInfo> { + public int compare(InputMethodInfo imi1, InputMethodInfo imi2) { + if (imi2 == null) return 0; + if (imi1 == null) return 1; + if (mPackageManager != null) { + CharSequence imiId1 = imi1.loadLabel(mPackageManager); + CharSequence imiId2 = imi2.loadLabel(mPackageManager); + if (imiId1 != null && imiId2 != null) { + return imiId1.toString().compareTo(imiId2.toString()); + } + } + return imi1.getId().compareTo(imi2.getId()); + } + } + public InputMethodsPanel(Context context, AttributeSet attrs) { this(context, attrs, 0); } @@ -190,8 +209,8 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel, O mRadioViewAndImiMap.clear(); mPackageManager = mContext.getPackageManager(); - HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledIMIs - = getEnabledInputMethodAndSubtypeList(); + Map<InputMethodInfo, List<InputMethodSubtype>> enabledIMIs = + getEnabledInputMethodAndSubtypeList(); // TODO: Sort by alphabet and mode. Set<InputMethodInfo> cachedImiSet = enabledIMIs.keySet(); for (InputMethodInfo imi: cachedImiSet) { @@ -278,7 +297,7 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel, O } } - private HashMap<InputMethodInfo, List<InputMethodSubtype>> + private TreeMap<InputMethodInfo, List<InputMethodSubtype>> getEnabledInputMethodAndSubtypeList() { String newEnabledIMIs = Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.ENABLED_INPUT_METHODS); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index e26b8ea..9549930 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -81,7 +81,7 @@ public class TabletStatusBar extends StatusBar implements public static final int MAX_NOTIFICATION_ICONS = 5; // IME switcher icon is big and occupy width of two icons - public static final int MAX_NOTIFICATION_ICONS_IME_BUTTON_VISIBLE = MAX_NOTIFICATION_ICONS - 2; + public static final int MAX_NOTIFICATION_ICONS_IME_BUTTON_VISIBLE = MAX_NOTIFICATION_ICONS - 1; public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000; public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001; @@ -860,11 +860,8 @@ public class TabletStatusBar extends StatusBar implements if (DEBUG) { Slog.d(TAG, (visible?"showing":"hiding") + " the IME button"); } - int oldVisibility = mInputMethodSwitchButton.getVisibility(); mInputMethodSwitchButton.setIMEButtonVisible(token, visible); - if (oldVisibility != mInputMethodSwitchButton.getVisibility()) { - updateNotificationIcons(); - } + updateNotificationIcons(); mInputMethodsPanel.setImeToken(token); mBackButton.setImageResource( visible ? R.drawable.ic_sysbar_back_ime : R.drawable.ic_sysbar_back); diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 21c1e81..0147b1a 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -1356,14 +1356,27 @@ public class InputMethodManagerService extends IInputMethodManager.Stub public boolean switchToLastInputMethod(IBinder token) { synchronized (mMethodMap) { - Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked(); - if (lastIme != null) { - InputMethodInfo imi = mMethodMap.get(lastIme.first); - if (imi != null) { - setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode( - imi, Integer.valueOf(lastIme.second))); - return true; + final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked(); + if (lastIme == null) return false; + final InputMethodInfo lastImi = mMethodMap.get(lastIme.first); + if (lastImi == null) return false; + + final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId); + final int lastSubtypeHash = Integer.valueOf(lastIme.second); + // If the last IME is the same as the current IME and the last subtype is not defined, + // there is no need to switch to the last IME. + if (imiIdIsSame && lastSubtypeHash == NOT_A_SUBTYPE_ID) return false; + + int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID + : mCurrentSubtype.hashCode(); + if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) { + if (DEBUG) { + Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second + ", from: " + + mCurMethodId + ", " + currentSubtypeHash); } + setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode( + lastImi, lastSubtypeHash)); + return true; } return false; } diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 059c0b8..5806de2 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -2087,7 +2087,7 @@ class PackageManagerService extends IPackageManager.Stub { return (List<ResolveInfo>) mActivities.queryIntentForPackage(intent, resolvedType, flags, pkg.activities); } - return null; + return new ArrayList<ResolveInfo>(); } } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 694af70..291ebc5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2170,8 +2170,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); - LOGD("screenshot: FBO created, status=0x%x", status); - if (status == GL_FRAMEBUFFER_COMPLETE_OES) { // invert everything, b/c glReadPixel() below will invert the FB @@ -2187,8 +2185,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); - LOGD("screenshot: glClear() issued"); - const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { @@ -2199,8 +2195,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, } } - LOGD("screenshot: All layers rendered"); - // XXX: this is needed on tegra glScissor(0, 0, sw, sh); @@ -2215,10 +2209,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, new MemoryHeapBase(size, 0, "screen-capture") ); void* const ptr = base->getBase(); if (ptr) { - - LOGD("screenshot: about to call glReadPixels(0,0,%d,%d,...,%p)", - sw, sh, ptr); - // capture the screen with glReadPixels() glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); if (glGetError() == GL_NO_ERROR) { @@ -2231,9 +2221,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, } else { result = NO_MEMORY; } - - LOGD("screenshot: glReadPixels() returned %s", strerror(result)); - } glEnable(GL_SCISSOR_TEST); glViewport(0, 0, hw_w, hw_h); @@ -2244,18 +2231,14 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, result = BAD_VALUE; } - LOGD("screenshot: about to release FBO resources"); - // release FBO resources glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); glDeleteRenderbuffersOES(1, &tname); glDeleteFramebuffersOES(1, &name); - LOGD("screenshot: about to call compositionComplete()"); - hw.compositionComplete(); - LOGD("screenshot: result = %s", strerror(result)); + LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); return result; } diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 61f8e1a..2895b69 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -18,7 +18,7 @@ package="com.android.test.hwui"> <uses-permission android:name="android.permission.INTERNET" /> - <uses-sdk android:minSdkVersion="Honeycomb" /> + <uses-sdk android:minSdkVersion="11" /> <application android:label="HwUi" diff --git a/tests/HwAccelerationTest/default.properties b/tests/HwAccelerationTest/default.properties index 5a8ea50..da2dcdd 100644 --- a/tests/HwAccelerationTest/default.properties +++ b/tests/HwAccelerationTest/default.properties @@ -8,4 +8,4 @@ # project structure. # Project target. -target=android-Froyo +target=android-Honeycomb |
