diff options
185 files changed, 1945 insertions, 430 deletions
diff --git a/api/current.xml b/api/current.xml index c4fc0e470c56..a36f0665498b 100644 --- a/api/current.xml +++ b/api/current.xml @@ -35340,6 +35340,17 @@ visibility="public" > </field> +<field name="EXTRA_NEW_SEARCH" + type="java.lang.String" + transient="false" + volatile="false" + value=""new_search"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="EXTRA_SELECT_QUERY" type="java.lang.String" transient="false" @@ -156122,6 +156133,17 @@ visibility="public" > </field> +<field name="EXTRA_CREATE_NEW_TAB" + type="java.lang.String" + transient="false" + volatile="false" + value=""create_new_tab"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="EXTRA_HEADERS" type="java.lang.String" transient="false" diff --git a/core/java/android/animation/package.html b/core/java/android/animation/package.html index ff4326092c41..92eeb20c96be 100644 --- a/core/java/android/animation/package.html +++ b/core/java/android/animation/package.html @@ -15,7 +15,7 @@ behaviors.</p> <p> For a guide on how to use the property animation system, see the -<a href="{@docRoot}guide/topics/media/index.html">Animation</a> developer guide. +<a href="{@docRoot}guide/topics/graphics/animation.html">Animation</a> developer guide. </p> </body> </html> diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index a660076b4b03..77dc08486810 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -30,11 +30,17 @@ import android.os.RemoteException; import android.os.Handler; import android.os.Parcel; import android.os.Parcelable; +import android.os.ServiceManager; import android.os.SystemProperties; import android.text.TextUtils; import android.util.DisplayMetrics; +import android.util.Log; +import com.android.internal.app.IUsageStats; +import com.android.internal.os.PkgUsageStats; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Interact with the overall activities running in the system. @@ -1233,4 +1239,29 @@ public class ActivityManager { public static boolean isRunningInTestHarness() { return SystemProperties.getBoolean("ro.test_harness", false); } + + /** + * Returns the launch count of each installed package. + * + * @hide + */ + public Map<String, Integer> getAllPackageLaunchCounts() { + try { + IUsageStats usageStatsService = IUsageStats.Stub.asInterface( + ServiceManager.getService("usagestats")); + if (usageStatsService == null) { + return new HashMap<String, Integer>(); + } + + Map<String, Integer> launchCounts = new HashMap<String, Integer>(); + for (PkgUsageStats pkgUsageStats : usageStatsService.getAllPkgUsageStats()) { + launchCounts.put(pkgUsageStats.packageName, pkgUsageStats.launchCount); + } + + return launchCounts; + } catch (RemoteException e) { + Log.w(TAG, "Could not query launch counts", e); + return new HashMap<String, Integer>(); + } + } } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 4370ebf93c28..ccd65dee36dd 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -82,6 +82,7 @@ public class Notification implements Parcelable /** * The resource id of a drawable to use as the icon in the status bar. + * This is required; notifications with an invalid icon resource will not be shown. */ public int icon; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index e3242c102379..6541c54edb5f 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -83,12 +83,14 @@ public class NotificationManager } /** - * Persistent notification on the status bar, + * Post a notification to be shown in the status bar. If a notification with + * the same id has already been posted by your application and has not yet been canceled, it + * will be replaced by the updated information. * * @param id An identifier for this notification unique within your * application. - * @param notification A {@link Notification} object describing how to - * notify the user, other than the view you're providing. Must not be null. + * @param notification A {@link Notification} object describing what to show the user. Must not + * be null. */ public void notify(int id, Notification notification) { @@ -96,13 +98,15 @@ public class NotificationManager } /** - * Persistent notification on the status bar, + * Post a notification to be shown in the status bar. If a notification with + * the same tag and id has already been posted by your application and has not yet been + * canceled, it will be replaced by the updated information. * * @param tag A string identifier for this notification. May be {@code null}. * @param id An identifier for this notification. The pair (tag, id) must be unique * within your application. - * @param notification A {@link Notification} object describing how to - * notify the user, other than the view you're providing. Must not be null. + * @param notification A {@link Notification} object describing what to + * show the user. Must not be null. */ public void notify(String tag, int id, Notification notification) { diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index 671501255e28..aab087fcf54f 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -138,6 +138,12 @@ public class SearchManager public final static String EXTRA_SELECT_QUERY = "select_query"; /** + * Boolean extra data key for {@link Intent#ACTION_WEB_SEARCH} intents. If {@code true}, + * this search should open a new browser window, rather than using an existing one. + */ + public final static String EXTRA_NEW_SEARCH = "new_search"; + + /** * Boolean extra data key for a suggestion provider to return in {@link Cursor#getExtras} to * indicate that the search is not complete yet. This can be used by the search UI * to indicate that a search is in progress. The suggestion provider can return partial results diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index c2f3ae70b8b2..d8a5b45c9cda 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -508,23 +508,86 @@ public class Camera { * finish processing the data in them. * * <p>The size of the buffer is determined by multiplying the preview - * image width, height, and bytes per pixel. The width and height can be - * read from {@link Camera.Parameters#getPreviewSize()}. Bytes per pixel + * image width, height, and bytes per pixel. The width and height can be + * read from {@link Camera.Parameters#getPreviewSize()}. Bytes per pixel * can be computed from * {@link android.graphics.ImageFormat#getBitsPerPixel(int)} / 8, * using the image format from {@link Camera.Parameters#getPreviewFormat()}. * * <p>This method is only necessary when - * {@link #setPreviewCallbackWithBuffer(PreviewCallback)} is used. When + * {@link #setPreviewCallbackWithBuffer(PreviewCallback)} is used. When * {@link #setPreviewCallback(PreviewCallback)} or * {@link #setOneShotPreviewCallback(PreviewCallback)} are used, buffers - * are automatically allocated. + * are automatically allocated. When a supplied buffer is too small to + * hold the preview frame data, preview callback will return null and + * the buffer will be removed from the buffer queue. * * @param callbackBuffer the buffer to add to the queue. * The size should be width * height * bits_per_pixel / 8. * @see #setPreviewCallbackWithBuffer(PreviewCallback) */ - public native final void addCallbackBuffer(byte[] callbackBuffer); + public final void addCallbackBuffer(byte[] callbackBuffer) + { + _addCallbackBuffer(callbackBuffer, CAMERA_MSG_PREVIEW_FRAME); + } + + /** + * Adds a pre-allocated buffer to the raw image callback buffer queue. + * Applications can add one or more buffers to the queue. When a raw image + * frame arrives and there is still at least one available buffer, the + * buffer will be used to hold the raw image data and removed from the + * queue. Then raw image callback is invoked with the buffer. If a raw + * image frame arrives but there is no buffer left, the frame is + * discarded. Applications should add buffers back when they finish + * processing the data in them by calling this method again in order + * to avoid running out of raw image callback buffers. + * + * <p>The size of the buffer is determined by multiplying the raw image + * width, height, and bytes per pixel. The width and height can be + * read from {@link Camera.Parameters#getPictureSize()}. Bytes per pixel + * can be computed from + * {@link android.graphics.ImageFormat#getBitsPerPixel(int)} / 8, + * using the image format from {@link Camera.Parameters#getPreviewFormat()}. + * + * <p>This method is only necessary when the PictureCallbck for raw image + * is used while calling {@link #takePicture(Camera.ShutterCallback, + * Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)}. + * + * Please note that by calling this method, the mode for application-managed + * callback buffers is triggered. If this method has never been called, + * null will be returned by the raw image callback since there is + * no image callback buffer available. Furthermore, When a supplied buffer + * is too small to hold the raw image data, raw image callback will return + * null and the buffer will be removed from the buffer queue. + * + * @param callbackBuffer the buffer to add to the raw image callback buffer + * queue. The size should be width * height * (bits per pixel) / 8. An + * null callbackBuffer will be ignored and won't be added to the queue. + * + * @see #takePicture(Camera.ShutterCallback, + * Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)}. + * + * {@hide} + */ + public final void addRawImageCallbackBuffer(byte[] callbackBuffer) + { + addCallbackBuffer(callbackBuffer, CAMERA_MSG_RAW_IMAGE); + } + + private final void addCallbackBuffer(byte[] callbackBuffer, int msgType) + { + // CAMERA_MSG_VIDEO_FRAME may be allowed in the future. + if (msgType != CAMERA_MSG_PREVIEW_FRAME && + msgType != CAMERA_MSG_RAW_IMAGE) { + throw new IllegalArgumentException( + "Unsupported message type: " + msgType); + } + + _addCallbackBuffer(callbackBuffer, msgType); + } + + private native final void _addCallbackBuffer( + byte[] callbackBuffer, int msgType); private class EventHandler extends Handler { @@ -735,7 +798,7 @@ public class Camera { PictureCallback jpeg) { takePicture(shutter, raw, null, jpeg); } - private native final void native_takePicture(); + private native final void native_takePicture(int msgType); /** * Triggers an asynchronous image capture. The camera service will initiate @@ -743,7 +806,8 @@ public class Camera { * The shutter callback occurs after the image is captured. This can be used * to trigger a sound to let the user know that image has been captured. The * raw callback occurs when the raw image data is available (NOTE: the data - * may be null if the hardware does not have enough memory to make a copy). + * will be null if there is no raw image callback buffer available or the + * raw image callback buffer is not large enough to hold the raw image). * The postview callback occurs when a scaled, fully processed postview * image is available (NOTE: not all hardware supports this). The jpeg * callback occurs when the compressed image is available. If the @@ -762,6 +826,8 @@ public class Camera { * @param raw the callback for raw (uncompressed) image data, or null * @param postview callback with postview image data, may be null * @param jpeg the callback for JPEG image data, or null + * + * @see #addRawImageCallbackBuffer(byte[]) */ public final void takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback postview, PictureCallback jpeg) { @@ -769,7 +835,23 @@ public class Camera { mRawImageCallback = raw; mPostviewCallback = postview; mJpegCallback = jpeg; - native_takePicture(); + + // If callback is not set, do not send me callbacks. + int msgType = 0; + if (mShutterCallback != null) { + msgType |= CAMERA_MSG_SHUTTER; + } + if (mRawImageCallback != null) { + msgType |= CAMERA_MSG_RAW_IMAGE; + } + if (mPostviewCallback != null) { + msgType |= CAMERA_MSG_POSTVIEW_FRAME; + } + if (mJpegCallback != null) { + msgType |= CAMERA_MSG_COMPRESSED_IMAGE; + } + + native_takePicture(msgType); } /** diff --git a/core/java/android/pim/ICalendar.java b/core/java/android/pim/ICalendar.java index cc0f45ee2402..9c4eaf4f5765 100644 --- a/core/java/android/pim/ICalendar.java +++ b/core/java/android/pim/ICalendar.java @@ -578,6 +578,23 @@ public class ICalendar { + text); } parameter.name = text.substring(startIndex + 1, equalIndex); + } else if (c == '"') { + if (parameter == null) { + throw new FormatException("Expected parameter before '\"' in " + text); + } + if (equalIndex == -1) { + throw new FormatException("Expected '=' within parameter in " + text); + } + if (state.index > equalIndex + 1) { + throw new FormatException("Parameter value cannot contain a '\"' in " + text); + } + final int endQuote = text.indexOf('"', state.index + 1); + if (endQuote < 0) { + throw new FormatException("Expected closing '\"' in " + text); + } + parameter.value = text.substring(state.index + 1, endQuote); + state.index = endQuote + 1; + return parameter; } ++state.index; } diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java index 3bfd005d2058..57ee440755cd 100644 --- a/core/java/android/provider/Browser.java +++ b/core/java/android/provider/Browser.java @@ -139,8 +139,6 @@ public class Browser { public static final int SEARCHES_PROJECTION_SEARCH_INDEX = 1; public static final int SEARCHES_PROJECTION_DATE_INDEX = 2; - private static final String SEARCHES_WHERE_CLAUSE = "search = ?"; - /* Set a cap on the count of history items in the history/bookmark table, to prevent db and layout operations from dragging to a crawl. Revisit this cap when/if db/layout performance @@ -167,6 +165,13 @@ public class Browser { } /** + * Passed along with an Intent to a browser, specifying that a new tab + * be created. Overrides EXTRA_APPLICATION_ID; if both are set, a new tab + * will be used, rather than using the same one. + */ + public static final String EXTRA_CREATE_NEW_TAB = "create_new_tab"; + + /** * Stores a Bitmap extra in an {@link Intent} representing the screenshot of * a page to share. When receiving an {@link Intent#ACTION_SEND} from the * Browser, use this to access the screenshot. diff --git a/core/java/android/webkit/SelectActionModeCallback.java b/core/java/android/webkit/SelectActionModeCallback.java index ea09fc0c0ed0..104deb1c82f0 100644 --- a/core/java/android/webkit/SelectActionModeCallback.java +++ b/core/java/android/webkit/SelectActionModeCallback.java @@ -83,6 +83,7 @@ class SelectActionModeCallback implements ActionMode.Callback { case com.android.internal.R.id.websearch: mode.finish(); Intent i = new Intent(Intent.ACTION_WEB_SEARCH); + i.putExtra(SearchManager.EXTRA_NEW_SEARCH, true); i.putExtra(SearchManager.QUERY, mWebView.getSelection()); mWebView.getContext().startActivity(i); break; diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index ef4e4e0a18a9..cf72ec40f604 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -701,8 +701,8 @@ public class ProgressBar extends View { if (mProgress > max) { mProgress = max; - refreshProgress(R.id.progress, mProgress, false); } + refreshProgress(R.id.progress, mProgress, false); } } diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 9f70509f43c0..bfbfd374bbe7 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -53,25 +53,48 @@ public: virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr); virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); - void addCallbackBuffer(JNIEnv *env, jbyteArray cbb); + void addCallbackBuffer(JNIEnv *env, jbyteArray cbb, int msgType); void setCallbackMode(JNIEnv *env, bool installed, bool manualMode); sp<Camera> getCamera() { Mutex::Autolock _l(mLock); return mCamera; } + bool isRawImageCallbackBufferAvailable() const; void release(); private: void copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int msgType); + void clearCallbackBuffers_l(JNIEnv *env, Vector<jbyteArray> *buffers); void clearCallbackBuffers_l(JNIEnv *env); + jbyteArray getCallbackBuffer(JNIEnv *env, Vector<jbyteArray> *buffers, size_t bufferSize); jobject mCameraJObjectWeak; // weak reference to java object jclass mCameraJClass; // strong reference to java class sp<Camera> mCamera; // strong reference to native object Mutex mLock; + /* + * Global reference application-managed raw image buffer queue. + * + * Manual-only mode is supported for raw image callbacks, which is + * set whenever method addCallbackBuffer() with msgType = + * CAMERA_MSG_RAW_IMAGE is called; otherwise, null is returned + * with raw image callbacks. + */ + Vector<jbyteArray> mRawImageCallbackBuffers; + + /* + * Application-managed preview buffer queue and the flags + * associated with the usage of the preview buffer callback. + */ Vector<jbyteArray> mCallbackBuffers; // Global reference application managed byte[] bool mManualBufferMode; // Whether to use application managed buffers. - bool mManualCameraCallbackSet; // Whether the callback has been set, used to reduce unnecessary calls to set the callback. + bool mManualCameraCallbackSet; // Whether the callback has been set, used to + // reduce unnecessary calls to set the callback. }; +bool JNICameraContext::isRawImageCallbackBufferAvailable() const +{ + return !mRawImageCallbackBuffers.isEmpty(); +} + sp<Camera> get_native_camera(JNIEnv *env, jobject thiz, JNICameraContext** pContext) { sp<Camera> camera; @@ -128,10 +151,48 @@ void JNICameraContext::notify(int32_t msgType, int32_t ext1, int32_t ext2) return; } JNIEnv *env = AndroidRuntime::getJNIEnv(); + + /* + * If the notification or msgType is CAMERA_MSG_RAW_IMAGE_NOTIFY, change it + * to CAMERA_MSG_RAW_IMAGE since CAMERA_MSG_RAW_IMAGE_NOTIFY is not exposed + * to the Java app. + */ + if (msgType == CAMERA_MSG_RAW_IMAGE_NOTIFY) { + msgType = CAMERA_MSG_RAW_IMAGE; + } + env->CallStaticVoidMethod(mCameraJClass, fields.post_event, mCameraJObjectWeak, msgType, ext1, ext2, NULL); } +jbyteArray JNICameraContext::getCallbackBuffer( + JNIEnv* env, Vector<jbyteArray>* buffers, size_t bufferSize) +{ + jbyteArray obj = NULL; + + // Vector access should be protected by lock in postData() + if (!buffers->isEmpty()) { + LOGV("Using callback buffer from queue of length %d", buffers->size()); + jbyteArray globalBuffer = buffers->itemAt(0); + buffers->removeAt(0); + + obj = (jbyteArray)env->NewLocalRef(globalBuffer); + env->DeleteGlobalRef(globalBuffer); + + if (obj != NULL) { + jsize bufferLength = env->GetArrayLength(obj); + if ((int)bufferLength < (int)bufferSize) { + LOGE("Callback buffer was too small! Expected %d bytes, but got %d bytes!", + bufferSize, bufferLength); + env->DeleteLocalRef(obj); + return NULL; + } + } + } + + return obj; +} + void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int msgType) { jbyteArray obj = NULL; @@ -141,7 +202,7 @@ void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int ssize_t offset; size_t size; sp<IMemoryHeap> heap = dataPtr->getMemory(&offset, &size); - LOGV("postData: off=%d, size=%d", offset, size); + LOGV("copyAndPost: off=%ld, size=%d", offset, size); uint8_t *heapBase = (uint8_t*)heap->base(); if (heapBase != NULL) { @@ -151,32 +212,28 @@ void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int LOGV("Allocating callback buffer"); obj = env->NewByteArray(size); } else { - // Vector access should be protected by lock in postData() - if(!mCallbackBuffers.isEmpty()) { - LOGV("Using callback buffer from queue of length %d", mCallbackBuffers.size()); - jbyteArray globalBuffer = mCallbackBuffers.itemAt(0); - mCallbackBuffers.removeAt(0); - - obj = (jbyteArray)env->NewLocalRef(globalBuffer); - env->DeleteGlobalRef(globalBuffer); - - if (obj != NULL) { - jsize bufferLength = env->GetArrayLength(obj); - if ((int)bufferLength < (int)size) { - LOGE("Manually set buffer was too small! Expected %d bytes, but got %d!", - size, bufferLength); - env->DeleteLocalRef(obj); - return; + switch (msgType) { + case CAMERA_MSG_PREVIEW_FRAME: { + obj = getCallbackBuffer(env, &mCallbackBuffers, size); + + if (mCallbackBuffers.isEmpty()) { + LOGV("Out of buffers, clearing callback!"); + mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP); + mManualCameraCallbackSet = false; + + if (obj == NULL) { + return; + } } + break; } - } - - if(mCallbackBuffers.isEmpty()) { - LOGV("Out of buffers, clearing callback!"); - mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP); - mManualCameraCallbackSet = false; - - if (obj == NULL) { + case CAMERA_MSG_RAW_IMAGE: { + obj = getCallbackBuffer(env, &mRawImageCallbackBuffers, size); + break; + } + default: { + jniThrowException(env, + "java/lang/RuntimeException", "Unsupported message type"); return; } } @@ -212,21 +269,27 @@ void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr) } // return data based on callback type - switch(msgType) { - case CAMERA_MSG_VIDEO_FRAME: - // should never happen - break; - // don't return raw data to Java - case CAMERA_MSG_RAW_IMAGE: - LOGV("rawCallback"); - env->CallStaticVoidMethod(mCameraJClass, fields.post_event, - mCameraJObjectWeak, msgType, 0, 0, NULL); - break; - default: - // TODO: Change to LOGV - LOGV("dataCallback(%d, %p)", msgType, dataPtr.get()); - copyAndPost(env, dataPtr, msgType); - break; + switch (msgType) { + case CAMERA_MSG_VIDEO_FRAME: + // should never happen + break; + + // For backward-compatibility purpose, if there is no callback + // buffer for raw image, the callback returns null. + case CAMERA_MSG_RAW_IMAGE: + LOGV("rawCallback"); + if (mRawImageCallbackBuffers.isEmpty()) { + env->CallStaticVoidMethod(mCameraJClass, fields.post_event, + mCameraJObjectWeak, msgType, 0, 0, NULL); + } else { + copyAndPost(env, dataPtr, msgType); + } + break; + + default: + LOGV("dataCallback(%d, %p)", msgType, dataPtr.get()); + copyAndPost(env, dataPtr, msgType); + break; } } @@ -251,7 +314,7 @@ void JNICameraContext::setCallbackMode(JNIEnv *env, bool installed, bool manualM if (!installed) { mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP); - clearCallbackBuffers_l(env); + clearCallbackBuffers_l(env, &mCallbackBuffers); } else if (mManualBufferMode) { if (!mCallbackBuffers.isEmpty()) { mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_CAMERA); @@ -259,24 +322,44 @@ void JNICameraContext::setCallbackMode(JNIEnv *env, bool installed, bool manualM } } else { mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_BARCODE_SCANNER); - clearCallbackBuffers_l(env); + clearCallbackBuffers_l(env, &mCallbackBuffers); } } -void JNICameraContext::addCallbackBuffer(JNIEnv *env, jbyteArray cbb) +void JNICameraContext::addCallbackBuffer( + JNIEnv *env, jbyteArray cbb, int msgType) { + LOGV("addCallbackBuffer: 0x%x", msgType); if (cbb != NULL) { Mutex::Autolock _l(mLock); - jbyteArray callbackBuffer = (jbyteArray)env->NewGlobalRef(cbb); - mCallbackBuffers.push(cbb); - - LOGV("Adding callback buffer to queue, %d total", mCallbackBuffers.size()); - - // We want to make sure the camera knows we're ready for the next frame. - // This may have come unset had we not had a callbackbuffer ready for it last time. - if (mManualBufferMode && !mManualCameraCallbackSet) { - mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_CAMERA); - mManualCameraCallbackSet = true; + switch (msgType) { + case CAMERA_MSG_PREVIEW_FRAME: { + jbyteArray callbackBuffer = (jbyteArray)env->NewGlobalRef(cbb); + mCallbackBuffers.push(callbackBuffer); + + LOGV("Adding callback buffer to queue, %d total", + mCallbackBuffers.size()); + + // We want to make sure the camera knows we're ready for the + // next frame. This may have come unset had we not had a + // callbackbuffer ready for it last time. + if (mManualBufferMode && !mManualCameraCallbackSet) { + mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_CAMERA); + mManualCameraCallbackSet = true; + } + break; + } + case CAMERA_MSG_RAW_IMAGE: { + jbyteArray callbackBuffer = (jbyteArray)env->NewGlobalRef(cbb); + mRawImageCallbackBuffers.push(callbackBuffer); + break; + } + default: { + jniThrowException(env, + "java/lang/IllegalArgumentException", + "Unsupported message type"); + return; + } } } else { LOGE("Null byte array!"); @@ -285,10 +368,15 @@ void JNICameraContext::addCallbackBuffer(JNIEnv *env, jbyteArray cbb) void JNICameraContext::clearCallbackBuffers_l(JNIEnv *env) { - LOGV("Clearing callback buffers, %d remained", mCallbackBuffers.size()); - while(!mCallbackBuffers.isEmpty()) { - env->DeleteGlobalRef(mCallbackBuffers.top()); - mCallbackBuffers.pop(); + clearCallbackBuffers_l(env, &mCallbackBuffers); + clearCallbackBuffers_l(env, &mRawImageCallbackBuffers); +} + +void JNICameraContext::clearCallbackBuffers_l(JNIEnv *env, Vector<jbyteArray> *buffers) { + LOGV("Clearing callback buffers, %d remained", buffers->size()); + while (!buffers->isEmpty()) { + env->DeleteGlobalRef(buffers->top()); + buffers->pop(); } } @@ -458,13 +546,13 @@ static void android_hardware_Camera_setHasPreviewCallback(JNIEnv *env, jobject t context->setCallbackMode(env, installed, manualBuffer); } -static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes) { - LOGV("addCallbackBuffer"); +static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes, int msgType) { + LOGV("addCallbackBuffer: 0x%x", msgType); JNICameraContext* context = reinterpret_cast<JNICameraContext*>(env->GetIntField(thiz, fields.context)); if (context != NULL) { - context->addCallbackBuffer(env, bytes); + context->addCallbackBuffer(env, bytes, msgType); } } @@ -492,14 +580,32 @@ static void android_hardware_Camera_cancelAutoFocus(JNIEnv *env, jobject thiz) } } -static void android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz) +static void android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz, int msgType) { LOGV("takePicture"); JNICameraContext* context; sp<Camera> camera = get_native_camera(env, thiz, &context); if (camera == 0) return; - if (camera->takePicture() != NO_ERROR) { + /* + * When CAMERA_MSG_RAW_IMAGE is requested, if the raw image callback + * buffer is available, CAMERA_MSG_RAW_IMAGE is enabled to get the + * notification _and_ the data; otherwise, CAMERA_MSG_RAW_IMAGE_NOTIFY + * is enabled to receive the callback notification but no data. + * + * Note that CAMERA_MSG_RAW_IMAGE_NOTIFY is not exposed to the + * Java application. + */ + if (msgType & CAMERA_MSG_RAW_IMAGE) { + LOGV("Enable raw image callback buffer"); + if (!context->isRawImageCallbackBufferAvailable()) { + LOGV("Enable raw image notification, since no callback buffer exists"); + msgType &= ~CAMERA_MSG_RAW_IMAGE; + msgType |= CAMERA_MSG_RAW_IMAGE_NOTIFY; + } + } + + if (camera->takePicture(msgType) != NO_ERROR) { jniThrowException(env, "java/lang/RuntimeException", "takePicture failed"); return; } @@ -638,8 +744,8 @@ static JNINativeMethod camMethods[] = { { "setHasPreviewCallback", "(ZZ)V", (void *)android_hardware_Camera_setHasPreviewCallback }, - { "addCallbackBuffer", - "([B)V", + { "_addCallbackBuffer", + "([BI)V", (void *)android_hardware_Camera_addCallbackBuffer }, { "native_autoFocus", "()V", @@ -648,7 +754,7 @@ static JNINativeMethod camMethods[] = { "()V", (void *)android_hardware_Camera_cancelAutoFocus }, { "native_takePicture", - "()V", + "(I)V", (void *)android_hardware_Camera_takePicture }, { "native_setParameters", "(Ljava/lang/String;)V", diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp index fc806a502f15..667ba75ebd46 100644 --- a/core/jni/android_net_wifi_Wifi.cpp +++ b/core/jni/android_net_wifi_Wifi.cpp @@ -556,6 +556,18 @@ static jboolean android_net_wifi_setSuspendOptimizationsCommand(JNIEnv* env, job return doBooleanCommand(cmdstr, "OK"); } +static void android_net_wifi_enableBackgroundScan(JNIEnv* env, jobject clazz, jboolean enable) +{ + //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml + //and will need an update if the names are changed + if (enable) { + doBooleanCommand("DRIVER BGSCAN-START", "OK"); + } + else { + doBooleanCommand("DRIVER BGSCAN-STOP", "OK"); + } +} + // ---------------------------------------------------------------------------- /* @@ -623,6 +635,7 @@ static JNINativeMethod gWifiMethods[] = { (void*) android_net_wifi_setSuspendOptimizationsCommand}, { "setCountryCodeCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_setCountryCodeCommand}, + { "enableBackgroundScan", "(Z)V", (void*) android_net_wifi_enableBackgroundScan}, }; int register_android_net_wifi_WifiManager(JNIEnv* env) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 1df6fe5d8dec..12d7afd6eb20 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1196,7 +1196,7 @@ <permission android:name="android.permission.PACKAGE_USAGE_STATS" android:label="@string/permlab_pkgUsageStats" android:description="@string/permdesc_pkgUsageStats" - android:protectionLevel="signature" /> + android:protectionLevel="signatureOrSystem" /> <!-- Allows an application to collect battery statistics --> <permission android:name="android.permission.BATTERY_STATS" diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 0edd33e35c86..ce37943b492c 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -194,6 +194,13 @@ <!-- Boolean indicating whether the wifi chipset has dual frequency band support --> <bool translatable="false" name="config_wifi_dual_band_support">false</bool> + <!-- Boolean indicating whether the wifi chipset supports background scanning mechanism. + This mechanism allows the host to remain in suspend state and the dongle to actively + scan and wake the host when a configured SSID is detected by the dongle. This chipset + capability can provide power savings when wifi needs to be always kept on. + The driver commands needed to support the feature are BGSCAN-START and BGSCAN-STOP --> + <bool translatable="false" name="config_wifi_background_scan_support">false</bool> + <!-- Flag indicating whether the keyguard should be bypassed when the slider is open. This can be set or unset depending how easily the slider can be opened (for example, in a pocket or purse). --> diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java index 1374e7f8afef..41104fe4ad72 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java @@ -108,15 +108,6 @@ public class WifiApStress fail("thread in sleep is interrupted"); } assertTrue("no uplink data connection after Wi-Fi tethering", mAct.pingTest(null)); - // Wait for 5 minutes, and verify the data connection again. - // bug id: 3400027 - try { - Thread.sleep(5 * 60 * 1000); - } catch (Exception e) { - fail("thread in sleep is interrupted"); - } - // Verify the uplink data connection - assertTrue("no uplink data connection", mAct.pingTest(null)); // Disable soft AP assertTrue(mAct.mWifiManager.setWifiApEnabled(config, false)); // Wait for 30 seconds until Wi-Fi tethering is stopped diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd index f826f43d3712..ef1deba470e4 100644 --- a/docs/html/guide/appendix/market-filters.jd +++ b/docs/html/guide/appendix/market-filters.jd @@ -24,6 +24,8 @@ manifest file to the configurations defined by the device, as well as other fact <li><a href="{@docRoot}guide/practices/compatibility.html">Android Compatibility</a></li> <li><code><a +href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html"><supports-gl-texture></a></code></li> +<li><code><a href="{@docRoot}guide/topics/manifest/supports-screens-element.html"><supports-screens></a></code></li> <li><code><a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html"><uses-configuration></a></code></li> @@ -395,5 +397,12 @@ href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code with alternative resources.</p> </td> </tr> + <tr> + <td><nobr><a href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html">{@code +<supports-gl-texture>}</a></nobr></td> + <td> + <p>Android Market filters the application unless one or more of the GL texture compression formats supported by the application are also supported by the device. </p> + </td> + </tr> </table> diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd index bac6bf43be98..8509466d4856 100644 --- a/docs/html/guide/appendix/media-formats.jd +++ b/docs/html/guide/appendix/media-formats.jd @@ -168,7 +168,7 @@ page.title=Android Supported Media Formats <tr> -<td rowspan="3">Video</td> +<td rowspan="4">Video</td> <td>H.263</td> <td style="text-align: center;"><big>•</big></td> <td style="text-align: center;"><big>•</big></td> @@ -192,6 +192,14 @@ page.title=Android Supported Media Formats <td>3GPP (.3gp)</td> </tr> +<tr> +<td>VP8</td> +<td> </td> +<td style="text-align: center;"><big>•</big><br><small>(Android 2.3.3+)</small></td> +<td> </td> +<td><a href="http://www.webmproject.org/">WebM</a> (.webm)</td> +</tr> + </tbody></table> diff --git a/docs/html/guide/developing/building/building-cmdline.jd b/docs/html/guide/developing/building/building-cmdline.jd index 81c117828bef..5f193bc2a988 100644 --- a/docs/html/guide/developing/building/building-cmdline.jd +++ b/docs/html/guide/developing/building/building-cmdline.jd @@ -72,7 +72,7 @@ ant debug <p>This creates your debug <code>.apk</code> file inside the project <code>bin/</code> directory, named <code><your_project_name>-debug.apk</code>. The file is already signed with the debug key and has been aligned with - <a href="{@docRoot}/guide/developing/tools/zipalign.html"><code>zipalign</code></a>. + <a href="{@docRoot}guide/developing/tools/zipalign.html"><code>zipalign</code></a>. </p> </li> </ol> diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index d81b41670924..b13600cc742c 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -60,7 +60,7 @@ <li class="toggle-list"> <div><a href="<?cs var:toroot ?>guide/topics/fundamentals/activities.html"> <span class="en">Activities</span> - </a> <span class="new">new!</span></div> + </a> <span class="new-child">new!</span></div> <ul> <li><a href="<?cs var:toroot ?>guide/topics/fundamentals/fragments.html"> <span class="en">Fragments</span> @@ -69,18 +69,17 @@ <span class="en">Loaders</span> </a> <span class="new">new!</span></li> <li><a href="<?cs var:toroot ?>guide/topics/fundamentals/tasks-and-back-stack.html"> - <span class="en">Tasks and Back Stack</span> - </a> <span class="new">new!</span></li> + <span class="en">Tasks and Back Stack</span></a></li> </ul> </li> <li class="toggle-list"> <div><a href="<?cs var:toroot ?>guide/topics/fundamentals/services.html"> <span class="en">Services</span> - </a> <span class="new">new!</span></div> + </a></div> <ul> <li><a href="<?cs var:toroot ?>guide/topics/fundamentals/bound-services.html"> <span class="en">Bound Services</span> - </a> <span class="new">new!</span></li> + </a></li> </ul> </li> <li><a href="<?cs var:toroot ?>guide/topics/providers/content-providers.html"> @@ -91,7 +90,7 @@ </a></li> <li><a href="<?cs var:toroot ?>guide/topics/fundamentals/processes-and-threads.html"> <span class="en">Processes and Threads</span> - </a> <span class="new">new!</span></li> + </a></li> </ul> @@ -100,7 +99,7 @@ <div><a href="<?cs var:toroot ?>guide/topics/ui/index.html"> <span class="en">User Interface</span> </a> - <span class="new">more!</span></div> + <span class="new-child">new!</span></div> <ul> <li><a href="<?cs var:toroot ?>guide/topics/ui/declaring-layout.html"> <span class="en">Declaring Layout</span> @@ -130,10 +129,9 @@ </a></li> </ul> </li> - <li> - <a href="<?cs var:toroot ?>guide/topics/ui/drag-drop.html"> - Dragging and Dropping - </a><span class="new">new!</span> + <li><a href="<?cs var:toroot ?>guide/topics/ui/drag-drop.html"> + <span class="en">Dragging and Dropping</span> + </a> <span class="new">new!</span> </li> <li><a href="<?cs var:toroot ?>guide/topics/ui/themes.html"> <span class="en">Applying Styles and Themes</span> @@ -225,6 +223,7 @@ <li><a href="<?cs var:toroot ?>guide/topics/manifest/provider-element.html"><provider></a></li> <li><a href="<?cs var:toroot ?>guide/topics/manifest/receiver-element.html"><receiver></a></li> <li><a href="<?cs var:toroot ?>guide/topics/manifest/service-element.html"><service></a></li> + <li><a href="<?cs var:toroot ?>guide/topics/manifest/supports-gl-texture-element.html"><supports-gl-texture></a></li> <li><a href="<?cs var:toroot ?>guide/topics/manifest/supports-screens-element.html"><supports-screens></a></li> <!-- ##api level 4## --> <li><a href="<?cs var:toroot ?>guide/topics/manifest/uses-configuration-element.html"><uses-configuration></a></li> <li><a href="<?cs var:toroot ?>guide/topics/manifest/uses-feature-element.html"><uses-feature></a></li> <!-- ##api level 4## --> @@ -240,7 +239,7 @@ <div><a href="<?cs var:toroot ?>guide/topics/graphics/index.html"> <span class="en">Graphics</span> </a> - <span class="new">more!</span></div> + <span class="new-child">new!</span></div> <ul> <li><a href="<?cs var:toroot ?>guide/topics/graphics/2d-graphics.html"> <span class="en">2D Graphics</span> @@ -250,10 +249,10 @@ </a></li> <li><a href="<?cs var:toroot ?>guide/topics/graphics/renderscript.html"> <span class="en">3D with Renderscript</span> - </a><span class="new">new!</span></li> + </a> <span class="new">new!</span></li> <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html"> <span class="en">Property Animation</span> - </a><span class="new">new!</span></li> + </a> <span class="new">new!</span></li> <li><a href="<?cs var:toroot ?>guide/topics/graphics/view-animation.html"> <span class="en">View Animation</span> </a></li> @@ -653,6 +652,9 @@ <li><a href="<?cs var:toroot ?>guide/practices/screens_support.html"> <span class="en">Supporting Multiple Screens</span> </a></li> + <li><a href="<?cs var:toroot ?>guide/practices/optimizing-for-3.0.html"> + <span class="en">Optimizing Apps for Android 3.0</span> + </a> <span class="new">new!</span></li> <li class="toggle-list"> <div><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/index.html"> <span class="en">UI Guidelines</span> diff --git a/docs/html/sdk/android-3.0-optimize.jd b/docs/html/guide/practices/optimizing-for-3.0.jd index a22e69af2076..a22e69af2076 100644 --- a/docs/html/sdk/android-3.0-optimize.jd +++ b/docs/html/guide/practices/optimizing-for-3.0.jd diff --git a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd index 7f35b047d305..31ad466dc0b3 100644 --- a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd +++ b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd @@ -1,4 +1,6 @@ page.title=Activity and Task Design Guidelines +parent.title=UI Guidelines +parent.link=index.html @jd:body <div id="qv-wrapper"> diff --git a/docs/html/guide/practices/ui_guidelines/menu_design.jd b/docs/html/guide/practices/ui_guidelines/menu_design.jd index 840ee66b64d2..7751a7b46efa 100644 --- a/docs/html/guide/practices/ui_guidelines/menu_design.jd +++ b/docs/html/guide/practices/ui_guidelines/menu_design.jd @@ -1,4 +1,6 @@ page.title=Menu Design Guidelines +parent.title=UI Guidelines +parent.link=index.html @jd:body <div id="qv-wrapper"> diff --git a/docs/html/guide/practices/ui_guidelines/widget_design.jd b/docs/html/guide/practices/ui_guidelines/widget_design.jd index e9780696f3b8..49aa4981c581 100644 --- a/docs/html/guide/practices/ui_guidelines/widget_design.jd +++ b/docs/html/guide/practices/ui_guidelines/widget_design.jd @@ -1,4 +1,6 @@ page.title=Widget Design Guidelines +parent.title=UI Guidelines +parent.link=index.html @jd:body <div id="qv-wrapper"> diff --git a/docs/html/guide/topics/graphics/renderscript.jd b/docs/html/guide/topics/graphics/renderscript.jd index 0e64c786ab11..60bffdb1a49a 100644 --- a/docs/html/guide/topics/graphics/renderscript.jd +++ b/docs/html/guide/topics/graphics/renderscript.jd @@ -115,7 +115,7 @@ parent.link=index.html <code><em>ScriptC_renderscript_filename</em></code>. Accessor methods are generated, so the Android system layer can access the values. The <code>get</code> method comes with a one-way communication restriction. - The Android system layer always caches the last value that is set and returns that during a call to a <code>get<code> method. + The Android system layer always caches the last value that is set and returns that during a call to a <code>get</code> method. If the native Renderscript code changes the value, the change does not propagate back to the Android system layer. If the global variables are initialized in the native Renderscript code, those values are used to initialize the corresponding values in the Android system. If global variables are marked as <code>const</code>, @@ -373,11 +373,11 @@ parent.link=index.html graphics context by calling {@link android.renderscript.RenderScriptGL#bindProgramVertex bindProgramVertex()}. It is then used for all subsequent draw calls until you bind a new program. If the program has constant inputs, the - user needs to bind an allocation containing those inputs. The allocation’s type must match + user needs to bind an allocation containing those inputs. The allocation's type must match the one provided during creation. The Renderscript library then does all the necessary plumbing to send those constants to the graphics hardware. Varying inputs to the shader, such as position, normal, and texture coordinates are matched by name between the input - Element and the Mesh object being drawn. The signatures don’t have to be exact or in any + Element and the Mesh object being drawn. The signatures don't have to be exact or in any strict order. As long as the input name in the shader matches a channel name and size available on the mesh, the run-time would take care of connecting the two. Unlike OpenGL, there is no need to link the vertex and fragment programs.</p> @@ -396,7 +396,7 @@ parent.link=index.html <td>rs_program_fragment</td> <td><p>The Renderscript fragment program, also known as the fragment shader, is responsible for - manipulating pixel data in a user-defined way. It’s constructed from a GLSL shader string + manipulating pixel data in a user-defined way. It's constructed from a GLSL shader string containing the program body, textures inputs, and a Type object describing the constants used by the program. Like the vertex programs, when an allocation with constant input values is bound to the shader, its values are sent to the graphics program automatically. Note that the @@ -445,7 +445,7 @@ parent.link=index.html mip-maps are used and the amount of anisotropy required. There may be situations where hardware limitations prevent the exact behavior from being matched. In these cases, the runtime attempts to provide the closest possible approximation. For example, the user - requested 16x anisotropy, but only 8x was set because it’s the best available on the + requested 16x anisotropy, but only 8x was set because it's the best available on the hardware.</td> </tr> diff --git a/docs/html/guide/topics/manifest/action-element.jd b/docs/html/guide/topics/manifest/action-element.jd index d7ba78d73418..8ad94cdc1d50 100644 --- a/docs/html/guide/topics/manifest/action-element.jd +++ b/docs/html/guide/topics/manifest/action-element.jd @@ -1,4 +1,6 @@ page.title=<action> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/activity-alias-element.jd b/docs/html/guide/topics/manifest/activity-alias-element.jd index 4521b4bddc3f..ba2c1542ce0f 100644 --- a/docs/html/guide/topics/manifest/activity-alias-element.jd +++ b/docs/html/guide/topics/manifest/activity-alias-element.jd @@ -1,4 +1,6 @@ page.title=<activity-alias> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd index 5e0b5367896f..c910686946bc 100644 --- a/docs/html/guide/topics/manifest/activity-element.jd +++ b/docs/html/guide/topics/manifest/activity-element.jd @@ -1,4 +1,6 @@ page.title=<activity> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> @@ -14,6 +16,7 @@ page.title=<activity> android:<a href="#exclude">excludeFromRecents</a>=["true" | "false"] android:<a href="#exported">exported</a>=["true" | "false"] android:<a href="#finish">finishOnTaskLaunch</a>=["true" | "false"] + android:<a href="#hwaccel">hardwareAccelerated</a>=["true" | "false"] android:<a href="#icon">icon</a>="<i>drawable resource</i>" android:<a href="#label">label</a>="<i>string resource</i>" android:<a href="#lmode">launchMode</a>=["multiple" | "singleTop" | @@ -286,6 +289,24 @@ are both "{@code true}", this attribute trumps the other. The affinity of the activity is ignored. The activity is not re-parented, but destroyed. </p> +<dt><a name="hwaccel"></a>{@code android:hardwareAccelerated}</dt> +<dd>Whether or not hardware-accelerated rendering should be enabled for this +Activity — "{@code true}" if it should be enabled, and "{@code false}" if +not. The default value is "{@code false}". + +<p>Starting from Android 3.0, a hardware-accelerated OpenGL renderer is +available to applications, to improve performance for many common 2D graphics +operations. When the hardware-accelerated renderer is enabled, most operations +in Canvas, Paint, Xfermode, ColorFilter, Shader, and Camera are accelerated. +This results in smoother animations, smoother scrolling, and improved +responsiveness overall, even for applications that do not explicitly make use +the framework's OpenGL libraries. </p> + +<p>Note that not all of the OpenGL 2D operations are accelerated. If you enable +the hardware-accelerated renderer, test your application to ensure that it can +make use of the renderer without errors.</p> +</dd> + <dt><a name="icon"></a>{@code android:icon}</dt> <dd>An icon representing the activity. The icon is displayed to users when a representation of the activity is required on-screen. For example, icons diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd index 1fadc6e32c85..41313ed35cc2 100644 --- a/docs/html/guide/topics/manifest/application-element.jd +++ b/docs/html/guide/topics/manifest/application-element.jd @@ -1,4 +1,6 @@ page.title=<application> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> @@ -9,6 +11,7 @@ page.title=<application> android:<a href="#desc">description</a>="<i>string resource</i>" android:<a href="#enabled">enabled</a>=["true" | "false"] android:<a href="#code">hasCode</a>=["true" | "false"] + android:<a href="#hwaccel">hardwareAccelerated</a>=["true" | "false"] android:<a href="#icon">icon</a>="<i>drawable resource</i>" android:<a href="#killrst">killAfterRestore</a>=["true" | "false"] android:<a href="#label">label</a>="<i>string resource</i>" @@ -108,7 +111,26 @@ The default value is "{@code true}". <p> An application would not have any code of its own only if it's using nothing but built-in component classes, such as an activity that uses the {@link -android.app.AliasActivity} class, a rare occurrence. +android.app.AliasActivity} class, a rare occurrence.</p> +</dd> + +<dt><a name="hwaccel"></a>{@code android:hardwareAccelerated}</dt> +<dd>Whether or not hardware-accelerated rendering should be enabled for all +Activities and Views in this application — "{@code true}" if it +should be enabled, and "{@code false}" if not. The default value is "{@code false}". + +<p>Starting from Android 3.0, a hardware-accelerated OpenGL renderer is +available to applications, to improve performance for many common 2D graphics +operations. When the hardware-accelerated renderer is enabled, most operations +in Canvas, Paint, Xfermode, ColorFilter, Shader, and Camera are accelerated. +This results in smoother animations, smoother scrolling, and improved +responsiveness overall, even for applications that do not explicitly make use +the framework's OpenGL libraries. </p> + +<p>Note that not all of the OpenGL 2D operations are accelerated. If you enable +the hardware-accelerated renderer, test your application to ensure that it can +make use of the renderer without errors.</p> +</dd> <dt><a name="icon"></a>{@code android:icon}</dt> <dd>An icon for the application as whole, and the default icon for diff --git a/docs/html/guide/topics/manifest/category-element.jd b/docs/html/guide/topics/manifest/category-element.jd index b9a1aa68df65..f392c0a30f52 100644 --- a/docs/html/guide/topics/manifest/category-element.jd +++ b/docs/html/guide/topics/manifest/category-element.jd @@ -1,4 +1,6 @@ page.title=<category> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/compatible-screens-element.jd b/docs/html/guide/topics/manifest/compatible-screens-element.jd index 9fb0fd2c891d..866987489290 100644 --- a/docs/html/guide/topics/manifest/compatible-screens-element.jd +++ b/docs/html/guide/topics/manifest/compatible-screens-element.jd @@ -1,4 +1,6 @@ page.title=<compatible-screens> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/data-element.jd b/docs/html/guide/topics/manifest/data-element.jd index b77fd059917b..9b0d0df6ae06 100644 --- a/docs/html/guide/topics/manifest/data-element.jd +++ b/docs/html/guide/topics/manifest/data-element.jd @@ -1,4 +1,6 @@ page.title=<data> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/grant-uri-permission-element.jd b/docs/html/guide/topics/manifest/grant-uri-permission-element.jd index 9dafe8514f12..dc98cbb55709 100644 --- a/docs/html/guide/topics/manifest/grant-uri-permission-element.jd +++ b/docs/html/guide/topics/manifest/grant-uri-permission-element.jd @@ -1,4 +1,6 @@ page.title=<grant-uri-permission> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/instrumentation-element.jd b/docs/html/guide/topics/manifest/instrumentation-element.jd index b18e77757bd6..9408b8435049 100644 --- a/docs/html/guide/topics/manifest/instrumentation-element.jd +++ b/docs/html/guide/topics/manifest/instrumentation-element.jd @@ -1,4 +1,6 @@ page.title=<instrumentation> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/intent-filter-element.jd b/docs/html/guide/topics/manifest/intent-filter-element.jd index 2b1322c5021f..d2934005f47b 100644 --- a/docs/html/guide/topics/manifest/intent-filter-element.jd +++ b/docs/html/guide/topics/manifest/intent-filter-element.jd @@ -1,4 +1,6 @@ page.title=<intent-filter> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/manifest-element.jd b/docs/html/guide/topics/manifest/manifest-element.jd index 7f21e6bbb9fb..a8125b3384cb 100644 --- a/docs/html/guide/topics/manifest/manifest-element.jd +++ b/docs/html/guide/topics/manifest/manifest-element.jd @@ -1,4 +1,6 @@ page.title=<manifest> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/manifest-intro.jd b/docs/html/guide/topics/manifest/manifest-intro.jd index d7a3e3ef6a7b..0f2030556587 100644 --- a/docs/html/guide/topics/manifest/manifest-intro.jd +++ b/docs/html/guide/topics/manifest/manifest-intro.jd @@ -83,6 +83,8 @@ other mention of the element name. <a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html"><uses-configuration /></a> <!-- ##api level 3## --> <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><uses-feature /></a> <!-- ##api level 4## --> <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html"><supports-screens /></a> <!-- ##api level 4## --> + <a href="{@docRoot}guide/topics/manifest/compatible-screens-element.html"><compatible-screens /></a> <!-- ##api level 9## --> + <a href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html"><supports-gl-texture /></a> <!-- ##api level 11## --> <a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a> diff --git a/docs/html/guide/topics/manifest/meta-data-element.jd b/docs/html/guide/topics/manifest/meta-data-element.jd index 101b05a4987e..85a871d0bebd 100644 --- a/docs/html/guide/topics/manifest/meta-data-element.jd +++ b/docs/html/guide/topics/manifest/meta-data-element.jd @@ -1,4 +1,6 @@ page.title=<meta-data> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/path-permission-element.jd b/docs/html/guide/topics/manifest/path-permission-element.jd index 5c271a73b86f..e644d6819bff 100644 --- a/docs/html/guide/topics/manifest/path-permission-element.jd +++ b/docs/html/guide/topics/manifest/path-permission-element.jd @@ -1,4 +1,6 @@ page.title=<path-permission> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/permission-element.jd b/docs/html/guide/topics/manifest/permission-element.jd index ad64d5dd31f7..c256fb1961c1 100644 --- a/docs/html/guide/topics/manifest/permission-element.jd +++ b/docs/html/guide/topics/manifest/permission-element.jd @@ -1,4 +1,6 @@ page.title=<permission> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/permission-group-element.jd b/docs/html/guide/topics/manifest/permission-group-element.jd index 0ad76a68044f..fc1de1fc7b64 100644 --- a/docs/html/guide/topics/manifest/permission-group-element.jd +++ b/docs/html/guide/topics/manifest/permission-group-element.jd @@ -1,4 +1,6 @@ page.title=<permission-group> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/permission-tree-element.jd b/docs/html/guide/topics/manifest/permission-tree-element.jd index 6d6cd0a1bfdd..a9c00cdf13e5 100644 --- a/docs/html/guide/topics/manifest/permission-tree-element.jd +++ b/docs/html/guide/topics/manifest/permission-tree-element.jd @@ -1,4 +1,6 @@ page.title=<permission-tree> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/provider-element.jd b/docs/html/guide/topics/manifest/provider-element.jd index c80b20742cc2..dd0022405152 100644 --- a/docs/html/guide/topics/manifest/provider-element.jd +++ b/docs/html/guide/topics/manifest/provider-element.jd @@ -1,4 +1,6 @@ page.title=<provider> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/receiver-element.jd b/docs/html/guide/topics/manifest/receiver-element.jd index b2089177b605..7012c0fda67f 100644 --- a/docs/html/guide/topics/manifest/receiver-element.jd +++ b/docs/html/guide/topics/manifest/receiver-element.jd @@ -1,4 +1,6 @@ page.title=<receiver> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/service-element.jd b/docs/html/guide/topics/manifest/service-element.jd index 0a44e2c0cf54..d9a81b3a05e4 100644 --- a/docs/html/guide/topics/manifest/service-element.jd +++ b/docs/html/guide/topics/manifest/service-element.jd @@ -1,4 +1,6 @@ page.title=<service> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/supports-gl-texture-element.jd b/docs/html/guide/topics/manifest/supports-gl-texture-element.jd new file mode 100644 index 000000000000..6c4a05a4351e --- /dev/null +++ b/docs/html/guide/topics/manifest/supports-gl-texture-element.jd @@ -0,0 +1,189 @@ +page.title=<supports-gl-texture> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html +@jd:body + +<dl class="xml"> + +<dt>syntax:</dt> +<dd> +<pre class="stx"> +<supports-gl-texture android:<a href="#name">name</a>="<em>string</em>" /> +</pre> +</dd> + +<dt>contained in:</dt> +<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd> + + <div class="sidebox-wrapper"> + <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png"> + <div id="qv-sub-rule"> + <img src="{@docRoot}assets/images/icon_market.jpg" + style="float:left;margin:0;padding:0;"> + <p style="color:#669999;">Android Market and <code + style="color:#669999;"><supports-gl-texture></code> elements</p> + <p style="margin-top:1em;">Android Market filters applications according + to the texture compression formats that they support, to ensure that + they can be installed only on devices that can handle their textures + properly. Developers can use texture compression filtering + as a way of targeting specific device types, based on GPU platform.</p> + + <p style="margin-top:1em;" class="caution">For important information about how + Android Market uses <code><supports-gl-texture></code> elements as + the basis for filtering, please read <a href="#market-texture-filtering">Android + Market and texture compression filtering</a>, below.</p> +</div> +</div> + +<dt>description:</dt> +<dd>Declares a single GL texture compression format that is supported by +the application. + +<p>An application "supports" a GL texture compression format if it is capable of +providing texture assets that are compressed in that format, once the +application is installed on a device. The application can provide the +compressed assets locally, from inside the <code>.apk</code>, or it can download them +from a server at runtime.</p> + +<p>Each <code><supports-gl-texture></code> element declares exactly one +supported texture compression format, specified as the value of a +<code>android:name</code> attribute. If your application supports multiple +texture compression formats, you can declare multiple +<code><supports-gl-texture></code> elements. For example:</p> + +<pre><supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /> +<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" /></pre> + +<p>Declared <code><supports-gl-texture></code> elements are informational, +meaning that the Android system itself does not examine the elements at install +time to ensure matching support on the device. However, other services +(such as Android Market) or applications can check your application's +<code><supports-gl-texture></code> declarations as part of handling or +interacting with your application. For this reason, it's very important that +you declare all of the texture compression formats (from the list below) that +your application is capable of supporting. </p> + +<p>Applications and devices typically declare their supported GL texture +compression formats using the same set of well-known strings, as listed below. +The set of format strings may grow over time, as needed, and since the values +are strings, applications are free to declare other formats as needed.</p> + +<p>Assuming that the application is built with SDK Platform Tools r3 or higher, +filtering based on the <code><supports-gl-texture></code> element is activated +for all API levels.</p> + +<dt>attributes:</dt> + +<dd> +<dl class="attr"> + + <dt><a name="name"></a>{@code android:name}</dt> + <dd>Specifies a single GL texture compression format supported by the application, + as a descriptor string. Common descriptor values are listed in the table below. + +<table> +<tr> +<th>Texture Compression Format Descriptor</th> +<th>Comments</th> +</tr> +<tr> +<td><code>GL_OES_compressed_ETC1_RGB8_texture</code></td> +<td>Ericsson texture compression. Specified in OpenGL ES 2.0 and available in all +Android-powered devices that support OpenGL ES 2.0.</td> +</tr> +<tr> +<td><code>GL_OES_compressed_paletted_texture</code></td> +<td>Generic paletted texture compression.</td> +</tr> +<tr> +<td><code>GL_AMD_compressed_3DC_texture</code></td> +<td>ATI 3Dc texture compression. </td> +</tr> +<tr> +<td><code>GL_AMD_compressed_ATC_texture</code></td> +<td>ATI texture compression. Available on devices running Adreno GPU, including +HTC Nexus One, Droid Incredible, EVO, and others. For widest compatibility, +devices may also declare a <code><supports-gl-texture></code> element with the +descriptor <code>GL_ATI_texture_compression_atitc</code>. </td> +</tr> +<tr> +<td><code>GL_EXT_texture_compression_latc</code></td> +<td>Luminance alpha texture compression. </td> +</tr> +<tr> +<td><code>GL_EXT_texture_compression_dxt1</code></td> +<td>S3 DXT1 texture compression. Supported on devices running Nvidia Tegra2 +platform, including Motorala Xoom, Motorola Atrix, Droid Bionic, and +others.</td> +</tr> +<tr> +<td><code>GL_EXT_texture_compression_s3tc</code></td> +<td>S3 texture compression, nonspecific to DXT variant. Supported on devices +running Nvidia Tegra2 platform, including Motorala Xoom, Motorola Atrix, Droid +Bionic, and others. If your application requires a specific DXT variant, declare +that descriptor instead of this one.</td> +</tr> +<tr> +<td><code>GL_IMG_texture_compression_pvrtc</code></td> +<td>PowerVR texture compression. Available in devices running PowerVR SGX530/540 +GPU, such as Motorola DROID series; Samsung Galaxy S, Nexus S, and Galaxy Tab; +and others.</td> +</tr> +</table> + +</dd> +</dl></dd> + +<!-- ##api level indication## +<dt>introduced in:</dt> +<dd>API Level </dd>--> + +<dt>see also:</dt> +<dd> + <ul> + <li><a href="{@docRoot}guide/appendix/market-filters.html">Android Market Filters</a></li> + </ul> +</dd> + +<h2 id="market-texture-filtering">Android Market and texture compression filtering</h2> + +<p>Android Market filters the applications that are visible to users, so that +users can see and download only those applications that are compatible with +their devices. One of the ways Market filters applications is by texture +compression compatibility, giving you control over the availability of your +application to various devices, based on the capabilities of their GPUs.</p> + +<p>To determine an application's texture compression compatibility with a given +user's device, Android Market compares:</p> + +<ul> +<li>Texture compression formats that are supported by the application — +an application declares its supported texture compression formats in +<code><supports-gl-texture></code> elements in its manifest <br/>with...</li> +<li>Texture compression formats that are supported by the GPU on the device — +a device reports the formats it supports as read-only system properties.</li> +</ul> + +<p>Each time you upload an application to the Android Market Publisher Site, +Android Market scans the application's manifest file and looks for any +<code><supports-gl-texture></code> elements. It extracts the +format descriptors from the elements and stores them internally as +metadata associated with the application <code>.apk</code> and the application +version. </p> + +<p>When a user searches or browses for applications on Android Market, +the service compares the texture compression formats supported by the application +with those supported by the user's device. The comparison is based on the format +descriptor strings and a match must be exact.</p> + +<p>If <em>any</em> of an application's supported texture compression formats is +also supported by the device, Android Market allows the user to see the +application and potentially download it. Otherwise, if none of the application's +formats is supported by the device, Android Market filters the application so +that it is not available for download. </p> + +<p>If an application does not declare any <code><supports-gl-texture></code> elements, +Android Market does not apply any filtering based on GL texture compression format.</p> + +</dl> + diff --git a/docs/html/guide/topics/manifest/supports-screens-element.jd b/docs/html/guide/topics/manifest/supports-screens-element.jd index 92c769e37c18..ee99a3706349 100644 --- a/docs/html/guide/topics/manifest/supports-screens-element.jd +++ b/docs/html/guide/topics/manifest/supports-screens-element.jd @@ -1,4 +1,6 @@ page.title=<supports-screens> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/uses-configuration-element.jd b/docs/html/guide/topics/manifest/uses-configuration-element.jd index 4578c63fa72f..20ec85f51af5 100755 --- a/docs/html/guide/topics/manifest/uses-configuration-element.jd +++ b/docs/html/guide/topics/manifest/uses-configuration-element.jd @@ -1,4 +1,6 @@ page.title=<uses-configuration> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <!-- ##api level 3## see comment below --> diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd index 0828e8b25edc..fec6a980e305 100644 --- a/docs/html/guide/topics/manifest/uses-feature-element.jd +++ b/docs/html/guide/topics/manifest/uses-feature-element.jd @@ -1,4 +1,6 @@ page.title=<uses-feature> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/uses-library-element.jd b/docs/html/guide/topics/manifest/uses-library-element.jd index 1d38c1afee0a..d94ad9fb3ab7 100644 --- a/docs/html/guide/topics/manifest/uses-library-element.jd +++ b/docs/html/guide/topics/manifest/uses-library-element.jd @@ -1,4 +1,6 @@ page.title=<uses-library> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> @@ -44,7 +46,7 @@ page.title=<uses-library> <dd> Android Market filters applications based on the libraries installed on the user's device. For more information about filtering, see the topic - <a href="{@docRoot}/guide/appendix/market-filters.html">Market Filters</a>. + <a href="{@docRoot}guide/appendix/market-filters.html">Market Filters</a>. </dd> </dl> <p> diff --git a/docs/html/guide/topics/manifest/uses-permission-element.jd b/docs/html/guide/topics/manifest/uses-permission-element.jd index 085b9f0eeca2..967fc5a65316 100644 --- a/docs/html/guide/topics/manifest/uses-permission-element.jd +++ b/docs/html/guide/topics/manifest/uses-permission-element.jd @@ -1,4 +1,6 @@ page.title=<uses-permission> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd index 971d4cb3aba7..b371f34ba72e 100644 --- a/docs/html/guide/topics/manifest/uses-sdk-element.jd +++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd @@ -1,4 +1,6 @@ page.title=<uses-sdk> +parent.title=The AndroidManifest.xml File +parent.link=manifest-intro.html @jd:body <dl class="xml"> diff --git a/docs/html/guide/topics/ui/drag-drop.jd b/docs/html/guide/topics/ui/drag-drop.jd index c33c5078a9e5..0329c192e5ef 100644 --- a/docs/html/guide/topics/ui/drag-drop.jd +++ b/docs/html/guide/topics/ui/drag-drop.jd @@ -1,5 +1,8 @@ page.title=Dragging and Dropping +parent.title=User Interface +parent.link=index.html @jd:body + <div id="qv-wrapper"> <div id="qv"> <h2>Quickview</h2> diff --git a/docs/html/guide/topics/ui/notifiers/index.jd b/docs/html/guide/topics/ui/notifiers/index.jd index d29324cc8797..8fc57fc750d3 100644 --- a/docs/html/guide/topics/ui/notifiers/index.jd +++ b/docs/html/guide/topics/ui/notifiers/index.jd @@ -1,4 +1,6 @@ page.title=Notifying the User +parent.title=User Interface +parent.link=../index.html @jd:body <div id="qv-wrapper"> diff --git a/docs/html/resources/community-more.jd b/docs/html/resources/community-more.jd index 9f16feaffbf2..df729265cc05 100644 --- a/docs/html/resources/community-more.jd +++ b/docs/html/resources/community-more.jd @@ -24,7 +24,11 @@ page.title=IRC and Twitter </tr> </table> -<p>If you haven't used IRC before, check <a href="http://en.wikipedia.org/wiki/List_of_IRC_clients">http://en.wikipedia.org/wiki/List_of_IRC_clients »</a> for a helpful list of IRC clients. Alternatively, you could also use this <a href="http://java.freenode.net/index.php?channel=android-dev">web interface »</a>, which does not require any installation, to join discussions on the Android IRC channels. </p> +<p>If you haven't used IRC before, check <a +href="http://en.wikipedia.org/wiki/List_of_IRC_clients">http://en.wikipedia.org/wiki/ +List_of_IRC_clients »</a> for a helpful list of IRC clients. Alternatively, you could also use +this <a href="http://webchat.freenode.net/?channels=android-dev">web interface »</a>, which +does not require any installation, to join discussions on the Android IRC channels. </p> <p>Here are some tips for using IRC:</h4> diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js index b80e59a556b0..e919de94ee0a 100644 --- a/docs/html/resources/resources-data.js +++ b/docs/html/resources/resources-data.js @@ -496,7 +496,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'new'], + tags: ['sample', 'new', 'newfeature', 'performance', 'gamedev', 'gl'], path: 'samples/Renderscript/index.html', title: { en: 'Renderscript' diff --git a/docs/html/sdk/android-3.0-highlights.jd b/docs/html/sdk/android-3.0-highlights.jd index 591f08806da0..ebeb3789f48d 100644 --- a/docs/html/sdk/android-3.0-highlights.jd +++ b/docs/html/sdk/android-3.0-highlights.jd @@ -46,7 +46,9 @@ page.title=Android 3.0 Platform Highlights <p>Welcome to Android 3.0!</p> <p>The Android 3.0 platform introduces many new and exciting features for users and developers. -This document provides a glimpse of some of the new features and technologies, as delivered in the Android 3.0 Preview SDK. For more information about the SDK or how to download it, please see the <a href="{@docRoot}sdk/preview/index.html">Preview SDK</a> document.</p> +This document provides a glimpse of some of the new features and technologies, as delivered in +Android 3.0. For a more detailed look at new developer APIs, see the <a +href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform</a> document.</p> <ul> <li><a href="#UserFeatures">New User Features</a></li> @@ -259,7 +261,8 @@ allowscriptaccess="always" allowfullscreen="true" width="278" height="180"></emb </object> </div> -<p>For more information about the new developer APIs, see the Android 3.0 Platform notes in the SDK Preview documentation, available by download through the Android SDK Manager.</p> +<p>For more information about the new developer APIs, see the <a +href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform</a> document.</p> <p>For a video overview of platform features, see the Android 3.0 Sneak Peek. </p> diff --git a/docs/html/sdk/android-3.0.jd b/docs/html/sdk/android-3.0.jd index 6c88146d7c84..6c087bb41b7c 100644 --- a/docs/html/sdk/android-3.0.jd +++ b/docs/html/sdk/android-3.0.jd @@ -1,4 +1,4 @@ -page.title=Android 3.0 Platform Preview +page.title=Android 3.0 Platform sdk.platform.version=3.0 sdk.platform.apiLevel=11 @jd:body @@ -25,7 +25,7 @@ Differences Report »</a> </li> <h2>See Also</h2> <ol> - <li><a href="{@docRoot}sdk/android-3.0-optimize.html">Optimizing Apps for Android 3.0</a></li> + <li><a href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing Apps for Android 3.0</a></li> </ol> </div> @@ -48,10 +48,12 @@ href="{@docRoot}sdk/index.html">download the SDK Starter Package</a> first.</p> href="{@docRoot}sdk/android-{@sdkPlatformVersion}-highlights.html">Platform Highlights</a>.</p> -<p>Also see the <a href="{@docRoot}sdk/android-3.0-optimize.html">Optimizing Apps for Android -3.0</a> document for information about how to optimize your existing applications for Android 3.0 -devices, even if you want to remain compatible with previous versions.</p> - +<p class="note"><strong>Note:</strong> +If you've already published an Android application, please test and optimize your application on +Android 3.0 as soon as possible. You should do so to be sure your application provides the best +experience possible on the latest Android-powered devices. For information about what you can do, +read <a href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing Apps for Android +3.0</a>.</p> <h2 id="relnotes">Revisions</h2> @@ -866,8 +868,8 @@ dimensions.</p> <h3>JSON utilities</h3> <p>New classes, {@link android.util.JsonReader} and {@link android.util.JsonWriter}, help you -read and write JSON streams. The new APIs compliment the {@link org.json} classes which manipulate a -document in memory.</p> +read and write JSON streams. The new APIs complement the {@link org.json} classes, which manipulate +a document in memory.</p> <p>You can create an instance of {@link android.util.JsonReader} by calling its constructor method and passing the {@link java.io.InputStreamReader} that feeds the JSON string. diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd index df8869e4b854..7f6f0105ad67 100644 --- a/docs/html/sdk/index.jd +++ b/docs/html/sdk/index.jd @@ -2,20 +2,20 @@ page.title=Android SDK sdk.redirect=0 sdk.win_installer=installer_r10-windows.exe -sdk.win_installer_bytes=32845713 -sdk.win_installer_checksum=4e4356c472a6271ac9c062df0219dcb3 +sdk.win_installer_bytes=32878481 +sdk.win_installer_checksum=8ffa2dd734829d0bbd3ea601b50b36c7 sdk.win_download=android-sdk_r10-windows.zip -sdk.win_bytes=30112516 -sdk.win_checksum=643a75d99f5d4ca39dcf743fe894d599 +sdk.win_bytes=32832260 +sdk.win_checksum=1e42b8f528d9ca6d9b887c58c6f1b9a2 sdk.mac_download=android-sdk_r10-mac_x86.zip -sdk.mac_bytes=28224540 -sdk.mac_checksum=4d0a99a458e4f4bde65a01f8545f27e9 +sdk.mac_bytes=28847132 +sdk.mac_checksum=e3aa5578a6553b69cc36659c9505be3f sdk.linux_download=android-sdk_r10-linux_x86.tgz -sdk.linux_bytes=26556013 -sdk.linux_checksum=10cafdd44771bfe2ba9d4440886389e7 +sdk.linux_bytes=26981997 +sdk.linux_checksum=c022dda3a56c8a67698e6a39b0b1a4e0 @jd:body diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd index 40231a315e5d..bc9ba4be6259 100644 --- a/docs/html/sdk/ndk/index.jd +++ b/docs/html/sdk/ndk/index.jd @@ -1,16 +1,16 @@ ndk=true -ndk.win_download=android-ndk-r6-windows.zip -ndk.win_bytes=64147764 -ndk.win_checksum=771b56328b7fc7751aa8040fb9dd09f0 +ndk.win_download=android-ndk-r5b-windows.zip +ndk.win_bytes=61299831 +ndk.win_checksum=87745ada305ab639399161ab4faf684c -ndk.mac_download=android-ndk-r6-darwin-x86.tar.bz2 -ndk.mac_bytes=50244722 -ndk.mac_checksum=d107f6d63478b73e09ed2eecd4c62bd3 +ndk.mac_download=android-ndk-r5b-darwin-x86.tar.bz2 +ndk.mac_bytes=50210863 +ndk.mac_checksum=019a14622a377b3727ec789af6707037 -ndk.linux_download=android-ndk-r6-linux-x86.tar.bz2 -ndk.linux_bytes=44088689 -ndk.linux_checksum=c83c3ab5a5e5a3b3fe7b907735ce77d4 +ndk.linux_download=android-ndk-r5b-linux-x86.tar.bz2 +ndk.linux_bytes=44138539 +ndk.linux_checksum=4c0045ddc2bfd657be9d5177d0e0b7e7 page.title=Android NDK @jd:body @@ -61,55 +61,6 @@ padding: .25em 1em; <div class="toggleable open"> <a href="#" - onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-opened.png" - class="toggle-img" - height="9px" - width="9px" /> Android NDK, Revision 6</a> <em>(February 2011)</em> - - <div class="toggleme"> - <p>This release of the NDK introduces the following header files:</p> - <ul> - <li><p><code><android/asset_manager.h></code>: Allows access to assets - using 64-bit file offsets and sizes. This is useful for very large assets that exceed - 2GB, as required by some games. The following APIs are provided:<p> - <ul> - <li><code>AAsset_getLength64</code></li> - <li><code>AAsset_getRemainingLength64</code></li> - <li><code>AAsset_openFileDescriptor64</code></li> - <li><code>AAsset_seek64</code></li> - </ul> - </li> - - <li><code><android/input.h></code>: Provides the following AMETA_XXX constants - that are related to the new input framework in Honeycomb: -<pre> -AMETA_FUNCTION_ON = 0x08, -AMETA_CTRL_ON = 0x1000, -AMETA_CTRL_LEFT_ON = 0x2000, -AMETA_CTRL_RIGHT_ON = 0x4000, -AMETA_META_ON = 0x10000, -AMETA_META_LEFT_ON = 0x20000, -AMETA_META_RIGHT_ON = 0x40000, -AMETA_CAPS_LOCK_ON = 0x100000, -AMETA_NUM_LOCK_ON = 0x200000, -AMETA_SCROLL_LOCK_ON = 0x400000, -</pre> - </li> - - <li><code><android/keycodes></code>: Provides <code>AKEYCODE_XXX</code> - constants that are related to the new input framework in Honeycomb. - </li> - - <li><code><android/native_activity.h></code>: Adds a new field to the - system-allocated <code>ANativeActivity</code> structure named <code>obbPath</code> that - contains the path of your application's OBB files, if any. - </li> - </ul> - </div> - </div> - -<div class="toggleable closed"> - <a href="#" onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs index c1894d89c393..a1c26db3208c 100644 --- a/docs/html/sdk/sdk_toc.cs +++ b/docs/html/sdk/sdk_toc.cs @@ -80,7 +80,6 @@ class="new">new!</span></li> <div><a href="<?cs var:toroot ?>sdk/android-3.0.html"> <span class="en">Android 3.0 Platform</span></a> <span class="new">new!</span></div> <ul> - <li><a href="<?cs var:toroot ?>sdk/android-3.0-optimize.html">Optimizing Apps for 3.0</a></li> <li><a href="<?cs var:toroot ?>sdk/android-3.0-highlights.html">Platform Highlights</a></li> <li><a href="<?cs var:toroot ?>sdk/api_diff/11/changes.html">API Differences Report »</a></li> </ul> @@ -152,8 +151,8 @@ class="new">new!</span></li> <span style="display:none" class="zh-TW"></span> </h2> <ul> - <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r6</a> - <span class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r5b</a> + </li> <li><a href="<?cs var:toroot ?>sdk/ndk/overview.html">What is the NDK?</a></li> </ul> </li> diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index cffee5fd4e9c..8d1756152eca 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -240,7 +240,7 @@ public class BitmapFactory { /** * The resulting height of the bitmap, set independent of the state of * inJustDecodeBounds. However, if there is an error trying to decode, - * outHeight will be set to -1. + * outHeight will be set to -1. */ public int outHeight; diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 65c6ccfa25d7..208975199622 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -811,11 +811,12 @@ public class GradientDrawable extends Drawable { com.android.internal.R.styleable.DrawableCorners_bottomRightRadius, radius); if (topLeftRadius != radius || topRightRadius != radius || bottomLeftRadius != radius || bottomRightRadius != radius) { + // The corner radii are specified in clockwise order (see Path.addRoundRect()) setCornerRadii(new float[] { topLeftRadius, topLeftRadius, topRightRadius, topRightRadius, - bottomLeftRadius, bottomLeftRadius, - bottomRightRadius, bottomRightRadius + bottomRightRadius, bottomRightRadius, + bottomLeftRadius, bottomLeftRadius }); } a.recycle(); diff --git a/include/camera/Camera.h b/include/camera/Camera.h index e5f7e623c476..f3c8f64ad3de 100644 --- a/include/camera/Camera.h +++ b/include/camera/Camera.h @@ -66,16 +66,17 @@ namespace android { // msgType in notifyCallback and dataCallback functions enum { - CAMERA_MSG_ERROR = 0x001, - CAMERA_MSG_SHUTTER = 0x002, - CAMERA_MSG_FOCUS = 0x004, - CAMERA_MSG_ZOOM = 0x008, - CAMERA_MSG_PREVIEW_FRAME = 0x010, - CAMERA_MSG_VIDEO_FRAME = 0x020, - CAMERA_MSG_POSTVIEW_FRAME = 0x040, - CAMERA_MSG_RAW_IMAGE = 0x080, - CAMERA_MSG_COMPRESSED_IMAGE = 0x100, - CAMERA_MSG_ALL_MSGS = 0x1FF + CAMERA_MSG_ERROR = 0x0001, + CAMERA_MSG_SHUTTER = 0x0002, + CAMERA_MSG_FOCUS = 0x0004, + CAMERA_MSG_ZOOM = 0x0008, + CAMERA_MSG_PREVIEW_FRAME = 0x0010, + CAMERA_MSG_VIDEO_FRAME = 0x0020, + CAMERA_MSG_POSTVIEW_FRAME = 0x0040, + CAMERA_MSG_RAW_IMAGE = 0x0080, + CAMERA_MSG_COMPRESSED_IMAGE = 0x0100, + CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x0200, + CAMERA_MSG_ALL_MSGS = 0xFFFF }; // cmdType in sendCommand functions @@ -207,7 +208,7 @@ public: status_t cancelAutoFocus(); // take a picture - picture returned from callback - status_t takePicture(); + status_t takePicture(int msgType); // set preview/capture parameters - key/value pairs status_t setParameters(const String8& params); diff --git a/include/camera/ICamera.h b/include/camera/ICamera.h index b2310a64c7d7..2344b3f3f423 100644 --- a/include/camera/ICamera.h +++ b/include/camera/ICamera.h @@ -70,7 +70,7 @@ public: virtual status_t startRecording() = 0; // stop recording mode - virtual void stopRecording() = 0; + virtual void stopRecording() = 0; // get recording state virtual bool recordingEnabled() = 0; @@ -84,8 +84,14 @@ public: // cancel auto focus virtual status_t cancelAutoFocus() = 0; - // take a picture - virtual status_t takePicture() = 0; + /* + * take a picture. + * @param msgType the message type an application selectively turn on/off + * on a photo-by-photo basis. The supported message types are: + * CAMERA_MSG_SHUTTER, CAMERA_MSG_RAW_IMAGE, CAMERA_MSG_COMPRESSED_IMAGE, + * and CAMERA_MSG_POSTVIEW_FRAME. Any other message types will be ignored. + */ + virtual status_t takePicture(int msgType) = 0; // set preview/capture parameters - key/value pairs virtual status_t setParameters(const String8& params) = 0; diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 0bfb166a464d..cce9129c0f80 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -54,6 +54,22 @@ public: virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; virtual sp<IOMX> getOMX() = 0; + + // codecs usage tracking for the battery app + enum BatteryDataBits { + // tracking audio codec + kBatteryDataTrackAudio = 1, + // tracking video codec + kBatteryDataTrackVideo = 2, + // codec is started, otherwise codec is paused + kBatteryDataCodecStarted = 4, + // tracking decoder (for media player), + // otherwise tracking encoder (for media recorder) + kBatteryDataTrackDecoder = 8, + }; + + virtual void addBatteryData(uint32_t params) = 0; + virtual status_t pullBatteryData(Parcel* reply) = 0; }; // ---------------------------------------------------------------------------- diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp index 907f119b8174..e2883121e497 100644 --- a/libs/camera/Camera.cpp +++ b/libs/camera/Camera.cpp @@ -301,12 +301,12 @@ status_t Camera::cancelAutoFocus() } // take a picture -status_t Camera::takePicture() +status_t Camera::takePicture(int msgType) { - LOGV("takePicture"); + LOGV("takePicture: 0x%x", msgType); sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; - return c->takePicture(); + return c->takePicture(msgType); } // set preview/capture parameters - key/value pairs diff --git a/libs/camera/ICamera.cpp b/libs/camera/ICamera.cpp index 0881d65ae3d2..931b57d048aa 100644 --- a/libs/camera/ICamera.cpp +++ b/libs/camera/ICamera.cpp @@ -223,11 +223,12 @@ public: } // take a picture - returns an IMemory (ref-counted mmap) - status_t takePicture() + status_t takePicture(int msgType) { - LOGV("takePicture"); + LOGV("takePicture: 0x%x", msgType); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + data.writeInt32(msgType); remote()->transact(TAKE_PICTURE, data, &reply); status_t ret = reply.readInt32(); return ret; @@ -401,7 +402,8 @@ status_t BnCamera::onTransact( case TAKE_PICTURE: { LOGV("TAKE_PICTURE"); CHECK_INTERFACE(ICamera, data, reply); - reply->writeInt32(takePicture()); + int msgType = data.readInt32(); + reply->writeInt32(takePicture(msgType)); return NO_ERROR; } break; case SET_PARAMETERS: { diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java index ee2c1e8cb2d0..a027bc629967 100644 --- a/media/java/android/media/MediaFile.java +++ b/media/java/android/media/MediaFile.java @@ -141,7 +141,9 @@ public class MediaFile { private static boolean isWMAEnabled() { List<AudioDecoder> decoders = DecoderCapabilities.getAudioDecoders(); - for (AudioDecoder decoder: decoders) { + int count = decoders.size(); + for (int i = 0; i < count; i++) { + AudioDecoder decoder = decoders.get(i); if (decoder == AudioDecoder.AUDIO_DECODER_WMA) { return true; } @@ -149,6 +151,18 @@ public class MediaFile { return false; } + private static boolean isWMVEnabled() { + List<VideoDecoder> decoders = DecoderCapabilities.getVideoDecoders(); + int count = decoders.size(); + for (int i = 0; i < count; i++) { + VideoDecoder decoder = decoders.get(i); + if (decoder == VideoDecoder.VIDEO_DECODER_WMV) { + return true; + } + } + return false; + } + static { addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3); addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG); @@ -184,8 +198,10 @@ public class MediaFile { addFileType("WEBM", FILE_TYPE_MKV, "video/x-matroska"); addFileType("TS", FILE_TYPE_MP2TS, "video/mp2ts"); - addFileType("WMV", FILE_TYPE_WMV, "video/x-ms-wmv", MtpConstants.FORMAT_WMV); - addFileType("ASF", FILE_TYPE_ASF, "video/x-ms-asf"); + if (isWMVEnabled()) { + addFileType("WMV", FILE_TYPE_WMV, "video/x-ms-wmv", MtpConstants.FORMAT_WMV); + addFileType("ASF", FILE_TYPE_ASF, "video/x-ms-asf"); + } addFileType("JPG", FILE_TYPE_JPEG, "image/jpeg", MtpConstants.FORMAT_EXIF_JPEG); addFileType("JPEG", FILE_TYPE_JPEG, "image/jpeg", MtpConstants.FORMAT_EXIF_JPEG); diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index f61ac0f794b8..9c92ace2f47e 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1055,7 +1055,14 @@ public class MediaPlayer /** * Releases resources associated with this MediaPlayer object. * It is considered good practice to call this method when you're - * done using the MediaPlayer. + * done using the MediaPlayer. For instance, whenever the Activity + * of an application is paused, this method should be invoked to + * release the MediaPlayer object. In addition to unnecessary resources + * (such as memory and instances of codecs) being hold, failure to + * call this method immediately if a MediaPlayer object is no longer + * needed may also lead to continuous battery consumption for mobile + * devices, and playback failure if no multiple instances of the + * same codec is supported on a device. */ public void release() { stayAwake(false); @@ -1228,6 +1235,14 @@ public class MediaPlayer private native final void native_setup(Object mediaplayer_this); private native final void native_finalize(); + /** + * @param reply Parcel with audio/video duration info for battery + tracking usage + * @return The status code. + * {@hide} + */ + public native static int native_pullBatteryData(Parcel reply); + @Override protected void finalize() { native_finalize(); } diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java index ad2bf954543e..e0df257eca55 100644 --- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java +++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java @@ -3807,7 +3807,6 @@ class MediaArtistNativeHelper { } catch (Throwable e) { // Allocating to new size with Fixed count try { - System.gc(); rgb888 = new int[thumbnailSize * MAX_THUMBNAIL_PERMITTED]; bitmaps = new Bitmap[MAX_THUMBNAIL_PERMITTED]; thumbnailCount = MAX_THUMBNAIL_PERMITTED; diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java index 69088edd32b7..4faa83a02fe3 100755 --- a/media/java/android/media/videoeditor/MediaImageItem.java +++ b/media/java/android/media/videoeditor/MediaImageItem.java @@ -197,7 +197,6 @@ public class MediaImageItem extends MediaItem { fl.close(); } imageBitmap.recycle(); - System.gc(); } /* diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 0884e350d769..ca544328952c 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -36,6 +36,8 @@ #include "android_util_Binder.h" #include <binder/Parcel.h> #include <surfaceflinger/Surface.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> // ---------------------------------------------------------------------------- @@ -723,6 +725,21 @@ static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env, jobject thiz process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL ); } +static jint +android_media_MediaPlayer_pullBatteryData(JNIEnv *env, jobject thiz, jobject java_reply) +{ + sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player")); + sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); + if (service.get() == NULL) { + jniThrowException(env, "java/lang/RuntimeException", "cannot get MediaPlayerService"); + return UNKNOWN_ERROR; + } + + Parcel *reply = parcelForJavaObject(env, java_reply); + + return service->pullBatteryData(reply); +} + // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { @@ -758,6 +775,7 @@ static JNINativeMethod gMethods[] = { {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id}, {"setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer_setAuxEffectSendLevel}, {"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer_attachAuxEffect}, + {"native_pullBatteryData", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_pullBatteryData}, }; static const char* const kClassPathName = "android/media/MediaPlayer"; diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp index 77199e12e719..17a0362862e0 100644 --- a/media/libmedia/IMediaPlayerService.cpp +++ b/media/libmedia/IMediaPlayerService.cpp @@ -37,7 +37,9 @@ enum { DECODE_FD, CREATE_MEDIA_RECORDER, CREATE_METADATA_RETRIEVER, - GET_OMX + GET_OMX, + ADD_BATTERY_DATA, + PULL_BATTERY_DATA }; class BpMediaPlayerService: public BpInterface<IMediaPlayerService> @@ -156,6 +158,19 @@ public: remote()->transact(GET_OMX, data, &reply); return interface_cast<IOMX>(reply.readStrongBinder()); } + + virtual void addBatteryData(uint32_t params) { + Parcel data, reply; + data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); + data.writeInt32(params); + remote()->transact(ADD_BATTERY_DATA, data, &reply); + } + + virtual status_t pullBatteryData(Parcel* reply) { + Parcel data; + data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); + return remote()->transact(PULL_BATTERY_DATA, data, reply); + } }; IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService"); @@ -270,6 +285,17 @@ status_t BnMediaPlayerService::onTransact( reply->writeStrongBinder(omx->asBinder()); return NO_ERROR; } break; + case ADD_BATTERY_DATA: { + CHECK_INTERFACE(IMediaPlayerService, data, reply); + uint32_t params = data.readInt32(); + addBatteryData(params); + return NO_ERROR; + } break; + case PULL_BATTERY_DATA: { + CHECK_INTERFACE(IMediaPlayerService, data, reply); + pullBatteryData(reply); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 60bdd6233b91..8c6f76b19996 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -23,6 +23,7 @@ #include <sys/types.h> #include <sys/stat.h> +#include <sys/time.h> #include <dirent.h> #include <unistd.h> @@ -51,6 +52,8 @@ #include <media/Metadata.h> #include <media/AudioTrack.h> +#include <private/android_filesystem_config.h> + #include "MediaRecorderClient.h" #include "MediaPlayerService.h" #include "MetadataRetrieverClient.h" @@ -1762,4 +1765,93 @@ int MediaPlayerService::AudioCache::getSessionId() return 0; } +void MediaPlayerService::addBatteryData(uint32_t params) +{ + Mutex::Autolock lock(mLock); + int uid = IPCThreadState::self()->getCallingUid(); + if (uid == AID_MEDIA) { + return; + } + int index = mBatteryData.indexOfKey(uid); + int32_t time = systemTime() / 1000000L; + + if (index < 0) { // create a new entry for this UID + BatteryUsageInfo info; + info.audioTotalTime = 0; + info.videoTotalTime = 0; + info.audioLastTime = 0; + info.videoLastTime = 0; + info.refCount = 0; + + mBatteryData.add(uid, info); + } + + BatteryUsageInfo &info = mBatteryData.editValueFor(uid); + + if (params & kBatteryDataCodecStarted) { + if (params & kBatteryDataTrackAudio) { + info.audioLastTime -= time; + info.refCount ++; + } + if (params & kBatteryDataTrackVideo) { + info.videoLastTime -= time; + info.refCount ++; + } + } else { + if (info.refCount == 0) { + LOGW("Battery track warning: refCount is already 0"); + return; + } else if (info.refCount < 0) { + LOGE("Battery track error: refCount < 0"); + mBatteryData.removeItem(uid); + return; + } + + if (params & kBatteryDataTrackAudio) { + info.audioLastTime += time; + info.refCount --; + } + if (params & kBatteryDataTrackVideo) { + info.videoLastTime += time; + info.refCount --; + } + + // no stream is being played by this UID + if (info.refCount == 0) { + info.audioTotalTime += info.audioLastTime; + info.audioLastTime = 0; + info.videoTotalTime += info.videoLastTime; + info.videoLastTime = 0; + } + } +} + +status_t MediaPlayerService::pullBatteryData(Parcel* reply) { + Mutex::Autolock lock(mLock); + BatteryUsageInfo info; + int size = mBatteryData.size(); + + reply->writeInt32(size); + int i = 0; + + while (i < size) { + info = mBatteryData.valueAt(i); + + reply->writeInt32(mBatteryData.keyAt(i)); //UID + reply->writeInt32(info.audioTotalTime); + reply->writeInt32(info.videoTotalTime); + + info.audioTotalTime = 0; + info.videoTotalTime = 0; + + // remove the UID entry where no stream is being played + if (info.refCount <= 0) { + mBatteryData.removeItemsAt(i); + size --; + i --; + } + i++; + } + return NO_ERROR; +} } // namespace android diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 62f8ed67bf96..9f41db034028 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -204,7 +204,31 @@ public: void removeClient(wp<Client> client); + // For battery usage tracking purpose + struct BatteryUsageInfo { + // how many streams are being played by one UID + int refCount; + // a temp variable to store the duration(ms) of audio codecs + // when we start a audio codec, we minus the system time from audioLastTime + // when we pause it, we add the system time back to the audioLastTime + // so after the pause, audioLastTime = pause time - start time + // if multiple audio streams are played (or recorded), then audioLastTime + // = the total playing time of all the streams + int32_t audioLastTime; + // when all the audio streams are being paused, we assign audioLastTime to + // this variable, so this value could be provided to the battery app + // in the next pullBatteryData call + int32_t audioTotalTime; + + int32_t videoLastTime; + int32_t videoTotalTime; + }; + KeyedVector<int, BatteryUsageInfo> mBatteryData; + // Collect info of the codec usage from media player and media recorder + virtual void addBatteryData(uint32_t params); + // API for the Battery app to pull the data of codecs usage + virtual status_t pullBatteryData(Parcel* reply); private: class Client : public BnMediaPlayer { diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 87fdbf248c37..e3dfabb02493 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -20,6 +20,10 @@ #include "StagefrightRecorder.h" +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> + +#include <media/IMediaPlayerService.h> #include <media/stagefright/AudioSource.h> #include <media/stagefright/AMRWriter.h> #include <media/stagefright/CameraSource.h> @@ -46,9 +50,23 @@ namespace android { +// To collect the encoder usage for the battery app +static void addBatteryData(uint32_t params) { + sp<IBinder> binder = + defaultServiceManager()->getService(String16("media.player")); + sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); + CHECK(service.get() != NULL); + + service->addBatteryData(params); +} + + StagefrightRecorder::StagefrightRecorder() : mWriter(NULL), mWriterAux(NULL), - mOutputFd(-1), mOutputFdAux(-1) { + mOutputFd(-1), mOutputFdAux(-1), + mAudioSource(AUDIO_SOURCE_LIST_END), + mVideoSource(VIDEO_SOURCE_LIST_END), + mStarted(false) { LOGV("Constructor"); reset(); @@ -745,30 +763,54 @@ status_t StagefrightRecorder::start() { return UNKNOWN_ERROR; } + status_t status = OK; + switch (mOutputFormat) { case OUTPUT_FORMAT_DEFAULT: case OUTPUT_FORMAT_THREE_GPP: case OUTPUT_FORMAT_MPEG_4: - return startMPEG4Recording(); + status = startMPEG4Recording(); + break; case OUTPUT_FORMAT_AMR_NB: case OUTPUT_FORMAT_AMR_WB: - return startAMRRecording(); + status = startAMRRecording(); + break; case OUTPUT_FORMAT_AAC_ADIF: case OUTPUT_FORMAT_AAC_ADTS: - return startAACRecording(); + status = startAACRecording(); + break; case OUTPUT_FORMAT_RTP_AVP: - return startRTPRecording(); + status = startRTPRecording(); + break; case OUTPUT_FORMAT_MPEG2TS: - return startMPEG2TSRecording(); + status = startMPEG2TSRecording(); + break; default: LOGE("Unsupported output file format: %d", mOutputFormat); - return UNKNOWN_ERROR; + status = UNKNOWN_ERROR; + break; + } + + if ((status == OK) && (!mStarted)) { + mStarted = true; + + uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted; + if (mAudioSource != AUDIO_SOURCE_LIST_END) { + params |= IMediaPlayerService::kBatteryDataTrackAudio; + } + if (mVideoSource != VIDEO_SOURCE_LIST_END) { + params |= IMediaPlayerService::kBatteryDataTrackVideo; + } + + addBatteryData(params); } + + return status; } sp<MediaSource> StagefrightRecorder::createAudioSource() { @@ -1458,6 +1500,21 @@ status_t StagefrightRecorder::pause() { mWriterAux->pause(); } + if (mStarted) { + mStarted = false; + + uint32_t params = 0; + if (mAudioSource != AUDIO_SOURCE_LIST_END) { + params |= IMediaPlayerService::kBatteryDataTrackAudio; + } + if (mVideoSource != VIDEO_SOURCE_LIST_END) { + params |= IMediaPlayerService::kBatteryDataTrackVideo; + } + + addBatteryData(params); + } + + return OK; } @@ -1494,6 +1551,21 @@ status_t StagefrightRecorder::stop() { } } + if (mStarted) { + mStarted = false; + + uint32_t params = 0; + if (mAudioSource != AUDIO_SOURCE_LIST_END) { + params |= IMediaPlayerService::kBatteryDataTrackAudio; + } + if (mVideoSource != VIDEO_SOURCE_LIST_END) { + params |= IMediaPlayerService::kBatteryDataTrackVideo; + } + + addBatteryData(params); + } + + return err; } diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index 72225dbdd78d..2c440c1a0dec 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -107,6 +107,8 @@ private: bool mIsMetaDataStoredInVideoBuffers; MediaProfiles *mEncoderProfiles; + bool mStarted; + status_t setupMPEG4Recording( bool useSplitCameraSource, int outputFd, diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index b1d3630c67df..1b63ab2461c4 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -28,6 +28,8 @@ #include "include/MPEG2TSExtractor.h" #include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <media/IMediaPlayerService.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/AudioPlayer.h> @@ -155,8 +157,17 @@ private: const AwesomeNativeWindowRenderer &); }; -//////////////////////////////////////////////////////////////////////////////// +// To collect the decoder usage +void addBatteryData(uint32_t params) { + sp<IBinder> binder = + defaultServiceManager()->getService(String16("media.player")); + sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); + CHECK(service.get() != NULL); + + service->addBatteryData(params); +} +//////////////////////////////////////////////////////////////////////////////// AwesomePlayer::AwesomePlayer() : mQueueStarted(false), mTimeSource(NULL), @@ -379,6 +390,17 @@ void AwesomePlayer::reset_l() { mDrmManagerClient = NULL; } + if (mFlags & PLAYING) { + uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder; + if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) { + params |= IMediaPlayerService::kBatteryDataTrackAudio; + } + if (mVideoSource != NULL) { + params |= IMediaPlayerService::kBatteryDataTrackVideo; + } + addBatteryData(params); + } + if (mFlags & PREPARING) { mFlags |= PREPARE_CANCELLED; if (mConnectingDataSource != NULL) { @@ -779,6 +801,16 @@ status_t AwesomePlayer::play_l() { seekTo_l(0); } + uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted + | IMediaPlayerService::kBatteryDataTrackDecoder; + if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) { + params |= IMediaPlayerService::kBatteryDataTrackAudio; + } + if (mVideoSource != NULL) { + params |= IMediaPlayerService::kBatteryDataTrackVideo; + } + addBatteryData(params); + return OK; } @@ -933,6 +965,16 @@ status_t AwesomePlayer::pause_l(bool at_eos) { Playback::PAUSE, 0); } + uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder; + if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) { + params |= IMediaPlayerService::kBatteryDataTrackAudio; + } + if (mVideoSource != NULL) { + params |= IMediaPlayerService::kBatteryDataTrackVideo; + } + + addBatteryData(params); + return OK; } diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp index e6fe6186d45b..3689557bbf92 100644 --- a/media/libstagefright/CameraSourceTimeLapse.cpp +++ b/media/libstagefright/CameraSourceTimeLapse.cpp @@ -277,7 +277,7 @@ void CameraSourceTimeLapse::threadTimeLapseEntry() { // this thread as read() will make a copy of this last frame and keep // returning it in the quick stop mode. Mutex::Autolock autoLock(mQuickStopLock); - CHECK_EQ(OK, mCamera->takePicture()); + CHECK_EQ(OK, mCamera->takePicture(CAMERA_MSG_RAW_IMAGE)); if (mQuickStop) { LOGV("threadTimeLapseEntry: Exiting due to mQuickStop = true"); return; diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png Binary files differnew file mode 100644 index 000000000000..1aea61279908 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png Binary files differnew file mode 100644 index 000000000000..425535eb5d36 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_4g.png Binary files differnew file mode 100644 index 000000000000..fcad3632587d --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_4g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_4g.png Binary files differnew file mode 100644 index 000000000000..4ff7db3b4e61 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_4g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_4g.png Binary files differnew file mode 100644 index 000000000000..2c4a07f0ef99 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_4g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_4g.png Binary files differnew file mode 100644 index 000000000000..879c703f7b1f --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_4g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inadnout_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inadnout_e.png Binary files differnew file mode 100644 index 000000000000..61a7503f2123 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inadnout_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_4g.png Binary files differnew file mode 100644 index 000000000000..c5edf2c19e3f --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_4g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_4g.png Binary files differnew file mode 100644 index 000000000000..ddf88bedb964 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png Binary files differindex 78ece9e344f6..c77e61e2deaf 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png Binary files differindex 31fc1b023d00..b9f721aa0bf1 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png Binary files differnew file mode 100644 index 000000000000..cff969e25276 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png Binary files differindex 19adb4b02744..d2d7ab3dae12 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png Binary files differindex fd419ea4d64e..83ce6d09cb41 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png Binary files differindex 94e77ae79e8f..abe511f83c20 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png Binary files differindex 91328c0211c0..d685af8c10e3 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png Binary files differindex 2fee69248af9..8c697a18cf4f 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png Binary files differnew file mode 100644 index 000000000000..9a4b807e9b1e --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png Binary files differindex d0968aa19a5a..eb11d04d2e99 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png Binary files differindex 991228b06a21..6e54de0d4373 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png Binary files differindex ae03e3891a98..5bfb33b3a0b2 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_1x.png Binary files differindex 97b011e0bda4..119067b5dc2d 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_1x.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_1x.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_3g.png Binary files differindex a826866c3bdb..a70cc2ecaa08 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_3g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_3g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_4g.png Binary files differnew file mode 100644 index 000000000000..ea3dba76e6e8 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_e.png Binary files differindex f6a68916921b..53221b99b767 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_e.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_e.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_g.png Binary files differindex 19b98167e602..11d44d00f5bc 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_h.png Binary files differindex f8c09614f216..9defd7919823 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_h.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_h.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_1x.png Binary files differindex 22deb701e357..136576d4a542 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_1x.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_1x.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_3g.png Binary files differindex c7c1b49227ed..26ca31fedf0e 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_3g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_3g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_4g.png Binary files differnew file mode 100644 index 000000000000..de8c5ee5bc58 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_e.png Binary files differindex d9a0702c7952..64dbf3c60353 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_e.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_e.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_g.png Binary files differindex 6beed8a1b7fa..34923fb98400 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_h.png Binary files differindex e4179c13f2ff..506b5c61cd65 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_h.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_h.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_1x.png Binary files differindex 4b2f86d3b4a1..163976fd87ad 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_1x.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_1x.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_3g.png Binary files differindex 6779604782f6..a6af649bac56 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_3g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_3g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_4g.png Binary files differnew file mode 100644 index 000000000000..0c08e522f935 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_e.png Binary files differindex 1309a9790ddc..1d02edbc8db4 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_e.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_e.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_g.png Binary files differindex 2fc1e8ec2865..edc95360027d 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_h.png Binary files differindex 0eef2c10c82c..8376817cd8e6 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_h.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_h.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png Binary files differindex f8904e2c3fb3..ecef547e84d5 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png Binary files differindex 3ef306e7db26..a7c48b6eaaff 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_4g.png Binary files differnew file mode 100644 index 000000000000..f4bcd9a18169 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png Binary files differindex 2ff6d90d3b54..b46bb3a65ba8 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png Binary files differindex 8ff49b0f3830..e8b70f298207 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png Binary files differindex f416203aeedc..4e23c4ebae67 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inadnout_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inadnout_e.png Binary files differnew file mode 100644 index 000000000000..ced91751c16e --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inadnout_e.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png Binary files differindex 24b7daacd561..92d4a19f9d52 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png Binary files differindex 5ea91427ef76..a208736046b4 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_4g.png Binary files differnew file mode 100644 index 000000000000..f407bc97ae0a --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png Binary files differindex 002bf46436f1..b8a65c239720 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png Binary files differindex 924b84f54a7c..a978b680285d 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png Binary files differindex bd0d1caaf772..710dd52e0e26 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png Binary files differindex f583eecac5fc..a7b35e4c2448 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_4g.png Binary files differnew file mode 100644 index 000000000000..bb0544919b0a --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_4g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png Binary files differindex 66940eaf40ea..a14422250d74 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png Binary files differindex 0381f52d4de0..b0eafb66ec1f 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png Binary files differindex 0b84fe8ccbd9..f6b83d0a0093 100644 --- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png +++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index afb73a9033d8..60fb61d91602 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -668,7 +668,7 @@ public class TabletStatusBar extends StatusBar implements } public void updateNotification(IBinder key, StatusBarNotification notification) { - if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO"); + if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")"); final NotificationData.Entry oldEntry = mNotificationData.findByKey(key); if (oldEntry == null) { @@ -685,7 +685,8 @@ public class TabletStatusBar extends StatusBar implements Slog.d(TAG, "old notification: when=" + oldNotification.notification.when + " ongoing=" + oldNotification.isOngoing() + " expanded=" + oldEntry.expanded - + " contentView=" + oldContentView); + + " contentView=" + oldContentView + + " rowParent=" + oldEntry.row.getParent()); Slog.d(TAG, "new notification: when=" + notification.notification.when + " ongoing=" + oldNotification.isOngoing() + " contentView=" + contentView); @@ -806,16 +807,17 @@ public class TabletStatusBar extends StatusBar implements } } if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + mNotificationDNDMode = Prefs.read(mContext) + .getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT); + if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); + Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes" + (mNotificationDNDMode?" (DND)":"")); mTicker.halt(); } else { - Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: no"); + Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: no" + (mNotificationDNDMode?" (DND)":"")); } + // refresh icons to show either notifications or the DND message - mNotificationDNDMode = Prefs.read(mContext) - .getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT); - Slog.d(TAG, "DND: " + mNotificationDNDMode); reloadAllNotificationIcons(); } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { @@ -1241,29 +1243,34 @@ public class TabletStatusBar extends StatusBar implements if (mIconLayout == null) return; + // first, populate the main notification panel + loadNotificationPanel(); + final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight); // alternate behavior in DND mode - if (mNotificationDNDMode && mIconLayout.getChildCount() == 0) { - final StatusBarIconView iconView = new StatusBarIconView(mContext, "_dnd"); - iconView.setImageResource(R.drawable.ic_notification_dnd); - iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - iconView.setPadding(mIconHPadding, 0, mIconHPadding, 0); - - final Notification dndNotification = new Notification.Builder(mContext) - .setContentTitle(mContext.getText(R.string.notifications_off_title)) - .setContentText(mContext.getText(R.string.notifications_off_text)) - .setSmallIcon(R.drawable.ic_notification_dnd) - .setOngoing(true) - .getNotification(); - - mNotificationDNDDummyEntry = new NotificationData.Entry( - null, - new StatusBarNotification("", 0, "", 0, 0, dndNotification), - iconView); - - mIconLayout.addView(iconView, params); + if (mNotificationDNDMode) { + if (mIconLayout.getChildCount() == 0) { + final StatusBarIconView iconView = new StatusBarIconView(mContext, "_dnd"); + iconView.setImageResource(R.drawable.ic_notification_dnd); + iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + iconView.setPadding(mIconHPadding, 0, mIconHPadding, 0); + + final Notification dndNotification = new Notification.Builder(mContext) + .setContentTitle(mContext.getText(R.string.notifications_off_title)) + .setContentText(mContext.getText(R.string.notifications_off_text)) + .setSmallIcon(R.drawable.ic_notification_dnd) + .setOngoing(true) + .getNotification(); + + mNotificationDNDDummyEntry = new NotificationData.Entry( + null, + new StatusBarNotification("", 0, "", 0, 0, dndNotification), + iconView); + + mIconLayout.addView(iconView, params); + } return; } @@ -1305,8 +1312,6 @@ public class TabletStatusBar extends StatusBar implements mIconLayout.addView(v, i, params); } } - - loadNotificationPanel(); } private void loadNotificationPanel() { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 97949441fce5..f6649fd74af1 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -2570,6 +2570,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private int getCurrentLandscapeRotation(int lastRotation) { + // if the user has locked rotation, we ignore the sensor + if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { + if (isLandscapeOrSeascape(mUserRotation)) { + return mUserRotation; + } else { + // it seems odd to obey the sensor at all if rotation lock is enabled + return mLandscapeRotation; + } + } + int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation); if (isLandscapeOrSeascape(sensorRotation)) { return sensorRotation; @@ -2587,6 +2597,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private int getCurrentPortraitRotation(int lastRotation) { + // if the user has locked rotation, we ignore the sensor + if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { + if (isAnyPortrait(mUserRotation)) { + return mUserRotation; + } else { + // it seems odd to obey the sensor at all if rotation lock is enabled + return mPortraitRotation; + } + } + int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation); if (isAnyPortrait(sensorRotation)) { return sensorRotation; diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 3d8ca7a3da13..a09e16b3b412 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -727,17 +727,30 @@ status_t CameraService::Client::cancelAutoFocus() { } // take a picture - image is returned in callback -status_t CameraService::Client::takePicture() { - LOG1("takePicture (pid %d)", getCallingPid()); +status_t CameraService::Client::takePicture(int msgType) { + LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType); Mutex::Autolock lock(mLock); status_t result = checkPidAndHardware(); if (result != NO_ERROR) return result; - enableMsgType(CAMERA_MSG_SHUTTER | - CAMERA_MSG_POSTVIEW_FRAME | - CAMERA_MSG_RAW_IMAGE | - CAMERA_MSG_COMPRESSED_IMAGE); + if ((msgType & CAMERA_MSG_RAW_IMAGE) && + (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) { + LOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY" + " cannot be both enabled"); + return BAD_VALUE; + } + + // We only accept picture related message types + // and ignore other types of messages for takePicture(). + int picMsgType = msgType + & (CAMERA_MSG_SHUTTER | + CAMERA_MSG_POSTVIEW_FRAME | + CAMERA_MSG_RAW_IMAGE | + CAMERA_MSG_RAW_IMAGE_NOTIFY | + CAMERA_MSG_COMPRESSED_IMAGE); + + enableMsgType(picMsgType); return mHardware->takePicture(); } diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index ccb9cf7082cc..1c43b00f7ff1 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -108,7 +108,7 @@ private: virtual void releaseRecordingFrame(const sp<IMemory>& mem); virtual status_t autoFocus(); virtual status_t cancelAutoFocus(); - virtual status_t takePicture(); + virtual status_t takePicture(int msgType); virtual status_t setParameters(const String8& params); virtual String8 getParameters() const; virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2); diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index cc25e8d09996..f9b94a309f25 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -96,6 +96,9 @@ public class WifiService extends IWifiManager.Stub { private boolean mDeviceIdle; private int mPluggedType; + /* Chipset supports background scan */ + private final boolean mBackgroundScanSupported; + // true if the user enabled Wifi while in airplane mode private AtomicBoolean mAirplaneModeOverwridden = new AtomicBoolean(false); @@ -369,6 +372,9 @@ public class WifiService extends IWifiManager.Stub { Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l; mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(new Handler()); mNotificationEnabledSettingObserver.register(); + + mBackgroundScanSupported = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_wifi_background_scan_support); } /** @@ -900,6 +906,9 @@ public class WifiService extends IWifiManager.Stub { reportStartWorkSource(); evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(true); + if (mBackgroundScanSupported) { + mWifiStateMachine.enableBackgroundScan(false); + } mWifiStateMachine.enableAllNetworks(); updateWifiState(); } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { @@ -909,6 +918,9 @@ public class WifiService extends IWifiManager.Stub { mScreenOff = true; evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(false); + if (mBackgroundScanSupported) { + mWifiStateMachine.enableBackgroundScan(true); + } /* * Set a timer to put Wi-Fi to sleep, but only if the screen is off * AND the "stay on while plugged in" setting doesn't match the diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 0f7d6392e496..57af001fabc8 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -341,6 +341,45 @@ void Layer::onDraw(const Region& clip) const drawWithOpenGL(clip, tex); } +// As documented in libhardware header, formats in the range +// 0x100 - 0x1FF are specific to the HAL implementation, and +// are known to have no alpha channel +// TODO: move definition for device-specific range into +// hardware.h, instead of using hard-coded values here. +#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) + +bool Layer::needsBlending(const sp<GraphicBuffer>& buffer) const +{ + // If buffers where set with eOpaque flag, all buffers are known to + // be opaque without having to check their actual format + if (mNeedsBlending && buffer != NULL) { + PixelFormat format = buffer->getPixelFormat(); + + if (HARDWARE_IS_DEVICE_FORMAT(format)) { + return false; + } + + PixelFormatInfo info; + status_t err = getPixelFormatInfo(format, &info); + if (!err && info.h_alpha <= info.l_alpha) { + return false; + } + } + + // Return opacity as determined from flags and format options + // passed to setBuffers() + return mNeedsBlending; +} + +bool Layer::needsBlending() const +{ + if (mBufferManager.hasActiveBuffer()) { + return needsBlending(mBufferManager.getActiveBuffer()); + } + + return mNeedsBlending; +} + bool Layer::needsFiltering() const { if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { @@ -588,6 +627,9 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) // we retired a buffer, which becomes the new front buffer const bool noActiveBuffer = !mBufferManager.hasActiveBuffer(); + const bool activeBlending = + noActiveBuffer ? true : needsBlending(mBufferManager.getActiveBuffer()); + if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); mPostedDirtyRegion.clear(); @@ -602,6 +644,12 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); if (newFrontBuffer != NULL) { + if (!noActiveBuffer && activeBlending != needsBlending(newFrontBuffer)) { + // new buffer has different opacity than previous active buffer, need + // to recompute visible regions accordingly + recomputeVisibleRegions = true; + } + // get the dirty region // compute the posted region const Region dirty(lcblk->getDirtyRegion(buf)); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 2b3841466d70..bccc9004fd99 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -75,7 +75,8 @@ public: virtual uint32_t doTransaction(uint32_t transactionFlags); virtual void lockPageFlip(bool& recomputeVisibleRegions); virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); - virtual bool needsBlending() const { return mNeedsBlending; } + virtual bool needsBlending(const sp<GraphicBuffer>& buffer) const; + virtual bool needsBlending() const; virtual bool needsDithering() const { return mNeedsDithering; } virtual bool needsFiltering() const; virtual bool isSecure() const { return mSecure; } diff --git a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml b/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml index 5211b0a9b6e0..d3c492eacf43 100644 --- a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml +++ b/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml @@ -9,5 +9,7 @@ android:layout_width="wrap_content"/> <ImageView android:layout_height="wrap_content" - android:layout_width="wrap_content"/> + android:layout_width="wrap_content" + android:layout_marginLeft="3dip" + android:layout_marginRight="5dip"/> </merge> diff --git a/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java index e1934774f672..a50a2bd039f5 100644 --- a/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java @@ -63,7 +63,7 @@ public class AvoidXfermode_Delegate extends Xfermode_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreate(int opColor, int tolerance, int nativeMode) { AvoidXfermode_Delegate newDelegate = new AvoidXfermode_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java index c6fde7be289b..9a8cf0462131 100644 --- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java @@ -76,7 +76,7 @@ public class BitmapShader_Delegate extends Shader_Delegate { bitmap.getImage(), Shader_Delegate.getTileMode(shaderTileModeX), Shader_Delegate.getTileMode(shaderTileModeY)); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java index 0c8776628646..b6d5725ab07b 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java @@ -245,12 +245,12 @@ public final class Bitmap_Delegate { @LayoutlibDelegate /*package*/ static void nativeDestructor(int nativeBitmap) { - sManager.removeDelegate(nativeBitmap); + sManager.removeJavaReferenceFor(nativeBitmap); } @LayoutlibDelegate /*package*/ static void nativeRecycle(int nativeBitmap) { - sManager.removeDelegate(nativeBitmap); + sManager.removeJavaReferenceFor(nativeBitmap); } @LayoutlibDelegate @@ -522,7 +522,7 @@ public final class Bitmap_Delegate { private static Bitmap createBitmap(Bitmap_Delegate delegate, boolean isMutable, int density) { // get its native_int - int nativeInt = sManager.addDelegate(delegate); + int nativeInt = sManager.addNewDelegate(delegate); // and create/return a new Bitmap with it return new Bitmap(nativeInt, null /* buffer */, isMutable, null /*ninePatchChunk*/, density); diff --git a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java index 92d0d0af5d3f..4becba130127 100644 --- a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java @@ -57,7 +57,7 @@ public class BlurMaskFilter_Delegate extends MaskFilter_Delegate { @LayoutlibDelegate /*package*/ static int nativeConstructor(float radius, int style) { BlurMaskFilter_Delegate newDelegate = new BlurMaskFilter_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java index e8a99b5d6711..f0e727febe96 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java @@ -64,7 +64,7 @@ public final class Canvas_Delegate { private Bitmap_Delegate mBitmap; private GcSnapshot mSnapshot; - private int mDrawFilter = 0; + private DrawFilter_Delegate mDrawFilter = null; // ---- Public Helper methods ---- @@ -95,7 +95,7 @@ public final class Canvas_Delegate { * @return the delegate or null. */ public DrawFilter_Delegate getDrawFilter() { - return DrawFilter_Delegate.getDelegate(mDrawFilter); + return mDrawFilter; } // ---- native methods ---- @@ -313,12 +313,12 @@ public final class Canvas_Delegate { // create a new Canvas_Delegate with the given bitmap and return its new native int. Canvas_Delegate newDelegate = new Canvas_Delegate(bitmapDelegate); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } else { // create a new Canvas_Delegate and return its new native int. Canvas_Delegate newDelegate = new Canvas_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } } @@ -510,26 +510,18 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeSetDrawFilter(int nativeCanvas, - int nativeFilter) { + /*package*/ static void nativeSetDrawFilter(int nativeCanvas, int nativeFilter) { Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas); if (canvasDelegate == null) { return; } - canvasDelegate.mDrawFilter = nativeFilter; + canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter); - // get the delegate only because we don't support them at all for the moment, so - // we can display the message now. - - DrawFilter_Delegate filterDelegate = DrawFilter_Delegate.getDelegate(nativeFilter); - if (canvasDelegate == null) { - return; - } - - if (filterDelegate.isSupported() == false) { + if (canvasDelegate.mDrawFilter != null && + canvasDelegate.mDrawFilter.isSupported() == false) { Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER, - filterDelegate.getSupportMessage(), null, null /*data*/); + canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/); } } @@ -956,7 +948,7 @@ public final class Canvas_Delegate { draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/, new GcSnapshot.Drawable() { public void draw(Graphics2D graphics, Paint_Delegate paint) { - // WARNING: the logic in this method is similar to Paint.measureText. + // WARNING: the logic in this method is similar to Paint_Delegate.measureText. // Any change to this method should be reflected in Paint.measureText // Paint.TextAlign indicates how the text is positioned relative to X. // LEFT is the default and there's nothing to do. @@ -1139,7 +1131,7 @@ public final class Canvas_Delegate { canvasDelegate.dispose(); // remove it from the manager. - sManager.removeDelegate(nativeCanvas); + sManager.removeJavaReferenceFor(nativeCanvas); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java index 789c6e6904bf..e786eb587b1d 100644 --- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java @@ -57,7 +57,7 @@ public abstract class ColorFilter_Delegate { @LayoutlibDelegate /*package*/ static void finalizer(int native_instance, int nativeColorFilter) { - sManager.removeDelegate(native_instance); + sManager.removeJavaReferenceFor(native_instance); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java index 462b1e640725..2de344b41f8a 100644 --- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java @@ -57,7 +57,7 @@ public class ColorMatrixColorFilter_Delegate extends ColorFilter_Delegate { @LayoutlibDelegate /*package*/ static int nativeColorMatrixFilter(float[] array) { ColorMatrixColorFilter_Delegate newDelegate = new ColorMatrixColorFilter_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java index 2bdaa5bdbf5c..7c04a8709db2 100644 --- a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java @@ -64,7 +64,7 @@ public class ComposePathEffect_Delegate extends PathEffect_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreate(int outerpe, int innerpe) { ComposePathEffect_Delegate newDelegate = new ComposePathEffect_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java index a2ecb8f6a1a6..f6e1d0094925 100644 --- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java @@ -67,7 +67,7 @@ public class ComposeShader_Delegate extends Shader_Delegate { int native_mode) { // FIXME not supported yet. ComposeShader_Delegate newDelegate = new ComposeShader_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate @@ -75,7 +75,7 @@ public class ComposeShader_Delegate extends Shader_Delegate { int porterDuffMode) { // FIXME not supported yet. ComposeShader_Delegate newDelegate = new ComposeShader_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java index c677de83ba7f..b0f8168aa3a0 100644 --- a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java @@ -64,7 +64,7 @@ public class CornerPathEffect_Delegate extends PathEffect_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreate(float radius) { CornerPathEffect_Delegate newDelegate = new CornerPathEffect_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java index 12a4d4a348d9..d97c2eccd508 100644 --- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java @@ -75,7 +75,7 @@ public final class DashPathEffect_Delegate extends PathEffect_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreate(float intervals[], float phase) { DashPathEffect_Delegate newDelegate = new DashPathEffect_Delegate(intervals, phase); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java index ac6971284583..ec4a810fbda5 100644 --- a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java @@ -64,7 +64,7 @@ public class DiscretePathEffect_Delegate extends PathEffect_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreate(float length, float deviation) { DiscretePathEffect_Delegate newDelegate = new DiscretePathEffect_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java index a98f0a941090..37c7359b5814 100644 --- a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java @@ -57,7 +57,7 @@ public abstract class DrawFilter_Delegate { @LayoutlibDelegate /*package*/ static void nativeDestructor(int nativeDrawFilter) { - sManager.removeDelegate(nativeDrawFilter); + sManager.removeJavaReferenceFor(nativeDrawFilter); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java index 31f8bbfb1f8e..ebc1c1d2eca4 100644 --- a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java @@ -58,7 +58,7 @@ public class EmbossMaskFilter_Delegate extends MaskFilter_Delegate { /*package*/ static int nativeConstructor(float[] direction, float ambient, float specular, float blurRadius) { EmbossMaskFilter_Delegate newDelegate = new EmbossMaskFilter_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java index fcb62a8a9592..51e0576169c4 100644 --- a/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java @@ -57,7 +57,7 @@ public class LayerRasterizer_Delegate extends Rasterizer_Delegate { @LayoutlibDelegate /*package*/ static int nativeConstructor() { LayerRasterizer_Delegate newDelegate = new LayerRasterizer_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java index b2725343b791..0ee883dcd68c 100644 --- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java @@ -57,7 +57,7 @@ public class LightingColorFilter_Delegate extends ColorFilter_Delegate { @LayoutlibDelegate /*package*/ static int native_CreateLightingFilter(int mul, int add) { LightingColorFilter_Delegate newDelegate = new LightingColorFilter_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java index 80605779fcf9..a2ba758a7e0c 100644 --- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java @@ -59,7 +59,7 @@ public final class LinearGradient_Delegate extends Gradient_Delegate { int colors[], float positions[], int tileMode) { LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(x0, y0, x1, y1, colors, positions, Shader_Delegate.getTileMode(tileMode)); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java index 4adca276a7d8..5a6167dc6a3d 100644 --- a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java @@ -57,7 +57,7 @@ public abstract class MaskFilter_Delegate { @LayoutlibDelegate /*package*/ static void nativeDestructor(int native_filter) { - sManager.removeDelegate(native_filter); + sManager.removeJavaReferenceFor(native_filter); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java index 68a476f170ef..251aa16ba48b 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java @@ -189,7 +189,7 @@ public final class Matrix_Delegate { } } - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate @@ -765,7 +765,7 @@ public final class Matrix_Delegate { @LayoutlibDelegate /*package*/ static void finalizer(int native_instance) { - sManager.removeDelegate(native_instance); + sManager.removeJavaReferenceFor(native_instance); } // ---- Private helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java index dfcb5916b8cc..71d346a93553 100644 --- a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java @@ -57,7 +57,7 @@ public class PaintFlagsDrawFilter_Delegate extends DrawFilter_Delegate { @LayoutlibDelegate /*package*/ static int nativeConstructor(int clearBits, int setBits) { PaintFlagsDrawFilter_Delegate newDelegate = new PaintFlagsDrawFilter_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java index f5d2547799d8..51b3efe12cd7 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java @@ -32,6 +32,7 @@ import java.awt.Stroke; import java.awt.Toolkit; import java.awt.font.FontRenderContext; import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -75,19 +76,19 @@ public class Paint_Delegate { private int mCap; private int mJoin; private int mTextAlign; - private int mTypeface; + private Typeface_Delegate mTypeface; private float mStrokeWidth; private float mStrokeMiter; private float mTextSize; private float mTextScaleX; private float mTextSkewX; - private int mXfermode; - private int mColorFilter; - private int mShader; - private int mPathEffect; - private int mMaskFilter; - private int mRasterizer; + private Xfermode_Delegate mXfermode; + private ColorFilter_Delegate mColorFilter; + private Shader_Delegate mShader; + private PathEffect_Delegate mPathEffect; + private MaskFilter_Delegate mMaskFilter; + private Rasterizer_Delegate mRasterizer; // ---- Public Helper methods ---- @@ -172,17 +173,16 @@ public class Paint_Delegate { } public Stroke getJavaStroke() { - PathEffect_Delegate effectDelegate = PathEffect_Delegate.getDelegate(mPathEffect); - if (effectDelegate != null) { - if (effectDelegate.isSupported()) { - Stroke stroke = effectDelegate.getStroke(this); + if (mPathEffect != null) { + if (mPathEffect.isSupported()) { + Stroke stroke = mPathEffect.getStroke(this); assert stroke != null; if (stroke != null) { return stroke; } } else { Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT, - effectDelegate.getSupportMessage(), + mPathEffect.getSupportMessage(), null, null /*data*/); } } @@ -201,7 +201,7 @@ public class Paint_Delegate { * @return the delegate or null. */ public Xfermode_Delegate getXfermode() { - return Xfermode_Delegate.getDelegate(mXfermode); + return mXfermode; } /** @@ -210,7 +210,7 @@ public class Paint_Delegate { * @return the delegate or null. */ public ColorFilter_Delegate getColorFilter() { - return ColorFilter_Delegate.getDelegate(mColorFilter); + return mColorFilter; } /** @@ -219,7 +219,7 @@ public class Paint_Delegate { * @return the delegate or null. */ public Shader_Delegate getShader() { - return Shader_Delegate.getDelegate(mShader); + return mShader; } /** @@ -228,7 +228,7 @@ public class Paint_Delegate { * @return the delegate or null. */ public MaskFilter_Delegate getMaskFilter() { - return MaskFilter_Delegate.getDelegate(mMaskFilter); + return mMaskFilter; } /** @@ -237,7 +237,7 @@ public class Paint_Delegate { * @return the delegate or null. */ public Rasterizer_Delegate getRasterizer() { - return Rasterizer_Delegate.getDelegate(mRasterizer); + return mRasterizer; } // ---- native methods ---- @@ -542,9 +542,6 @@ public class Paint_Delegate { @LayoutlibDelegate /*package*/ static float native_measureText(Paint thisPaint, char[] text, int index, int count) { - // WARNING: the logic in this method is similar to Canvas.drawText. - // Any change to this method should be reflected in Canvas.drawText - // get the delegate Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint); if (delegate == null) { @@ -567,25 +564,57 @@ public class Paint_Delegate { @LayoutlibDelegate /*package*/ static int native_breakText(Paint thisPaint, char[] text, int index, int count, float maxWidth, float[] measuredWidth) { - // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, - "Paint.native_breakText is not supported.", null, null /*data*/); - return 0; + + // get the delegate + Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint); + if (delegate == null) { + return 0; + } + + int inc = count > 0 ? 1 : -1; + + int measureIndex = 0; + float measureAcc = 0; + for (int i = index; i != index + count; i += inc, measureIndex++) { + int start, end; + if (i < index) { + start = i; + end = index; + } else { + start = index; + end = i; + } + + // measure from start to end + float res = delegate.measureText(text, start, end - start + 1); + + if (measuredWidth != null) { + measuredWidth[measureIndex] = res; + } + + measureAcc += res; + if (res > maxWidth) { + // we should not return this char index, but since it's 0-based + // and we need to return a count, we simply return measureIndex; + return measureIndex; + } + + } + + return measureIndex; } @LayoutlibDelegate /*package*/ static int native_breakText(Paint thisPaint, String text, boolean measureForwards, float maxWidth, float[] measuredWidth) { - // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, - "Paint.native_breakText is not supported.", null, null /*data*/); - return 0; + return native_breakText(thisPaint, text.toCharArray(), 0, text.length(), maxWidth, + measuredWidth); } @LayoutlibDelegate /*package*/ static int native_init() { Paint_Delegate newDelegate = new Paint_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate @@ -597,7 +626,7 @@ public class Paint_Delegate { } Paint_Delegate newDelegate = new Paint_Delegate(delegate); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate @@ -728,7 +757,9 @@ public class Paint_Delegate { return shader; } - return delegate.mShader = shader; + delegate.mShader = Shader_Delegate.getDelegate(shader); + + return shader; } @LayoutlibDelegate @@ -739,13 +770,12 @@ public class Paint_Delegate { return filter; } - delegate.mColorFilter = filter; + delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);; // since none of those are supported, display a fidelity warning right away - ColorFilter_Delegate filterDelegate = delegate.getColorFilter(); - if (filterDelegate != null && filterDelegate.isSupported() == false) { + if (delegate.mColorFilter != null && delegate.mColorFilter.isSupported() == false) { Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER, - filterDelegate.getSupportMessage(), null, null /*data*/); + delegate.mColorFilter.getSupportMessage(), null, null /*data*/); } return filter; @@ -759,7 +789,9 @@ public class Paint_Delegate { return xfermode; } - return delegate.mXfermode = xfermode; + delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode); + + return xfermode; } @LayoutlibDelegate @@ -770,7 +802,9 @@ public class Paint_Delegate { return effect; } - return delegate.mPathEffect = effect; + delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect); + + return effect; } @LayoutlibDelegate @@ -781,13 +815,12 @@ public class Paint_Delegate { return maskfilter; } - delegate.mMaskFilter = maskfilter; + delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter); // since none of those are supported, display a fidelity warning right away - MaskFilter_Delegate filterDelegate = delegate.getMaskFilter(); - if (filterDelegate != null && filterDelegate.isSupported() == false) { + if (delegate.mMaskFilter != null && delegate.mMaskFilter.isSupported() == false) { Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER, - filterDelegate.getSupportMessage(), null, null /*data*/); + delegate.mMaskFilter.getSupportMessage(), null, null /*data*/); } return maskfilter; @@ -801,9 +834,9 @@ public class Paint_Delegate { return 0; } - delegate.mTypeface = typeface; + delegate.mTypeface = Typeface_Delegate.getDelegate(typeface); delegate.updateFontObject(); - return delegate.mTypeface; + return typeface; } @LayoutlibDelegate @@ -814,13 +847,12 @@ public class Paint_Delegate { return rasterizer; } - delegate.mRasterizer = rasterizer; + delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer); // since none of those are supported, display a fidelity warning right away - Rasterizer_Delegate rasterizerDelegate = delegate.getRasterizer(); - if (rasterizerDelegate != null && rasterizerDelegate.isSupported() == false) { + if (delegate.mRasterizer != null && delegate.mRasterizer.isSupported() == false) { Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER, - rasterizerDelegate.getSupportMessage(), null, null /*data*/); + delegate.mRasterizer.getSupportMessage(), null, null /*data*/); } return rasterizer; @@ -862,19 +894,49 @@ public class Paint_Delegate { @LayoutlibDelegate /*package*/ static int native_getTextWidths(int native_object, char[] text, int index, int count, float[] widths) { - // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, - "Paint.getTextWidths is not supported.", null, null /*data*/); + // get the delegate from the native int. + Paint_Delegate delegate = sManager.getDelegate(native_object); + if (delegate == null) { + return 0; + } + + if (delegate.mFonts.size() > 0) { + // FIXME: handle multi-char characters (see measureText) + float totalAdvance = 0; + for (int i = 0; i < count; i++) { + char c = text[i + index]; + boolean found = false; + for (FontInfo info : delegate.mFonts) { + if (info.mFont.canDisplay(c)) { + float adv = info.mMetrics.charWidth(c); + totalAdvance += adv; + if (widths != null) { + widths[i] = adv; + } + + found = true; + break; + } + } + + if (found == false) { + // no advance for this char. + if (widths != null) { + widths[i] = 0.f; + } + } + } + + return (int) totalAdvance; + } + return 0; } @LayoutlibDelegate /*package*/ static int native_getTextWidths(int native_object, String text, int start, int end, float[] widths) { - // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, - "Paint.getTextWidths is not supported.", null, null /*data*/); - return 0; + return native_getTextWidths(native_object, text.toCharArray(), start, end - start, widths); } @LayoutlibDelegate @@ -971,22 +1033,33 @@ public class Paint_Delegate { @LayoutlibDelegate /*package*/ static void nativeGetStringBounds(int nativePaint, String text, int start, int end, Rect bounds) { - // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, - "Paint.getStringBounds is not supported.", null, null /*data*/); + nativeGetCharArrayBounds(nativePaint, text.toCharArray(), start, end - start, bounds); } @LayoutlibDelegate /*package*/ static void nativeGetCharArrayBounds(int nativePaint, char[] text, int index, int count, Rect bounds) { - // FIXME - Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, - "Paint.getCharArrayBounds is not supported.", null, null /*data*/); + + // get the delegate from the native int. + Paint_Delegate delegate = sManager.getDelegate(nativePaint); + if (delegate == null) { + return; + } + + // FIXME should test if the main font can display all those characters. + // See MeasureText + if (delegate.mFonts.size() > 0) { + FontInfo mainInfo = delegate.mFonts.get(0); + + Rectangle2D rect = mainInfo.mFont.getStringBounds(text, index, index + count, + delegate.mFontContext); + bounds.set(0, 0, (int) rect.getWidth(), (int) rect.getHeight()); + } } @LayoutlibDelegate /*package*/ static void finalizer(int nativePaint) { - sManager.removeDelegate(nativePaint); + sManager.removeJavaReferenceFor(nativePaint); } // ---- Private delegate/helper methods ---- @@ -1028,18 +1101,18 @@ public class Paint_Delegate { mCap = Paint.Cap.BUTT.nativeInt; mJoin = Paint.Join.MITER.nativeInt; mTextAlign = 0; - mTypeface = Typeface.sDefaults[0].native_instance; + mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance); mStrokeWidth = 1.f; mStrokeMiter = 4.f; mTextSize = 20.f; mTextScaleX = 1.f; mTextSkewX = 0.f; - mXfermode = 0; - mColorFilter = 0; - mShader = 0; - mPathEffect = 0; - mMaskFilter = 0; - mRasterizer = 0; + mXfermode = null; + mColorFilter = null; + mShader = null; + mPathEffect = null; + mMaskFilter = null; + mRasterizer = null; updateFontObject(); } @@ -1048,9 +1121,9 @@ public class Paint_Delegate { */ @SuppressWarnings("deprecation") private void updateFontObject() { - if (mTypeface != 0) { + if (mTypeface != null) { // Get the fonts from the TypeFace object. - List<Font> fonts = Typeface_Delegate.getFonts(mTypeface); + List<Font> fonts = mTypeface.getFonts(); // create new font objects as well as FontMetrics, based on the current text size // and skew info. @@ -1073,6 +1146,10 @@ public class Paint_Delegate { } /*package*/ float measureText(char[] text, int index, int count) { + + // WARNING: the logic in this method is similar to Canvas_Delegate.native_drawText + // Any change to this method should be reflected there as well + if (mFonts.size() > 0) { FontInfo mainFont = mFonts.get(0); int i = index; @@ -1120,6 +1197,8 @@ public class Paint_Delegate { i += size; } } + + return total; } return 0; diff --git a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java index 98a5386067a7..c448f0ec0f20 100644 --- a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java @@ -65,7 +65,7 @@ public class PathDashPathEffect_Delegate extends PathEffect_Delegate { /*package*/ static int nativeCreate(int native_path, float advance, float phase, int native_style) { PathDashPathEffect_Delegate newDelegate = new PathDashPathEffect_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java index bbbebdd8df2f..4d5311af42ae 100644 --- a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java @@ -61,7 +61,7 @@ public abstract class PathEffect_Delegate { @LayoutlibDelegate /*package*/ static void nativeDestructor(int native_patheffect) { - sManager.removeDelegate(native_patheffect); + sManager.removeJavaReferenceFor(native_patheffect); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java index 9510ce00e214..c29e9b6a0142 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java @@ -90,7 +90,7 @@ public final class Path_Delegate { // create the delegate Path_Delegate newDelegate = new Path_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate @@ -104,7 +104,7 @@ public final class Path_Delegate { newDelegate.set(pathDelegate); } - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate @@ -440,7 +440,7 @@ public final class Path_Delegate { @LayoutlibDelegate /*package*/ static void finalizer(int nPath) { - sManager.removeDelegate(nPath); + sManager.removeJavaReferenceFor(nPath); } diff --git a/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java index bbb20e956163..4ab044bd107a 100644 --- a/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java @@ -63,7 +63,7 @@ public class PixelXorXfermode_Delegate extends Xfermode_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreate(int opColor) { PixelXorXfermode_Delegate newDelegate = new PixelXorXfermode_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java index 33f6c4465527..c45dbaad344d 100644 --- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java @@ -57,7 +57,7 @@ public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate { @LayoutlibDelegate /*package*/ static int native_CreatePorterDuffFilter(int srcColor, int porterDuffMode) { PorterDuffColorFilter_Delegate newDelegate = new PorterDuffColorFilter_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java index 116a773c9832..4301c1a2c5d7 100644 --- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java @@ -129,7 +129,7 @@ public class PorterDuffXfermode_Delegate extends Xfermode_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreateXfermode(int mode) { PorterDuffXfermode_Delegate newDelegate = new PorterDuffXfermode_Delegate(mode); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java index 8723ed1a6584..9bf78b4c7249 100644 --- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java @@ -58,7 +58,7 @@ public class RadialGradient_Delegate extends Gradient_Delegate { int colors[], float positions[], int tileMode) { RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(x, y, radius, colors, positions, Shader_Delegate.getTileMode(tileMode)); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java index 28262787f9ba..e388bd9fc1b0 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java @@ -57,7 +57,7 @@ public abstract class Rasterizer_Delegate { @LayoutlibDelegate /*package*/ static void finalizer(int native_instance) { - sManager.removeDelegate(native_instance); + sManager.removeJavaReferenceFor(native_instance); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java index 7b912154930f..91f4347482ab 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java @@ -266,12 +266,12 @@ public class Region_Delegate { @LayoutlibDelegate /*package*/ static int nativeConstructor() { Region_Delegate newDelegate = new Region_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate /*package*/ static void nativeDestructor(int native_region) { - sManager.removeDelegate(native_region); + sManager.removeJavaReferenceFor(native_region); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java index a1b8bdd12fdf..a008d151c6ae 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java @@ -45,7 +45,7 @@ public abstract class Shader_Delegate { // ---- delegate helper data ---- // ---- delegate data ---- - private int mLocalMatrix = 0; + private Matrix_Delegate mLocalMatrix = null; // ---- Public Helper methods ---- @@ -77,7 +77,7 @@ public abstract class Shader_Delegate { @LayoutlibDelegate /*package*/ static void nativeDestructor(int native_shader, int native_skiaShader) { - sManager.removeDelegate(native_shader); + sManager.removeJavaReferenceFor(native_shader); } @LayoutlibDelegate @@ -89,15 +89,14 @@ public abstract class Shader_Delegate { return; } - shaderDelegate.mLocalMatrix = matrix_instance; + shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance); } // ---- Private delegate/helper methods ---- protected java.awt.geom.AffineTransform getLocalMatrix() { - Matrix_Delegate localMatrixDelegate = Matrix_Delegate.getDelegate(mLocalMatrix); - if (localMatrixDelegate != null) { - return localMatrixDelegate.getAffineTransform(); + if (mLocalMatrix != null) { + return mLocalMatrix.getAffineTransform(); } return new java.awt.geom.AffineTransform(); diff --git a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java index 0c9ee48ebd64..410df0cf72f5 100644 --- a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java @@ -64,7 +64,7 @@ public class SumPathEffect_Delegate extends PathEffect_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreate(int first, int second) { SumPathEffect_Delegate newDelegate = new SumPathEffect_Delegate(); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java index 382e34c41ad4..966e06e4a8b2 100644 --- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java @@ -54,7 +54,7 @@ public class SweepGradient_Delegate extends Gradient_Delegate { @LayoutlibDelegate /*package*/ static int nativeCreate1(float x, float y, int colors[], float positions[]) { SweepGradient_Delegate newDelegate = new SweepGradient_Delegate(x, y, colors, positions); - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java index 1992341d1423..5af16aeb5fb3 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java @@ -74,6 +74,10 @@ public final class Typeface_Delegate { sPostInitDelegate.clear(); } + public static Typeface_Delegate getDelegate(int nativeTypeface) { + return sManager.getDelegate(nativeTypeface); + } + public static List<Font> getFonts(Typeface typeface) { return getFonts(typeface.native_instance); } @@ -84,7 +88,11 @@ public final class Typeface_Delegate { return null; } - return delegate.mFonts; + return delegate.getFonts(); + } + + public List<Font> getFonts() { + return mFonts; } // ---- native methods ---- @@ -105,7 +113,7 @@ public final class Typeface_Delegate { sPostInitDelegate.add(newDelegate); } - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate @@ -125,7 +133,7 @@ public final class Typeface_Delegate { sPostInitDelegate.add(newDelegate); } - return sManager.addDelegate(newDelegate); + return sManager.addNewDelegate(newDelegate); } @LayoutlibDelegate @@ -144,7 +152,7 @@ public final class Typeface_Delegate { @LayoutlibDelegate /*package*/ static void nativeUnref(int native_instance) { - sManager.removeDelegate(native_instance); + sManager.removeJavaReferenceFor(native_instance); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java index 88df02739c6e..f3401fcadb65 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java @@ -61,7 +61,7 @@ public abstract class Xfermode_Delegate { @LayoutlibDelegate /*package*/ static void finalizer(int native_instance) { - sManager.removeDelegate(native_instance); + sManager.removeJavaReferenceFor(native_instance); } // ---- Private delegate/helper methods ---- diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java index 04d06e4bb45e..9fab51a61092 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java @@ -30,7 +30,7 @@ import android.widget.TextView; public class PhoneSystemBar extends CustomBar { public PhoneSystemBar(Context context, Density density) throws XmlPullParserException { - super(context, density, "/bars/tablet_system_bar.xml"); + super(context, density, "/bars/phone_system_bar.xml"); setGravity(mGravity | Gravity.RIGHT); setBackgroundColor(0xFF000000); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java index 05a258d56c66..295c98c3eafa 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java @@ -16,8 +16,14 @@ package com.android.layoutlib.bridge.impl; +import com.android.layoutlib.bridge.util.SparseWeakArray; + import android.util.SparseArray; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + /** * Manages native delegates. * @@ -44,13 +50,32 @@ import android.util.SparseArray; * will do is call {@link #getDelegate(int)} to get the Java object matching the int. * * Typical native init methods are returning a new int back to the Java class, so - * {@link #addDelegate(Object)} does the same. + * {@link #addNewDelegate(Object)} does the same. + * + * The JNI references are counted, so we do the same through a {@link WeakReference}. Because + * the Java object needs to count as a reference (even though it only holds an int), we use the + * following mechanism: + * + * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(int)} adds and removes + * the delegate to/from a list. This list hold the reference and prevents the GC from reclaiming + * the delegate. + * + * - {@link #addNewDelegate(Object)} also adds the delegate to a {@link SparseArray} that holds a + * {@link WeakReference} to the delegate. This allows the delegate to be deleted automatically + * when nothing references it. This means that any class that holds a delegate (except for the + * Java main class) must not use the int but the Delegate class instead. The integers must + * only be used in the API between the main Java class and the Delegate. * * @param <T> the delegate class to manage */ public final class DelegateManager<T> { - - private final SparseArray<T> mDelegates = new SparseArray<T>(); + private final SparseWeakArray<T> mDelegates = new SparseWeakArray<T>(); + /** list used to store delegates when their main object holds a reference to them. + * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed + * @see #addNewDelegate(Object) + * @see #removeJavaReferenceFor(int) + */ + private final List<T> mJavaReferences = new ArrayList<T>(); private int mDelegateCounter = 0; /** @@ -77,17 +102,20 @@ public final class DelegateManager<T> { * @param newDelegate the delegate to add * @return a unique native int to identify the delegate */ - public int addDelegate(T newDelegate) { + public int addNewDelegate(T newDelegate) { int native_object = ++mDelegateCounter; mDelegates.put(native_object, newDelegate); + assert !mJavaReferences.contains(newDelegate); + mJavaReferences.add(newDelegate); return native_object; } /** - * Removes the delegate matching the given native int. - * @param native_object the native int. + * Removes the main reference on the given delegate. + * @param native_object the native integer representing the delegate. */ - public void removeDelegate(int native_object) { - mDelegates.remove(native_object); + public void removeJavaReferenceFor(int native_object) { + T delegate = getDelegate(native_object); + mJavaReferences.remove(delegate); } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java new file mode 100644 index 000000000000..22f1609e6dc6 --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java @@ -0,0 +1,368 @@ +/* + * 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.layoutlib.bridge.util; + + +import com.android.internal.util.ArrayUtils; + +import android.util.SparseArray; + +import java.lang.ref.WeakReference; + +/** + * This is a custom {@link SparseArray} that uses {@link WeakReference} around the objects added + * to it. When the array is compacted, not only deleted indices but also empty references + * are removed, making the array efficient at removing references that were reclaimed. + * + * The code is taken from {@link SparseArray} directly and adapted to use weak references. + * + * Because our usage means that we never actually call {@link #remove(int)} or {@link #delete(int)}, + * we must manually check if there are reclaimed references to trigger an internal compact step + * (which is normally only triggered when an item is manually removed). + * + * SparseArrays map integers to Objects. Unlike a normal array of Objects, + * there can be gaps in the indices. It is intended to be more efficient + * than using a HashMap to map Integers to Objects. + */ +@SuppressWarnings("unchecked") +public class SparseWeakArray<E> { + + private static final Object DELETED_REF = new Object(); + private static final WeakReference<?> DELETED = new WeakReference(DELETED_REF); + private boolean mGarbage = false; + + /** + * Creates a new SparseArray containing no mappings. + */ + public SparseWeakArray() { + this(10); + } + + /** + * Creates a new SparseArray containing no mappings that will not + * require any additional memory allocation to store the specified + * number of mappings. + */ + public SparseWeakArray(int initialCapacity) { + initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); + + mKeys = new int[initialCapacity]; + mValues = new WeakReference[initialCapacity]; + mSize = 0; + } + + /** + * Gets the Object mapped from the specified key, or <code>null</code> + * if no such mapping has been made. + */ + public E get(int key) { + return get(key, null); + } + + /** + * Gets the Object mapped from the specified key, or the specified Object + * if no such mapping has been made. + */ + public E get(int key, E valueIfKeyNotFound) { + int i = binarySearch(mKeys, 0, mSize, key); + + if (i < 0 || mValues[i] == DELETED || mValues[i].get() == null) { + return valueIfKeyNotFound; + } else { + return (E) mValues[i].get(); + } + } + + /** + * Removes the mapping from the specified key, if there was any. + */ + public void delete(int key) { + int i = binarySearch(mKeys, 0, mSize, key); + + if (i >= 0) { + if (mValues[i] != DELETED) { + mValues[i] = DELETED; + mGarbage = true; + } + } + } + + /** + * Alias for {@link #delete(int)}. + */ + public void remove(int key) { + delete(key); + } + + /** + * Removes the mapping at the specified index. + */ + public void removeAt(int index) { + if (mValues[index] != DELETED) { + mValues[index] = DELETED; + mGarbage = true; + } + } + + private void gc() { + // Log.e("SparseArray", "gc start with " + mSize); + + int n = mSize; + int o = 0; + int[] keys = mKeys; + WeakReference<?>[] values = mValues; + + for (int i = 0; i < n; i++) { + WeakReference<?> val = values[i]; + + // Don't keep any non DELETED values, but only the one that still have a valid + // reference. + if (val != DELETED && val.get() != null) { + if (i != o) { + keys[o] = keys[i]; + values[o] = val; + } + + o++; + } + } + + mGarbage = false; + mSize = o; + + // Log.e("SparseArray", "gc end with " + mSize); + } + + /** + * Adds a mapping from the specified key to the specified value, + * replacing the previous mapping from the specified key if there + * was one. + */ + public void put(int key, E value) { + int i = binarySearch(mKeys, 0, mSize, key); + + if (i >= 0) { + mValues[i] = new WeakReference(value); + } else { + i = ~i; + + if (i < mSize && (mValues[i] == DELETED || mValues[i].get() == null)) { + mKeys[i] = key; + mValues[i] = new WeakReference(value); + return; + } + + if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) { + gc(); + + // Search again because indices may have changed. + i = ~binarySearch(mKeys, 0, mSize, key); + } + + if (mSize >= mKeys.length) { + int n = ArrayUtils.idealIntArraySize(mSize + 1); + + int[] nkeys = new int[n]; + WeakReference<?>[] nvalues = new WeakReference[n]; + + // Log.e("SparseArray", "grow " + mKeys.length + " to " + n); + System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); + System.arraycopy(mValues, 0, nvalues, 0, mValues.length); + + mKeys = nkeys; + mValues = nvalues; + } + + if (mSize - i != 0) { + // Log.e("SparseArray", "move " + (mSize - i)); + System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i); + System.arraycopy(mValues, i, mValues, i + 1, mSize - i); + } + + mKeys[i] = key; + mValues[i] = new WeakReference(value); + mSize++; + } + } + + /** + * Returns the number of key-value mappings that this SparseArray + * currently stores. + */ + public int size() { + if (mGarbage) { + gc(); + } + + return mSize; + } + + /** + * Given an index in the range <code>0...size()-1</code>, returns + * the key from the <code>index</code>th key-value mapping that this + * SparseArray stores. + */ + public int keyAt(int index) { + if (mGarbage) { + gc(); + } + + return mKeys[index]; + } + + /** + * Given an index in the range <code>0...size()-1</code>, returns + * the value from the <code>index</code>th key-value mapping that this + * SparseArray stores. + */ + public E valueAt(int index) { + if (mGarbage) { + gc(); + } + + return (E) mValues[index].get(); + } + + /** + * Given an index in the range <code>0...size()-1</code>, sets a new + * value for the <code>index</code>th key-value mapping that this + * SparseArray stores. + */ + public void setValueAt(int index, E value) { + if (mGarbage) { + gc(); + } + + mValues[index] = new WeakReference(value); + } + + /** + * Returns the index for which {@link #keyAt} would return the + * specified key, or a negative number if the specified + * key is not mapped. + */ + public int indexOfKey(int key) { + if (mGarbage) { + gc(); + } + + return binarySearch(mKeys, 0, mSize, key); + } + + /** + * Returns an index for which {@link #valueAt} would return the + * specified key, or a negative number if no keys map to the + * specified value. + * Beware that this is a linear search, unlike lookups by key, + * and that multiple keys can map to the same value and this will + * find only one of them. + */ + public int indexOfValue(E value) { + if (mGarbage) { + gc(); + } + + for (int i = 0; i < mSize; i++) + if (mValues[i].get() == value) + return i; + + return -1; + } + + /** + * Removes all key-value mappings from this SparseArray. + */ + public void clear() { + int n = mSize; + WeakReference<?>[] values = mValues; + + for (int i = 0; i < n; i++) { + values[i] = null; + } + + mSize = 0; + mGarbage = false; + } + + /** + * Puts a key/value pair into the array, optimizing for the case where + * the key is greater than all existing keys in the array. + */ + public void append(int key, E value) { + if (mSize != 0 && key <= mKeys[mSize - 1]) { + put(key, value); + return; + } + + if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) { + gc(); + } + + int pos = mSize; + if (pos >= mKeys.length) { + int n = ArrayUtils.idealIntArraySize(pos + 1); + + int[] nkeys = new int[n]; + WeakReference<?>[] nvalues = new WeakReference[n]; + + // Log.e("SparseArray", "grow " + mKeys.length + " to " + n); + System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); + System.arraycopy(mValues, 0, nvalues, 0, mValues.length); + + mKeys = nkeys; + mValues = nvalues; + } + + mKeys[pos] = key; + mValues[pos] = new WeakReference(value); + mSize = pos + 1; + } + + private boolean hasReclaimedRefs() { + for (int i = 0 ; i < mSize ; i++) { + if (mValues[i].get() == null) { // DELETED.get() never returns null. + return true; + } + } + + return false; + } + + private static int binarySearch(int[] a, int start, int len, int key) { + int high = start + len, low = start - 1, guess; + + while (high - low > 1) { + guess = (high + low) / 2; + + if (a[guess] < key) + low = guess; + else + high = guess; + } + + if (high == start + len) + return ~(start + len); + else if (a[high] == key) + return high; + else + return ~high; + } + + private int[] mKeys; + private WeakReference<?>[] mValues; + private int mSize; +} diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 39676b044001..909605dc55d4 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -170,4 +170,6 @@ public class WifiNative { * @return the event string sent by the supplicant. */ public native static String waitForEvent(); + + public native static void enableBackgroundScan(boolean enable); } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index fc42ab8bdad9..676218e9eb4c 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -112,9 +112,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { private String mLastBssid; private int mLastNetworkId; private boolean mEnableRssiPolling = false; + private boolean mEnableBackgroundScan = false; private int mRssiPollToken = 0; private int mReconnectCount = 0; private boolean mIsScanMode = false; + private boolean mScanResultIsPending = false; private boolean mBluetoothConnectionActive = false; @@ -300,6 +302,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { static final int CMD_START_WPS = 89; /* Set the frequency band */ static final int CMD_SET_FREQUENCY_BAND = 90; + /* Enable background scan for configured networks */ + static final int CMD_ENABLE_BACKGROUND_SCAN = 91; /* Commands from/to the SupplicantStateTracker */ /* Reset the supplicant state tracker */ @@ -823,6 +827,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0)); } + public void enableBackgroundScan(boolean enabled) { + sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0)); + } + public void enableAllNetworks() { sendMessage(CMD_ENABLE_ALL_NETWORKS); } @@ -1538,6 +1546,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_ENABLE_RSSI_POLL: mEnableRssiPolling = (message.arg1 == 1); break; + case CMD_ENABLE_BACKGROUND_SCAN: + mEnableBackgroundScan = (message.arg1 == 1); + break; /* Discard */ case CMD_LOAD_DRIVER: case CMD_UNLOAD_DRIVER: @@ -1973,6 +1984,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { eventLoggingEnabled = false; setScanResults(WifiNative.scanResultsCommand()); sendScanResultsAvailableBroadcast(); + mScanResultIsPending = false; break; case CMD_PING_SUPPLICANT: boolean ok = WifiNative.pingCommand(); @@ -2180,6 +2192,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_START_SCAN: eventLoggingEnabled = false; WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE); + mScanResultIsPending = true; break; case CMD_SET_HIGH_PERF_MODE: setHighPerfModeEnabledNative(message.arg1 == 1); @@ -2681,8 +2694,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { * back to CONNECT_MODE. */ WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE); - WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE); - break; + /* Have the parent state handle the rest */ + return NOT_HANDLED; /* Ignore connection to same network */ case CMD_CONNECT_NETWORK: int netId = message.arg1; @@ -2771,21 +2784,35 @@ public class WifiStateMachine extends HierarchicalStateMachine { } class DisconnectedState extends HierarchicalState { + private boolean mAlarmEnabled = false; @Override public void enter() { if (DBG) Log.d(TAG, getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); - /** - * In a disconnected state, an infrequent scan that wakes - * up the device is needed to ensure a user connects to - * an access point on the move + /* + * We initiate background scanning if it is enabled, otherwise we + * initiate an infrequent scan that wakes up the device to ensure + * a user connects to an access point on the move */ - long scanMs = Settings.Secure.getLong(mContext.getContentResolver(), + if (mEnableBackgroundScan) { + /* If a regular scan result is pending, do not initiate background + * scan until the scan results are returned. This is needed because + * initiating a background scan will cancel the regular scan and + * scan results will not be returned until background scanning is + * cleared + */ + if (!mScanResultIsPending) { + WifiNative.enableBackgroundScan(true); + } + } else { + long scanMs = Settings.Secure.getLong(mContext.getContentResolver(), Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS); - mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, + mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + scanMs, scanMs, mScanIntent); + mAlarmEnabled = true; + } } @Override public boolean processMessage(Message message) { @@ -2800,6 +2827,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { transitionTo(mScanModeState); } break; + case CMD_ENABLE_BACKGROUND_SCAN: + mEnableBackgroundScan = (message.arg1 == 1); + WifiNative.enableBackgroundScan(mEnableBackgroundScan); + break; /* Ignore network disconnect */ case NETWORK_DISCONNECTION_EVENT: break; @@ -2808,6 +2839,20 @@ public class WifiStateMachine extends HierarchicalStateMachine { setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state)); /* DriverStartedState does the rest of the handling */ return NOT_HANDLED; + case CMD_START_SCAN: + /* Disable background scan temporarily during a regular scan */ + if (mEnableBackgroundScan) { + WifiNative.enableBackgroundScan(false); + } + /* Handled in parent state */ + return NOT_HANDLED; + case SCAN_RESULTS_EVENT: + /* Re-enable background scan when a pending scan result is received */ + if (mEnableBackgroundScan && mScanResultIsPending) { + WifiNative.enableBackgroundScan(true); + } + /* Handled in parent state */ + return NOT_HANDLED; default: return NOT_HANDLED; } @@ -2817,7 +2862,14 @@ public class WifiStateMachine extends HierarchicalStateMachine { @Override public void exit() { - mAlarmManager.cancel(mScanIntent); + /* No need for a background scan upon exit from a disconnected state */ + if (mEnableBackgroundScan) { + WifiNative.enableBackgroundScan(false); + } + if (mAlarmEnabled) { + mAlarmManager.cancel(mScanIntent); + mAlarmEnabled = false; + } } } |