diff options
83 files changed, 2089 insertions, 938 deletions
diff --git a/api/current.txt b/api/current.txt index ecbc9d298a5f..4997ae6a98ee 100644 --- a/api/current.txt +++ b/api/current.txt @@ -207,6 +207,7 @@ package android { field public static final int actionModeCutDrawable = 16843537; // 0x1010311 field public static final int actionModePasteDrawable = 16843539; // 0x1010313 field public static final int actionModeSelectAllDrawable = 16843647; // 0x101037f + field public static final int actionModeStyle = 16843688; // 0x10103a8 field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6 field public static final int actionProviderClass = 16843677; // 0x101039d field public static final int actionViewClass = 16843516; // 0x10102fc @@ -20494,6 +20495,14 @@ package android.util { ctor public Base64OutputStream(java.io.OutputStream, int); } + public final deprecated class Config { + field public static final deprecated boolean DEBUG = false; + field public static final deprecated boolean LOGD = true; + field public static final deprecated boolean LOGV = false; + field public static final deprecated boolean PROFILE = false; + field public static final deprecated boolean RELEASE = true; + } + public class DebugUtils { method public static boolean isObjectSelected(java.lang.Object); } @@ -20922,11 +20931,13 @@ package android.view { method public abstract android.view.Menu getMenu(); method public abstract android.view.MenuInflater getMenuInflater(); method public abstract java.lang.CharSequence getSubtitle(); + method public java.lang.Object getTag(); method public abstract java.lang.CharSequence getTitle(); method public abstract void invalidate(); method public abstract void setCustomView(android.view.View); method public abstract void setSubtitle(java.lang.CharSequence); method public abstract void setSubtitle(int); + method public void setTag(java.lang.Object); method public abstract void setTitle(java.lang.CharSequence); method public abstract void setTitle(int); } @@ -22039,9 +22050,12 @@ package android.view { method public android.graphics.SurfaceTexture getSurfaceTexture(); method public android.view.TextureView.SurfaceTextureListener getSurfaceTextureListener(); method public boolean isAvailable(); + method public android.graphics.Canvas lockCanvas(); + method public android.graphics.Canvas lockCanvas(android.graphics.Rect); method protected final void onDraw(android.graphics.Canvas); method public void setOpaque(boolean); method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener); + method public void unlockCanvasAndPost(android.graphics.Canvas); } public static abstract interface TextureView.SurfaceTextureListener { @@ -23894,7 +23908,7 @@ package android.view.inputmethod { method public boolean isWatchingCursor(android.view.View); method public void restartInput(android.view.View); method public void sendAppPrivateCommand(android.view.View, java.lang.String, android.os.Bundle); - method public boolean setAdditionalInputMethodSubtypes(android.os.IBinder, android.view.inputmethod.InputMethodSubtype[]); + method public boolean setAdditionalInputMethodSubtypes(java.lang.String, android.view.inputmethod.InputMethodSubtype[]); method public boolean setCurrentInputMethodSubtype(android.view.inputmethod.InputMethodSubtype); method public void setInputMethod(android.os.IBinder, java.lang.String); method public void setInputMethodAndSubtype(android.os.IBinder, java.lang.String, android.view.inputmethod.InputMethodSubtype); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index c6a746b237f1..f6cd866d4e34 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -70,7 +70,7 @@ import android.view.HardwareRenderer; import android.view.View; import android.view.ViewDebug; import android.view.ViewManager; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; @@ -3558,6 +3558,7 @@ public final class ActivityThread { } final void handleTrimMemory(int level) { + WindowManagerImpl.getDefault().trimMemory(level); } private final void handleBindApplication(AppBindData data) { @@ -4071,7 +4072,7 @@ public final class ActivityThread { sThreadLocal.set(this); mSystemThread = system; if (!system) { - ViewAncestor.addFirstDrawHandler(new Runnable() { + ViewRootImpl.addFirstDrawHandler(new Runnable() { public void run() { ensureJitEnabled(); } @@ -4101,7 +4102,7 @@ public final class ActivityThread { } } - ViewAncestor.addConfigCallback(new ComponentCallbacks() { + ViewRootImpl.addConfigCallback(new ComponentCallbacks() { public void onConfigurationChanged(Configuration newConfig) { synchronized (mPackages) { // We need to apply this change to the resources diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 42eda0212e01..8e2d360b5637 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -168,6 +168,7 @@ public class SearchDialog extends Dialog { SearchBar searchBar = (SearchBar) findViewById(com.android.internal.R.id.search_bar); searchBar.setSearchDialog(this); mSearchView = (SearchView) findViewById(com.android.internal.R.id.search_view); + mSearchView.setIconified(false); mSearchView.setOnCloseListener(mOnCloseListener); mSearchView.setOnQueryTextListener(mOnQueryChangeListener); mSearchView.setOnSuggestionListener(mOnSuggestionSelectionListener); @@ -633,31 +634,6 @@ public class SearchDialog extends Dialog { } /** - * Overrides the handling of the back key to move back to the previous - * sources or dismiss the search dialog, instead of dismissing the input - * method. - */ - @Override - public boolean dispatchKeyEventPreIme(KeyEvent event) { - if (DBG) - Log.d(LOG_TAG, "onKeyPreIme(" + event + ")"); - if (mSearchDialog != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { - KeyEvent.DispatcherState state = getKeyDispatcherState(); - if (state != null) { - if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { - state.startTracking(event, this); - return true; - } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled() - && state.isTracking(event)) { - mSearchDialog.onBackPressed(); - return true; - } - } - } - return super.dispatchKeyEventPreIme(event); - } - - /** * Don't allow action modes in a SearchBar, it looks silly. */ @Override diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index c179b3576211..4c21d049a6fc 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -662,12 +662,6 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { writer.println("nothing to dump"); } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - //Log.i("Service", "Finalizing Service: " + this); - } // ------------------ Internal API ------------------ diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 7fd5a7d3dcd0..8472b3149686 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -40,7 +40,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.DisplayMetrics; import android.util.Log; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; import java.io.FileOutputStream; import java.io.IOException; @@ -592,7 +592,7 @@ public class WallpaperManager { public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) { try { //Log.v(TAG, "Sending new wallpaper offsets from app..."); - ViewAncestor.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( + ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( windowToken, xOffset, yOffset, mWallpaperXStep, mWallpaperYStep); //Log.v(TAG, "...app returning after sending offsets!"); } catch (RemoteException e) { @@ -630,7 +630,7 @@ public class WallpaperManager { int x, int y, int z, Bundle extras) { try { //Log.v(TAG, "Sending new wallpaper offsets from app..."); - ViewAncestor.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand( + ViewRootImpl.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand( windowToken, action, x, y, z, extras, false); //Log.v(TAG, "...app returning after sending offsets!"); } catch (RemoteException e) { @@ -650,7 +650,7 @@ public class WallpaperManager { */ public void clearWallpaperOffsets(IBinder windowToken) { try { - ViewAncestor.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( + ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition( windowToken, -1, -1, -1, -1); } catch (RemoteException e) { // Ignore. diff --git a/core/java/android/content/SearchRecentSuggestionsProvider.java b/core/java/android/content/SearchRecentSuggestionsProvider.java index 3d89e92d4348..e1a8d21f9970 100644 --- a/core/java/android/content/SearchRecentSuggestionsProvider.java +++ b/core/java/android/content/SearchRecentSuggestionsProvider.java @@ -186,6 +186,9 @@ public class SearchRecentSuggestionsProvider extends ContentProvider { mSuggestionProjection = new String [] { "0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT, + "'android.resource://system/" + + com.android.internal.R.drawable.ic_menu_recent_history + "' AS " + + SearchManager.SUGGEST_COLUMN_ICON_1, "display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1, "display2 AS " + SearchManager.SUGGEST_COLUMN_TEXT_2, "query AS " + SearchManager.SUGGEST_COLUMN_QUERY, @@ -196,6 +199,9 @@ public class SearchRecentSuggestionsProvider extends ContentProvider { mSuggestionProjection = new String [] { "0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT, + "'android.resource://system/" + + com.android.internal.R.drawable.ic_menu_recent_history + "' AS " + + SearchManager.SUGGEST_COLUMN_ICON_1, "display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1, "query AS " + SearchManager.SUGGEST_COLUMN_QUERY, "_id" diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index 67d200cd40ff..b5486234b224 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -409,9 +409,10 @@ public class UsbManager { /** * Sets the current USB function. + * If function is null, then the current function is set to the default function. * - * @param function name of the USB function - * @param makeDefault true if this should be set as the default + * @param function name of the USB function, or null to restore the default function + * @param makeDefault true if the function should be set as the new default function * * {@hide} */ diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 8fc8b9dbb31f..c51ba2a0a643 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -51,7 +51,7 @@ import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.View; import android.view.ViewGroup; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.WindowManagerImpl; import android.view.WindowManagerPolicy; @@ -650,7 +650,7 @@ public abstract class WallpaperService extends Service { mWindowToken = wrapper.mWindowToken; mSurfaceHolder.setSizeFromLayout(); mInitializing = true; - mSession = ViewAncestor.getWindowSession(getMainLooper()); + mSession = ViewRootImpl.getWindowSession(getMainLooper()); mWindow.setSession(mSession); diff --git a/core/java/android/util/Config.java b/core/java/android/util/Config.java new file mode 100644 index 000000000000..70dc9aaa0a4c --- /dev/null +++ b/core/java/android/util/Config.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2006 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; + +/** + * @deprecated This class is not useful, it just returns the same value for + * all constants, and has always done this. Do not use it. + */ +@Deprecated +public final class Config { + /** @hide */ public Config() {} + + /** + * @deprecated Always false. + */ + @Deprecated + public static final boolean DEBUG = false; + + /** + * @deprecated Always true. + */ + @Deprecated + public static final boolean RELEASE = true; + + /** + * @deprecated Always false. + */ + @Deprecated + public static final boolean PROFILE = false; + + /** + * @deprecated Always false. + */ + @Deprecated + public static final boolean LOGV = false; + + /** + * @deprecated Always true. + */ + @Deprecated + public static final boolean LOGD = true; +} diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java index bfafa987ceda..e9549834b215 100644 --- a/core/java/android/view/ActionMode.java +++ b/core/java/android/view/ActionMode.java @@ -23,6 +23,36 @@ package android.view; * Examples of good action modes include selection modes, search, content editing, etc. */ public abstract class ActionMode { + private Object mTag; + + /** + * Set a tag object associated with this ActionMode. + * + * <p>Like the tag available to views, this allows applications to associate arbitrary + * data with an ActionMode for later reference. + * + * @param tag Tag to associate with this ActionMode + * + * @see #getTag() + */ + public void setTag(Object tag) { + mTag = tag; + } + + /** + * Retrieve the tag object associated with this ActionMode. + * + * <p>Like the tag available to views, this allows applications to associate arbitrary + * data with an ActionMode for later reference. + * + * @return Tag associated with this ActionMode + * + * @see #setTag(Object) + */ + public Object getTag() { + return mTag; + } + /** * Set the title of the action mode. This method will have no visible effect if * a custom view has been set. diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 4987e2f6b0a4..80244bbe9244 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -286,6 +286,38 @@ class GLES20Canvas extends HardwareCanvas { private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction); + + /////////////////////////////////////////////////////////////////////////// + // Memory + /////////////////////////////////////////////////////////////////////////// + + /** + * @see #flushCaches(int) + */ + public static final int FLUSH_CACHES_MODERATE = 0; + + /** + * @see #flushCaches(int) + */ + public static final int FLUSH_CACHES_FULL = 1; + + /** + * Flush caches to reclaim as much memory as possible. The amount of memory + * to reclaim is indicate by the level parameter. + * + * The level can be one of {@link #FLUSH_CACHES_MODERATE} or + * {@link #FLUSH_CACHES_FULL}. + * + * @param level Hint about the amount of memory to reclaim + * + * @hide + */ + public static void flushCaches(int level) { + nFlushCaches(level); + } + + private static native void nFlushCaches(int level); + /////////////////////////////////////////////////////////////////////////// // Display list /////////////////////////////////////////////////////////////////////////// diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 011e44c5157c..9a2564fc052e 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -17,6 +17,7 @@ package android.view; +import android.content.ComponentCallbacks; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.SurfaceTexture; @@ -263,6 +264,18 @@ public abstract class HardwareRenderer { } /** + * Invoke this method when the system is running out of memory. This + * method will attempt to recover as much memory as possible, based on + * the specified hint. + * + * @param level Hint about the amount of memory that should be trimmed, + * see {@link android.content.ComponentCallbacks} + */ + static void trimMemory(int level) { + Gl20Renderer.flushCaches(level); + } + + /** * Indicates whether hardware acceleration is currently enabled. * * @return True if hardware acceleration is in use, false otherwise. @@ -858,5 +871,16 @@ public abstract class HardwareRenderer { } return null; } + + static void flushCaches(int level) { + switch (level) { + case ComponentCallbacks.TRIM_MEMORY_MODERATE: + GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE); + break; + case ComponentCallbacks.TRIM_MEMORY_COMPLETE: + GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL); + break; + } + } } } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 764899fae527..cbdb38e3181a 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -426,7 +426,7 @@ public class SurfaceView extends View { if (!mHaveFrame) { return; } - ViewAncestor viewRoot = (ViewAncestor) getRootView().getParent(); + ViewRootImpl viewRoot = (ViewRootImpl) getRootView().getParent(); if (viewRoot != null) { mTranslator = viewRoot.mTranslator; } diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index d656f315a4db..96d6f095d300 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -20,6 +20,7 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.util.AttributeSet; import android.util.Log; @@ -107,6 +108,14 @@ public class TextureView extends View { private SurfaceTexture.OnFrameAvailableListener mUpdateListener; + private Canvas mCanvas; + private int mSaveCount; + + private final Object[] mNativeWindowLock = new Object[0]; + // Used from native code, do not write! + @SuppressWarnings({"UnusedDeclaration"}) + private int mNativeWindow; + /** * Creates a new TextureView. * @@ -190,7 +199,11 @@ public class TextureView extends View { mListener.onSurfaceTextureDestroyed(mSurface); } - mLayer.destroy(); + synchronized (mNativeWindowLock) { + nDestroyNativeWindow(); + } + + mLayer.destroy(); mSurface = null; mLayer = null; } @@ -274,6 +287,7 @@ public class TextureView extends View { mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mOpaque); mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer); nSetDefaultBufferSize(mSurface, getWidth(), getHeight()); + nCreateNativeWindow(mSurface); mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() { @Override @@ -431,6 +445,79 @@ public class TextureView extends View { } /** + * <p>Start editing the pixels in the surface. The returned Canvas can be used + * to draw into the surface's bitmap. A null is returned if the surface has + * not been created or otherwise cannot be edited. You will usually need + * to implement + * {@link SurfaceTextureListener#onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int)} + * to find out when the Surface is available for use.</p> + * + * <p>The content of the Surface is never preserved between unlockCanvas() + * and lockCanvas(), for this reason, every pixel within the Surface area + * must be written. The only exception to this rule is when a dirty + * rectangle is specified, in which case, non-dirty pixels will be + * preserved.</p> + * + * @return A Canvas used to draw into the surface. + * + * @see #lockCanvas(android.graphics.Rect) + * @see #unlockCanvasAndPost(android.graphics.Canvas) + */ + public Canvas lockCanvas() { + return lockCanvas(null); + } + + /** + * Just like {@link #lockCanvas()} but allows specification of a dirty + * rectangle. Every pixel within that rectangle must be written; however + * pixels outside the dirty rectangle will be preserved by the next call + * to lockCanvas(). + * + * @param dirty Area of the surface that will be modified. + + * @return A Canvas used to draw into the surface. + * + * @see #lockCanvas() + * @see #unlockCanvasAndPost(android.graphics.Canvas) + */ + public Canvas lockCanvas(Rect dirty) { + if (!isAvailable()) return null; + + if (mCanvas == null) { + mCanvas = new Canvas(); + } + + synchronized (mNativeWindowLock) { + nLockCanvas(mNativeWindow, mCanvas, dirty); + } + mSaveCount = mCanvas.save(); + + return mCanvas; + } + + /** + * Finish editing pixels in the surface. After this call, the surface's + * current pixels will be shown on the screen, but its content is lost, + * in particular there is no guarantee that the content of the Surface + * will remain unchanged when lockCanvas() is called again. + * + * @param canvas The Canvas previously returned by lockCanvas() + * + * @see #lockCanvas() + * @see #lockCanvas(android.graphics.Rect) + */ + public void unlockCanvasAndPost(Canvas canvas) { + if (mCanvas != null && canvas == mCanvas) { + canvas.restoreToCount(mSaveCount); + mSaveCount = 0; + + synchronized (mNativeWindowLock) { + nUnlockCanvasAndPost(mNativeWindow, mCanvas); + } + } + } + + /** * Returns the {@link SurfaceTexture} used by this view. This method * may return null if the view is not attached to a window or if the surface * texture has not been initialized yet. @@ -506,6 +593,12 @@ public class TextureView extends View { public void onSurfaceTextureUpdated(SurfaceTexture surface); } + private native void nCreateNativeWindow(SurfaceTexture surface); + private native void nDestroyNativeWindow(); + private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture, int width, int height); + + private static native void nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty); + private static native void nUnlockCanvasAndPost(int nativeWindow, Canvas canvas); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index dba6d317bbec..59cb216fa9b8 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5043,9 +5043,9 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit } /** Gets the ViewAncestor, or null if not attached. */ - /*package*/ ViewAncestor getViewAncestor() { + /*package*/ ViewRootImpl getViewRootImpl() { View root = getRootView(); - return root != null ? (ViewAncestor)root.getParent() : null; + return root != null ? (ViewRootImpl)root.getParent() : null; } /** @@ -5061,7 +5061,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit public final boolean requestFocusFromTouch() { // Leave touch mode if we need to if (isInTouchMode()) { - ViewAncestor viewRoot = getViewAncestor(); + ViewRootImpl viewRoot = getViewRootImpl(); if (viewRoot != null) { viewRoot.ensureTouchMode(false); } @@ -5653,7 +5653,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit if (mAttachInfo != null) { return mAttachInfo.mInTouchMode; } else { - return ViewAncestor.isInTouchMode(); + return ViewRootImpl.isInTouchMode(); } } @@ -8254,7 +8254,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit handler = attachInfo.mHandler; } else { // Assume that post will succeed later - ViewAncestor.getRunQueue().post(action); + ViewRootImpl.getRunQueue().post(action); return true; } @@ -8284,7 +8284,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit handler = attachInfo.mHandler; } else { // Assume that post will succeed later - ViewAncestor.getRunQueue().postDelayed(action, delayMillis); + ViewRootImpl.getRunQueue().postDelayed(action, delayMillis); return true; } @@ -8308,7 +8308,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit handler = attachInfo.mHandler; } else { // Assume that post will succeed later - ViewAncestor.getRunQueue().removeCallbacks(action); + ViewRootImpl.getRunQueue().removeCallbacks(action); return true; } @@ -11580,9 +11580,9 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit viewParent = view.mParent; } - if (viewParent instanceof ViewAncestor) { + if (viewParent instanceof ViewRootImpl) { // *cough* - final ViewAncestor vr = (ViewAncestor)viewParent; + final ViewRootImpl vr = (ViewRootImpl)viewParent; location[1] -= vr.mCurScrollY; } } @@ -12709,7 +12709,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit surface.unlockCanvasAndPost(canvas); } - final ViewAncestor root = getViewAncestor(); + final ViewRootImpl root = getViewRootImpl(); // Cache the local state object for delivery with DragEvents root.setLocalDragState(myLocalState); @@ -13916,7 +13916,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit Canvas mCanvas; /** - * A Handler supplied by a view's {@link android.view.ViewAncestor}. This + * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This * handler can be used to pump events in the UI events queue. */ final Handler mHandler; diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index f7f5a21399dd..b85159b2eaa8 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -366,7 +366,7 @@ public class ViewDebug { } private static BufferedWriter sHierarchyTraces; - private static ViewAncestor sHierarhcyRoot; + private static ViewRootImpl sHierarhcyRoot; private static String sHierarchyTracePrefix; /** @@ -415,7 +415,7 @@ public class ViewDebug { * @hide */ public static long getViewAncestorInstanceCount() { - return Debug.countInstancesOfClass(ViewAncestor.class); + return Debug.countInstancesOfClass(ViewRootImpl.class); } /** @@ -748,7 +748,7 @@ public class ViewDebug { return; } - sHierarhcyRoot = (ViewAncestor) view.getRootView().getParent(); + sHierarhcyRoot = (ViewRootImpl) view.getRootView().getParent(); } /** @@ -1100,7 +1100,7 @@ public class ViewDebug { private static void outputDisplayList(View root, String parameter) throws IOException { final View view = findView(root, parameter); - view.getViewAncestor().outputDisplayList(view); + view.getViewRootImpl().outputDisplayList(view); } private static void capture(View root, final OutputStream clientStream, String parameter) diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index cb3e9c684cbd..5f7673aacee6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -954,7 +954,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final float tx = event.mX; final float ty = event.mY; - ViewAncestor root = getViewAncestor(); + ViewRootImpl root = getViewRootImpl(); // Dispatch down the view hierarchy switch (event.mAction) { @@ -3839,13 +3839,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (drawAnimation) { if (view != null) { view.mPrivateFlags |= DRAW_ANIMATION; - } else if (parent instanceof ViewAncestor) { - ((ViewAncestor) parent).mIsAnimating = true; + } else if (parent instanceof ViewRootImpl) { + ((ViewRootImpl) parent).mIsAnimating = true; } } - if (parent instanceof ViewAncestor) { - ((ViewAncestor) parent).invalidate(); + if (parent instanceof ViewRootImpl) { + ((ViewRootImpl) parent).invalidate(); parent = null; } else if (view != null) { if ((view.mPrivateFlags & DRAWN) == DRAWN || @@ -3902,8 +3902,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (drawAnimation) { if (view != null) { view.mPrivateFlags |= DRAW_ANIMATION; - } else if (parent instanceof ViewAncestor) { - ((ViewAncestor) parent).mIsAnimating = true; + } else if (parent instanceof ViewRootImpl) { + ((ViewRootImpl) parent).mIsAnimating = true; } } @@ -4426,7 +4426,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // If this group is dirty, check that the parent is dirty as well if ((mPrivateFlags & DIRTY_MASK) != 0) { final ViewParent parent = getParent(); - if (parent != null && !(parent instanceof ViewAncestor)) { + if (parent != null && !(parent instanceof ViewRootImpl)) { if ((((View) parent).mPrivateFlags & DIRTY_MASK) == 0) { result = false; android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG, @@ -4995,7 +4995,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @hide */ public void requestTransitionStart(LayoutTransition transition) { - ViewAncestor viewAncestor = getViewAncestor(); + ViewRootImpl viewAncestor = getViewRootImpl(); viewAncestor.requestTransitionStart(transition); } diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewRootImpl.java index ac73611b950a..470493d221c3 100644 --- a/core/java/android/view/ViewAncestor.java +++ b/core/java/android/view/ViewRootImpl.java @@ -92,7 +92,7 @@ import java.util.List; * {@hide} */ @SuppressWarnings({"EmptyCatchBlock", "PointlessBooleanExpression"}) -public final class ViewAncestor extends Handler implements ViewParent, +public final class ViewRootImpl extends Handler implements ViewParent, View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks { private static final String TAG = "ViewAncestor"; private static final boolean DBG = false; @@ -303,7 +303,7 @@ public final class ViewAncestor extends Handler implements ViewParent, } } - public ViewAncestor(Context context) { + public ViewRootImpl(Context context) { super(); if (MEASURE_LATENCY) { @@ -3807,14 +3807,14 @@ public final class ViewAncestor extends Handler implements ViewParent, } static class InputMethodCallback extends IInputMethodCallback.Stub { - private WeakReference<ViewAncestor> mViewAncestor; + private WeakReference<ViewRootImpl> mViewAncestor; - public InputMethodCallback(ViewAncestor viewAncestor) { - mViewAncestor = new WeakReference<ViewAncestor>(viewAncestor); + public InputMethodCallback(ViewRootImpl viewAncestor) { + mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor); } public void finishedEvent(int seq, boolean handled) { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchFinishedEvent(seq, handled); } @@ -3826,15 +3826,15 @@ public final class ViewAncestor extends Handler implements ViewParent, } static class W extends IWindow.Stub { - private final WeakReference<ViewAncestor> mViewAncestor; + private final WeakReference<ViewRootImpl> mViewAncestor; - W(ViewAncestor viewAncestor) { - mViewAncestor = new WeakReference<ViewAncestor>(viewAncestor); + W(ViewRootImpl viewAncestor) { + mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor); } public void resized(int w, int h, Rect coveredInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchResized(w, h, coveredInsets, visibleInsets, reportDraw, newConfig); @@ -3842,21 +3842,21 @@ public final class ViewAncestor extends Handler implements ViewParent, } public void dispatchAppVisibility(boolean visible) { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchAppVisibility(visible); } } public void dispatchGetNewSurface() { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchGetNewSurface(); } } public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.windowFocusChanged(hasFocus, inTouchMode); } @@ -3872,7 +3872,7 @@ public final class ViewAncestor extends Handler implements ViewParent, } public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { final View view = viewAncestor.mView; if (view != null) { @@ -3903,7 +3903,7 @@ public final class ViewAncestor extends Handler implements ViewParent, } public void closeSystemDialogs(String reason) { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchCloseSystemDialogs(reason); } @@ -3931,14 +3931,14 @@ public final class ViewAncestor extends Handler implements ViewParent, /* Drag/drop */ public void dispatchDragEvent(DragEvent event) { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchDragEvent(event); } } public void dispatchSystemUiVisibilityChanged(int visibility) { - final ViewAncestor viewAncestor = mViewAncestor.get(); + final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchSystemUiVisibilityChanged(visibility); } @@ -4269,7 +4269,7 @@ public final class ViewAncestor extends Handler implements ViewParent, if (!registered) { mAttachInfo.mAccessibilityWindowId = mAccessibilityManager.addAccessibilityInteractionConnection(mWindow, - new AccessibilityInteractionConnection(ViewAncestor.this)); + new AccessibilityInteractionConnection(ViewRootImpl.this)); } } @@ -4289,10 +4289,10 @@ public final class ViewAncestor extends Handler implements ViewParent, */ final class AccessibilityInteractionConnection extends IAccessibilityInteractionConnection.Stub { - private final WeakReference<ViewAncestor> mViewAncestor; + private final WeakReference<ViewRootImpl> mViewAncestor; - AccessibilityInteractionConnection(ViewAncestor viewAncestor) { - mViewAncestor = new WeakReference<ViewAncestor>(viewAncestor); + AccessibilityInteractionConnection(ViewRootImpl viewAncestor) { + mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor); } public void findAccessibilityNodeInfoByAccessibilityId(int accessibilityId, @@ -4421,7 +4421,7 @@ public final class ViewAncestor extends Handler implements ViewParent, try { FindByAccessibilitytIdPredicate predicate = mFindByAccessibilityIdPredicate; predicate.init(accessibilityId); - View root = ViewAncestor.this.mView; + View root = ViewRootImpl.this.mView; View target = root.findViewByPredicate(predicate); if (target != null && target.isShown()) { info = target.createAccessibilityNodeInfo(); @@ -4453,7 +4453,7 @@ public final class ViewAncestor extends Handler implements ViewParent, AccessibilityNodeInfo info = null; try { - View root = ViewAncestor.this.mView; + View root = ViewRootImpl.this.mView; View target = root.findViewById(viewId); if (target != null && target.isShown()) { info = target.createAccessibilityNodeInfo(); @@ -4499,7 +4499,7 @@ public final class ViewAncestor extends Handler implements ViewParent, if (accessibilityViewId != View.NO_ID) { root = findViewByAccessibilityId(accessibilityViewId); } else { - root = ViewAncestor.this.mView; + root = ViewRootImpl.this.mView; } if (root == null || !root.isShown()) { @@ -4624,7 +4624,7 @@ public final class ViewAncestor extends Handler implements ViewParent, } private View findViewByAccessibilityId(int accessibilityId) { - View root = ViewAncestor.this.mView; + View root = ViewRootImpl.this.mView; if (root == null) { return null; } diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index 54e7c04a4636..a451bb52204f 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -16,18 +16,16 @@ package android.view; -import java.util.HashMap; - import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.os.IBinder; import android.util.AndroidRuntimeException; import android.util.Log; -import android.util.Slog; -import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; +import java.util.HashMap; + final class WindowLeaked extends AndroidRuntimeException { public WindowLeaked(String msg) { super(msg); @@ -80,7 +78,7 @@ public class WindowManagerImpl implements WindowManager { public static final int ADD_PERMISSION_DENIED = -8; private View[] mViews; - private ViewAncestor[] mRoots; + private ViewRootImpl[] mRoots; private WindowManager.LayoutParams[] mParams; private final static Object sLock = new Object(); @@ -204,7 +202,7 @@ public class WindowManagerImpl implements WindowManager { final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params; - ViewAncestor root; + ViewRootImpl root; View panelParentView = null; synchronized (this) { @@ -241,7 +239,7 @@ public class WindowManagerImpl implements WindowManager { } } - root = new ViewAncestor(view.getContext()); + root = new ViewRootImpl(view.getContext()); root.mAddNesting = 1; if (cih == null) { root.mCompatibilityInfo = new CompatibilityInfoHolder(); @@ -254,7 +252,7 @@ public class WindowManagerImpl implements WindowManager { if (mViews == null) { index = 1; mViews = new View[1]; - mRoots = new ViewAncestor[1]; + mRoots = new ViewRootImpl[1]; mParams = new WindowManager.LayoutParams[1]; } else { index = mViews.length + 1; @@ -262,7 +260,7 @@ public class WindowManagerImpl implements WindowManager { mViews = new View[index]; System.arraycopy(old, 0, mViews, 0, index-1); old = mRoots; - mRoots = new ViewAncestor[index]; + mRoots = new ViewRootImpl[index]; System.arraycopy(old, 0, mRoots, 0, index-1); old = mParams; mParams = new WindowManager.LayoutParams[index]; @@ -290,7 +288,7 @@ public class WindowManagerImpl implements WindowManager { synchronized (this) { int index = findViewLocked(view, true); - ViewAncestor root = mRoots[index]; + ViewRootImpl root = mRoots[index]; mParams[index] = wparams; root.setLayoutParams(wparams, false); } @@ -312,7 +310,7 @@ public class WindowManagerImpl implements WindowManager { public void removeViewImmediate(View view) { synchronized (this) { int index = findViewLocked(view, true); - ViewAncestor root = mRoots[index]; + ViewRootImpl root = mRoots[index]; View curView = root.getView(); root.mAddNesting = 0; @@ -328,7 +326,7 @@ public class WindowManagerImpl implements WindowManager { } View removeViewLocked(int index) { - ViewAncestor root = mRoots[index]; + ViewRootImpl root = mRoots[index]; View view = root.getView(); // Don't really remove until we have matched all calls to add(). @@ -356,7 +354,7 @@ public class WindowManagerImpl implements WindowManager { removeItem(tmpViews, mViews, index); mViews = tmpViews; - ViewAncestor[] tmpRoots = new ViewAncestor[count-1]; + ViewRootImpl[] tmpRoots = new ViewRootImpl[count-1]; removeItem(tmpRoots, mRoots, index); mRoots = tmpRoots; @@ -383,7 +381,7 @@ public class WindowManagerImpl implements WindowManager { //Log.i("foo", "@ " + i + " token " + mParams[i].token // + " view " + mRoots[i].getView()); if (token == null || mParams[i].token == token) { - ViewAncestor root = mRoots[i]; + ViewRootImpl root = mRoots[i]; root.mAddNesting = 1; //Log.i("foo", "Force closing " + root); @@ -402,7 +400,16 @@ public class WindowManagerImpl implements WindowManager { } } } - + + /** + * @param level See {@link android.content.ComponentCallbacks} + */ + public void trimMemory(int level) { + if (HardwareRenderer.isAvailable()) { + HardwareRenderer.trimMemory(level); + } + } + public void setStoppedState(IBinder token, boolean stopped) { synchronized (this) { if (mViews == null) @@ -410,7 +417,7 @@ public class WindowManagerImpl implements WindowManager { int count = mViews.length; for (int i=0; i<count; i++) { if (token == null || mParams[i].token == token) { - ViewAncestor root = mRoots[i]; + ViewRootImpl root = mRoots[i]; root.setStopped(stopped); } } @@ -422,7 +429,7 @@ public class WindowManagerImpl implements WindowManager { int count = mViews.length; config = new Configuration(config); for (int i=0; i<count; i++) { - ViewAncestor root = mRoots[i]; + ViewRootImpl root = mRoots[i]; root.requestUpdateConfiguration(config); } } @@ -430,13 +437,13 @@ public class WindowManagerImpl implements WindowManager { public WindowManager.LayoutParams getRootViewLayoutParameter(View view) { ViewParent vp = view.getParent(); - while (vp != null && !(vp instanceof ViewAncestor)) { + while (vp != null && !(vp instanceof ViewRootImpl)) { vp = vp.getParent(); } if (vp == null) return null; - ViewAncestor vr = (ViewAncestor)vp; + ViewRootImpl vr = (ViewRootImpl)vp; int N = mRoots.length; for (int i = 0; i < N; ++i) { @@ -456,8 +463,7 @@ public class WindowManagerImpl implements WindowManager { return new Display(Display.DEFAULT_DISPLAY, null); } - private static void removeItem(Object[] dst, Object[] src, int index) - { + private static void removeItem(Object[] dst, Object[] src, int index) { if (dst.length > 0) { if (index > 0) { System.arraycopy(src, 0, dst, 0, index); @@ -468,8 +474,7 @@ public class WindowManagerImpl implements WindowManager { } } - private int findViewLocked(View view, boolean required) - { + private int findViewLocked(View view, boolean required) { synchronized (this) { final int count = mViews != null ? mViews.length : 0; for (int i=0; i<count; i++) { diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index abe3c2ccd490..5ec1ec3e03f3 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -34,7 +34,7 @@ import android.util.LogPrinter; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.View; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; class ComposingText implements NoCopySpan { } @@ -502,7 +502,7 @@ public class BaseInputConnection implements InputConnection { } } if (h != null) { - h.sendMessage(h.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME, + h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME, event)); } } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index a1a7281c7710..da5baf86a97c 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -26,6 +26,7 @@ import com.android.internal.view.IInputMethodSession; import com.android.internal.view.InputBindResult; import android.content.Context; +import android.content.pm.PackageManager; import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; @@ -42,7 +43,7 @@ import android.util.Printer; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -655,7 +656,7 @@ public final class InputMethodManager { if (vh != null) { // This will result in a call to reportFinishInputConnection() // below. - vh.sendMessage(vh.obtainMessage(ViewAncestor.FINISH_INPUT_CONNECTION, + vh.sendMessage(vh.obtainMessage(ViewRootImpl.FINISH_INPUT_CONNECTION, mServedInputConnection)); } } @@ -1112,9 +1113,9 @@ public final class InputMethodManager { void scheduleCheckFocusLocked(View view) { Handler vh = view.getHandler(); - if (vh != null && !vh.hasMessages(ViewAncestor.CHECK_FOCUS)) { + if (vh != null && !vh.hasMessages(ViewRootImpl.CHECK_FOCUS)) { // This will result in a call to checkFocus() below. - vh.sendMessage(vh.obtainMessage(ViewAncestor.CHECK_FOCUS)); + vh.sendMessage(vh.obtainMessage(ViewRootImpl.CHECK_FOCUS)); } } @@ -1580,16 +1581,16 @@ public final class InputMethodManager { } /** - * Set additional input method subtypes. - * @param imeToken Supplies the identifying token given to an input method. + * Set additional input method subtypes. Only a process which shares the same uid with the IME + * can add additional input method subtypes to the IME. + * @param imiId Id of InputMethodInfo which additional input method subtypes will be added to. * @param subtypes subtypes will be added as additional subtypes of the current input method. * @return true if the additional input method subtypes are successfully added. */ - public boolean setAdditionalInputMethodSubtypes( - IBinder imeToken, InputMethodSubtype[] subtypes) { + public boolean setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { synchronized (mH) { try { - return mService.setAdditionalInputMethodSubtypes(imeToken, subtypes); + return mService.setAdditionalInputMethodSubtypes(imiId, subtypes); } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); return false; diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index 5aa60f4f7b39..738bcb921ca4 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -35,7 +35,7 @@ import android.os.Message; import android.util.Log; import android.util.TypedValue; import android.view.Surface; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; import android.view.WindowManager; import junit.framework.Assert; @@ -228,7 +228,7 @@ class BrowserFrame extends Handler { sConfigCallback = new ConfigCallback( (WindowManager) appContext.getSystemService( Context.WINDOW_SERVICE)); - ViewAncestor.addConfigCallback(sConfigCallback); + ViewRootImpl.addConfigCallback(sConfigCallback); } sConfigCallback.addHandler(this); diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index b9eb5ff01852..f82c61a2bdb2 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -28,7 +28,7 @@ import android.util.Pair; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; -import com.android.internal.R.styleable; +import com.android.internal.R; import java.lang.reflect.Array; import java.util.ArrayList; @@ -167,7 +167,7 @@ public class GridLayout extends ViewGroup { // Misc constants private static final String TAG = GridLayout.class.getName(); - static final boolean DEBUG = false; + static boolean DEBUG = false; private static final int PRF = 1; // Defaults @@ -178,19 +178,17 @@ public class GridLayout extends ViewGroup { private static final boolean DEFAULT_ORDER_PRESERVED = false; private static final int DEFAULT_ALIGNMENT_MODE = ALIGN_MARGINS; private static final int DEFAULT_CONTAINER_MARGIN = 0; - private static final int DEFAULT_MARGIN = 8; - private static final int DEFAULT_CONTAINER_PADDING = 16; private static final int MAX_SIZE = 100000; // TypedArray indices - private static final int ORIENTATION = styleable.GridLayout_orientation; - private static final int ROW_COUNT = styleable.GridLayout_rowCount; - private static final int COLUMN_COUNT = styleable.GridLayout_columnCount; - private static final int USE_DEFAULT_MARGINS = styleable.GridLayout_useDefaultMargins; - private static final int ALIGNMENT_MODE = styleable.GridLayout_alignmentMode; - private static final int ROW_ORDER_PRESERVED = styleable.GridLayout_rowOrderPreserved; - private static final int COLUMN_ORDER_PRESERVED = styleable.GridLayout_columnOrderPreserved; + private static final int ORIENTATION = R.styleable.GridLayout_orientation; + private static final int ROW_COUNT = R.styleable.GridLayout_rowCount; + private static final int COLUMN_COUNT = R.styleable.GridLayout_columnCount; + private static final int USE_DEFAULT_MARGINS = R.styleable.GridLayout_useDefaultMargins; + private static final int ALIGNMENT_MODE = R.styleable.GridLayout_alignmentMode; + private static final int ROW_ORDER_PRESERVED = R.styleable.GridLayout_rowOrderPreserved; + private static final int COLUMN_ORDER_PRESERVED = R.styleable.GridLayout_columnOrderPreserved; // Instance variables @@ -201,6 +199,7 @@ public class GridLayout extends ViewGroup { private boolean mUseDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS; private int mAlignmentMode = DEFAULT_ALIGNMENT_MODE; private int mDefaultGravity = Gravity.NO_GRAVITY; + private int mDefaultGap; // Constructors @@ -212,7 +211,8 @@ public class GridLayout extends ViewGroup { if (DEBUG) { setWillNotDraw(false); } - TypedArray a = context.obtainStyledAttributes(attrs, styleable.GridLayout); + mDefaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap); + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout); try { setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT)); setColumnCount(a.getInt(COLUMN_COUNT, DEFAULT_COUNT)); @@ -382,7 +382,7 @@ public class GridLayout extends ViewGroup { public void setUseDefaultMargins(boolean useDefaultMargins) { mUseDefaultMargins = useDefaultMargins; if (useDefaultMargins) { - int padding = DEFAULT_CONTAINER_PADDING; + int padding = mDefaultGap; setPadding(padding, padding, padding, padding); } requestLayout(); @@ -538,7 +538,7 @@ public class GridLayout extends ViewGroup { } private int getDefaultMargin(View c, boolean horizontal, boolean leading) { - return DEFAULT_MARGIN; + return mDefaultGap / 2; } private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) { @@ -787,6 +787,12 @@ public class GridLayout extends ViewGroup { invalidateStructure(); } + @Override + public void removeAllViews() { + super.removeAllViews(); + invalidateStructure(); + } + // Measurement private boolean isGone(View c) { @@ -1596,8 +1602,8 @@ public class GridLayout extends ViewGroup { * each cell group. The fundamental parameters associated with each cell group are * gathered into their vertical and horizontal components and stored * in the {@link #rowSpec} and {@link #columnSpec} layout parameters. - * {@link android.widget.GridLayout.Spec Specs} are immutable structures and may be shared between the layout - * parameters of different children. + * {@link android.widget.GridLayout.Spec Specs} are immutable structures + * and may be shared between the layout parameters of different children. * <p> * The row and column specs contain the leading and trailing indices along each axis * and together specify the four grid indices that delimit the cells of this cell group. @@ -1667,24 +1673,25 @@ public class GridLayout extends ViewGroup { // TypedArray indices - private static final int MARGIN = styleable.ViewGroup_MarginLayout_layout_margin; - private static final int LEFT_MARGIN = styleable.ViewGroup_MarginLayout_layout_marginLeft; - private static final int TOP_MARGIN = styleable.ViewGroup_MarginLayout_layout_marginTop; - private static final int RIGHT_MARGIN = styleable.ViewGroup_MarginLayout_layout_marginRight; + private static final int MARGIN = R.styleable.ViewGroup_MarginLayout_layout_margin; + private static final int LEFT_MARGIN = R.styleable.ViewGroup_MarginLayout_layout_marginLeft; + private static final int TOP_MARGIN = R.styleable.ViewGroup_MarginLayout_layout_marginTop; + private static final int RIGHT_MARGIN = + R.styleable.ViewGroup_MarginLayout_layout_marginRight; private static final int BOTTOM_MARGIN = - styleable.ViewGroup_MarginLayout_layout_marginBottom; + R.styleable.ViewGroup_MarginLayout_layout_marginBottom; - private static final int COLUMN = styleable.GridLayout_Layout_layout_column; - private static final int COLUMN_SPAN = styleable.GridLayout_Layout_layout_columnSpan; + private static final int COLUMN = R.styleable.GridLayout_Layout_layout_column; + private static final int COLUMN_SPAN = R.styleable.GridLayout_Layout_layout_columnSpan; private static final int COLUMN_FLEXIBILITY = - styleable.GridLayout_Layout_layout_columnFlexibility; + R.styleable.GridLayout_Layout_layout_columnFlexibility; - private static final int ROW = styleable.GridLayout_Layout_layout_row; - private static final int ROW_SPAN = styleable.GridLayout_Layout_layout_rowSpan; + private static final int ROW = R.styleable.GridLayout_Layout_layout_row; + private static final int ROW_SPAN = R.styleable.GridLayout_Layout_layout_rowSpan; private static final int ROW_FLEXIBILITY = - styleable.GridLayout_Layout_layout_rowFlexibility; + R.styleable.GridLayout_Layout_layout_rowFlexibility; - private static final int GRAVITY = styleable.GridLayout_Layout_layout_gravity; + private static final int GRAVITY = R.styleable.GridLayout_Layout_layout_gravity; // Instance variables @@ -1804,7 +1811,8 @@ public class GridLayout extends ViewGroup { // This method could be parametrized and moved into MarginLayout. private void reInitSuper(Context context, AttributeSet attrs) { - TypedArray a = context.obtainStyledAttributes(attrs, styleable.ViewGroup_MarginLayout); + TypedArray a = + context.obtainStyledAttributes(attrs, R.styleable.ViewGroup_MarginLayout); try { int margin = a.getDimensionPixelSize(MARGIN, DEFAULT_MARGIN); @@ -1840,7 +1848,7 @@ public class GridLayout extends ViewGroup { } private void init(Context context, AttributeSet attrs, int defaultGravity) { - TypedArray a = context.obtainStyledAttributes(attrs, styleable.GridLayout_Layout); + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout_Layout); try { int gravity = a.getInt(GRAVITY, defaultGravity); @@ -2301,10 +2309,10 @@ public class GridLayout extends ViewGroup { */ @Deprecated public static class Group extends Spec { - /** - * @deprecated Please replace with {@link #spec(int, int, Alignment)} - * @hide - */ + /** + * @deprecated Please replace with {@link #spec(int, int, Alignment)} + * @hide + */ @Deprecated public Group(int start, int size, Alignment alignment) { super(start, size, alignment, UNDEFINED_FLEXIBILITY); diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index f3bda439fbe8..b2d1a1e53573 100644 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -18,8 +18,6 @@ package android.widget; import static android.widget.SuggestionsAdapter.getColumnString; -import com.android.internal.R; - import android.app.PendingIntent; import android.app.SearchManager; import android.app.SearchableInfo; @@ -39,10 +37,14 @@ import android.net.Uri; import android.os.Bundle; import android.speech.RecognizerIntent; import android.text.Editable; +import android.text.Spannable; +import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.TextWatcher; +import android.text.style.ImageSpan; import android.util.AttributeSet; import android.util.Log; +import android.util.TypedValue; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -51,6 +53,8 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.TextView.OnEditorActionListener; +import com.android.internal.R; + import java.util.WeakHashMap; /** @@ -87,6 +91,8 @@ public class SearchView extends LinearLayout { private View mSearchEditFrame; private View mVoiceButton; private SearchAutoComplete mQueryTextView; + private View mDropDownAnchor; + private ImageView mSearchHintIcon; private boolean mSubmitButtonEnabled; private CharSequence mQueryHint; private boolean mQueryRefinement; @@ -195,6 +201,7 @@ public class SearchView extends LinearLayout { mSubmitButton = findViewById(R.id.search_go_btn); mCloseButton = (ImageView) findViewById(R.id.search_close_btn); mVoiceButton = findViewById(R.id.search_voice_btn); + mSearchHintIcon = (ImageView) findViewById(R.id.search_mag_icon); mSearchButton.setOnClickListener(mOnClickListener); mCloseButton.setOnClickListener(mOnClickListener); @@ -244,7 +251,20 @@ public class SearchView extends LinearLayout { mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mDropDownAnchor = findViewById(mQueryTextView.getDropDownAnchor()); + if (mDropDownAnchor != null) { + mDropDownAnchor.addOnLayoutChangeListener(new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + adjustDropDownSizeAndPosition(); + } + + }); + } + updateViewsVisibility(mIconifiedByDefault); + updateQueryHint(); } /** @@ -263,7 +283,7 @@ public class SearchView extends LinearLayout { } // Cache the voice search capability mVoiceButtonEnabled = hasVoiceSearch(); - updateViewsVisibility(mIconifiedByDefault); + updateViewsVisibility(isIconified()); } /** @@ -300,7 +320,6 @@ public class SearchView extends LinearLayout { mQueryTextView.clearFocus(); setImeVisibility(false); mClearingFocus = false; - updateViewsVisibility(mIconifiedByDefault); } /** @@ -555,6 +574,7 @@ public class SearchView extends LinearLayout { mSearchButton.setVisibility(visCollapsed); updateSubmitButton(hasText); mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE); + mSearchHintIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE); updateCloseButton(); updateVoiceButton(!hasText); updateSubmitArea(); @@ -822,9 +842,29 @@ public class SearchView extends LinearLayout { return result; } + private int getSearchIconId() { + TypedValue outValue = new TypedValue(); + getContext().getTheme().resolveAttribute(com.android.internal.R.attr.searchViewSearchIcon, + outValue, true); + return outValue.resourceId; + } + + private CharSequence getDecoratedHint(CharSequence hintText) { + // If the field is always expanded, then don't add the search icon to the hint + if (!mIconifiedByDefault) return hintText; + + SpannableStringBuilder ssb = new SpannableStringBuilder(" "); // for the icon + ssb.append(hintText); + Drawable searchIcon = getContext().getResources().getDrawable(getSearchIconId()); + int textSize = (int) (mQueryTextView.getTextSize() * 1.25); + searchIcon.setBounds(0, 0, textSize, textSize); + ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return ssb; + } + private void updateQueryHint() { if (mQueryHint != null) { - mQueryTextView.setHint(mQueryHint); + mQueryTextView.setHint(getDecoratedHint(mQueryHint)); } else if (mSearchable != null) { CharSequence hint = null; int hintId = mSearchable.getHintId(); @@ -832,8 +872,10 @@ public class SearchView extends LinearLayout { hint = getContext().getString(hintId); } if (hint != null) { - mQueryTextView.setHint(hint); + mQueryTextView.setHint(getDecoratedHint(hint)); } + } else { + mQueryTextView.setHint(getDecoratedHint("")); } } @@ -922,9 +964,13 @@ public class SearchView extends LinearLayout { CharSequence text = mQueryTextView.getText(); if (TextUtils.isEmpty(text)) { if (mIconifiedByDefault) { - // query field already empty, hide the keyboard and remove focus - clearFocus(); - setImeVisibility(false); + // If the app doesn't override the close behavior + if (mOnCloseListener == null || !mOnCloseListener.onClose()) { + // hide the keyboard and remove focus + clearFocus(); + // collapse the search field + updateViewsVisibility(true); + } } } else { mQueryTextView.setText(""); @@ -932,10 +978,6 @@ public class SearchView extends LinearLayout { setImeVisibility(true); } - if (mIconifiedByDefault && (mOnCloseListener == null || !mOnCloseListener.onClose())) { - updateViewsVisibility(mIconifiedByDefault); - setImeVisibility(false); - } } private void onSearchClicked() { @@ -975,6 +1017,28 @@ public class SearchView extends LinearLayout { updateFocusedState(mQueryTextView.hasFocus()); } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + } + + private void adjustDropDownSizeAndPosition() { + if (mDropDownAnchor.getWidth() > 1) { + Resources res = getContext().getResources(); + int anchorPadding = mSearchPlate.getPaddingLeft(); + Rect dropDownPadding = new Rect(); + int iconOffset = mIconifiedByDefault + ? res.getDimensionPixelSize(R.dimen.dropdownitem_icon_width) + + res.getDimensionPixelSize(R.dimen.dropdownitem_text_padding_left) + : 0; + mQueryTextView.getDropDownBackground().getPadding(dropDownPadding); + mQueryTextView.setDropDownHorizontalOffset(-(dropDownPadding.left + iconOffset) + + anchorPadding); + mQueryTextView.setDropDownWidth(mDropDownAnchor.getWidth() + dropDownPadding.left + + dropDownPadding.right + iconOffset - (anchorPadding)); + } + } + private boolean onItemClicked(int position, int actionKey, String actionMsg) { if (mOnSuggestionListener == null || !mOnSuggestionListener.onSuggestionClick(position)) { @@ -1393,5 +1457,32 @@ public class SearchView extends LinearLayout { public boolean enoughToFilter() { return mThreshold <= 0 || super.enoughToFilter(); } + + @Override + public boolean onKeyPreIme(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + // special case for the back key, we do not even try to send it + // to the drop down list but instead, consume it immediately + if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { + KeyEvent.DispatcherState state = getKeyDispatcherState(); + if (state != null) { + state.startTracking(event, this); + } + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + KeyEvent.DispatcherState state = getKeyDispatcherState(); + if (state != null) { + state.handleUpEvent(event); + } + if (event.isTracking() && !event.isCanceled()) { + mSearchView.clearFocus(); + mSearchView.setImeVisibility(false); + return true; + } + } + } + return super.onKeyPreIme(keyCode, event); + } + } } diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java index 2cfc0169a46e..9e32c9ab14bc 100644 --- a/core/java/android/widget/SuggestionsAdapter.java +++ b/core/java/android/widget/SuggestionsAdapter.java @@ -16,8 +16,6 @@ package android.widget; -import com.android.internal.R; - import android.app.SearchDialog; import android.app.SearchManager; import android.app.SearchableInfo; @@ -47,6 +45,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; +import com.android.internal.R; + import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -88,8 +88,8 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene private int mIconName2Col = INVALID_INDEX; private int mFlagsCol = INVALID_INDEX; - private final Runnable mStartSpinnerRunnable; - private final Runnable mStopSpinnerRunnable; + // private final Runnable mStartSpinnerRunnable; + // private final Runnable mStopSpinnerRunnable; /** * The amount of time we delay in the filter when the user presses the delete key. @@ -113,17 +113,18 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene mOutsideDrawablesCache = outsideDrawablesCache; - mStartSpinnerRunnable = new Runnable() { - public void run() { - // mSearchView.setWorking(true); // TODO: - } - }; - mStopSpinnerRunnable = new Runnable() { - public void run() { - // mSearchView.setWorking(false); // TODO: - } - }; + // mStartSpinnerRunnable = new Runnable() { + // public void run() { + // // mSearchView.setWorking(true); // TODO: + // } + // }; + // + // mStopSpinnerRunnable = new Runnable() { + // public void run() { + // // mSearchView.setWorking(false); // TODO: + // } + // }; // delay 500ms when deleting getFilter().setDelayer(new Filter.Delayer() { @@ -341,10 +342,10 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene } if (views.mIcon1 != null) { - setViewDrawable(views.mIcon1, getIcon1(cursor)); + setViewDrawable(views.mIcon1, getIcon1(cursor), View.INVISIBLE); } if (views.mIcon2 != null) { - setViewDrawable(views.mIcon2, getIcon2(cursor)); + setViewDrawable(views.mIcon2, getIcon2(cursor), View.GONE); } if (mQueryRefinement == REFINE_ALL || (mQueryRefinement == REFINE_BY_ENTRY @@ -414,13 +415,13 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene * Sets the drawable in an image view, makes sure the view is only visible if there * is a drawable. */ - private void setViewDrawable(ImageView v, Drawable drawable) { + private void setViewDrawable(ImageView v, Drawable drawable, int nullVisibility) { // Set the icon even if the drawable is null, since we need to clear any // previous icon. v.setImageDrawable(drawable); if (drawable == null) { - v.setVisibility(View.GONE); + v.setVisibility(nullVisibility); } else { v.setVisibility(View.VISIBLE); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 769f5e359275..66a07d31477c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -117,7 +117,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; import android.view.ViewConfiguration; import android.view.ViewDebug; import android.view.ViewGroup; @@ -3731,13 +3731,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener Handler h = getHandler(); if (h != null) { long eventTime = SystemClock.uptimeMillis(); - h.sendMessage(h.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME, + h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME, new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE | KeyEvent.FLAG_EDITOR_ACTION))); - h.sendMessage(h.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME, + h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME, new KeyEvent(SystemClock.uptimeMillis(), eventTime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java index 9e37c7bb1873..f3d891d11989 100644 --- a/core/java/android/widget/ZoomButtonsController.java +++ b/core/java/android/widget/ZoomButtonsController.java @@ -33,7 +33,7 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.View.OnClickListener; import android.view.WindowManager.LayoutParams; @@ -501,7 +501,7 @@ public class ZoomButtonsController implements View.OnTouchListener { } else { - ViewAncestor viewRoot = getOwnerViewAncestor(); + ViewRootImpl viewRoot = getOwnerViewRootImpl(); if (viewRoot != null) { viewRoot.dispatchKey(event); } @@ -526,15 +526,15 @@ public class ZoomButtonsController implements View.OnTouchListener { } } - private ViewAncestor getOwnerViewAncestor() { + private ViewRootImpl getOwnerViewRootImpl() { View rootViewOfOwner = mOwnerView.getRootView(); if (rootViewOfOwner == null) { return null; } ViewParent parentOfRootView = rootViewOfOwner.getParent(); - if (parentOfRootView instanceof ViewAncestor) { - return (ViewAncestor) parentOfRootView; + if (parentOfRootView instanceof ViewRootImpl) { + return (ViewRootImpl) parentOfRootView; } else { return null; } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 812f92badcfe..ce0299ca3d65 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -68,5 +68,5 @@ interface IInputMethodManager { boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype); boolean switchToLastInputMethod(in IBinder token); boolean setInputMethodEnabled(String id, boolean enabled); - boolean setAdditionalInputMethodSubtypes(in IBinder token, in InputMethodSubtype[] subtypes); + boolean setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); } diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java index 3070e3ebf194..fb33748ae2c8 100644 --- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java +++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java @@ -29,7 +29,7 @@ import android.util.Log; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.View; -import android.view.ViewAncestor; +import android.view.ViewRootImpl; import com.android.internal.R; public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { @@ -150,7 +150,7 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { KeyEvent event = events[i]; event = KeyEvent.changeFlags(event, event.getFlags() | KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE); - handler.sendMessage(handler.obtainMessage(ViewAncestor.DISPATCH_KEY, event)); + handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY, event)); } } } @@ -158,11 +158,11 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { public void sendDownUpKeyEvents(int keyEventCode) { long eventTime = SystemClock.uptimeMillis(); Handler handler = mTargetView.getHandler(); - handler.sendMessage(handler.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME, + handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME, new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE))); - handler.sendMessage(handler.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME, + handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME, new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP, keyEventCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE))); diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 06dc083695a1..514e59d8f29f 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -139,6 +139,7 @@ LOCAL_SRC_FILES:= \ android_bluetooth_common.cpp \ android_bluetooth_BluetoothAudioGateway.cpp \ android_bluetooth_BluetoothSocket.cpp \ + android_bluetooth_c.c \ android_server_BluetoothService.cpp \ android_server_BluetoothEventLoop.cpp \ android_server_BluetoothA2dpService.cpp \ diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index 6a13876031a9..30fe298207a2 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -323,9 +323,7 @@ size_t TextLayoutCacheValue::getSize() { void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, - size_t contextCount, int dirFlags) { - bool isRTL = dirFlags & 0x1; - + size_t contextCount, bool isRTL) { font->klass = &harfbuzzSkiaClass; font->userData = 0; // The values which harfbuzzSkiaClass returns are already scaled to @@ -374,10 +372,10 @@ void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec void TextLayoutCacheValue::shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, - size_t contextCount, int dirFlags) { + size_t contextCount, bool isRTL) { // Setup Harfbuzz Shaper setupShaperItem(shaperItem, font, fontData, paint, chars, start, count, - contextCount, dirFlags); + contextCount, isRTL); // Shape resetGlyphArrays(shaperItem); @@ -430,7 +428,7 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d", forceLTR, forceRTL); #endif - computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, + computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, forceRTL, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount); if (forceRTL && *outGlyphsCount > 1) { @@ -451,10 +449,15 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d", dirFlags, rc, paraDir); #endif if (rc == 1 || !U_SUCCESS(status)) { + bool isRTL = (paraDir == 1); +#if DEBUG_GLYPHS + LOGD("computeValuesWithHarfbuzz -- processing SINGLE run " + "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL); +#endif computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, - dirFlags, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount); + isRTL, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount); - if (dirFlags == 1 && *outGlyphsCount > 1) { + if (isRTL && *outGlyphsCount > 1) { reverseGlyphArray(*outGlyphs, *outGlyphsCount); } } else { @@ -485,14 +488,14 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar lengthRun = endRun - startRun; - int newFlags = (runDir == UBIDI_RTL) ? kDirection_RTL : kDirection_LTR; + bool isRTL = (runDir == UBIDI_RTL); jfloat runTotalAdvance = 0; #if DEBUG_GLYPHS - LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d newFlags=%d", - startRun, lengthRun, newFlags); + LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d", + startRun, lengthRun, isRTL); #endif computeRunValuesWithHarfbuzz(paint, chars, startRun, - lengthRun, contextCount, newFlags, + lengthRun, contextCount, isRTL, outAdvances, &runTotalAdvance, &runGlyphs, &runGlyphsCount); @@ -506,7 +509,7 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar LOGD(" -- glyphs[%d]=%d", j, runGlyphs[j]); } #endif - glyphRuns.push(GlyphRun(runGlyphs, runGlyphsCount, newFlags)); + glyphRuns.push(GlyphRun(runGlyphs, runGlyphsCount, isRTL)); } *outGlyphs = new jchar[*outGlyphsCount]; @@ -528,13 +531,15 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar ubidi_close(bidi); } else { // Cannot run BiDi, just consider one Run + bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL); #if DEBUG_GLYPHS - LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering only one Run"); + LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run " + "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL); #endif - computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, + computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, isRTL, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount); - if (dirFlags == 1 && *outGlyphsCount > 1) { + if (isRTL && *outGlyphsCount > 1) { reverseGlyphArray(*outGlyphs, *outGlyphsCount); } } @@ -545,17 +550,15 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar } void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, - size_t start, size_t count, size_t contextCount, int dirFlags, + size_t start, size_t count, size_t contextCount, bool isRTL, jfloat* outAdvances, jfloat* outTotalAdvance, jchar** outGlyphs, size_t* outGlyphsCount) { - bool isRTL = dirFlags & 0x1; - HB_ShaperItem shaperItem; HB_FontRec font; FontData fontData; shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count, - contextCount, dirFlags); + contextCount, isRTL); #if DEBUG_GLYPHS LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs, diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index 690caacd6c65..10dee87e09d8 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -128,11 +128,11 @@ public: static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, - int dirFlags); + bool isRTL); static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, - int dirFlags); + bool isRTL); static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, @@ -179,7 +179,7 @@ private: static void resetGlyphArrays(HB_ShaperItem* shaperItem); static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start, - size_t count, size_t contextCount, int dirFlags, + size_t count, size_t contextCount, bool isRTL, jfloat* outAdvances, jfloat* outTotalAdvance, jchar** outGlyphs, size_t* outGlyphsCount); }; // TextLayoutCacheValue diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp index cb742a3d5b1c..29c9c2db9734 100755 --- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp +++ b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "BluetoothAudioGateway.cpp" #include "android_bluetooth_common.h" +#include "android_bluetooth_c.h" #include "android_runtime/AndroidRuntime.h" #include "JNIHelp.h" #include "jni.h" @@ -491,7 +492,8 @@ static int setup_listening_socket(int dev, int channel) { } laddr.rc_family = AF_BLUETOOTH; - memcpy(&laddr.rc_bdaddr, BDADDR_ANY, sizeof(bdaddr_t)); + bdaddr_t any = android_bluetooth_bdaddr_any(); + memcpy(&laddr.rc_bdaddr, &any, sizeof(bdaddr_t)); laddr.rc_channel = channel; if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp index d09c4e9f6132..4c84324af266 100644 --- a/core/jni/android_bluetooth_BluetoothSocket.cpp +++ b/core/jni/android_bluetooth_BluetoothSocket.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "BluetoothSocket.cpp" #include "android_bluetooth_common.h" +#include "android_bluetooth_c.h" #include "android_runtime/AndroidRuntime.h" #include "JNIHelp.h" #include "utils/Log.h" @@ -245,7 +246,7 @@ static int bindListenNative(JNIEnv *env, jobject obj) { jint type; socklen_t addr_sz; struct sockaddr *addr; - bdaddr_t bdaddr = *BDADDR_ANY; + bdaddr_t bdaddr = android_bluetooth_bdaddr_any(); struct asocket *s = get_socketData(env, obj); if (!s) diff --git a/core/jni/android_bluetooth_c.c b/core/jni/android_bluetooth_c.c new file mode 100755 index 000000000000..b4c672711594 --- /dev/null +++ b/core/jni/android_bluetooth_c.c @@ -0,0 +1,31 @@ +/* +** Copyright 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. +*/ + +#ifdef HAVE_BLUETOOTH + +#include "android_bluetooth_c.h" + +/* + * A C helper for creating a bdaddr_t object with the value BDADDR_ANY. + * We have to do this in C because the macro BDADDR_ANY in bluetooth.h + * is not valid C++ code. + */ +bdaddr_t android_bluetooth_bdaddr_any(void) +{ + bdaddr_t any = *BDADDR_ANY; + return any; +} +#endif diff --git a/core/jni/android_bluetooth_c.h b/core/jni/android_bluetooth_c.h new file mode 100644 index 000000000000..e89024469475 --- /dev/null +++ b/core/jni/android_bluetooth_c.h @@ -0,0 +1,39 @@ +/* +** Copyright 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. +*/ + +#ifndef ANDROID_BLUETOOTH_C_H +#define ANDROID_BLUETOOTH_C_H +#ifdef HAVE_BLUETOOTH + +#include <bluetooth/bluetooth.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * A C helper for creating a bdaddr_t object with the value BDADDR_ANY. + * We have to do this in C because the macro BDADDR_ANY in bluetooth.h + * is not valid C++ code. + */ +bdaddr_t android_bluetooth_bdaddr_any(void); + +#ifdef __cplusplus +} +#endif + +#endif /*HAVE_BLUETOOTH*/ +#endif /*ANDROID_BLUETOOTH_C_H*/ diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 681f43f32b41..b0c2f2c2da07 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -127,6 +127,13 @@ static void android_view_GLES20Canvas_disableVsync(JNIEnv* env, jobject clazz) { } } +static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz, + Caches::FlushMode mode) { + if (Caches::hasInstance()) { + Caches::getInstance().flush(mode); + } +} + // ---------------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------------- @@ -735,6 +742,7 @@ static JNINativeMethod gMethods[] = { { "nIsBackBufferPreserved", "()Z", (void*) android_view_GLES20Canvas_isBackBufferPreserved }, { "nPreserveBackBuffer", "()Z", (void*) android_view_GLES20Canvas_preserveBackBuffer }, { "nDisableVsync", "()V", (void*) android_view_GLES20Canvas_disableVsync }, + { "nFlushCaches", "(I)V", (void*) android_view_GLES20Canvas_flushCaches }, { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer }, { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer }, @@ -859,10 +867,8 @@ int register_android_view_GLES20Canvas(JNIEnv* env) { const char* const kActivityThreadPathName = "android/app/ActivityThread"; -int register_android_app_ActivityThread(JNIEnv* env) -{ - return AndroidRuntime::registerNativeMethods( - env, kActivityThreadPathName, +int register_android_app_ActivityThread(JNIEnv* env) { + return AndroidRuntime::registerNativeMethods(env, kActivityThreadPathName, gActivityThreadMethods, NELEM(gActivityThreadMethods)); } diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp index b046b2360d55..9484c6b5798d 100644 --- a/core/jni/android_view_TextureView.cpp +++ b/core/jni/android_view_TextureView.cpp @@ -19,11 +19,48 @@ #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_graphics_SurfaceTexture.h> +#include <ui/Region.h> +#include <ui/Rect.h> + #include <gui/SurfaceTexture.h> +#include <gui/SurfaceTextureClient.h> + +#include <SkBitmap.h> +#include <SkCanvas.h> namespace android { // ---------------------------------------------------------------------------- +// JNI Glue +// ---------------------------------------------------------------------------- + +static struct { + jmethodID set; + jfieldID left; + jfieldID top; + jfieldID right; + jfieldID bottom; +} gRectClassInfo; + +static struct { + jfieldID nativeCanvas; + jfieldID surfaceFormat; +} gCanvasClassInfo; + +static struct { + jfieldID nativeWindow; +} gTextureViewClassInfo; + +#define GET_INT(object, field) \ + env->GetIntField(object, field) + +#define SET_INT(object, field, value) \ + env->SetIntField(object, field, value) + +#define INVOKEV(object, method, ...) \ + env->CallVoidMethod(object, method, __VA_ARGS__) + +// ---------------------------------------------------------------------------- // Native layer // ---------------------------------------------------------------------------- @@ -34,6 +71,118 @@ static void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject, surfaceTexture->setDefaultBufferSize(width, height); } +static inline SkBitmap::Config convertPixelFormat(int32_t format) { + switch (format) { + case WINDOW_FORMAT_RGBA_8888: + return SkBitmap::kARGB_8888_Config; + case WINDOW_FORMAT_RGBX_8888: + return SkBitmap::kARGB_8888_Config; + case WINDOW_FORMAT_RGB_565: + return SkBitmap::kRGB_565_Config; + default: + return SkBitmap::kNo_Config; + } +} + +/** + * This is a private API, and this implementation is also provided in the NDK. + * However, the NDK links against android_runtime, which means that using the + * NDK implementation would create a circular dependency between the libraries. + */ +static int32_t native_window_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, + Rect* inOutDirtyBounds) { + return window->perform(window, NATIVE_WINDOW_LOCK, outBuffer, inOutDirtyBounds); +} + +static int32_t native_window_unlockAndPost(ANativeWindow* window) { + return window->perform(window, NATIVE_WINDOW_UNLOCK_AND_POST); +} + +static void android_view_TextureView_createNativeWindow(JNIEnv* env, jobject textureView, + jobject surface) { + + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface)); + sp<ANativeWindow> window = new SurfaceTextureClient(surfaceTexture); + + window->incStrong(0); + SET_INT(textureView, gTextureViewClassInfo.nativeWindow, jint(window.get())); +} + +static void android_view_TextureView_destroyNativeWindow(JNIEnv* env, jobject textureView) { + + ANativeWindow* nativeWindow = (ANativeWindow*) + GET_INT(textureView, gTextureViewClassInfo.nativeWindow); + + if (nativeWindow) { + sp<ANativeWindow> window(nativeWindow); + window->decStrong(0); + SET_INT(textureView, gTextureViewClassInfo.nativeWindow, 0); + } +} + +static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject, + jint nativeWindow, jobject canvas, jobject dirtyRect) { + + if (!nativeWindow) { + return; + } + + ANativeWindow_Buffer buffer; + + Rect rect; + if (dirtyRect) { + rect.left = GET_INT(dirtyRect, gRectClassInfo.left); + rect.top = GET_INT(dirtyRect, gRectClassInfo.top); + rect.right = GET_INT(dirtyRect, gRectClassInfo.right); + rect.bottom = GET_INT(dirtyRect, gRectClassInfo.bottom); + } else { + rect.set(Rect(0x3FFF, 0x3FFF)); + } + + sp<ANativeWindow> window((ANativeWindow*) nativeWindow); + native_window_lock(window.get(), &buffer, &rect); + + ssize_t bytesCount = buffer.stride * bytesPerPixel(buffer.format); + + SkBitmap bitmap; + bitmap.setConfig(convertPixelFormat(buffer.format), buffer.width, buffer.height, bytesCount); + + if (buffer.format == WINDOW_FORMAT_RGBX_8888) { + bitmap.setIsOpaque(true); + } + + if (buffer.width > 0 && buffer.height > 0) { + bitmap.setPixels(buffer.bits); + } else { + bitmap.setPixels(NULL); + } + + SET_INT(canvas, gCanvasClassInfo.surfaceFormat, buffer.format); + SkCanvas* nativeCanvas = (SkCanvas*) GET_INT(canvas, gCanvasClassInfo.nativeCanvas); + nativeCanvas->setBitmapDevice(bitmap); + + SkRect clipRect; + clipRect.set(rect.left, rect.top, rect.right, rect.bottom); + nativeCanvas->clipRect(clipRect); + + if (dirtyRect) { + INVOKEV(dirtyRect, gRectClassInfo.set, + int(rect.left), int(rect.top), int(rect.right), int(rect.bottom)); + } +} + +static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject, + jint nativeWindow, jobject canvas) { + + SkCanvas* nativeCanvas = (SkCanvas*) GET_INT(canvas, gCanvasClassInfo.nativeCanvas); + nativeCanvas->setBitmapDevice(SkBitmap()); + + if (nativeWindow) { + sp<ANativeWindow> window((ANativeWindow*) nativeWindow); + native_window_unlockAndPost(window.get()); + } +} + // ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- @@ -42,10 +191,47 @@ const char* const kClassPathName = "android/view/TextureView"; static JNINativeMethod gMethods[] = { { "nSetDefaultBufferSize", "(Landroid/graphics/SurfaceTexture;II)V", - (void*) android_view_TextureView_setDefaultBufferSize } + (void*) android_view_TextureView_setDefaultBufferSize }, + + { "nCreateNativeWindow", "(Landroid/graphics/SurfaceTexture;)V", + (void*) android_view_TextureView_createNativeWindow }, + { "nDestroyNativeWindow", "()V", + (void*) android_view_TextureView_destroyNativeWindow }, + + { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V", + (void*) android_view_TextureView_lockCanvas }, + { "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V", + (void*) android_view_TextureView_unlockCanvasAndPost }, }; +#define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(!var, "Unable to find class " className); + +#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ + var = env->GetMethodID(clazz, methodName, methodDescriptor); \ + LOG_FATAL_IF(!var, "Unable to find method " methodName); + +#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ + var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ + LOG_FATAL_IF(!var, "Unable to find field" fieldName); + int register_android_view_TextureView(JNIEnv* env) { + jclass clazz; + FIND_CLASS(clazz, "android/graphics/Rect"); + GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V"); + GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I"); + GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I"); + GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I"); + GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I"); + + FIND_CLASS(clazz, "android/graphics/Canvas"); + GET_FIELD_ID(gCanvasClassInfo.nativeCanvas, clazz, "mNativeCanvas", "I"); + GET_FIELD_ID(gCanvasClassInfo.surfaceFormat, clazz, "mSurfaceFormat", "I"); + + FIND_CLASS(clazz, "android/view/TextureView"); + GET_FIELD_ID(gTextureViewClassInfo.nativeWindow, clazz, "mNativeWindow", "I"); + return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); } diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml index 790ac6b09601..f6b5b5372fe1 100644 --- a/core/res/res/layout/search_bar.xml +++ b/core/res/res/layout/search_bar.xml @@ -66,7 +66,6 @@ android:layout_height="wrap_content" android:layout_weight="1" android:maxWidth="600dip" - android:iconifiedByDefault="false" android:layout_gravity="center_vertical" /> diff --git a/core/res/res/layout/search_dropdown_item_icons_2line.xml b/core/res/res/layout/search_dropdown_item_icons_2line.xml index 53906f94e025..acef2cc71ef0 100644 --- a/core/res/res/layout/search_dropdown_item_icons_2line.xml +++ b/core/res/res/layout/search_dropdown_item_icons_2line.xml @@ -19,21 +19,21 @@ --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:paddingLeft="4dip" - android:paddingRight="2dip" + android:paddingLeft="@dimen/dropdownitem_text_padding_left" + android:paddingRight="4dip" android:layout_width="match_parent" android:layout_height="?android:attr/searchResultListItemHeight" > <!-- Icons come first in the layout, since their placement doesn't depend on the placement of the text views. --> <ImageView android:id="@android:id/icon1" - android:layout_width="48dip" + android:layout_width="@dimen/dropdownitem_icon_width" android:layout_height="48dip" android:scaleType="centerInside" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" - android:visibility="gone" /> + android:visibility="invisible" /> <ImageView android:id="@+id/edit_query" android:layout_width="48dip" diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml index fee27ebe67c3..6b70d8dc42f7 100644 --- a/core/res/res/layout/search_view.xml +++ b/core/res/res/layout/search_view.xml @@ -22,6 +22,8 @@ android:id="@+id/search_bar" android:layout_width="match_parent" android:layout_height="match_parent" + android:paddingLeft="8dip" + android:paddingRight="8dip" android:orientation="horizontal" > @@ -30,7 +32,7 @@ android:id="@+id/search_badge" android:layout_width="wrap_content" android:layout_height="match_parent" - android:layout_gravity="center_vertical" + android:gravity="center_vertical" android:layout_marginBottom="2dip" android:drawablePadding="0dip" android:textAppearance="?android:attr/textAppearanceMedium" @@ -54,12 +56,21 @@ android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_vertical" - android:layout_marginLeft="8dip" - android:layout_marginRight="8dip" android:layout_marginTop="4dip" android:layout_marginBottom="4dip" android:orientation="horizontal"> + <ImageView + android:id="@+id/search_mag_icon" + android:layout_width="@dimen/dropdownitem_icon_width" + android:layout_height="wrap_content" + android:scaleType="centerInside" + android:layout_marginLeft="@dimen/dropdownitem_text_padding_left" + android:layout_gravity="center_vertical" + android:src="?android:attr/searchViewSearchIcon" + android:visibility="gone" + /> + <!-- Inner layout contains the app icon, button(s) and EditText --> <LinearLayout android:id="@+id/search_plate" @@ -70,14 +81,6 @@ android:orientation="horizontal" android:background="?android:attr/searchViewTextField"> - <ImageView - android:id="@+id/search_app_icon" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="center_vertical" - android:src="?android:attr/searchViewSearchIcon" - /> - <view class="android.widget.SearchView$SearchAutoComplete" android:id="@+id/search_src_text" android:layout_height="36dip" @@ -85,8 +88,8 @@ android:layout_weight="1" android:minWidth="@dimen/search_view_text_min_width" android:layout_gravity="bottom" - android:paddingLeft="8dip" - android:paddingRight="6dip" + android:paddingLeft="@dimen/dropdownitem_text_padding_left" + android:paddingRight="@dimen/dropdownitem_text_padding_right" android:singleLine="true" android:ellipsize="end" android:background="@null" @@ -100,7 +103,7 @@ <ImageView android:id="@+id/search_close_btn" - android:layout_width="wrap_content" + android:layout_width="@dimen/dropdownitem_icon_width" android:layout_height="match_parent" android:paddingLeft="8dip" android:paddingRight="8dip" @@ -131,7 +134,7 @@ android:visibility="gone" android:focusable="true" /> - + <ImageView android:id="@+id/search_voice_btn" android:layout_width="wrap_content" diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index abc56eccbfb9..2ba4e668fe22 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -138,4 +138,16 @@ <!-- Minimum popup width for selecting an activity in ActivityChooserDialog/ActivityChooserView. --> <dimen name="activity_chooser_popup_min_width">200dip</dimen> + <!-- The default gap between components in a layout. --> + <dimen name="default_gap">16dip</dimen> + + <!-- Text padding for dropdown items --> + <dimen name="dropdownitem_text_padding_left">6dip</dimen> + + <!-- Text padding for dropdown items --> + <dimen name="dropdownitem_text_padding_right">6dip</dimen> + + <!-- Width of the icon in a dropdown list --> + <dimen name="dropdownitem_icon_width">48dip</dimen> + </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 6dedc83eb087..f46462399452 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1787,6 +1787,11 @@ <public type="attr" name="colorActivatedHighlight" /> <public type="attr" name="colorMultiSelectHighlight" /> + <public type="attr" name="drawableStart" /> + <public type="attr" name="drawableEnd" /> + + <public type="attr" name="actionModeStyle" /> + <public type="style" name="TextAppearance.SuggestionHighlight" /> <public type="style" name="Theme.Holo.SplitActionBarWhenNarrow" /> <public type="style" name="Theme.Holo.Light.SplitActionBarWhenNarrow" /> @@ -1826,7 +1831,4 @@ <public type="color" name="holo_purple" /> <public type="color" name="holo_blue_bright" /> - <public type="attr" name="drawableStart" /> - <public type="attr" name="drawableEnd" /> - </resources> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 5b5e7c350f38..d647467a59fc 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -563,8 +563,8 @@ <style name="Widget.DropDownItem"> <item name="android:textAppearance">@style/TextAppearance.Widget.DropDownItem</item> - <item name="android:paddingLeft">6dip</item> - <item name="android:paddingRight">6dip</item> + <item name="android:paddingLeft">@dimen/dropdownitem_text_padding_left</item> + <item name="android:paddingRight">@dimen/dropdownitem_text_padding_right</item> <item name="android:gravity">center_vertical</item> </style> diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h index 5ec469e9b841..cfe2aa13b68b 100644 --- a/include/gui/SurfaceTextureClient.h +++ b/include/gui/SurfaceTextureClient.h @@ -21,6 +21,7 @@ #include <gui/SurfaceTexture.h> #include <ui/egl/android_natives.h> +#include <ui/Region.h> #include <utils/RefBase.h> #include <utils/threads.h> @@ -37,29 +38,24 @@ public: sp<ISurfaceTexture> getISurfaceTexture() const; -private: - friend class Surface; +protected: + SurfaceTextureClient(); + void setISurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture); +private: // can't be copied SurfaceTextureClient& operator = (const SurfaceTextureClient& rhs); SurfaceTextureClient(const SurfaceTextureClient& rhs); + void init(); // ANativeWindow hooks - static int cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); - static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer); - static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); - static int perform(ANativeWindow* window, int operation, ...); - static int query(const ANativeWindow* window, int what, int* value); - static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); - static int setSwapInterval(ANativeWindow* window, int interval); - - int cancelBuffer(ANativeWindowBuffer* buffer); - int dequeueBuffer(ANativeWindowBuffer** buffer); - int lockBuffer(ANativeWindowBuffer* buffer); - int perform(int operation, va_list args); - int query(int what, int* value) const; - int queueBuffer(ANativeWindowBuffer* buffer); - int setSwapInterval(int interval); + static int hook_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); + static int hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer); + static int hook_lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); + static int hook_perform(ANativeWindow* window, int operation, ...); + static int hook_query(const ANativeWindow* window, int what, int* value); + static int hook_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); + static int hook_setSwapInterval(ANativeWindow* window, int interval); int dispatchConnect(va_list args); int dispatchDisconnect(va_list args); @@ -71,26 +67,38 @@ private: int dispatchSetBuffersTimestamp(va_list args); int dispatchSetCrop(va_list args); int dispatchSetUsage(va_list args); - - int connect(int api); - int disconnect(int api); - int setBufferCount(int bufferCount); - int setBuffersDimensions(int w, int h); - int setBuffersFormat(int format); - int setBuffersTransform(int transform); - int setBuffersTimestamp(int64_t timestamp); - int setCrop(Rect const* rect); - int setUsage(uint32_t reqUsage); - - void freeAllBuffers(); - int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; - - int getConnectedApi() const; + int dispatchLock(va_list args); + int dispatchUnlockAndPost(va_list args); + +protected: + virtual int cancelBuffer(ANativeWindowBuffer* buffer); + virtual int dequeueBuffer(ANativeWindowBuffer** buffer); + virtual int lockBuffer(ANativeWindowBuffer* buffer); + virtual int perform(int operation, va_list args); + virtual int query(int what, int* value) const; + virtual int queueBuffer(ANativeWindowBuffer* buffer); + virtual int setSwapInterval(int interval); + + virtual int connect(int api); + virtual int disconnect(int api); + virtual int setBufferCount(int bufferCount); + virtual int setBuffersDimensions(int w, int h); + virtual int setBuffersFormat(int format); + virtual int setBuffersTransform(int transform); + virtual int setBuffersTimestamp(int64_t timestamp); + virtual int setCrop(Rect const* rect); + virtual int setUsage(uint32_t reqUsage); + virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); + virtual int unlockAndPost(); enum { MIN_UNDEQUEUED_BUFFERS = SurfaceTexture::MIN_UNDEQUEUED_BUFFERS }; enum { NUM_BUFFER_SLOTS = SurfaceTexture::NUM_BUFFER_SLOTS }; enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; +private: + void freeAllBuffers(); + int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; + // mSurfaceTexture is the interface to the surface texture server. All // operations on the surface texture client ultimately translate into // interactions with the server using this interface. @@ -145,6 +153,12 @@ private: // variables of SurfaceTexture objects. It must be locked whenever the // member variables are accessed. mutable Mutex mMutex; + + // must be used from the lock/unlock thread + sp<GraphicBuffer> mLockedBuffer; + sp<GraphicBuffer> mPostedBuffer; + mutable Region mOldDirtyRegion; + bool mConnectedToCpu; }; }; // namespace android diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index ea5a9d3c9939..1136f6c0a917 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -25,6 +25,8 @@ #include <utils/KeyedVector.h> #include <utils/String8.h> +class ANativeWindow; + namespace android { class Surface; @@ -196,6 +198,8 @@ private: status_t prepareAsync_l(); status_t getDuration_l(int *msec); status_t setDataSource(const sp<IMediaPlayer>& player); + void disconnectNativeWindow(); + status_t reset_l(); sp<IMediaPlayer> mPlayer; thread_id_t mLockThreadId; @@ -218,6 +222,8 @@ private: int mVideoHeight; int mAudioSessionId; float mSendLevel; + sp<ANativeWindow> mConnectedWindow; + sp<IBinder> mConnectedWindowBinder; }; }; // namespace android diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h index dc2a84562082..c2a494de41b6 100644 --- a/include/surfaceflinger/Surface.h +++ b/include/surfaceflinger/Surface.h @@ -28,6 +28,8 @@ #include <ui/Region.h> #include <ui/egl/android_natives.h> +#include <gui/SurfaceTextureClient.h> + #include <surfaceflinger/ISurface.h> #include <surfaceflinger/ISurfaceComposerClient.h> @@ -37,14 +39,9 @@ namespace android { // --------------------------------------------------------------------------- -class GraphicBuffer; -class GraphicBufferMapper; -class IOMX; class ISurfaceTexture; -class Rect; class Surface; class SurfaceComposerClient; -class SurfaceTextureClient; // --------------------------------------------------------------------------- @@ -129,8 +126,7 @@ private: // --------------------------------------------------------------------------- -class Surface - : public EGLNativeBase<ANativeWindow, Surface, RefBase> +class Surface : public SurfaceTextureClient { public: struct SurfaceInfo { @@ -158,32 +154,14 @@ public: sp<ISurfaceTexture> getSurfaceTexture(); // the lock/unlock APIs must be used from the same thread - status_t lock(SurfaceInfo* info, bool blocking = true); - status_t lock(SurfaceInfo* info, Region* dirty, bool blocking = true); + status_t lock(SurfaceInfo* info, Region* dirty = NULL); status_t unlockAndPost(); sp<IBinder> asBinder() const; private: - /* - * Android frameworks friends - * (eventually this should go away and be replaced by proper APIs) - */ - // camera and camcorder need access to the ISurface binder interface for preview - friend class CameraService; - friend class MediaRecorder; - // MediaPlayer needs access to ISurface for display - friend class MediaPlayer; - friend class IOMX; - friend class SoftwareRenderer; // this is just to be able to write some unit tests friend class Test; - // videoEditor preview classes - friend class VideoEditorPreviewController; - friend class PreviewRenderer; - -private: - friend class SurfaceComposerClient; friend class SurfaceControl; // can't be copied @@ -194,62 +172,27 @@ private: Surface(const Parcel& data, const sp<IBinder>& ref); ~Surface(); - - /* - * ANativeWindow hooks - */ - static int setSwapInterval(ANativeWindow* window, int interval); - static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer); - static int cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); - static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); - static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer); - static int query(const ANativeWindow* window, int what, int* value); - static int perform(ANativeWindow* window, int operation, ...); - - int setSwapInterval(int interval); - int dequeueBuffer(ANativeWindowBuffer** buffer); - int lockBuffer(ANativeWindowBuffer* buffer); - int queueBuffer(ANativeWindowBuffer* buffer); - int cancelBuffer(ANativeWindowBuffer* buffer); - int query(int what, int* value) const; - int perform(int operation, va_list args); - /* * private stuff... */ void init(); status_t validate(bool inCancelBuffer = false) const; - int getConnectedApi() const; - static void cleanCachedSurfacesLocked(); + virtual int query(int what, int* value) const; + // constants status_t mInitCheck; sp<ISurface> mSurface; - sp<SurfaceTextureClient> mSurfaceTextureClient; uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; - - // protected by mSurfaceLock. These are also used from lock/unlock - // but in that case, they must be called form the same thread. - mutable Region mDirtyRegion; - - // must be used from the lock/unlock thread - sp<GraphicBuffer> mLockedBuffer; - sp<GraphicBuffer> mPostedBuffer; - mutable Region mOldDirtyRegion; - bool mReserved; // query() must be called from dequeueBuffer() thread uint32_t mWidth; uint32_t mHeight; - // Inherently thread-safe - mutable Mutex mSurfaceLock; - mutable Mutex mApiLock; - // A cache of Surface objects that have been deserialized into this process. static Mutex sCachedSurfacesLock; static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces; diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 9185e1e9930c..dabe643f270c 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -46,59 +46,6 @@ namespace android { -// ---------------------------------------------------------------------- - -static status_t copyBlt( - const sp<GraphicBuffer>& dst, - const sp<GraphicBuffer>& src, - const Region& reg) -{ - // src and dst with, height and format must be identical. no verification - // is done here. - status_t err; - uint8_t const * src_bits = NULL; - err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); - LOGE_IF(err, "error locking src buffer %s", strerror(-err)); - - uint8_t* dst_bits = NULL; - err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); - LOGE_IF(err, "error locking dst buffer %s", strerror(-err)); - - Region::const_iterator head(reg.begin()); - Region::const_iterator tail(reg.end()); - if (head != tail && src_bits && dst_bits) { - const size_t bpp = bytesPerPixel(src->format); - const size_t dbpr = dst->stride * bpp; - const size_t sbpr = src->stride * bpp; - - while (head != tail) { - const Rect& r(*head++); - ssize_t h = r.height(); - if (h <= 0) continue; - size_t size = r.width() * bpp; - uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; - uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; - if (dbpr==sbpr && size==sbpr) { - size *= h; - h = 1; - } - do { - memcpy(d, s, size); - d += dbpr; - s += sbpr; - } while (--h > 0); - } - } - - if (src_bits) - src->unlock(); - - if (dst_bits) - dst->unlock(); - - return err; -} - // ============================================================================ // SurfaceControl // ============================================================================ @@ -277,7 +224,8 @@ sp<Surface> SurfaceControl::getSurface() const // --------------------------------------------------------------------------- Surface::Surface(const sp<SurfaceControl>& surface) - : mInitCheck(NO_INIT), + : SurfaceTextureClient(), + mInitCheck(NO_INIT), mSurface(surface->mSurface), mIdentity(surface->mIdentity), mFormat(surface->mFormat), mFlags(surface->mFlags), @@ -287,7 +235,8 @@ Surface::Surface(const sp<SurfaceControl>& surface) } Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref) - : mInitCheck(NO_INIT) + : SurfaceTextureClient(), + mInitCheck(NO_INIT) { mSurface = interface_cast<ISurface>(ref); mIdentity = parcel.readInt32(); @@ -363,36 +312,21 @@ void Surface::cleanCachedSurfacesLocked() { void Surface::init() { - ANativeWindow::setSwapInterval = setSwapInterval; - ANativeWindow::dequeueBuffer = dequeueBuffer; - ANativeWindow::cancelBuffer = cancelBuffer; - ANativeWindow::lockBuffer = lockBuffer; - ANativeWindow::queueBuffer = queueBuffer; - ANativeWindow::query = query; - ANativeWindow::perform = perform; - if (mSurface != NULL) { sp<ISurfaceTexture> surfaceTexture(mSurface->getSurfaceTexture()); LOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface"); if (surfaceTexture != NULL) { - mSurfaceTextureClient = new SurfaceTextureClient(surfaceTexture); - mSurfaceTextureClient->setUsage(GraphicBuffer::USAGE_HW_RENDER); + setISurfaceTexture(surfaceTexture); + setUsage(GraphicBuffer::USAGE_HW_RENDER); } DisplayInfo dinfo; SurfaceComposerClient::getDisplayInfo(0, &dinfo); const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi; const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi; - - const_cast<int&>(ANativeWindow::minSwapInterval) = - mSurfaceTextureClient->minSwapInterval; - - const_cast<int&>(ANativeWindow::maxSwapInterval) = - mSurfaceTextureClient->maxSwapInterval; - const_cast<uint32_t&>(ANativeWindow::flags) = 0; - if (mSurfaceTextureClient != 0) { + if (surfaceTexture != NULL) { mInitCheck = NO_ERROR; } } @@ -402,7 +336,6 @@ Surface::~Surface() { // clear all references and trigger an IPC now, to make sure things // happen without delay, since these resources are quite heavy. - mSurfaceTextureClient.clear(); mSurface.clear(); IPCThreadState::self()->flushCommands(); } @@ -431,77 +364,6 @@ sp<IBinder> Surface::asBinder() const { // ---------------------------------------------------------------------------- -int Surface::setSwapInterval(ANativeWindow* window, int interval) { - Surface* self = getSelf(window); - return self->setSwapInterval(interval); -} - -int Surface::dequeueBuffer(ANativeWindow* window, - ANativeWindowBuffer** buffer) { - Surface* self = getSelf(window); - return self->dequeueBuffer(buffer); -} - -int Surface::cancelBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer) { - Surface* self = getSelf(window); - return self->cancelBuffer(buffer); -} - -int Surface::lockBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer) { - Surface* self = getSelf(window); - return self->lockBuffer(buffer); -} - -int Surface::queueBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer) { - Surface* self = getSelf(window); - return self->queueBuffer(buffer); -} - -int Surface::query(const ANativeWindow* window, - int what, int* value) { - const Surface* self = getSelf(window); - return self->query(what, value); -} - -int Surface::perform(ANativeWindow* window, - int operation, ...) { - va_list args; - va_start(args, operation); - Surface* self = getSelf(window); - int res = self->perform(operation, args); - va_end(args); - return res; -} - -// ---------------------------------------------------------------------------- - -int Surface::setSwapInterval(int interval) { - return mSurfaceTextureClient->setSwapInterval(interval); -} - -int Surface::dequeueBuffer(ANativeWindowBuffer** buffer) { - status_t err = mSurfaceTextureClient->dequeueBuffer(buffer); - if (err == NO_ERROR) { - mDirtyRegion.set(buffer[0]->width, buffer[0]->height); - } - return err; -} - -int Surface::cancelBuffer(ANativeWindowBuffer* buffer) { - return mSurfaceTextureClient->cancelBuffer(buffer); -} - -int Surface::lockBuffer(ANativeWindowBuffer* buffer) { - return mSurfaceTextureClient->lockBuffer(buffer); -} - -int Surface::queueBuffer(ANativeWindowBuffer* buffer) { - return mSurfaceTextureClient->queueBuffer(buffer); -} - int Surface::query(int what, int* value) const { switch (what) { case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: @@ -509,141 +371,39 @@ int Surface::query(int what, int* value) const { *value = 1; return NO_ERROR; case NATIVE_WINDOW_CONCRETE_TYPE: - // TODO: this is not needed anymore *value = NATIVE_WINDOW_SURFACE; return NO_ERROR; } - return mSurfaceTextureClient->query(what, value); -} - -int Surface::perform(int operation, va_list args) { - return mSurfaceTextureClient->perform(operation, args); + return SurfaceTextureClient::query(what, value); } // ---------------------------------------------------------------------------- -int Surface::getConnectedApi() const { - return mSurfaceTextureClient->getConnectedApi(); -} +status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn) { + ANativeWindow_Buffer outBuffer; -// ---------------------------------------------------------------------------- - -status_t Surface::lock(SurfaceInfo* info, bool blocking) { - return Surface::lock(info, NULL, blocking); -} - -status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) -{ - if (getConnectedApi()) { - LOGE("Surface::lock(%p) failed. Already connected to another API", - (ANativeWindow*)this); - CallStack stack; - stack.update(); - stack.dump(""); - return INVALID_OPERATION; - } - - if (mApiLock.tryLock() != NO_ERROR) { - LOGE("calling Surface::lock from different threads!"); - CallStack stack; - stack.update(); - stack.dump(""); - return WOULD_BLOCK; + ARect temp; + ARect* inOutDirtyBounds = NULL; + if (dirtyIn) { + temp = dirtyIn->getBounds(); + inOutDirtyBounds = &temp; } - /* Here we're holding mApiLock */ - - if (mLockedBuffer != 0) { - LOGE("Surface::lock failed, already locked"); - mApiLock.unlock(); - return INVALID_OPERATION; - } - - // we're intending to do software rendering from this point - mSurfaceTextureClient->setUsage( - GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds); - ANativeWindowBuffer* out; - status_t err = mSurfaceTextureClient->dequeueBuffer(&out); - LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); if (err == NO_ERROR) { - sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); - err = mSurfaceTextureClient->lockBuffer(backBuffer.get()); - LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)", - backBuffer->handle, strerror(-err)); - if (err == NO_ERROR) { - const Rect bounds(backBuffer->width, backBuffer->height); - const Region boundsRegion(bounds); - Region scratch(boundsRegion); - Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch); - newDirtyRegion &= boundsRegion; - - // figure out if we can copy the frontbuffer back - const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); - const bool canCopyBack = (frontBuffer != 0 && - backBuffer->width == frontBuffer->width && - backBuffer->height == frontBuffer->height && - backBuffer->format == frontBuffer->format && - !(mFlags & ISurfaceComposer::eDestroyBackbuffer)); - - // the dirty region we report to surfaceflinger is the one - // given by the user (as opposed to the one *we* return to the - // user). - mDirtyRegion = newDirtyRegion; - - if (canCopyBack) { - // copy the area that is invalid and not repainted this round - const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); - if (!copyback.isEmpty()) - copyBlt(backBuffer, frontBuffer, copyback); - } else { - // if we can't copy-back anything, modify the user's dirty - // region to make sure they redraw the whole buffer - newDirtyRegion = boundsRegion; - } - - // keep track of the are of the buffer that is "clean" - // (ie: that will be redrawn) - mOldDirtyRegion = newDirtyRegion; - - void* vaddr; - status_t res = backBuffer->lock( - GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - newDirtyRegion.bounds(), &vaddr); - - LOGW_IF(res, "failed locking buffer (handle = %p)", - backBuffer->handle); - - mLockedBuffer = backBuffer; - other->w = backBuffer->width; - other->h = backBuffer->height; - other->s = backBuffer->stride; - other->usage = backBuffer->usage; - other->format = backBuffer->format; - other->bits = vaddr; - } + other->w = uint32_t(outBuffer.width); + other->h = uint32_t(outBuffer.height); + other->s = uint32_t(outBuffer.stride); + other->usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; + other->format = uint32_t(outBuffer.format); + other->bits = outBuffer.bits; } - mApiLock.unlock(); return err; } - -status_t Surface::unlockAndPost() -{ - if (mLockedBuffer == 0) { - LOGE("Surface::unlockAndPost failed, no locked buffer"); - return INVALID_OPERATION; - } - - status_t err = mLockedBuffer->unlock(); - LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); - - err = mSurfaceTextureClient->queueBuffer(mLockedBuffer.get()); - LOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", - mLockedBuffer->handle, strerror(-err)); - mPostedBuffer = mLockedBuffer; - mLockedBuffer = 0; - return err; +status_t Surface::unlockAndPost() { + return SurfaceTextureClient::unlockAndPost(); } // ---------------------------------------------------------------------------- diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 14104810f8bc..a12d40adcabb 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -495,7 +495,7 @@ status_t SurfaceTexture::setTransform(uint32_t transform) { } status_t SurfaceTexture::connect(int api) { - LOGV("SurfaceTexture::connect"); + LOGV("SurfaceTexture::connect(this=%p, %d)", this, api); Mutex::Autolock lock(mMutex); int err = NO_ERROR; switch (api) { @@ -504,6 +504,8 @@ status_t SurfaceTexture::connect(int api) { case NATIVE_WINDOW_API_MEDIA: case NATIVE_WINDOW_API_CAMERA: if (mConnectedApi != NO_CONNECTED_API) { + LOGE("connect: already connected (cur=%d, req=%d)", + mConnectedApi, api); err = -EINVAL; } else { mConnectedApi = api; @@ -517,7 +519,7 @@ status_t SurfaceTexture::connect(int api) { } status_t SurfaceTexture::disconnect(int api) { - LOGV("SurfaceTexture::disconnect"); + LOGV("SurfaceTexture::disconnect(this=%p, %d)", this, api); Mutex::Autolock lock(mMutex); int err = NO_ERROR; switch (api) { @@ -528,6 +530,8 @@ status_t SurfaceTexture::disconnect(int api) { if (mConnectedApi == api) { mConnectedApi = NO_CONNECTED_API; } else { + LOGE("disconnect: connected to another api (cur=%d, req=%d)", + mConnectedApi, api); err = -EINVAL; } break; diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp index f39cabf09c15..d5b7c89f8f95 100644 --- a/libs/gui/SurfaceTextureClient.cpp +++ b/libs/gui/SurfaceTextureClient.cpp @@ -24,24 +24,45 @@ namespace android { SurfaceTextureClient::SurfaceTextureClient( - const sp<ISurfaceTexture>& surfaceTexture): - mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(0), - mReqHeight(0), mReqFormat(0), mReqUsage(0), - mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO), - mQueryWidth(0), mQueryHeight(0), mQueryFormat(0), - mMutex() { + const sp<ISurfaceTexture>& surfaceTexture) +{ + SurfaceTextureClient::init(); + SurfaceTextureClient::setISurfaceTexture(surfaceTexture); +} + +SurfaceTextureClient::SurfaceTextureClient() { + SurfaceTextureClient::init(); +} + +void SurfaceTextureClient::init() { // Initialize the ANativeWindow function pointers. - ANativeWindow::setSwapInterval = setSwapInterval; - ANativeWindow::dequeueBuffer = dequeueBuffer; - ANativeWindow::cancelBuffer = cancelBuffer; - ANativeWindow::lockBuffer = lockBuffer; - ANativeWindow::queueBuffer = queueBuffer; - ANativeWindow::query = query; - ANativeWindow::perform = perform; + ANativeWindow::setSwapInterval = hook_setSwapInterval; + ANativeWindow::dequeueBuffer = hook_dequeueBuffer; + ANativeWindow::cancelBuffer = hook_cancelBuffer; + ANativeWindow::lockBuffer = hook_lockBuffer; + ANativeWindow::queueBuffer = hook_queueBuffer; + ANativeWindow::query = hook_query; + ANativeWindow::perform = hook_perform; const_cast<int&>(ANativeWindow::minSwapInterval) = 0; const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; + mReqWidth = 0; + mReqHeight = 0; + mReqFormat = 0; + mReqUsage = 0; + mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; + mQueryWidth = 0; + mQueryHeight = 0; + mQueryFormat = 0; + mConnectedToCpu = false; +} + +void SurfaceTextureClient::setISurfaceTexture( + const sp<ISurfaceTexture>& surfaceTexture) +{ + mSurfaceTexture = surfaceTexture; + // Get a reference to the allocator. mAllocator = mSurfaceTexture->getAllocator(); } @@ -50,42 +71,42 @@ sp<ISurfaceTexture> SurfaceTextureClient::getISurfaceTexture() const { return mSurfaceTexture; } -int SurfaceTextureClient::setSwapInterval(ANativeWindow* window, int interval) { +int SurfaceTextureClient::hook_setSwapInterval(ANativeWindow* window, int interval) { SurfaceTextureClient* c = getSelf(window); return c->setSwapInterval(interval); } -int SurfaceTextureClient::dequeueBuffer(ANativeWindow* window, +int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer) { SurfaceTextureClient* c = getSelf(window); return c->dequeueBuffer(buffer); } -int SurfaceTextureClient::cancelBuffer(ANativeWindow* window, +int SurfaceTextureClient::hook_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer) { SurfaceTextureClient* c = getSelf(window); return c->cancelBuffer(buffer); } -int SurfaceTextureClient::lockBuffer(ANativeWindow* window, +int SurfaceTextureClient::hook_lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer) { SurfaceTextureClient* c = getSelf(window); return c->lockBuffer(buffer); } -int SurfaceTextureClient::queueBuffer(ANativeWindow* window, +int SurfaceTextureClient::hook_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer) { SurfaceTextureClient* c = getSelf(window); return c->queueBuffer(buffer); } -int SurfaceTextureClient::query(const ANativeWindow* window, +int SurfaceTextureClient::hook_query(const ANativeWindow* window, int what, int* value) { const SurfaceTextureClient* c = getSelf(window); return c->query(what, value); } -int SurfaceTextureClient::perform(ANativeWindow* window, int operation, ...) { +int SurfaceTextureClient::hook_perform(ANativeWindow* window, int operation, ...) { va_list args; va_start(args, operation); SurfaceTextureClient* c = getSelf(window); @@ -219,7 +240,6 @@ int SurfaceTextureClient::query(int what, int* value) const { *value = 0; return NO_ERROR; case NATIVE_WINDOW_CONCRETE_TYPE: - // TODO: this is not needed anymore *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT; return NO_ERROR; } @@ -260,6 +280,12 @@ int SurfaceTextureClient::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_FORMAT: res = dispatchSetBuffersFormat(args); break; + case NATIVE_WINDOW_LOCK: + res = dispatchLock(args); + break; + case NATIVE_WINDOW_UNLOCK_AND_POST: + res = dispatchUnlockAndPost(args); + break; default: res = NAME_NOT_FOUND; break; @@ -324,28 +350,37 @@ int SurfaceTextureClient::dispatchSetBuffersTimestamp(va_list args) { return setBuffersTimestamp(timestamp); } +int SurfaceTextureClient::dispatchLock(va_list args) { + ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*); + ARect* inOutDirtyBounds = va_arg(args, ARect*); + return lock(outBuffer, inOutDirtyBounds); +} + +int SurfaceTextureClient::dispatchUnlockAndPost(va_list args) { + return unlockAndPost(); +} + + int SurfaceTextureClient::connect(int api) { LOGV("SurfaceTextureClient::connect"); Mutex::Autolock lock(mMutex); - return mSurfaceTexture->connect(api); + int err = mSurfaceTexture->connect(api); + if (!err && api == NATIVE_WINDOW_API_CPU) { + mConnectedToCpu = true; + } + return err; } int SurfaceTextureClient::disconnect(int api) { LOGV("SurfaceTextureClient::disconnect"); Mutex::Autolock lock(mMutex); - return mSurfaceTexture->disconnect(api); -} - -int SurfaceTextureClient::getConnectedApi() const -{ - // XXX: This method will be going away shortly, and is currently bogus. It - // always returns "nothing is connected". It will go away once Surface gets - // updated to actually connect as the 'CPU' API when locking a buffer. - Mutex::Autolock lock(mMutex); - return 0; + int err = mSurfaceTexture->disconnect(api); + if (!err && api == NATIVE_WINDOW_API_CPU) { + mConnectedToCpu = false; + } + return err; } - int SurfaceTextureClient::setUsage(uint32_t reqUsage) { LOGV("SurfaceTextureClient::setUsage"); @@ -443,4 +478,160 @@ void SurfaceTextureClient::freeAllBuffers() { } } +// ---------------------------------------------------------------------- +// the lock/unlock APIs must be used from the same thread + +static status_t copyBlt( + const sp<GraphicBuffer>& dst, + const sp<GraphicBuffer>& src, + const Region& reg) +{ + // src and dst with, height and format must be identical. no verification + // is done here. + status_t err; + uint8_t const * src_bits = NULL; + err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); + LOGE_IF(err, "error locking src buffer %s", strerror(-err)); + + uint8_t* dst_bits = NULL; + err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); + LOGE_IF(err, "error locking dst buffer %s", strerror(-err)); + + Region::const_iterator head(reg.begin()); + Region::const_iterator tail(reg.end()); + if (head != tail && src_bits && dst_bits) { + const size_t bpp = bytesPerPixel(src->format); + const size_t dbpr = dst->stride * bpp; + const size_t sbpr = src->stride * bpp; + + while (head != tail) { + const Rect& r(*head++); + ssize_t h = r.height(); + if (h <= 0) continue; + size_t size = r.width() * bpp; + uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; + uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; + if (dbpr==sbpr && size==sbpr) { + size *= h; + h = 1; + } + do { + memcpy(d, s, size); + d += dbpr; + s += sbpr; + } while (--h > 0); + } + } + + if (src_bits) + src->unlock(); + + if (dst_bits) + dst->unlock(); + + return err; +} + +// ---------------------------------------------------------------------------- + +status_t SurfaceTextureClient::lock( + ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) +{ + if (mLockedBuffer != 0) { + LOGE("Surface::lock failed, already locked"); + return INVALID_OPERATION; + } + + if (!mConnectedToCpu) { + int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU); + if (err) { + return err; + } + // we're intending to do software rendering from this point + setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + } + + ANativeWindowBuffer* out; + status_t err = dequeueBuffer(&out); + LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); + if (err == NO_ERROR) { + sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); + err = lockBuffer(backBuffer.get()); + LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)", + backBuffer->handle, strerror(-err)); + if (err == NO_ERROR) { + const Rect bounds(backBuffer->width, backBuffer->height); + + Region newDirtyRegion; + if (inOutDirtyBounds) { + newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds)); + newDirtyRegion.andSelf(bounds); + } else { + newDirtyRegion.set(bounds); + } + + // figure out if we can copy the frontbuffer back + const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); + const bool canCopyBack = (frontBuffer != 0 && + backBuffer->width == frontBuffer->width && + backBuffer->height == frontBuffer->height && + backBuffer->format == frontBuffer->format); + + if (canCopyBack) { + // copy the area that is invalid and not repainted this round + const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); + if (!copyback.isEmpty()) + copyBlt(backBuffer, frontBuffer, copyback); + } else { + // if we can't copy-back anything, modify the user's dirty + // region to make sure they redraw the whole buffer + newDirtyRegion.set(bounds); + } + + // keep track of the are of the buffer that is "clean" + // (ie: that will be redrawn) + mOldDirtyRegion = newDirtyRegion; + + if (inOutDirtyBounds) { + *inOutDirtyBounds = newDirtyRegion.getBounds(); + } + + void* vaddr; + status_t res = backBuffer->lock( + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + newDirtyRegion.bounds(), &vaddr); + + LOGW_IF(res, "failed locking buffer (handle = %p)", + backBuffer->handle); + + mLockedBuffer = backBuffer; + outBuffer->width = backBuffer->width; + outBuffer->height = backBuffer->height; + outBuffer->stride = backBuffer->stride; + outBuffer->format = backBuffer->format; + outBuffer->bits = vaddr; + } + } + return err; +} + +status_t SurfaceTextureClient::unlockAndPost() +{ + if (mLockedBuffer == 0) { + LOGE("Surface::unlockAndPost failed, no locked buffer"); + return INVALID_OPERATION; + } + + status_t err = mLockedBuffer->unlock(); + LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); + + err = queueBuffer(mLockedBuffer.get()); + LOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", + mLockedBuffer->handle, strerror(-err)); + + mPostedBuffer = mLockedBuffer; + mLockedBuffer = 0; + return err; +} + }; // namespace android diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index 519b40e44a57..2b8f204563cd 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -613,4 +613,90 @@ TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) { } } +class MultiSurfaceTextureClientTest : public ::testing::Test { + +public: + MultiSurfaceTextureClientTest() : + mEglDisplay(EGL_NO_DISPLAY), + mEglContext(EGL_NO_CONTEXT) { + for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { + mEglSurfaces[i] = EGL_NO_CONTEXT; + } + } + +protected: + + enum { NUM_SURFACE_TEXTURES = 32 }; + + virtual void SetUp() { + mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + ASSERT_EQ(EGL_SUCCESS, eglGetError()); + ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay); + + EGLint majorVersion, minorVersion; + EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion)); + ASSERT_EQ(EGL_SUCCESS, eglGetError()); + + EGLConfig myConfig; + EGLint numConfigs = 0; + EGLint configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1, + &numConfigs)); + ASSERT_EQ(EGL_SUCCESS, eglGetError()); + + mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT, + 0); + ASSERT_EQ(EGL_SUCCESS, eglGetError()); + ASSERT_NE(EGL_NO_CONTEXT, mEglContext); + + for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { + sp<SurfaceTexture> st(new SurfaceTexture(i)); + sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st)); + mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig, + static_cast<ANativeWindow*>(stc.get()), NULL); + ASSERT_EQ(EGL_SUCCESS, eglGetError()); + ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]); + } + } + + virtual void TearDown() { + eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { + if (mEglSurfaces[i] != EGL_NO_SURFACE) { + eglDestroySurface(mEglDisplay, mEglSurfaces[i]); + } + } + + if (mEglContext != EGL_NO_CONTEXT) { + eglDestroyContext(mEglDisplay, mEglContext); + } + + if (mEglDisplay != EGL_NO_DISPLAY) { + eglTerminate(mEglDisplay); + } + } + + EGLDisplay mEglDisplay; + EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES]; + EGLContext mEglContext; +}; + +// XXX: This test is disabled because it causes a hang on some devices. See bug +// 5015672. +TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) { + for (int iter = 0; iter < 8; iter++) { + for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { + eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i], + mEglContext); + glClear(GL_COLOR_BUFFER_BIT); + eglSwapBuffers(mEglDisplay, mEglSurfaces[i]); + } + } +} + } // namespace android diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index e232dddd3951..7114b6adc30e 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -33,6 +33,16 @@ ANDROID_SINGLETON_STATIC_INSTANCE(Caches); namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// +// Macros +/////////////////////////////////////////////////////////////////////////////// + +#if DEBUG_CACHE_FLUSH + #define FLUSH_LOGD(...) LOGD(__VA_ARGS__) +#else + #define FLUSH_LOGD(...) +#endif + +/////////////////////////////////////////////////////////////////////////////// // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// @@ -150,6 +160,30 @@ void Caches::deleteLayerDeferred(Layer* layer) { mLayerGarbage.push(layer); } +void Caches::flush(FlushMode mode) { + FLUSH_LOGD("Flushing caches (mode %d)", mode); + + clearGarbage(); + + switch (mode) { + case kFlushMode_Full: + textureCache.clear(); + patchCache.clear(); + dropShadowCache.clear(); + gradientCache.clear(); + // fall through + case kFlushMode_Moderate: + layerCache.clear(); + pathCache.clear(); + roundRectShapeCache.clear(); + circleShapeCache.clear(); + ovalShapeCache.clear(); + rectShapeCache.clear(); + arcShapeCache.clear(); + break; + } +} + /////////////////////////////////////////////////////////////////////////////// // VBO /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index e64d8ac48d56..76dff4b4078b 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -100,6 +100,18 @@ class Caches: public Singleton<Caches> { Vector<Layer*> mLayerGarbage; public: + enum FlushMode { + kFlushMode_Moderate = 0, + kFlushMode_Full + }; + + /** + * Flush the cache. + * + * @param mode Indicates how much of the cache should be flushed + */ + void flush(FlushMode mode); + /** * Indicates whether the renderer is in debug mode. * This debug mode provides limited information to app developers. diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h index 2cdc8c39e9f9..5db73db9fc35 100644 --- a/libs/hwui/Debug.h +++ b/libs/hwui/Debug.h @@ -26,6 +26,9 @@ // Turn on to enable memory usage summary on each frame #define DEBUG_MEMORY_USAGE 0 +// Turn on to enable debugging of cache flushes +#define DEBUG_CACHE_FLUSH 1 + // Turn on to enable layers debugging when rendered as regions #define DEBUG_LAYERS_AS_REGIONS 0 diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 9c10c754ba0a..794747d654f2 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -303,6 +303,10 @@ int FramebufferNativeWindow::perform(ANativeWindow* window, case NATIVE_WINDOW_CONNECT: case NATIVE_WINDOW_DISCONNECT: break; + case NATIVE_WINDOW_LOCK: + return INVALID_OPERATION; + case NATIVE_WINDOW_UNLOCK_AND_POST: + return INVALID_OPERATION; default: return NAME_NOT_FOUND; } diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 7b7ba74f9a84..178039c6e03b 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -27,6 +27,8 @@ #include <binder/IServiceManager.h> #include <binder/IPCThreadState.h> +#include <gui/SurfaceTextureClient.h> + #include <media/mediaplayer.h> #include <media/AudioTrack.h> @@ -38,6 +40,7 @@ #include <utils/String8.h> #include <system/audio.h> +#include <system/window.h> namespace android { @@ -194,13 +197,62 @@ status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *m return mPlayer->getMetadata(update_only, apply_filter, metadata); } +void MediaPlayer::disconnectNativeWindow() { + if (mConnectedWindow != NULL) { + status_t err = native_window_disconnect(mConnectedWindow.get(), + NATIVE_WINDOW_API_MEDIA); + + if (err != OK) { + LOGW("native_window_disconnect returned an error: %s (%d)", + strerror(-err), err); + } + } + mConnectedWindow.clear(); +} + status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface) { LOGV("setVideoSurface"); Mutex::Autolock _l(mLock); if (mPlayer == 0) return NO_INIT; - return mPlayer->setVideoSurface(surface); + sp<IBinder> binder(surface == NULL ? NULL : surface->asBinder()); + if (mConnectedWindowBinder == binder) { + return OK; + } + + if (surface != NULL) { + status_t err = native_window_connect(surface.get(), + NATIVE_WINDOW_API_MEDIA); + + if (err != OK) { + // Note that we must do the reset before disconnecting from the ANW. + // Otherwise queue/dequeue calls could be made on the disconnected + // ANW, which may result in errors. + reset_l(); + + disconnectNativeWindow(); + + return err; + } + } + + // Note that we must set the player's new surface before disconnecting the + // old one. Otherwise queue/dequeue calls could be made on the disconnected + // ANW, which may result in errors. + status_t err = mPlayer->setVideoSurface(surface); + + disconnectNativeWindow(); + + mConnectedWindow = surface; + + if (err == OK) { + mConnectedWindowBinder = binder; + } else { + disconnectNativeWindow(); + } + + return err; } status_t MediaPlayer::setVideoSurfaceTexture( @@ -210,7 +262,46 @@ status_t MediaPlayer::setVideoSurfaceTexture( Mutex::Autolock _l(mLock); if (mPlayer == 0) return NO_INIT; - return mPlayer->setVideoSurfaceTexture(surfaceTexture); + sp<IBinder> binder(surfaceTexture == NULL ? NULL : + surfaceTexture->asBinder()); + if (mConnectedWindowBinder == binder) { + return OK; + } + + sp<ANativeWindow> anw; + if (surfaceTexture != NULL) { + anw = new SurfaceTextureClient(surfaceTexture); + status_t err = native_window_connect(anw.get(), + NATIVE_WINDOW_API_MEDIA); + + if (err != OK) { + // Note that we must do the reset before disconnecting from the ANW. + // Otherwise queue/dequeue calls could be made on the disconnected + // ANW, which may result in errors. + reset_l(); + + disconnectNativeWindow(); + + return err; + } + } + + // Note that we must set the player's new SurfaceTexture before + // disconnecting the old one. Otherwise queue/dequeue calls could be made + // on the disconnected ANW, which may result in errors. + status_t err = mPlayer->setVideoSurfaceTexture(surfaceTexture); + + disconnectNativeWindow(); + + mConnectedWindow = anw; + + if (err == OK) { + mConnectedWindowBinder = binder; + } else { + disconnectNativeWindow(); + } + + return err; } // must call with lock held @@ -434,10 +525,8 @@ status_t MediaPlayer::seekTo(int msec) return result; } -status_t MediaPlayer::reset() +status_t MediaPlayer::reset_l() { - LOGV("reset"); - Mutex::Autolock _l(mLock); mLoop = false; if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR; mPrepareSync = false; @@ -458,6 +547,13 @@ status_t MediaPlayer::reset() return NO_ERROR; } +status_t MediaPlayer::reset() +{ + LOGV("reset"); + Mutex::Autolock _l(mLock); + return reset_l(); +} + status_t MediaPlayer::setAudioStreamType(int type) { LOGV("MediaPlayer::setAudioStreamType"); diff --git a/media/libstagefright/codecs/aacenc/src/bit_cnt.c b/media/libstagefright/codecs/aacenc/src/bit_cnt.c index dd0b9b452602..8853efc035e9 100644 --- a/media/libstagefright/codecs/aacenc/src/bit_cnt.c +++ b/media/libstagefright/codecs/aacenc/src/bit_cnt.c @@ -496,7 +496,7 @@ Word16 codeValues(Word16 *values, Word16 width, Word16 codeBook, HANDLE_BIT_BUF { Word32 i, t0, t1, t2, t3, t00, t01; - Word16 codeWord, codeLength; + UWord16 codeWord, codeLength; Word16 sign, signLength; diff --git a/media/libstagefright/codecs/aacenc/src/memalign.c b/media/libstagefright/codecs/aacenc/src/memalign.c index 7d2035274cf8..44dd4bab415d 100644 --- a/media/libstagefright/codecs/aacenc/src/memalign.c +++ b/media/libstagefright/codecs/aacenc/src/memalign.c @@ -23,6 +23,11 @@ #include "memalign.h" +#ifdef _MSC_VER +#include <stddef.h> +#else +#include <stdint.h> +#endif /***************************************************************************** * @@ -66,8 +71,8 @@ mem_malloc(VO_MEM_OPERATOR *pMemop, unsigned int size, unsigned char alignment, pMemop->Set(CodecID, tmp, 0, size + alignment); mem_ptr = - (unsigned char *) ((unsigned int) (tmp + alignment - 1) & - (~((unsigned int) (alignment - 1)))); + (unsigned char *) ((intptr_t) (tmp + alignment - 1) & + (~((intptr_t) (alignment - 1)))); if (mem_ptr == tmp) mem_ptr += alignment; diff --git a/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c b/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c deleted file mode 100644 index dd7c26d55a5a..000000000000 --- a/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - ** Copyright 2003-2010, VisualOn, Inc. - ** - ** 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. - */ -/******************************************************************************* - File: cmnMemory.c - - Content: sample code for memory operator implementation - -*******************************************************************************/ -#include "cmnMemory.h" - -#include <malloc.h> -#if defined LINUX -#include <string.h> -#endif - -//VO_MEM_OPERATOR g_memOP; - -VO_U32 cmnMemAlloc (VO_S32 uID, VO_MEM_INFO * pMemInfo) -{ - if (!pMemInfo) - return VO_ERR_INVALID_ARG; - - pMemInfo->VBuffer = malloc (pMemInfo->Size); - return 0; -} - -VO_U32 cmnMemFree (VO_S32 uID, VO_PTR pMem) -{ - free (pMem); - return 0; -} - -VO_U32 cmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize) -{ - memset (pBuff, uValue, uSize); - return 0; -} - -VO_U32 cmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize) -{ - memcpy (pDest, pSource, uSize); - return 0; -} - -VO_U32 cmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize) -{ - return 0; -} - -VO_S32 cmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize) -{ - return memcmp(pBuffer1, pBuffer2, uSize); -} - -VO_U32 cmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize) -{ - memmove (pDest, pSource, uSize); - return 0; -} - diff --git a/media/libstagefright/codecs/common/cmnMemory.c b/media/libstagefright/codecs/common/cmnMemory.c index dd7c26d55a5a..aa52bd98f070 100644 --- a/media/libstagefright/codecs/common/cmnMemory.c +++ b/media/libstagefright/codecs/common/cmnMemory.c @@ -21,10 +21,8 @@ *******************************************************************************/ #include "cmnMemory.h" -#include <malloc.h> -#if defined LINUX +#include <stdlib.h> #include <string.h> -#endif //VO_MEM_OPERATOR g_memOP; diff --git a/media/libstagefright/codecs/common/include/voType.h b/media/libstagefright/codecs/common/include/voType.h index 70b2e83e1b2e..5f659ab05110 100644 --- a/media/libstagefright/codecs/common/include/voType.h +++ b/media/libstagefright/codecs/common/include/voType.h @@ -101,7 +101,7 @@ typedef signed long VO_S32; since the compiler does not support the way the component was written. */ #ifndef VO_SKIP64BIT -#ifdef _WIN32 +#ifdef _MSC_VER /** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ typedef unsigned __int64 VO_U64; /** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */ diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp index 2c0e88eef996..5c016c478df7 100644 --- a/native/android/native_window.cpp +++ b/native/android/native_window.cpp @@ -81,39 +81,9 @@ int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) { - int type = -1; - if (window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &type) != 0 || - type != NATIVE_WINDOW_SURFACE) { - return BAD_VALUE; - } - - Region dirtyRegion; - Region* dirtyParam = NULL; - if (inOutDirtyBounds != NULL) { - dirtyRegion.set(*(Rect*)inOutDirtyBounds); - dirtyParam = &dirtyRegion; - } - - Surface::SurfaceInfo info; - status_t res = static_cast<Surface*>(window)->lock(&info, dirtyParam); - if (res != OK) { - return -1; - } - - outBuffer->width = (int32_t)info.w; - outBuffer->height = (int32_t)info.h; - outBuffer->stride = (int32_t)info.s; - outBuffer->format = (int32_t)info.format; - outBuffer->bits = info.bits; - - if (inOutDirtyBounds != NULL) { - *inOutDirtyBounds = dirtyRegion.getBounds(); - } - - return 0; + return window->perform(window, NATIVE_WINDOW_LOCK, outBuffer, inOutDirtyBounds); } int32_t ANativeWindow_unlockAndPost(ANativeWindow* window) { - status_t res = static_cast<Surface*>(window)->unlockAndPost(); - return res == android::OK ? 0 : -1; + return window->perform(window, NATIVE_WINDOW_UNLOCK_AND_POST); } diff --git a/native/include/android/native_window.h b/native/include/android/native_window.h index 337fa9611b70..2f4f2d33bec9 100644 --- a/native/include/android/native_window.h +++ b/native/include/android/native_window.h @@ -99,10 +99,16 @@ int32_t ANativeWindow_getFormat(ANativeWindow* window); * width and height must be either both zero or both non-zero. * */ -int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, int32_t height, int32_t format); +int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, + int32_t width, int32_t height, int32_t format); /** * Lock the window's next drawing surface for writing. + * inOutDirtyBounds is used as an in/out parameter, upon entering the + * function, it contains the dirty region, that is, the region the caller + * intends to redraw. When the function returns, inOutDirtyBounds is updated + * with the actual area the caller needs to redraw -- this region is often + * extended by ANativeWindow_lock. */ int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index dedbe5d70f8f..af5c72d92cdc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -218,9 +218,165 @@ public class PhoneStatusBarPolicy { R.drawable.stat_sys_roaming_cdma_0, R.drawable.stat_sys_roaming_cdma_0, R.drawable.stat_sys_roaming_cdma_0, - R.drawable.stat_sys_roaming_cdma_0 //83 + R.drawable.stat_sys_roaming_cdma_0, //83 + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0 //239 - // 128-255 Reserved + // 240-255 Reserved }; //***** Data connection icons diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 9b09983e3a82..0eff776af84f 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -502,77 +502,82 @@ void CameraService::Client::disconnect() { // ---------------------------------------------------------------------------- -// set the Surface that the preview will use -status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { - LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid()); +static void disconnectWindow(const sp<ANativeWindow>& window) { + if (window != 0) { + status_t result = native_window_disconnect(window.get(), + NATIVE_WINDOW_API_CAMERA); + if (result != NO_ERROR) { + LOGW("native_window_disconnect failed: %s (%d)", strerror(-result), + result); + } + } +} + +status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder, + const sp<ANativeWindow>& window) { Mutex::Autolock lock(mLock); status_t result = checkPidAndHardware(); if (result != NO_ERROR) return result; - result = NO_ERROR; - // return if no change in surface. - sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0); if (binder == mSurface) { - return result; + return NO_ERROR; } - if (mSurface != 0) { - LOG1("clearing old preview surface %p", mSurface.get()); + if (window != 0) { + result = native_window_connect(window.get(), NATIVE_WINDOW_API_CAMERA); + if (result != NO_ERROR) { + LOGE("native_window_connect failed: %s (%d)", strerror(-result), + result); + return result; + } } - mSurface = binder; - mPreviewWindow = surface; - // If preview has been already started, register preview - // buffers now. + // If preview has been already started, register preview buffers now. if (mHardware->previewEnabled()) { - if (mPreviewWindow != 0) { - native_window_set_buffers_transform(mPreviewWindow.get(), - mOrientation); - result = mHardware->setPreviewWindow(mPreviewWindow); + if (window != 0) { + native_window_set_buffers_transform(window.get(), mOrientation); + result = mHardware->setPreviewWindow(window); } } + if (result == NO_ERROR) { + // Everything has succeeded. Disconnect the old window and remember the + // new window. + disconnectWindow(mPreviewWindow); + mSurface = binder; + mPreviewWindow = window; + } else { + // Something went wrong after we connected to the new window, so + // disconnect here. + disconnectWindow(window); + } + return result; } +// set the Surface that the preview will use +status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { + LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid()); + + sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0); + sp<ANativeWindow> window(surface); + return setPreviewWindow(binder, window); +} + // set the SurfaceTexture that the preview will use status_t CameraService::Client::setPreviewTexture( const sp<ISurfaceTexture>& surfaceTexture) { LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(), getCallingPid()); - Mutex::Autolock lock(mLock); - status_t result = checkPidAndHardware(); - if (result != NO_ERROR) return result; - - // return if no change in surface. - // asBinder() is safe on NULL (returns NULL) - if (surfaceTexture->asBinder() == mSurface) { - return result; - } - if (mSurface != 0) { - LOG1("clearing old preview surface %p", mSurface.get()); - } - mSurface = surfaceTexture->asBinder(); + sp<IBinder> binder; + sp<ANativeWindow> window; if (surfaceTexture != 0) { - mPreviewWindow = new SurfaceTextureClient(surfaceTexture); - } else { - mPreviewWindow = 0; - } - - // If preview has been already started, set overlay or register preview - // buffers now. - if (mHardware->previewEnabled()) { - // XXX: What if the new preview window is 0? - if (mPreviewWindow != 0) { - native_window_set_buffers_transform(mPreviewWindow.get(), - mOrientation); - result = mHardware->setPreviewWindow(mPreviewWindow); - } + binder = surfaceTexture->asBinder(); + window = new SurfaceTextureClient(surfaceTexture); } - - return result; + return setPreviewWindow(binder, window); } // set the preview callback flag to affect how the received frames from diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 5e2d57151271..c5fefb86b8c6 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -161,6 +161,10 @@ private: int getOrientation(int orientation, bool mirror); + status_t setPreviewWindow( + const sp<IBinder>& binder, + const sp<ANativeWindow>& window); + // these are initialized in the constructor. sp<CameraService> mCameraService; // immutable after constructor sp<ICameraClient> mCameraClient; diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 18d393fde2f7..25979782afde 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -35,6 +35,7 @@ import org.xmlpull.v1.XmlSerializer; import android.app.ActivityManagerNative; import android.app.AlertDialog; +import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -47,6 +48,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; @@ -160,6 +162,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Ongoing notification private final NotificationManager mNotificationManager; + private final KeyguardManager mKeyguardManager; private final Notification mImeSwitcherNotification; private final PendingIntent mImeSwitchPendingIntent; private final boolean mShowOngoingImeSwitcherForPhones; @@ -520,6 +523,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } }); + mKeyguardManager = (KeyguardManager) + mContext.getSystemService(Context.KEYGUARD_SERVICE); mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); mImeSwitcherNotification = new Notification(); @@ -1632,19 +1637,27 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public boolean setAdditionalInputMethodSubtypes(IBinder token, InputMethodSubtype[] subtypes) { - if (token == null || mCurToken != token) { - return false; - } - if (subtypes == null || subtypes.length == 0) return false; + public boolean setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { + // By this IPC call, only a process which shares the same uid with the IME can add + // additional input method subtypes to the IME. + if (TextUtils.isEmpty(imiId) || subtypes == null || subtypes.length == 0) return false; synchronized (mMethodMap) { - final InputMethodInfo imi = mMethodMap.get(mCurMethodId); + final InputMethodInfo imi = mMethodMap.get(imiId); if (imi == null) return false; - final int N = subtypes.length; - mFileManager.addInputMethodSubtypes(imi, subtypes); - buildInputMethodListLocked(mMethodList, mMethodMap); - return true; + final PackageManager pm = mContext.getPackageManager(); + final String[] packageInfos = pm.getPackagesForUid(Binder.getCallingUid()); + if (packageInfos != null) { + final int packageNum = packageInfos.length; + for (int i = 0; i < packageNum; ++i) { + if (packageInfos[i].equals(imi.getPackageName())) { + mFileManager.addInputMethodSubtypes(imi, subtypes); + buildInputMethodListLocked(mMethodList, mMethodMap); + return true; + } + } + } } + return false; } private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) { @@ -2118,7 +2131,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } }); - if (showSubtypes) { + if (showSubtypes && !(mKeyguardManager.isKeyguardLocked() + && mKeyguardManager.isKeyguardSecure())) { mDialogBuilder.setPositiveButton( com.android.internal.R.string.configure_input_methods, new DialogInterface.OnClickListener() { diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java index 313979808ced..c80cd0a87115 100644 --- a/services/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/java/com/android/server/usb/UsbDeviceManager.java @@ -473,10 +473,7 @@ public class UsbDeviceManager { case MSG_SET_CURRENT_FUNCTION: String function = (String)msg.obj; boolean makeDefault = (msg.arg1 == 1); - if (makeDefault) { - if (function == null) { - throw new NullPointerException(); - } + if (function != null && makeDefault) { if (mAdbEnabled) { function = addFunction(function, UsbManager.USB_FUNCTION_ADB); } diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java index 118cd55fd975..8146fca74303 100644 --- a/services/java/com/android/server/wm/DragState.java +++ b/services/java/com/android/server/wm/DragState.java @@ -51,6 +51,8 @@ class DragState { float mCurrentX, mCurrentY; float mThumbOffsetX, mThumbOffsetY; InputChannel mServerChannel, mClientChannel; + InputApplicationHandle mDragApplicationHandle; + InputWindowHandle mDragWindowHandle; WindowState mTargetWindow; ArrayList<WindowState> mNotifiedWindows; boolean mDragInProgress; @@ -91,6 +93,38 @@ class DragState { mService.mInputManager.registerInputChannel(mServerChannel, null); InputQueue.registerInputChannel(mClientChannel, mService.mDragInputHandler, mService.mH.getLooper().getQueue()); + + mDragApplicationHandle = new InputApplicationHandle(null); + mDragApplicationHandle.name = "drag"; + mDragApplicationHandle.dispatchingTimeoutNanos = + WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; + + mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null); + mDragWindowHandle.name = "drag"; + mDragWindowHandle.inputChannel = mServerChannel; + mDragWindowHandle.layer = getDragLayerLw(); + mDragWindowHandle.layoutParamsFlags = 0; + mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG; + mDragWindowHandle.dispatchingTimeoutNanos = + WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; + mDragWindowHandle.visible = true; + mDragWindowHandle.canReceiveKeys = false; + mDragWindowHandle.hasFocus = true; + mDragWindowHandle.hasWallpaper = false; + mDragWindowHandle.paused = false; + mDragWindowHandle.ownerPid = Process.myPid(); + mDragWindowHandle.ownerUid = Process.myUid(); + mDragWindowHandle.inputFeatures = 0; + mDragWindowHandle.scaleFactor = 1.0f; + + // The drag window cannot receive new touches. + mDragWindowHandle.touchableRegion.setEmpty(); + + // The drag window covers the entire display + mDragWindowHandle.frameLeft = 0; + mDragWindowHandle.frameTop = 0; + mDragWindowHandle.frameRight = mService.mDisplay.getRealWidth(); + mDragWindowHandle.frameBottom = mService.mDisplay.getRealHeight(); } } diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java index 08a356033815..12ef23827342 100644 --- a/services/java/com/android/server/wm/InputMonitor.java +++ b/services/java/com/android/server/wm/InputMonitor.java @@ -42,10 +42,6 @@ final class InputMonitor { // When true, need to call updateInputWindowsLw(). private boolean mUpdateInputWindowsNeeded = true; - // Fake handles for the drag surface, lazily initialized. - private InputApplicationHandle mDragApplicationHandle; - private InputWindowHandle mDragWindowHandle; - // Array of window handles to provide to the input dispatcher. private InputWindowHandle[] mInputWindowHandles; private int mInputWindowHandleCount; @@ -121,44 +117,6 @@ final class InputMonitor { return 0; // abort dispatching } - private void addDragInputWindowLw() { - if (mDragWindowHandle == null) { - mDragApplicationHandle = new InputApplicationHandle(null); - mDragApplicationHandle.name = "drag"; - mDragApplicationHandle.dispatchingTimeoutNanos = - WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; - - mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null); - mDragWindowHandle.name = "drag"; - mDragWindowHandle.layoutParamsFlags = 0; - mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG; - mDragWindowHandle.dispatchingTimeoutNanos = - WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; - mDragWindowHandle.visible = true; - mDragWindowHandle.canReceiveKeys = false; - mDragWindowHandle.hasFocus = true; - mDragWindowHandle.hasWallpaper = false; - mDragWindowHandle.paused = false; - mDragWindowHandle.ownerPid = Process.myPid(); - mDragWindowHandle.ownerUid = Process.myUid(); - mDragWindowHandle.inputFeatures = 0; - mDragWindowHandle.scaleFactor = 1.0f; - - // The drag window cannot receive new touches. - mDragWindowHandle.touchableRegion.setEmpty(); - } - - mDragWindowHandle.layer = mService.mDragState.getDragLayerLw(); - - // The drag window covers the entire display - mDragWindowHandle.frameLeft = 0; - mDragWindowHandle.frameTop = 0; - mDragWindowHandle.frameRight = mService.mDisplay.getRealWidth(); - mDragWindowHandle.frameBottom = mService.mDisplay.getRealHeight(); - - addInputWindowHandleLw(mDragWindowHandle); - } - private void addInputWindowHandleLw(InputWindowHandle windowHandle) { if (mInputWindowHandles == null) { mInputWindowHandles = new InputWindowHandle[16]; @@ -202,7 +160,7 @@ final class InputMonitor { if (WindowManagerService.DEBUG_DRAG) { Log.d(WindowManagerService.TAG, "Inserting drag window"); } - addDragInputWindowLw(); + addInputWindowHandleLw(mService.mDragState.mDragWindowHandle); } final int N = windows.size(); @@ -429,4 +387,4 @@ final class InputMonitor { private void updateInputDispatchModeLw() { mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen); } -}
\ No newline at end of file +} diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java index 8427d1439895..f0d2fbaf018f 100644 --- a/telephony/java/com/android/internal/telephony/BaseCommands.java +++ b/telephony/java/com/android/internal/telephony/BaseCommands.java @@ -857,22 +857,28 @@ public abstract class BaseCommands implements CommandsInterface { */ public static int getLteOnCdmaModeStatic() { int retVal; - String productType; - - Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine); - if (matcher.find()) { - productType = matcher.group(1); - if (sLteOnCdmaProductType.equals(productType)) { - retVal = Phone.LTE_ON_CDMA_TRUE; + int curVal; + String productType = ""; + + curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE, + Phone.LTE_ON_CDMA_UNKNOWN); + retVal = curVal; + if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) { + Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine); + if (matcher.find()) { + productType = matcher.group(1); + if (sLteOnCdmaProductType.equals(productType)) { + retVal = Phone.LTE_ON_CDMA_TRUE; + } else { + retVal = Phone.LTE_ON_CDMA_FALSE; + } } else { retVal = Phone.LTE_ON_CDMA_FALSE; } - } else { - retVal = Phone.LTE_ON_CDMA_FALSE; - productType = ""; } - Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " product_type='" + productType + + Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal + + " product_type='" + productType + "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'"); return retVal; } diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index 60cf9b7f362b..abb45234dc8e 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -79,6 +79,15 @@ public interface TelephonyProperties */ static final String PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE = "telephony.lteOnCdmaProductType"; + /** + * The contents of this property is the one of {@link Phone#LTE_ON_CDMA_TRUE} or + * {@link Phone#LTE_ON_CDMA_FALSE}. If absent the value will assumed to be false + * and the {@see #PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE} will be used to determine its + * final value which could also be {@link Phone#LTE_ON_CDMA_FALSE}. + * {@see BaseCommands#getLteOnCdmaMode()} + */ + static final String PROPERTY_LTE_ON_CDMA_DEVICE = "telephony.lteOnCdmaDevice"; + static final String CURRENT_ACTIVE_PHONE = "gsm.current.phone-type"; //****** SIM Card diff --git a/tests/BiDiTests/res/layout/canvas2.xml b/tests/BiDiTests/res/layout/canvas2.xml new file mode 100644 index 000000000000..b3e038fba07d --- /dev/null +++ b/tests/BiDiTests/res/layout/canvas2.xml @@ -0,0 +1,66 @@ +<?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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/canvas2" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <LinearLayout + xmlns:local="http://schemas.android.com/apk/res/com.android.bidi" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <TextView + android:text="@string/ltr" + android:textSize="40dip" + android:gravity="center" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> + + <com.android.bidi.BiDiTestViewDrawText + local:text="@string/ltr" + android:layout_width="fill_parent" + android:layout_height="64dp" /> + + <TextView + android:text="@string/rtl" + android:textSize="40dip" + android:gravity="center" + android:layout_width="fill_parent" + android:layout_height="wrap_content"/> + + <com.android.bidi.BiDiTestViewDrawText + local:text="@string/rtl" + android:layout_width="fill_parent" + android:layout_height="64dp" /> + + <TextView + android:text="@string/composing" + android:textSize="40dip" + android:gravity="center" + android:layout_width="fill_parent" + android:layout_height="wrap_content"/> + + <com.android.bidi.BiDiTestViewDrawText + local:text="@string/composing" + android:layout_width="fill_parent" + android:layout_height="64dp" /> + + </LinearLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/tests/BiDiTests/res/values/attrs.xml b/tests/BiDiTests/res/values/attrs.xml new file mode 100644 index 000000000000..7f8a1d8f1e90 --- /dev/null +++ b/tests/BiDiTests/res/values/attrs.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <declare-styleable name="DrawTextTestView"> + <attr name="size" format="dimension" /> + <attr name="color" format="color" /> + <attr name="text" format="string" /> + </declare-styleable> +</resources>
\ No newline at end of file diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml index bc99e79bb253..1f6be7fd7ef6 100644 --- a/tests/BiDiTests/res/values/strings.xml +++ b/tests/BiDiTests/res/values/strings.xml @@ -42,5 +42,8 @@ <string name="textview_hebrew_text">םמab?!</string> <string name="textview_latin_text">abםמ?!</string> <string name="textview_multiline_text">םמ?!\nab?!\n?!</string> + <string name="ltr">Left to right text"</string> + <string name="rtl">"والحق أن تترك ونص"</string> + <string name="composing">"\u0644\u0627"</string> </resources> diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java index 7002c4148786..6b38cc145c26 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java @@ -102,6 +102,7 @@ public class BiDiTestActivity extends Activity { addItem(result, "Basic", BiDiTestBasic.class, R.id.basic); addItem(result, "Canvas", BiDiTestCanvas.class, R.id.canvas); + addItem(result, "Canvas2", BiDiTestCanvas2.class, R.id.canvas2); addItem(result, "Linear LTR", BiDiTestLinearLayoutLtr.class, R.id.linear_layout_ltr); addItem(result, "Linear RTL", BiDiTestLinearLayoutRtl.class, R.id.linear_layout_rtl); diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java new file mode 100644 index 000000000000..b801f0eefc60 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java @@ -0,0 +1,36 @@ +/* + * 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 com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.SeekBar; + +import static com.android.bidi.BiDiTestConstants.FONT_MAX_SIZE; +import static com.android.bidi.BiDiTestConstants.FONT_MIN_SIZE; + +public class BiDiTestCanvas2 extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.canvas2, container, false); + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java index 27e188718ec8..0126deafe89d 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java @@ -21,7 +21,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; -import android.graphics.Typeface; +import android.text.TextPaint; import android.util.AttributeSet; import android.util.Log; import android.view.View; @@ -37,7 +37,6 @@ public class BiDiTestView extends View { private static final float DEFAULT_ITALIC_SKEW_X = -0.25f; - private Paint paint = new Paint(); private Rect rect = new Rect(); private String NORMAL_TEXT; @@ -51,8 +50,7 @@ public class BiDiTestView extends View { private String CHINESE_TEXT; private String MIXED_TEXT_1; private String HEBREW_TEXT; - - private Typeface typeface; + private String RTL_TEXT; private int currentTextSize; @@ -83,9 +81,7 @@ public class BiDiTestView extends View { CHINESE_TEXT = context.getString(R.string.chinese_text); MIXED_TEXT_1 = context.getString(R.string.mixed_text_1); HEBREW_TEXT = context.getString(R.string.hebrew_text); - - typeface = paint.getTypeface(); - paint.setAntiAlias(true); + RTL_TEXT = context.getString(R.string.rtl); } public void setCurrentTextSize(int size) { @@ -95,54 +91,56 @@ public class BiDiTestView extends View { @Override public void onDraw(Canvas canvas) { - drawInsideRect(canvas, Color.BLACK); + drawInsideRect(canvas, new Paint(), Color.BLACK); int deltaX = 0; deltaX = testString(canvas, NORMAL_TEXT, ORIGIN, ORIGIN, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); deltaX += testString(canvas, ITALIC_TEXT, ORIGIN + deltaX, ORIGIN, - paint, typeface, true, false, Paint.DIRECTION_LTR, currentTextSize); + true, false, Paint.DIRECTION_LTR, currentTextSize); deltaX += testString(canvas, BOLD_TEXT, ORIGIN + deltaX, ORIGIN, - paint, typeface, false, true, Paint.DIRECTION_LTR, currentTextSize); + false, true, Paint.DIRECTION_LTR, currentTextSize); deltaX += testString(canvas, BOLD_ITALIC_TEXT, ORIGIN + deltaX, ORIGIN, - paint, typeface, true, true, Paint.DIRECTION_LTR, currentTextSize); + true, true, Paint.DIRECTION_LTR, currentTextSize); // Test with a long string deltaX = testString(canvas, NORMAL_LONG_TEXT, ORIGIN, ORIGIN + 2 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test with a long string deltaX = testString(canvas, NORMAL_LONG_TEXT_2, ORIGIN, ORIGIN + 4 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test with a long string deltaX = testString(canvas, NORMAL_LONG_TEXT_3, ORIGIN, ORIGIN + 6 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test Arabic ligature deltaX = testString(canvas, ARABIC_TEXT, ORIGIN, ORIGIN + 8 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_RTL, currentTextSize); + false, false, Paint.DIRECTION_RTL, currentTextSize); // Test Chinese deltaX = testString(canvas, CHINESE_TEXT, ORIGIN, ORIGIN + 10 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test Mixed (English and Arabic) deltaX = testString(canvas, MIXED_TEXT_1, ORIGIN, ORIGIN + 12 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test Hebrew - deltaX = testString(canvas, HEBREW_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_RTL, currentTextSize); + deltaX = testString(canvas, RTL_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize, + false, false, Paint.DIRECTION_RTL, currentTextSize); } - private int testString(Canvas canvas, String text, int x, int y, Paint paint, Typeface typeface, + private int testString(Canvas canvas, String text, int x, int y, boolean isItalic, boolean isBold, int dir, int textSize) { - paint.setTypeface(typeface); + + TextPaint paint = new TextPaint(); + paint.setAntiAlias(true); // Set paint properties boolean oldFakeBold = paint.isFakeBoldText(); @@ -153,9 +151,9 @@ public class BiDiTestView extends View { paint.setTextSkewX(DEFAULT_ITALIC_SKEW_X); } - Log.v(TAG, "START -- drawTextWithCanvasDrawText"); - drawTextWithCanvasDrawText(text, canvas, x, y, textSize, Color.WHITE, dir); - Log.v(TAG, "END -- drawTextWithCanvasDrawText"); + paint.setTextSize(textSize); + paint.setColor(Color.WHITE); + canvas.drawText(text, x, y, paint); int length = text.length(); float[] advances = new float[length]; @@ -167,13 +165,6 @@ public class BiDiTestView extends View { logAdvances(text, textWidthHB, textWidthICU, advances); drawMetricsAroundText(canvas, x, y, textWidthHB, textWidthICU, textSize, Color.RED, Color.GREEN); - paint.setColor(Color.WHITE); - - Log.v(TAG, "START -- drawText"); - setPaintDir(paint, dir); - canvas.drawText(text, x, y + currentTextSize, this.paint); - Log.v(TAG, "END -- drawText"); - // Restore old paint properties paint.setFakeBoldText(oldFakeBold); paint.setTextSkewX(oldTextSkewX); @@ -186,7 +177,7 @@ public class BiDiTestView extends View { paint.setBidiFlags(dir); } - private void drawInsideRect(Canvas canvas, int color) { + private void drawInsideRect(Canvas canvas, Paint paint, int color) { paint.setColor(color); int width = getWidth(); int height = getHeight(); @@ -194,16 +185,9 @@ public class BiDiTestView extends View { canvas.drawRect(rect, paint); } - private void drawTextWithCanvasDrawText(String text, Canvas canvas, - float x, float y, float textSize, int color, int dir) { - setPaintDir(paint, dir); - paint.setColor(color); - paint.setTextSize(textSize); - canvas.drawText(text, x, y, paint); - } - private void drawMetricsAroundText(Canvas canvas, int x, int y, float textWidthHB, float textWidthICU, int textSize, int color, int colorICU) { + Paint paint = new Paint(); paint.setColor(color); canvas.drawLine(x, y - textSize, x, y + 8, paint); canvas.drawLine(x, y + 8, x + textWidthHB, y + 8, paint); diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java new file mode 100644 index 000000000000..dfdb8072836a --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java @@ -0,0 +1,66 @@ +/* + * 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 com.android.bidi; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint.Align; +import android.text.TextPaint; +import android.util.AttributeSet; +import android.view.View; + +public class BiDiTestViewDrawText extends View { + private float mSize; + private int mColor; + private String mText; + + public BiDiTestViewDrawText(Context context) { + this(context, null); + } + + public BiDiTestViewDrawText(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public BiDiTestViewDrawText(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + final TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.DrawTextTestView, defStyle, 0); + mSize = a.getDimension(R.styleable.DrawTextTestView_size, 40.0f); + mColor = a.getColor(R.styleable.DrawTextTestView_color, Color.YELLOW); + final CharSequence text = a.getText(R.styleable.DrawTextTestView_text); + mText = (text != null) ? text.toString() : "(empty)"; + a.recycle(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + final int width = getWidth(); + final int height = getHeight(); + + final TextPaint paint = new TextPaint(); + paint.setTextSize(mSize); + paint.setColor(mColor); + paint.setTextAlign(Align.CENTER); + + canvas.drawText(mText, width / 2, height * 2 / 3, paint); + } +}
\ No newline at end of file diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java index af5006f28f15..38a85a3a2c98 100644 --- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java +++ b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java @@ -95,9 +95,7 @@ public class Activity2 extends Activity { } { Space v = new Space(context); - { - vg.addView(v, new LayoutParams(row5, col3)); - } + vg.addView(v, new LayoutParams(row5, col3)); } { Button v = new Button(context); diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 32a6a659172b..9fcd05aa3555 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -94,6 +94,15 @@ </activity> <activity + android:name="CanvasTextureViewActivity" + android:label="_CanvasTextureView"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="GLTextureViewActivity" android:label="_TextureViewGL"> <intent-filter> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java new file mode 100644 index 000000000000..81c22b88900b --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java @@ -0,0 +1,120 @@ +/* + * 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 com.android.test.hwui; + +import android.app.Activity; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.SurfaceTexture; +import android.os.Bundle; +import android.view.Gravity; +import android.view.TextureView; +import android.widget.FrameLayout; + +@SuppressWarnings({"UnusedDeclaration"}) +public class CanvasTextureViewActivity extends Activity + implements TextureView.SurfaceTextureListener { + private TextureView mTextureView; + private CanvasTextureViewActivity.RenderingThread mThread; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + FrameLayout content = new FrameLayout(this); + + mTextureView = new TextureView(this); + mTextureView.setSurfaceTextureListener(this); + mTextureView.setOpaque(false); + + content.addView(mTextureView, new FrameLayout.LayoutParams(500, 500, Gravity.CENTER)); + setContentView(content); + } + + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + mThread = new RenderingThread(mTextureView); + mThread.start(); + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + // Ignored + } + + @Override + public void onSurfaceTextureDestroyed(SurfaceTexture surface) { + if (mThread != null) mThread.stopRendering(); + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + // Ignored + } + + private static class RenderingThread extends Thread { + private final TextureView mSurface; + private volatile boolean mRunning = true; + + public RenderingThread(TextureView surface) { + mSurface = surface; + } + + @Override + public void run() { + float x = 0.0f; + float y = 0.0f; + float speedX = 5.0f; + float speedY = 3.0f; + + Paint paint = new Paint(); + paint.setColor(0xff00ff00); + + while (mRunning && !Thread.interrupted()) { + final Canvas canvas = mSurface.lockCanvas(null); + try { + canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); + canvas.drawRect(x, y, x + 20.0f, y + 20.0f, paint); + } finally { + mSurface.unlockCanvasAndPost(canvas); + } + + if (x + 20.0f + speedX >= mSurface.getWidth() || x + speedX <= 0.0f) { + speedX = -speedX; + } + if (y + 20.0f + speedY >= mSurface.getHeight() || y + speedY <= 0.0f) { + speedY = -speedY; + } + + x += speedX; + y += speedY; + + try { + Thread.sleep(15); + } catch (InterruptedException e) { + // Interrupted + } + } + } + + void stopRendering() { + interrupt(); + mRunning = false; + } + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java index 1394c32366b8..2519ebc4bbcb 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java @@ -107,7 +107,7 @@ public class BridgeIInputMethodManager implements IInputMethodManager { } - public boolean setAdditionalInputMethodSubtypes(IBinder arg0, InputMethodSubtype[] arg1) + public boolean setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1) throws RemoteException { // TODO Auto-generated method stub return false; |