diff --git a/api/current.xml b/api/current.xml index b430e2cc41581..d8ab697f31a43 100644 --- a/api/current.xml +++ b/api/current.xml @@ -68541,11 +68541,11 @@ visibility="public" > - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + The Bluetooth scan mode determines if the local adapter is * connectable and/or discoverable from remote Bluetooth devices. - *

For privacy reasons, it is recommended to limit the duration of time - * that the local adapter remains in a discoverable scan mode. For example, - * 2 minutes is a generous time to allow a remote Bluetooth device to - * initiate and complete its discovery process. + *

For privacy reasons, discoverable mode is automatically turned off + * after duration seconds. For example, 120 seconds should be + * enough for a remote device to initiate and complete its discovery + * process. *

Valid scan mode values are: * {@link #SCAN_MODE_NONE}, * {@link #SCAN_MODE_CONNECTABLE}, @@ -427,16 +427,23 @@ public final class BluetoothAdapter { * instead. * * @param mode valid scan mode + * @param duration time in seconds to apply scan mode, only used for + * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE} * @return true if the scan mode was set, false otherwise * @hide */ - public boolean setScanMode(int mode) { + public boolean setScanMode(int mode, int duration) { try { - return mService.setScanMode(mode); + return mService.setScanMode(mode, duration); } catch (RemoteException e) {Log.e(TAG, "", e);} return false; } + /** @hide */ + public boolean setScanMode(int mode) { + return setScanMode(mode, 120); + } + /** @hide */ public int getDiscoverableTimeout() { try { diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl index 203a61d8a1f68..1bc2f968b3838 100644 --- a/core/java/android/bluetooth/IBluetooth.aidl +++ b/core/java/android/bluetooth/IBluetooth.aidl @@ -35,7 +35,7 @@ interface IBluetooth boolean setName(in String name); int getScanMode(); - boolean setScanMode(int mode); + boolean setScanMode(int mode, int duration); int getDiscoverableTimeout(); boolean setDiscoverableTimeout(int timeout); diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index e47ea8467901a..a1da0e4897108 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -368,6 +368,9 @@ public class Camera { * uses auto-focus with the * <uses-feature> * manifest element.

+ *

If the current flash mode is not + * {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}, flash may be + * fired during auto-focus depending on the driver.

* * @param cb the callback to run */ @@ -637,12 +640,13 @@ public class Camera { */ public static final String FLASH_MODE_OFF = "off"; /** - * Flash will be fired automatically when required. The timing is - * decided by camera driver. + * Flash will be fired automatically when required. The flash may be fired + * during preview, auto-focus, or snapshot depending on the driver. */ public static final String FLASH_MODE_AUTO = "auto"; /** - * Flash will always be fired. The timing is decided by camera driver. + * Flash will always be fired during snapshot. The flash may also be + * fired during preview or auto-focus depending on the driver. */ public static final String FLASH_MODE_ON = "on"; /** @@ -650,9 +654,10 @@ public class Camera { */ public static final String FLASH_MODE_RED_EYE = "red-eye"; /** - * Constant emission of light. This can be used for video recording. + * Constant emission of light during preview, auto-focus and snapshot. + * This can also be used for video recording. */ - public static final String FLASH_MODE_VIDEO_LIGHT = "video-light"; + public static final String FLASH_MODE_TORCH = "torch"; // Values for scene mode settings. public static final String SCENE_MODE_AUTO = "auto"; diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index cd03869f42899..c7bce0f56e216 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -60,6 +60,7 @@ public final class ContactsContract { * @hide should be removed when users are updated to refer to SyncState * @deprecated use SyncState instead */ + @Deprecated public interface SyncStateColumns extends SyncStateContract.Columns { } @@ -224,49 +225,6 @@ public final class ContactsContract { */ public static final String IN_VISIBLE_GROUP = "in_visible_group"; - /** - * Contact presence status. See {@link Presence} - * for individual status definitions. This column is only returned if explicitly - * requested in the query projection. - *

Type: NUMBER

- */ - public static final String PRESENCE_STATUS = Presence.PRESENCE_STATUS; - - /** - * Contact presence custom status. This column is only returned if explicitly - * requested in the query projection. - *

Type: TEXT

- */ - public static final String PRESENCE_CUSTOM_STATUS = Presence.PRESENCE_CUSTOM_STATUS; - - /** - * The time when the latest presence custom status was inserted/updated. - * This column is only returned if explicitly requested in the query - * projection. - *

Type: TEXT

- * @hide TODO unhide - */ - public static final String PRESENCE_CUSTOM_STATUS_TIMESTAMP = - Presence.PRESENCE_CUSTOM_STATUS_TIMESTAMP; - - /** - * Protocol that supplied the latest status update (see {@link CommonDataKinds.Im#PROTOCOL}. - * This column is only returned if explicitly requested in the query - * projection. - *

Type: NUMBER

- * @hide TODO unhide - */ - public static final String PRESENCE_PROTOCOL = "presence_protocol"; - - /** - * Custom protocol that supplied the latest status update (see - * {@link CommonDataKinds.Im#CUSTOM_PROTOCOL}. This column is only - * returned if explicitly requested in the query projection. - *

Type: TEXT

- * @hide TODO unhide - */ - public static final String PRESENCE_CUSTOM_PROTOCOL = "presence_custom_protocol"; - /** * An indicator of whether this contact has at least one phone number. "1" if there is * at least one phone number, "0" otherwise. @@ -281,12 +239,55 @@ public final class ContactsContract { public static final String LOOKUP_KEY = "lookup"; } + private interface ContactStatusColumns { + /** + * Contact presence status. See {@link StatusUpdates} for individual status + * definitions. + *

Type: NUMBER

+ */ + public static final String CONTACT_PRESENCE = "contact_presence"; + + /** + * Contact's latest status update. + *

Type: TEXT

+ */ + public static final String CONTACT_STATUS = "contact_status"; + + /** + * The absolute time in milliseconds when the latest status was + * inserted/updated. + *

Type: NUMBER

+ */ + public static final String CONTACT_STATUS_TIMESTAMP = "contact_status_ts"; + + /** + * The package containing resources for this status: label and icon. + *

Type: NUMBER

+ */ + public static final String CONTACT_STATUS_RES_PACKAGE = "contact_status_res_package"; + + /** + * The resource ID of the label describing the source of contact + * status, e.g. "Google Talk". This resource is scoped by the + * {@link #CONTACT_STATUS_RES_PACKAGE}. + *

Type: NUMBER

+ */ + public static final String CONTACT_STATUS_LABEL = "contact_status_label"; + + /** + * The resource ID of the icon for the source of contact status. This + * resource is scoped by the {@link #CONTACT_STATUS_RES_PACKAGE}. + *

Type: NUMBER

+ */ + public static final String CONTACT_STATUS_ICON = "contact_status_icon"; + } + /** * Constants for the contacts table, which contains a record per group * of raw contacts representing the same person. */ public static class Contacts implements BaseColumns, ContactsColumns, - ContactOptionsColumns { + ContactOptionsColumns, ContactStatusColumns { /** * This utility class cannot be instantiated */ @@ -649,6 +650,46 @@ public final class ContactsContract { } } + private interface StatusColumns extends Im.CommonPresenceColumns { + /** + * Contact's latest presence level. + *

Type: INTEGER (one of the values below)

+ */ + public static final String PRESENCE = PRESENCE_STATUS; + + /** + * Contact latest status update. + *

Type: TEXT

+ */ + public static final String STATUS = PRESENCE_CUSTOM_STATUS; + + /** + * The absolute time in milliseconds when the latest status was inserted/updated. + *

Type: NUMBER

+ */ + public static final String STATUS_TIMESTAMP = "status_ts"; + + /** + * The package containing resources for this status: label and icon. + *

Type: NUMBER

+ */ + public static final String STATUS_RES_PACKAGE = "status_res_package"; + + /** + * The resource ID of the label describing the source of the status update, e.g. "Google + * Talk". This resource should be scoped by the {@link #STATUS_RES_PACKAGE}. + *

Type: NUMBER

+ */ + public static final String STATUS_LABEL = "status_label"; + + /** + * The resource ID of the icon for the source of the status update. + * This resource should be scoped by the {@link #STATUS_RES_PACKAGE}. + *

Type: NUMBER

+ */ + public static final String STATUS_ICON = "status_icon"; + } + private interface DataColumns { /** * The package name to use when creating {@link Resources} objects for @@ -736,8 +777,8 @@ public final class ContactsContract { /** * Combines all columns returned by {@link Data} table queries. */ - private interface DataColumnsWithJoins extends BaseColumns, DataColumns, RawContactsColumns, - ContactsColumns, ContactOptionsColumns { + private interface DataColumnsWithJoins extends BaseColumns, DataColumns, StatusColumns, + RawContactsColumns, ContactsColumns, ContactOptionsColumns, ContactStatusColumns { } @@ -758,15 +799,6 @@ public final class ContactsContract { */ public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "data"); - /** - * The content:// style URI for this table joined with {@link Presence} - * data where applicable. - * - * @hide - */ - public static final Uri CONTENT_WITH_PRESENCE_URI = Uri.withAppendedPath(AUTHORITY_URI, - "data_with_presence"); - /** * The MIME type of {@link #CONTENT_URI} providing a directory of data. */ @@ -841,8 +873,8 @@ public final class ContactsContract { } /** - * Additional data mixed in with {@link Im.CommonPresenceColumns} to link - * back to specific {@link ContactsContract.Contacts#_ID} entries. + * Additional data mixed in with {@link StatusColumns} to link + * back to specific {@link ContactsContract.Data#_ID} entries. */ private interface PresenceColumns { @@ -881,23 +913,22 @@ public final class ContactsContract { public static final String IM_ACCOUNT = "im_account"; } - public static final class Presence implements PresenceColumns, Im.CommonPresenceColumns { + /** + * A status update is linked to a {@link Data} row and captures the user's latest status + * update via the corresponding source, e.g. "Having lunch" via "Google Talk". + */ + // TODO make final as soon as Presence is removed + public static /*final*/ class StatusUpdates implements StatusColumns, PresenceColumns { /** * This utility class cannot be instantiated */ - private Presence() {} + private StatusUpdates() {} /** * The content:// style URI for this table */ - public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "presence"); - - /** - * The unique ID for a presence row. - *

Type: INTEGER (long)

- */ - public static final String _ID = "presence_id"; + public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "status_updates"); /** * Gets the resource ID for the proper presence icon. @@ -936,22 +967,20 @@ public final class ContactsContract { /** * The MIME type of {@link #CONTENT_URI} providing a directory of - * presence details. + * status update details. */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/im-presence"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/status-update"; /** * The MIME type of a {@link #CONTENT_URI} subdirectory of a single - * presence detail. + * status update detail. */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/im-presence"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/status-update"; + } + + @Deprecated + public static final class Presence extends StatusUpdates { - /** - * The time when the presence custom status was inserted/updated. - *

Type: TEXT

- * @hide TODO unhide - */ - public static final String PRESENCE_CUSTOM_STATUS_TIMESTAMP = "status_timestamp"; } /** diff --git a/core/java/android/provider/Im.java b/core/java/android/provider/Im.java index d5cc22070bc80..d3e2820d59264 100644 --- a/core/java/android/provider/Im.java +++ b/core/java/android/provider/Im.java @@ -896,11 +896,20 @@ public class Im { String BODY = "body"; /** - * The date this message is sent or received + * The date this message is sent or received. This represents the display date for + * the message. *

Type: INTEGER

*/ String DATE = "date"; + /** + * The real date for this message. While 'date' can be modified by the client + * to account for server time skew, the real_date is the original timestamp set + * by the server for incoming messages. + *

Type: INTEGER

+ */ + String REAL_DATE = "real_date"; + /** * Message Type, see {@link MessageType} *

Type: INTEGER

diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e3fc72d8ee602..1cd4506d8092e 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1416,6 +1416,7 @@ public final class Settings { DIM_SCREEN, SCREEN_OFF_TIMEOUT, SCREEN_BRIGHTNESS, + SCREEN_BRIGHTNESS_MODE, VIBRATE_ON, NOTIFICATIONS_USE_RING_VOLUME, MODE_RINGER, @@ -2404,7 +2405,6 @@ public final class Settings { public static final String[] SETTINGS_TO_BACKUP = { ADB_ENABLED, ALLOW_MOCK_LOCATION, - INSTALL_NON_MARKET_APPS, PARENTAL_CONTROL_ENABLED, PARENTAL_CONTROL_REDIRECT_URL, USB_MASS_STORAGE_ENABLED, diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java index de14b5b4e0bb5..8b9ba84cac5bd 100644 --- a/core/java/android/server/BluetoothService.java +++ b/core/java/android/server/BluetoothService.java @@ -78,6 +78,7 @@ public class BluetoothService extends IBluetooth.Stub { private static final int MESSAGE_REGISTER_SDP_RECORDS = 1; private static final int MESSAGE_FINISH_DISABLE = 2; private static final int MESSAGE_UUID_INTENT = 3; + private static final int MESSAGE_DISCOVERABLE_TIMEOUT = 4; // The timeout used to sent the UUIDs Intent // This timeout should be greater than the page timeout @@ -308,6 +309,15 @@ public class BluetoothService extends IBluetooth.Stub { if (address != null) sendUuidIntent(address); break; + case MESSAGE_DISCOVERABLE_TIMEOUT: + int mode = msg.arg1; + if (isEnabled()) { + // TODO: Switch back to the previous scan mode + // This is ok for now, because we only use + // CONNECTABLE and CONNECTABLE_DISCOVERABLE + setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE, -1); + } + break; } } }; @@ -679,23 +689,30 @@ public class BluetoothService extends IBluetooth.Stub { return setPropertyInteger("DiscoverableTimeout", timeout); } - public synchronized boolean setScanMode(int mode) { + public synchronized boolean setScanMode(int mode, int duration) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, "Need WRITE_SECURE_SETTINGS permission"); boolean pairable = false; boolean discoverable = false; + switch (mode) { case BluetoothAdapter.SCAN_MODE_NONE: + mHandler.removeMessages(MESSAGE_DISCOVERABLE_TIMEOUT); pairable = false; discoverable = false; break; case BluetoothAdapter.SCAN_MODE_CONNECTABLE: + mHandler.removeMessages(MESSAGE_DISCOVERABLE_TIMEOUT); pairable = true; discoverable = false; break; case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: + mHandler.removeMessages(MESSAGE_DISCOVERABLE_TIMEOUT); pairable = true; discoverable = true; + Message msg = mHandler.obtainMessage(MESSAGE_DISCOVERABLE_TIMEOUT); + mHandler.sendMessageDelayed(msg, duration * 1000); + if (DBG) Log.d(TAG, "BT Discoverable for " + duration + " seconds"); break; default: Log.w(TAG, "Requested invalid scan mode " + mode); diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 3ce1815a37d05..07034afb775c4 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -3587,9 +3587,13 @@ public class WebView extends AbsoluteLayout // update mMinZoomScale if the minimum zoom scale is not fixed if (!mMinZoomScaleFixed) { - mMinZoomScale = (float) getViewWidth() + // when change from narrow screen to wide screen, the new viewWidth + // can be wider than the old content width. We limit the minimum + // scale to 1.0f. The proper minimum scale will be calculated when + // the new picture shows up. + mMinZoomScale = Math.min(1.0f, (float) getViewWidth() / (mDrawHistory ? mHistoryPicture.getWidth() - : mZoomOverviewWidth); + : mZoomOverviewWidth)); } // we always force, in case our height changed, in which case we still @@ -3685,6 +3689,7 @@ public class WebView extends AbsoluteLayout switch (action) { case MotionEvent.ACTION_DOWN: { + mPreventDrag = PREVENT_DRAG_NO; if (!mScroller.isFinished()) { // stop the current scroll animation, but if this is // the start of a fling, allow it to add to the current @@ -3892,19 +3897,15 @@ public class WebView extends AbsoluteLayout mTouchMode = TOUCH_DONE_MODE; doDoubleTap(); break; - case TOUCH_SHORTPRESS_START_MODE: - case TOUCH_SHORTPRESS_MODE: - mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); - mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); - mTouchMode = TOUCH_DONE_MODE; - doShortPress(); - break; case TOUCH_SELECT_MODE: commitCopy(); mTouchSelection = false; break; case TOUCH_INIT_MODE: // tap + case TOUCH_SHORTPRESS_START_MODE: + case TOUCH_SHORTPRESS_MODE: mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); + mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); if ((deltaX * deltaX + deltaY * deltaY) > mTouchSlopSquare) { Log.w(LOGTAG, "Miss a drag as we are waiting for" + " WebCore's response for touch down."); @@ -3924,10 +3925,15 @@ public class WebView extends AbsoluteLayout mPreventDrag = PREVENT_DRAG_NO; } if (mPreventDrag == PREVENT_DRAG_NO) { - mPrivateHandler.sendMessageDelayed( - mPrivateHandler.obtainMessage( - RELEASE_SINGLE_TAP), - ViewConfiguration.getDoubleTapTimeout()); + if (mTouchMode == TOUCH_INIT_MODE) { + mPrivateHandler.sendMessageDelayed( + mPrivateHandler.obtainMessage( + RELEASE_SINGLE_TAP), + ViewConfiguration.getDoubleTapTimeout()); + } else { + mTouchMode = TOUCH_DONE_MODE; + doShortPress(); + } } break; } diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java index 86ee3dbc737bd..d7311c26dbb70 100644 --- a/core/java/com/android/internal/widget/ContactHeaderWidget.java +++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java @@ -96,9 +96,9 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList Contacts.PHOTO_ID, Contacts.DISPLAY_NAME, Contacts.STARRED, - Contacts.PRESENCE_STATUS, - Contacts.PRESENCE_CUSTOM_STATUS, - Contacts.PRESENCE_CUSTOM_STATUS_TIMESTAMP, + Contacts.CONTACT_PRESENCE, + Contacts.CONTACT_STATUS, + Contacts.CONTACT_STATUS_TIMESTAMP, }; int _ID = 0; int LOOKUP_KEY = 1; @@ -107,9 +107,9 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList //TODO: We need to figure out how we're going to get the phonetic name. //static final int HEADER_PHONETIC_NAME_COLUMN_INDEX int STARRED = 4; - int PRESENCE_STATUS = 5; - int PRESENCE_CUSTOM_STATUS = 6; - int PRESENCE_CUSTOM_STATUS_TIMESTAMP = 7; + int CONTACT_PRESENCE_STATUS = 5; + int CONTACT_STATUS = 6; + int CONTACT_STATUS_TIMESTAMP = 7; } //Projection used for looking up contact id from phone number @@ -429,8 +429,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey)); //Set the presence status - if (!c.isNull(ContactQuery.PRESENCE_STATUS)) { - int presence = c.getInt(ContactQuery.PRESENCE_STATUS); + if (!c.isNull(ContactQuery.CONTACT_PRESENCE_STATUS)) { + int presence = c.getInt(ContactQuery.CONTACT_PRESENCE_STATUS); mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence)); mPresenceView.setVisibility(View.VISIBLE); } else { @@ -438,13 +438,13 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList } //Set the status update - String status = c.getString(ContactQuery.PRESENCE_CUSTOM_STATUS); + String status = c.getString(ContactQuery.CONTACT_STATUS); if (!TextUtils.isEmpty(status)) { mStatusView.setText(status); mStatusView.setVisibility(View.VISIBLE); - if (!c.isNull(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP)) { - long date = c.getLong(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP); + if (!c.isNull(ContactQuery.CONTACT_STATUS_TIMESTAMP)) { + long date = c.getLong(ContactQuery.CONTACT_STATUS_TIMESTAMP); // Set the date/time field by mixing relative and absolute // times. diff --git a/core/java/com/google/android/mms/pdu/PduComposer.java b/core/java/com/google/android/mms/pdu/PduComposer.java index 2aa5e48f507ee..8940945a605a0 100644 --- a/core/java/com/google/android/mms/pdu/PduComposer.java +++ b/core/java/com/google/android/mms/pdu/PduComposer.java @@ -850,8 +850,7 @@ public class PduComposer { PositionMarker ctStart = mStack.mark(); // This contentTypeIdentifier should be used for type of attachment... - String contentType = new String( - mPduHeader.getTextString(PduHeaders.CONTENT_TYPE)); + String contentType = new String(mPduHeader.getTextString(PduHeaders.CONTENT_TYPE)); Integer contentTypeIdentifier = mContentTypeMap.get(contentType); if (contentTypeIdentifier == null) { // content type is mandatory @@ -862,7 +861,7 @@ public class PduComposer { // content-type parameter: start PduBody body = ((SendReq) mPdu).getBody(); - if (null == body) { + if (null == body || body.getPartsNum() == 0) { // empty message appendUintvarInteger(0); mStack.pop(); diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp index 70d74d52e7dfe..2532effe98bdc 100644 --- a/core/jni/android_bluetooth_BluetoothSocket.cpp +++ b/core/jni/android_bluetooth_BluetoothSocket.cpp @@ -402,7 +402,6 @@ static jint availableNative(JNIEnv *env, jobject obj) { return -1; } -/** jb must not be null. offset and offset+length must be within array */ static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset, jint length) { #ifdef HAVE_BLUETOOTH @@ -410,10 +409,20 @@ static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset, int ret; jbyte *b; + int sz; struct asocket *s = get_socketData(env, obj); if (!s) return -1; + if (jb == NULL) { + jniThrowIOException(env, EINVAL); + return -1; + } + sz = env->GetArrayLength(jb); + if (offset < 0 || length < 0 || offset + length > sz) { + jniThrowIOException(env, EINVAL); + return -1; + } b = env->GetByteArrayElements(jb, NULL); if (b == NULL) { @@ -436,7 +445,6 @@ static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset, return -1; } -/** jb must not be null. offset and offset+length must be within array */ static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset, jint length) { #ifdef HAVE_BLUETOOTH @@ -444,10 +452,20 @@ static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset, int ret; jbyte *b; + int sz; struct asocket *s = get_socketData(env, obj); if (!s) return -1; + if (jb == NULL) { + jniThrowIOException(env, EINVAL); + return -1; + } + sz = env->GetArrayLength(jb); + if (offset < 0 || length < 0 || offset + length > sz) { + jniThrowIOException(env, EINVAL); + return -1; + } b = env->GetByteArrayElements(jb, NULL); if (b == NULL) { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 9cf532477e041..60a2ecb17d254 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1123,10 +1123,11 @@ android:protectionLevel="signature" /> + @hide XXX Change to signature once the picker is moved to its + own apk as Ghod Intended. --> + android:protectionLevel="signatureOrSystem" /> false + + 15 + + 20 + diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index eb151835a5d0e..2a55d85382d55 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1460,8 +1460,8 @@ The battery is getting low: - less than %d%% - remaining. + %d%% + or less remaining. diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java index 0a586c4d5f7b2..73d82661edb3e 100644 --- a/graphics/java/android/renderscript/Element.java +++ b/graphics/java/android/renderscript/Element.java @@ -70,148 +70,169 @@ public class Element extends BaseObj { } } - public static final Element USER_U8 = new Element(); - public static final Element USER_I8 = new Element(); - public static final Element USER_U16 = new Element(); - public static final Element USER_I16 = new Element(); - public static final Element USER_U32 = new Element(); - public static final Element USER_I32 = new Element(); - public static final Element USER_FLOAT = new Element(); - - public static final Element A_8 = new Element(); - public static final Element RGB_565 = new Element(); - public static final Element RGB_888 = new Element(); - public static final Element RGBA_5551 = new Element(); - public static final Element RGBA_4444 = new Element(); - public static final Element RGBA_8888 = new Element(); - - public static final Element INDEX_16 = new Element(); - public static final Element XY_F32 = new Element(); - public static final Element XYZ_F32 = new Element(); - public static final Element ST_XY_F32 = new Element(); - public static final Element ST_XYZ_F32 = new Element(); - public static final Element NORM_XYZ_F32 = new Element(); - public static final Element NORM_ST_XYZ_F32 = new Element(); - - static void initPredefined(RenderScript rs) { - USER_U8.mEntries = new Entry[1]; - USER_U8.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 8, null); - USER_U8.init(rs); - - USER_I8.mEntries = new Entry[1]; - USER_I8.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 8, null); - USER_I8.init(rs); - - USER_U16.mEntries = new Entry[1]; - USER_U16.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 16, null); - USER_U16.init(rs); - - USER_I16.mEntries = new Entry[1]; - USER_I16.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 16, null); - USER_I16.init(rs); - - USER_U32.mEntries = new Entry[1]; - USER_U32.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 32, null); - USER_U32.init(rs); - - USER_I32.mEntries = new Entry[1]; - USER_I32.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 32, null); - USER_I32.init(rs); - - USER_FLOAT.mEntries = new Entry[1]; - USER_FLOAT.mEntries[0] = new Entry(DataType.FLOAT, DataKind.USER, false, 32, null); - USER_FLOAT.init(rs); - - A_8.mEntries = new Entry[1]; - A_8.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 8, "a"); - A_8.init(rs); - - RGB_565.mEntries = new Entry[3]; - RGB_565.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 5, "r"); - RGB_565.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 6, "g"); - RGB_565.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 5, "b"); - RGB_565.init(rs); - - RGB_888.mEntries = new Entry[3]; - RGB_888.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 8, "r"); - RGB_888.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 8, "g"); - RGB_888.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 8, "b"); - RGB_888.init(rs); - - RGBA_5551.mEntries = new Entry[4]; - RGBA_5551.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 5, "r"); - RGBA_5551.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 5, "g"); - RGBA_5551.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 5, "b"); - RGBA_5551.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 1, "a"); - RGBA_5551.init(rs); - - RGBA_4444.mEntries = new Entry[4]; - RGBA_4444.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 4, "r"); - RGBA_4444.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 4, "g"); - RGBA_4444.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 4, "b"); - RGBA_4444.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 4, "a"); - RGBA_4444.init(rs); - - RGBA_8888.mEntries = new Entry[4]; - RGBA_8888.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 8, "r"); - RGBA_8888.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 8, "g"); - RGBA_8888.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 8, "b"); - RGBA_8888.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 8, "a"); - RGBA_8888.init(rs); - - INDEX_16.mEntries = new Entry[1]; - INDEX_16.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.INDEX, false, 16, "index"); - INDEX_16.init(rs); - - XY_F32.mEntries = new Entry[2]; - XY_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); - XY_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); - XY_F32.init(rs); - - XYZ_F32.mEntries = new Entry[3]; - XYZ_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); - XYZ_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); - XYZ_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.Z, false, 32, "z"); - XYZ_F32.init(rs); - - ST_XY_F32.mEntries = new Entry[4]; - ST_XY_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.S, false, 32, "s"); - ST_XY_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.T, false, 32, "t"); - ST_XY_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); - ST_XY_F32.mEntries[3] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); - ST_XY_F32.init(rs); - - ST_XYZ_F32.mEntries = new Entry[5]; - ST_XYZ_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.S, false, 32, "s"); - ST_XYZ_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.T, false, 32, "t"); - ST_XYZ_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); - ST_XYZ_F32.mEntries[3] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); - ST_XYZ_F32.mEntries[4] = new Entry(DataType.FLOAT, DataKind.Z, false, 32, "z"); - ST_XYZ_F32.init(rs); - - NORM_XYZ_F32.mEntries = new Entry[6]; - NORM_XYZ_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.NX, false, 32, "nx"); - NORM_XYZ_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.NY, false, 32, "ny"); - NORM_XYZ_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.NZ, false, 32, "nz"); - NORM_XYZ_F32.mEntries[3] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); - NORM_XYZ_F32.mEntries[4] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); - NORM_XYZ_F32.mEntries[5] = new Entry(DataType.FLOAT, DataKind.Z, false, 32, "z"); - NORM_XYZ_F32.init(rs); - - NORM_ST_XYZ_F32.mEntries = new Entry[8]; - NORM_ST_XYZ_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.NX, false, 32, "nx"); - NORM_ST_XYZ_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.NY, false, 32, "ny"); - NORM_ST_XYZ_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.NZ, false, 32, "nz"); - NORM_ST_XYZ_F32.mEntries[3] = new Entry(DataType.FLOAT, DataKind.S, false, 32, "s"); - NORM_ST_XYZ_F32.mEntries[4] = new Entry(DataType.FLOAT, DataKind.T, false, 32, "t"); - NORM_ST_XYZ_F32.mEntries[5] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); - NORM_ST_XYZ_F32.mEntries[6] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); - NORM_ST_XYZ_F32.mEntries[7] = new Entry(DataType.FLOAT, DataKind.Z, false, 32, "z"); - NORM_ST_XYZ_F32.init(rs); - - rs.nInitElements(A_8.mID, RGBA_4444.mID, RGBA_8888.mID, RGB_565.mID); + public static Element USER_U8(RenderScript rs) { + if(rs.mElement_USER_U8 == null) { + rs.mElement_USER_U8 = new Element(rs, 1); + rs.mElement_USER_U8.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 8, null); + rs.mElement_USER_U8.init(); + } + return rs.mElement_USER_U8; } + public static Element USER_I8(RenderScript rs) { + if(rs.mElement_USER_I8 == null) { + rs.mElement_USER_I8 = new Element(rs, 1); + rs.mElement_USER_I8.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 8, null); + rs.mElement_USER_I8.init(); + } + return rs.mElement_USER_I8; + } + + public static Element USER_U16(RenderScript rs) { + if(rs.mElement_USER_U16 == null) { + rs.mElement_USER_U16 = new Element(rs, 1); + rs.mElement_USER_U16.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 16, null); + rs.mElement_USER_U16.init(); + } + return rs.mElement_USER_U16; + } + + public static Element USER_I16(RenderScript rs) { + if(rs.mElement_USER_I16 == null) { + rs.mElement_USER_I16 = new Element(rs, 1); + rs.mElement_USER_I16.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 16, null); + rs.mElement_USER_I16.init(); + } + return rs.mElement_USER_I16; + } + + public static Element USER_U32(RenderScript rs) { + if(rs.mElement_USER_U32 == null) { + rs.mElement_USER_U32 = new Element(rs, 1); + rs.mElement_USER_U32.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 32, null); + rs.mElement_USER_U32.init(); + } + return rs.mElement_USER_U32; + } + + public static Element USER_I32(RenderScript rs) { + if(rs.mElement_USER_I32 == null) { + rs.mElement_USER_I32 = new Element(rs, 1); + rs.mElement_USER_I32.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 32, null); + rs.mElement_USER_I32.init(); + } + return rs.mElement_USER_I32; + } + + public static Element USER_F32(RenderScript rs) { + if(rs.mElement_USER_FLOAT == null) { + rs.mElement_USER_FLOAT = new Element(rs, 1); + rs.mElement_USER_FLOAT.mEntries[0] = new Entry(DataType.FLOAT, DataKind.USER, false, 32, null); + rs.mElement_USER_FLOAT.init(); + } + return rs.mElement_USER_FLOAT; + } + + public static Element A_8(RenderScript rs) { + if(rs.mElement_A_8 == null) { + rs.mElement_A_8 = new Element(rs, 1); + rs.mElement_A_8.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 8, "a"); + rs.mElement_A_8.init(); + } + return rs.mElement_A_8; + } + + public static Element RGB_565(RenderScript rs) { + if(rs.mElement_RGB_565 == null) { + rs.mElement_RGB_565 = new Element(rs, 3); + rs.mElement_RGB_565.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 5, "r"); + rs.mElement_RGB_565.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 6, "g"); + rs.mElement_RGB_565.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 5, "b"); + rs.mElement_RGB_565.init(); + } + return rs.mElement_RGB_565; + } + + public static Element RGB_888(RenderScript rs) { + if(rs.mElement_RGB_888 == null) { + rs.mElement_RGB_888 = new Element(rs, 3); + rs.mElement_RGB_888.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 8, "r"); + rs.mElement_RGB_888.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 8, "g"); + rs.mElement_RGB_888.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 8, "b"); + rs.mElement_RGB_888.init(); + } + return rs.mElement_RGB_888; + } + + public static Element RGBA_5551(RenderScript rs) { + if(rs.mElement_RGBA_5551 == null) { + rs.mElement_RGBA_5551 = new Element(rs, 4); + rs.mElement_RGBA_5551.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 5, "r"); + rs.mElement_RGBA_5551.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 5, "g"); + rs.mElement_RGBA_5551.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 5, "b"); + rs.mElement_RGBA_5551.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 1, "a"); + rs.mElement_RGBA_5551.init(); + } + return rs.mElement_RGBA_5551; + } + + public static Element RGBA_4444(RenderScript rs) { + if(rs.mElement_RGBA_4444 == null) { + rs.mElement_RGBA_4444 = new Element(rs, 4); + rs.mElement_RGBA_4444.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 4, "r"); + rs.mElement_RGBA_4444.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 4, "g"); + rs.mElement_RGBA_4444.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 4, "b"); + rs.mElement_RGBA_4444.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 4, "a"); + rs.mElement_RGBA_4444.init(); + } + return rs.mElement_RGBA_4444; + } + + public static Element RGBA_8888(RenderScript rs) { + if(rs.mElement_RGBA_8888 == null) { + rs.mElement_RGBA_8888 = new Element(rs, 4); + rs.mElement_RGBA_8888.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 8, "r"); + rs.mElement_RGBA_8888.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 8, "g"); + rs.mElement_RGBA_8888.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 8, "b"); + rs.mElement_RGBA_8888.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 8, "a"); + rs.mElement_RGBA_8888.init(); + } + return rs.mElement_RGBA_8888; + } + + public static Element INDEX_16(RenderScript rs) { + if(rs.mElement_INDEX_16 == null) { + rs.mElement_INDEX_16 = new Element(rs, 1); + rs.mElement_INDEX_16.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.INDEX, false, 16, "index"); + rs.mElement_INDEX_16.init(); + } + return rs.mElement_INDEX_16; + } + + public static Element XY_F32(RenderScript rs) { + if(rs.mElement_XY_F32 == null) { + rs.mElement_XY_F32 = new Element(rs, 2); + rs.mElement_XY_F32.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.X, false, 32, "x"); + rs.mElement_XY_F32.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.Y, false, 32, "y"); + rs.mElement_XY_F32.init(); + } + return rs.mElement_XY_F32; + } + + public static Element XYZ_F32(RenderScript rs) { + if(rs.mElement_XYZ_F32 == null) { + rs.mElement_XYZ_F32 = new Element(rs, 3); + rs.mElement_XYZ_F32.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.X, false, 32, "x"); + rs.mElement_XYZ_F32.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.Y, false, 32, "y"); + rs.mElement_XYZ_F32.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.Z, false, 32, "z"); + rs.mElement_XYZ_F32.init(); + } + return rs.mElement_XYZ_F32; + } + + static void initPredefined(RenderScript rs) { + rs.nInitElements(A_8(rs).mID, RGBA_4444(rs).mID, RGBA_8888(rs).mID, RGB_565(rs).mID); + } public enum DataType { FLOAT (0), @@ -252,10 +273,10 @@ public class Element extends BaseObj { } } - Element() { - super(null); - mID = 0; + Element(RenderScript rs, int count) { + super(rs); mSize = 0; + mEntries = new Entry[count]; } public void destroy() throws IllegalStateException { @@ -300,8 +321,7 @@ public class Element extends BaseObj { e.mSize = (bits + 7) >> 3; } - void init(RenderScript rs) { - mRS = rs; + void init() { internalCreate(mRS, this); } @@ -463,10 +483,9 @@ public class Element extends BaseObj { } public Element create() { - Element e = new Element(); - e.mEntries = new Entry[mEntryCount]; + Element e = new Element(mRS, mEntryCount); java.lang.System.arraycopy(mEntries, 0, e.mEntries, 0, mEntryCount); - e.init(mRS); + e.init(); return e; } } diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java index 2a11bfb312684..ddb23ac967dcb 100644 --- a/graphics/java/android/renderscript/ProgramVertex.java +++ b/graphics/java/android/renderscript/ProgramVertex.java @@ -110,7 +110,7 @@ public class ProgramVertex extends BaseObj { mProjection = new Matrix(); mTexture = new Matrix(); - mAlloc = Allocation.createSized(rs, Element.USER_FLOAT, 48); + mAlloc = Allocation.createSized(rs, Element.USER_F32(rs), 48); mAlloc.subData1D(MODELVIEW_OFFSET, 16, mModel.mMat); mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); mAlloc.subData1D(TEXTURE_OFFSET, 16, mTexture.mMat); diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index ed616914af3b1..6b0b69610d9b7 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -191,7 +191,25 @@ public class RenderScript { @SuppressWarnings({"FieldCanBeLocal"}) private Surface mSurface; - private static boolean mElementsInitialized = false; + + Element mElement_USER_U8; + Element mElement_USER_I8; + Element mElement_USER_U16; + Element mElement_USER_I16; + Element mElement_USER_U32; + Element mElement_USER_I32; + Element mElement_USER_FLOAT; + + Element mElement_A_8; + Element mElement_RGB_565; + Element mElement_RGB_888; + Element mElement_RGBA_5551; + Element mElement_RGBA_4444; + Element mElement_RGBA_8888; + + Element mElement_INDEX_16; + Element mElement_XY_F32; + Element mElement_XYZ_F32; /////////////////////////////////////////////////////////////////////////////////// // @@ -203,12 +221,7 @@ public class RenderScript { nDeviceSetConfig(mDev, 0, 1); } mContext = nContextCreate(mDev, mSurface, 0, useDepth); - - // TODO: This should be protected by a lock - if(!mElementsInitialized) { - Element.initPredefined(this); - mElementsInitialized = true; - } + Element.initPredefined(this); } public void destroy() { diff --git a/graphics/java/android/renderscript/SimpleMesh.java b/graphics/java/android/renderscript/SimpleMesh.java index dc74c61fa14c8..987ec44432127 100644 --- a/graphics/java/android/renderscript/SimpleMesh.java +++ b/graphics/java/android/renderscript/SimpleMesh.java @@ -296,7 +296,7 @@ public class SimpleMesh extends BaseObj { Builder smb = new Builder(mRS); smb.addVertexType(mElement, mVtxCount / floatCount); - smb.setIndexType(Element.INDEX_16, mIndexCount); + smb.setIndexType(Element.INDEX_16(mRS), mIndexCount); smb.setPrimitive(Primitive.TRIANGLE); SimpleMesh sm = smb.create(); diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java index df60990c59456..ad4cf6be5381f 100644 --- a/graphics/java/android/renderscript/Type.java +++ b/graphics/java/android/renderscript/Type.java @@ -162,12 +162,19 @@ public class Type extends BaseObj { } public Builder(RenderScript rs, Element e) { + if(e.mID == 0) { + throw new IllegalArgumentException("Invalid element."); + } + mRS = rs; mEntries = new Entry[4]; mElement = e; } public void add(Dimension d, int value) { + if(value < 1) { + throw new IllegalArgumentException("Values of less than 1 for Dimensions are not valid."); + } if(mEntries.length >= mEntryCount) { Entry[] en = new Entry[mEntryCount + 8]; System.arraycopy(mEntries, 0, en, 0, mEntries.length); diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java index cee827b32c819..b5b6723be1799 100644 --- a/libs/rs/java/Film/src/com/android/film/FilmRS.java +++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java @@ -152,9 +152,9 @@ public class FilmRS { mBufferIDs = new int[13]; mImages = new Allocation[13]; mAllocIDs = Allocation.createSized(mRS, - Element.USER_FLOAT, mBufferIDs.length); + Element.USER_F32(mRS), mBufferIDs.length); - Element ie = Element.RGB_565; + Element ie = Element.RGB_565(mRS); mImages[0] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p01, ie, true); mImages[1] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p02, ie, true); mImages[2] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p03, ie, true); @@ -195,7 +195,7 @@ public class FilmRS { { mBufferState = new int[10]; mAllocState = Allocation.createSized(mRS, - Element.USER_FLOAT, mBufferState.length); + Element.USER_F32(mRS), mBufferState.length); mBufferState[STATE_LAST_FOCUS] = -1; mAllocState.data(mBufferState); } @@ -238,12 +238,12 @@ public class FilmRS { mAllocOffsets = Allocation.createSized(mRS, - Element.USER_I32, mFSM.mTriangleOffsets.length); + Element.USER_I32(mRS), mFSM.mTriangleOffsets.length); mAllocOffsets.data(mFSM.mTriangleOffsets); mScriptStrip.bindAllocation(mAllocOffsets, 4); mAllocOffsetsTex = Allocation.createSized(mRS, - Element.USER_FLOAT, mFSM.mTriangleOffsetsTex.length); + Element.USER_F32(mRS), mFSM.mTriangleOffsetsTex.length); mAllocOffsetsTex.data(mFSM.mTriangleOffsetsTex); mScriptStrip.bindAllocation(mAllocOffsetsTex, 5); diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java index ba74b587f5410..ff89bc3e5ecbe 100644 --- a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java +++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java @@ -182,7 +182,7 @@ public class RolloRS { mAllocScratchBuf = new int[32]; mAllocScratch = Allocation.createSized(mRS, - Element.USER_I32, mAllocScratchBuf.length); + Element.USER_I32(mRS), mAllocScratchBuf.length); mAllocScratch.data(mAllocScratchBuf); Log.e("rs", "Done loading named"); @@ -193,14 +193,14 @@ public class RolloRS { mIcons = new Allocation[29]; mAllocIconIDBuf = new int[mIcons.length]; mAllocIconID = Allocation.createSized(mRS, - Element.USER_I32, mAllocIconIDBuf.length); + Element.USER_I32(mRS), mAllocIconIDBuf.length); mLabels = new Allocation[29]; mAllocLabelIDBuf = new int[mLabels.length]; mAllocLabelID = Allocation.createSized(mRS, - Element.USER_I32, mLabels.length); + Element.USER_I32(mRS), mLabels.length); - Element ie8888 = Element.RGBA_8888; + Element ie8888 = Element.RGBA_8888(mRS); mIcons[0] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.browser, ie8888, true); mIcons[1] = Allocation.createFromBitmapResource(mRS, mRes, R.raw.market, ie8888, true); @@ -284,7 +284,7 @@ public class RolloRS { p.setTextSize(20); p.setColor(0xffffffff); c.drawText(t, 2, 26, p); - return Allocation.createFromBitmap(mRS, b, Element.RGBA_8888, true); + return Allocation.createFromBitmap(mRS, b, Element.RGBA_8888(mRS), true); } @@ -298,7 +298,7 @@ public class RolloRS { mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, -1, 0, mAllocIconIDBuf.length, 0, 0}; mAllocState = Allocation.createSized(mRS, - Element.USER_I32, mAllocStateBuf.length); + Element.USER_I32(mRS), mAllocStateBuf.length); mScript.bindAllocation(mAllocState, 0); mScript.bindAllocation(mAllocIconID, 1); mScript.bindAllocation(mAllocScratch, 2); diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 8ee6e5a453247..8ac9c26a2f37f 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -141,6 +141,7 @@ void Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32 if (size != sizeBytes) { LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes); + mType->dumpLOGV("type info"); return; } memcpy(ptr, data, size); diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp index 42e2e4fbf2299..de074c8ce664e 100644 --- a/libs/rs/rsComponent.cpp +++ b/libs/rs/rsComponent.cpp @@ -102,4 +102,9 @@ uint32_t Component::getGLType() const return 0; } +void Component::dumpLOGV(const char *prefix) const +{ + ObjectBase::dumpLOGV(prefix); + LOGV("%s component: %i %i %i %i", prefix, mType, mKind, mIsNormalized, mBits); +} diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h index 290cd57e3ab33..5366cc429e96b 100644 --- a/libs/rs/rsComponent.h +++ b/libs/rs/rsComponent.h @@ -56,6 +56,7 @@ public: const char * getCType() const; const char * getComponentName() const {return mName.string();} + virtual void dumpLOGV(const char *prefix) const; protected: diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp index a00fb52171285..67e4f1401066b 100644 --- a/libs/rs/rsElement.cpp +++ b/libs/rs/rsElement.cpp @@ -55,6 +55,8 @@ void Element::setComponent(uint32_t idx, Component *c) rsAssert(!mComponents[idx].get()); rsAssert(idx < mComponentCount); mComponents[idx].set(c); + +// Fixme: This should probably not be here c->incUserRef(); } @@ -179,6 +181,17 @@ uint32_t Element::getGLFormat() const } +void Element::dumpLOGV(const char *prefix) const +{ + ObjectBase::dumpLOGV(prefix); + LOGV("%s Element: components %i, size %i", prefix, mComponentCount, getSizeBytes()); + for (uint32_t ct = 0; ct < mComponentCount; ct++) { + char buf[1024]; + sprintf(buf, "%s component %i: ", prefix, ct); + mComponents[ct]->dumpLOGV(buf); + } +} + ElementState::ElementState() { } @@ -201,6 +214,9 @@ void rsi_ElementBegin(Context *rsc) void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name) { ElementState * sec = &rsc->mStateElement; + + rsAssert(bits > 0); + Component *c = new Component(rsc, static_cast(dk), static_cast(dt), @@ -215,6 +231,8 @@ RsElement rsi_ElementCreate(Context *rsc) ElementState * sec = &rsc->mStateElement; Element *se = new Element(rsc, sec->mComponentBuildList.size()); + rsAssert(se->getComponentCount() > 0); + for (size_t ct = 0; ct < se->getComponentCount(); ct++) { se->setComponent(ct, sec->mComponentBuildList[ct]); } diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h index 82da4417c9b10..b41c552d17c08 100644 --- a/libs/rs/rsElement.h +++ b/libs/rs/rsElement.h @@ -51,6 +51,9 @@ public: uint32_t getComponentCount() const {return mComponentCount;} Component * getComponent(uint32_t idx) const {return mComponents[idx].get();} + + void dumpLOGV(const char *prefix) const; + protected: // deallocate any components that are part of this element. void clear(); diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp index 720e8fccc4972..0008ea47c222b 100644 --- a/libs/rs/rsObjectBase.cpp +++ b/libs/rs/rsObjectBase.cpp @@ -41,7 +41,7 @@ ObjectBase::~ObjectBase() remove(); } -void ObjectBase::dumpObj(const char *op) const +void ObjectBase::dumpLOGV(const char *op) const { if (mName) { LOGV("%s RSobj %p, name %s, refs %i,%i from %s,%i links %p,%p,%p", @@ -79,7 +79,7 @@ bool ObjectBase::checkDelete() const { if (!(mSysRefCount | mUserRefCount)) { if (mRSC && mRSC->props.mLogObjects) { - dumpObj("checkDelete"); + dumpLOGV("checkDelete"); } delete this; return true; @@ -188,7 +188,7 @@ void ObjectBase::zeroAllUserRef(Context *rsc) LOGV("Objects remaining."); o = rsc->mObjHead; while (o) { - o->dumpObj(" "); + o->dumpLOGV(" "); o = o->mNext; } } diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h index ea5e37cc0eaaa..dc85ac7b21e39 100644 --- a/libs/rs/rsObjectBase.h +++ b/libs/rs/rsObjectBase.h @@ -50,7 +50,7 @@ public: static void zeroAllUserRef(Context *rsc); - void dumpObj(const char *op) const; + virtual void dumpLOGV(const char *prefix) const; protected: const char *mAllocFile; diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp index 5ce9ca2341ef7..ddaa2f0e14262 100644 --- a/libs/rs/rsType.cpp +++ b/libs/rs/rsType.cpp @@ -302,6 +302,16 @@ void Type::enableGLVertexBuffer() const } +void Type::dumpLOGV(const char *prefix) const +{ + char buf[1024]; + ObjectBase::dumpLOGV(prefix); + LOGV("%s Type: x=%i y=%i z=%i mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces); + sprintf(buf, "%s element: ", prefix); + mElement->dumpLOGV(buf); +} + + ////////////////////////////////////////////////// // namespace android { diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h index 116f1c74d6012..2c43405122ba0 100644 --- a/libs/rs/rsType.h +++ b/libs/rs/rsType.h @@ -69,6 +69,7 @@ public: void enableGLVertexBuffer() const; + void dumpLOGV(const char *prefix) const; protected: struct LOD { diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp index 19867a519a791..caf9bec767fd1 100644 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ b/libs/surfaceflinger/BufferAllocator.cpp @@ -102,6 +102,10 @@ status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, rec.vaddr = 0; rec.size = h * stride[0] * bytesPerPixel(format); list.add(*handle, rec); + } else { + String8 s; + dump(s); + LOGD("%s", s.string()); } return err; diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 065425d9f8577..4ee176c92a563 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -491,7 +491,7 @@ bool SurfaceFlinger::threadLoop() handlePageFlip(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); - if (LIKELY(hw.canDraw())) { + if (LIKELY(hw.canDraw() && !isFrozen())) { // repaint the framebuffer (if needed) handleRepaint(); @@ -512,14 +512,6 @@ bool SurfaceFlinger::threadLoop() void SurfaceFlinger::postFramebuffer() { - if (isFrozen()) { - // we are not allowed to draw, but pause a bit to make sure - // apps don't end up using the whole CPU, if they depend on - // surfaceflinger for synchronization. - usleep(8333); // 8.3ms ~ 120fps - return; - } - if (!mInvalidRegion.isEmpty()) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const nsecs_t now = systemTime(); diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index a5a8cc953e61c..872b2bc70f556 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -1743,7 +1743,7 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const if (Res_GETPACKAGE(resID)+1 == 0) { LOGW("No package identifier when getting name for resource number 0x%08x", resID); } else { - LOGW("Resources don't contain pacakge for resource number 0x%08x", resID); + LOGW("Resources don't contain package for resource number 0x%08x", resID); } return false; } @@ -1793,7 +1793,7 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag if (Res_GETPACKAGE(resID)+1 == 0) { LOGW("No package identifier when getting name for resource number 0x%08x", resID); } else { - LOGW("Resources don't contain pacakge for resource number 0x%08x", resID); + LOGW("Resources don't contain package for resource number 0x%08x", resID); } return BAD_INDEX; } diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java index 03ffc6764dfb9..8180a7cfbc30e 100644 --- a/media/java/android/media/MediaFile.java +++ b/media/java/android/media/MediaFile.java @@ -17,6 +17,7 @@ package android.media; import android.content.ContentValues; +import android.os.SystemProperties; import android.provider.MediaStore.Audio; import android.provider.MediaStore.Images; import android.provider.MediaStore.Video; @@ -103,7 +104,9 @@ public class MediaFile { addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav"); addFileType("AMR", FILE_TYPE_AMR, "audio/amr"); addFileType("AWB", FILE_TYPE_AWB, "audio/amr-wb"); - addFileType("WMA", FILE_TYPE_WMA, "audio/x-ms-wma"); + if (SystemProperties.getInt("ro.media.dec.aud.wma.enabled", 0) != 0) { + addFileType("WMA", FILE_TYPE_WMA, "audio/x-ms-wma"); + } addFileType("OGG", FILE_TYPE_OGG, "application/ogg"); addFileType("OGA", FILE_TYPE_OGG, "application/ogg"); addFileType("AAC", FILE_TYPE_AAC, "audio/aac"); @@ -123,8 +126,10 @@ public class MediaFile { addFileType("3GPP", FILE_TYPE_3GPP, "video/3gpp"); addFileType("3G2", FILE_TYPE_3GPP2, "video/3gpp2"); addFileType("3GPP2", FILE_TYPE_3GPP2, "video/3gpp2"); - addFileType("WMV", FILE_TYPE_WMV, "video/x-ms-wmv"); - addFileType("ASF", FILE_TYPE_ASF, "video/x-ms-asf"); + if (SystemProperties.getInt("ro.media.dec.vid.wmv.enabled", 0) != 0) { + addFileType("WMV", FILE_TYPE_WMV, "video/x-ms-wmv"); + addFileType("ASF", FILE_TYPE_ASF, "video/x-ms-asf"); + } addFileType("JPG", FILE_TYPE_JPEG, "image/jpeg"); addFileType("JPEG", FILE_TYPE_JPEG, "image/jpeg"); diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 21ad82badb692..3a3ae5f208bbf 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -1273,7 +1273,8 @@ public class MediaScanner } } - if (bestMatch == null) { + // if the match is not for an audio file, bail out + if (bestMatch == null || ! mAudioUri.equals(bestMatch.mTableUri)) { return false; } diff --git a/media/java/android/media/MiniThumbFile.java b/media/java/android/media/MiniThumbFile.java index c607218a2dc56..def0288c75094 100644 --- a/media/java/android/media/MiniThumbFile.java +++ b/media/java/android/media/MiniThumbFile.java @@ -215,7 +215,6 @@ public class MiniThumbFile { r.write(data); r.seek(pos); r.writeByte(1); // we have data in this slot - mChannel.force(true); } } catch (IOException ex) { Log.e(TAG, "couldn't save mini thumbnail data for " diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 9c0f7fd41f1ed..37628b7ea0d7d 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -952,7 +952,8 @@ static config_pair_t const config_base_attribute_list[] = { { EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE }, { EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE }, { EGL_MIN_SWAP_INTERVAL, 1 }, - { EGL_MAX_SWAP_INTERVAL, 4 }, + { EGL_MAX_SWAP_INTERVAL, 1 }, + { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT }, }; // These configs can override the base attribute list diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java index 77da8f1ee2bc9..3b91a383adb9c 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java @@ -40,16 +40,23 @@ public class SettingsHelper { private Context mContext; private AudioManager mAudioManager; private IContentService mContentService; + private IPowerManager mPowerManager; private static final String[] PROVIDERS = { "gmail-ls", "calendar", "contacts" }; private boolean mSilent; private boolean mVibrate; + private boolean mHasAutoBrightness; public SettingsHelper(Context context) { mContext = context; mAudioManager = (AudioManager) context .getSystemService(Context.AUDIO_SERVICE); mContentService = ContentResolver.getContentService(); + mPowerManager = IPowerManager.Stub.asInterface( + ServiceManager.getService("power")); + + mHasAutoBrightness = context.getResources().getBoolean( + com.android.internal.R.bool.config_automatic_brightness_available); } /** @@ -64,6 +71,18 @@ public class SettingsHelper { public boolean restoreValue(String name, String value) { if (Settings.System.SCREEN_BRIGHTNESS.equals(name)) { setBrightness(Integer.parseInt(value)); + } else if (Settings.System.SCREEN_BRIGHTNESS_MODE.equals(name)) { + if (mHasAutoBrightness) { + // When setting auto-brightness, must reset the brightness afterwards + try { + int curBrightness = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS); + setAutoBrightness(Integer.parseInt(value) != 0); + setBrightness(curBrightness); + } catch (Settings.SettingNotFoundException e) { + // no brightness setting at all? weird. skip this then. + } + } } else if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) { setSoundEffects(Integer.parseInt(value) == 1); } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) { @@ -73,6 +92,16 @@ public class SettingsHelper { return true; } + private void setAutoBrightness(boolean value) { + if (mPowerManager != null) { + try { + mPowerManager.setAutoBrightness(value); + } catch (RemoteException e) { + // unable to reach the power manager; skip + } + } + } + private void setGpsLocation(String value) { final String GPS = LocationManager.GPS_PROVIDER; boolean enabled = diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java index 53edf31a20395..bb369366837db 100644 --- a/services/java/com/android/server/BatteryService.java +++ b/services/java/com/android/server/BatteryService.java @@ -90,9 +90,6 @@ class BatteryService extends Binder { // This should probably be exposed in the API, though it's not critical private static final int BATTERY_PLUGGED_NONE = 0; - private static final int BATTERY_LEVEL_CLOSE_WARNING = 20; - private static final int BATTERY_LEVEL_WARNING = 15; - private final Context mContext; private final IBatteryStats mBatteryStats; @@ -114,7 +111,10 @@ class BatteryService extends Binder { private int mLastBatteryVoltage; private int mLastBatteryTemperature; private boolean mLastBatteryLevelCritical; - + + private int mLowBatteryWarningLevel; + private int mLowBatteryCloseWarningLevel; + private int mPlugType; private int mLastPlugType = -1; // Extra state so we can detect first run @@ -127,6 +127,11 @@ class BatteryService extends Binder { mContext = context; mBatteryStats = BatteryStatsService.getService(); + mLowBatteryWarningLevel = mContext.getResources().getInteger( + com.android.internal.R.integer.config_lowBatteryWarningLevel); + mLowBatteryCloseWarningLevel = mContext.getResources().getInteger( + com.android.internal.R.integer.config_lowBatteryCloseWarningLevel); + mUEventObserver.startObserving("SUBSYSTEM=power_supply"); // set initial status @@ -271,13 +276,15 @@ class BatteryService extends Binder { final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE; /* The ACTION_BATTERY_LOW broadcast is sent in these situations: - * - is just un-plugged (previously was plugged) and battery level is under WARNING, or - * - is not plugged and battery level crosses the WARNING boundary (becomes < 15). + * - is just un-plugged (previously was plugged) and battery level is + * less than or equal to WARNING, or + * - is not plugged and battery level falls to WARNING boundary + * (becomes <= mLowBatteryWarningLevel). */ final boolean sendBatteryLow = !plugged && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN - && mBatteryLevel < BATTERY_LEVEL_WARNING - && (oldPlugged || mLastBatteryLevel >= BATTERY_LEVEL_WARNING); + && mBatteryLevel <= mLowBatteryWarningLevel + && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel); sendIntent(); @@ -299,7 +306,7 @@ class BatteryService extends Binder { mSentLowBatteryBroadcast = true; statusIntent.setAction(Intent.ACTION_BATTERY_LOW); mContext.sendBroadcast(statusIntent); - } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= BATTERY_LEVEL_CLOSE_WARNING) { + } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) { mSentLowBatteryBroadcast = false; statusIntent.setAction(Intent.ACTION_BATTERY_OKAY); mContext.sendBroadcast(statusIntent); diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java index da64e54393cd3..6570bcdd495b3 100644 --- a/services/java/com/android/server/status/StatusBarPolicy.java +++ b/services/java/com/android/server/status/StatusBarPolicy.java @@ -670,11 +670,9 @@ public class StatusBarPolicy { private void showLowBatteryWarning() { closeLastBatteryView(); - /* Show exact battery level. - * Add 1 because the text says "less than X%". - */ + // Show exact battery level. CharSequence levelText = mContext.getString( - com.android.internal.R.string.battery_low_percent_format, mBatteryLevel + 1); + com.android.internal.R.string.battery_low_percent_format, mBatteryLevel); if (mBatteryLevelTextView != null) { mBatteryLevelTextView.setText(levelText); diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java index 861e37be3e2b2..32763b3a6ba7e 100644 --- a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java +++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java @@ -21,7 +21,7 @@ public class PowerMeasurement extends ActivityInstrumentationTestCase2